diff --git a/src/struphy/console/compile.py b/src/struphy/console/compile.py index 8992b02e5..6878c9304 100644 --- a/src/struphy/console/compile.py +++ b/src/struphy/console/compile.py @@ -89,7 +89,6 @@ def struphy_compile( and ".py" in file and "_tmp.py" not in file and "test" not in file - and "legacy" not in subdir and "__pycache__" not in subdir ): state["kernels"] += [os.path.join(subdir, file)] diff --git a/src/struphy/diagnostics/continuous_spectra.py b/src/struphy/diagnostics/continuous_spectra.py deleted file mode 100644 index c31d789c7..000000000 --- a/src/struphy/diagnostics/continuous_spectra.py +++ /dev/null @@ -1,368 +0,0 @@ -def get_mhd_continua_2d(space, domain, omega2, U_eig, m_range, omega_A, div_tol, comp_sound): - """ - Get the eigenfrequencies omega^2/omega_A^2 in the range (0, 1) sorted by shear Alfvén modes and slow sound modes. - - Parameters - ---------- - space : struphy.eigenvalue_solvers.spline_space.Tensor_spline_space - 2d finite element B-spline space. - - domain : struphy.geometry.base.Domain - The domain in which the eigenvalue problem has been solved. - - omega2 : array-like - Eigenfrequencies obtained from eigenvalue solver. - - U_eig : array-like - Eigenvectors obtained from eigenvalue solver. - - m_range : list - Range of poloidal mode numbers that shall be identified. - - omega_A : float - On-axis Alfvén frequency B0/R0. - - div_tol : float - Threshold for the maximum divergence of an eigenmode below which it is considered to be an Alfvénic mode. - - comp_sound : int - The component that is used for the slow sound mode analysis (2 : 2nd component or 3 : third component). - - Returns - ------- - a_spec : list of 2d numpy arrays - the radial location a_spec[m][0], squared eigenfrequencis a_spec[m][1] and global mode index a_spec[m][2] corresponding to shear Alfvén modes for each poloidal mode number m in m_range. - - s_spec : list of 2d numpy arrays - the radial location s_spec[m][0], squared eigenfrequencis s_spec[m][1] and global mode index s_spec[m][2] corresponding to slow sound modes for each poloidal mode number m in m_range. - """ - - import cunumpy as xp - - import struphy.bsplines.bsplines as bsp - - # greville points in radial direction (s) - gN_1 = bsp.greville(space.T[0], space.p[0], space.spl_kind[0]) - gD_1 = bsp.greville(space.t[0], space.p[0] - 1, space.spl_kind[0]) - - # greville points in angular direction (chi) - gN_2 = bsp.greville(space.T[1], space.p[1], space.spl_kind[1]) - gD_2 = bsp.greville(space.t[1], space.p[1] - 1, space.spl_kind[1]) - - # poloidal mode numbers - ms = xp.arange(m_range[1] - m_range[0] + 1) + m_range[0] - - # grid for normalized Jacobian determinant - det_df = domain.jacobian_det(gD_1, gD_2, 0.0) - - # remove singularity for polar domains - if domain.pole: - det_df = det_df[1:, :] - - det_df_norm = det_df / det_df.max() - - # Alfvén and sound spectra (location, squared frequency, mode number) - a_spec = [[[], [], []] for m in ms] - s_spec = [[[], [], []] for m in ms] - - # only consider eigenmodes in range omega^2/omega_A^2 = [0, 1] - modes_ind = xp.where((xp.real(omega2) / omega_A**2 < 1.0) & (xp.real(omega2) / omega_A**2 > 0.0))[0] - - for i in range(modes_ind.size): - # determine whether it's an Alfvén branch or sound branch by checking DIV(U) - if space.ck == 0: - divU = space.D0.dot(U_eig[:, modes_ind[i]])[space.NbaseD[1] :] - else: - divU = space.D0.dot(U_eig[:, modes_ind[i]]) - - # Alfvén branch - if abs(divU / det_df_norm.flatten()).max() < div_tol: - # get FEM coefficients (1st component) - U2_1_coeff = space.extract_2(U_eig[:, modes_ind[i]])[0] - - if space.basis_tor == "i": - U2_1_coeff = U2_1_coeff[:, :, 0] - else: - U2_1_coeff = (U2_1_coeff[:, :, 0] - 1j * U2_1_coeff[:, :, 1]) / 2 - - # determine radial location of singularity by looking for a peak in eigenfunction U2_1 - s_ind = xp.unravel_index(xp.argmax(abs(U2_1_coeff)), U2_1_coeff.shape)[0] - s = gN_1[s_ind] - - # perform fft to determine m - U2_1_fft = xp.fft.fft(U2_1_coeff) - - # determine m by looking for peak in Fourier spectrum at singularity - m = int((xp.fft.fftfreq(U2_1_fft[s_ind].size) * U2_1_fft[s_ind].size)[xp.argmax(abs(U2_1_fft[s_ind]))]) - - ## perform shift for negative m - # if m >= (space.Nel[1] + 1)//2: - # m -= space.Nel[1] - - # add to spectrum if found m is inside m_range - for j in range(ms.size): - if ms[j] == m: - a_spec[j][0].append(s) - a_spec[j][1].append(xp.real(omega2[modes_ind[i]])) - a_spec[j][2].append(modes_ind[i]) - - # Sound branch - else: - # get FEM coefficients (2nd component or 3rd component) - U2_coeff = space.extract_2(U_eig[:, modes_ind[i]])[comp_sound - 1] - - if space.basis_tor == "i": - U2_coeff = U2_coeff[:, :, 0] - else: - U2_coeff = (U2_coeff[:, :, 0] - 1j * U2_coeff[:, :, 1]) / 2 - - # determine radial location of singularity by looking for a peak in eigenfunction (U2_2 or U2_3) - s_ind = xp.unravel_index(xp.argmax(abs(U2_coeff)), U2_coeff.shape)[0] - s = gD_1[s_ind] - - # perform fft to determine m - U2_fft = xp.fft.fft(U2_coeff) - - # determine m by looking for peak in Fourier spectrum at singularity - m = int((xp.fft.fftfreq(U2_fft[s_ind].size) * U2_fft[s_ind].size)[xp.argmax(abs(U2_fft[s_ind]))]) - - ## perform shift for negative m - # if m >= (space.Nel[1] + 1)//2: - # m -= space.Nel[1] - - # add to spectrum if found m is inside m_range - for j in range(ms.size): - if ms[j] == m: - s_spec[j][0].append(s) - s_spec[j][1].append(xp.real(omega2[modes_ind[i]])) - s_spec[j][2].append(modes_ind[i]) - - # convert to array - for j in range(ms.size): - a_spec[j] = xp.array(a_spec[j]) - s_spec[j] = xp.array(s_spec[j]) - - return a_spec, s_spec - - -# command line interface -if __name__ == "__main__": - import argparse - import glob - import os - import shutil - - import cunumpy as xp - import yaml - - # parse arguments - parser = argparse.ArgumentParser( - description="Looks for eigenmodes in a given MHD eigenspectrum in a certain poloidal mode number range and plots the continuous shear Alfvén and slow sound spectra (frequency versus radial-like coordinate).", - ) - - parser.add_argument("m_l_alfvén", type=int, help="lower bound of poloidal mode number range for Alfvénic modes") - - parser.add_argument("m_u_alfvén", type=int, help="upper bound of poloidal mode number range for Alfvénic modes") - - parser.add_argument("m_l_sound", type=int, help="lower bound of poloidal mode number range for slow sound modes") - - parser.add_argument("m_u_sound", type=int, help="upper bound of poloidal mode number range for slow sound modes") - - parser.add_argument("-n", "--name", type=str, metavar="FILE", help="name of .npy file to analyze", required=True) - - parser.add_argument( - "-i", - "--input", - type=str, - metavar="DIR", - help="directory with eigenspectrum (.npy) and parameter (.yml) file, relative to /struphy/io/out/ (default=sim_1)", - default="sim_1", - ) - - parser.add_argument( - "--input-abs", - type=str, - metavar="DIR", - help="directory with eigenspectrum (.npy) and parameter (.yml) file, absolute path", - ) - - parser.add_argument( - "-t", - "--tol", - type=float, - metavar="tol", - help="threshold for the maximum divergence of an eigenmode below which it is considered to be an Alfvénic mode (default=0.05)", - default=0.05, - ) - - parser.add_argument( - "-c", - "--comp-sound", - type=int, - metavar="n", - help="the component that is used for the slow sound mode analysis (2 : 2nd component or 3 : 3rd component, default=3)", - default=3, - ) - - args = parser.parse_args() - - import struphy.utils.utils as utils - - # Read struphy state file - state = utils.read_state() - - o_path = state["o_path"] - - # create absolute input folder path - if args.input_abs is None: - input_path = os.path.join(o_path, args.input) - else: - input_path = args.input_abs - - # absolute path of .npy spectrum and toroidal mode number - spec_path = os.path.join(input_path, args.name) - n_tor = int(os.path.split(spec_path)[-1][-6:-4]) - - # load parameter file - with open(os.path.join(input_path, "parameters.yml")) as file: - params = yaml.load(file, Loader=yaml.FullLoader) - - # create domain and MHD equilibrium - from struphy.io.setup import setup_domain_and_equil - - domain, mhd_equil = setup_domain_and_equil(params) - - # get MHD equilibrium parameters - for k, v in params["fluid_background"].items(): - params_mhd = v - - # set up spline spaces - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space - - print("Toroidal mode number : ", n_tor) - - Nel = params["grid"]["Nel"] - p = params["grid"]["p"] - spl_kind = params["grid"]["spl_kind"] - nq_el = params["grid"]["nq_el"] - dirichlet_bc = params["grid"]["dirichlet_bc"] - polar_ck = params["grid"]["polar_ck"] - - fem_1d_1 = Spline_space_1d(Nel[0], p[0], spl_kind[0], nq_el[0], dirichlet_bc[0]) - fem_1d_2 = Spline_space_1d(Nel[1], p[1], spl_kind[1], nq_el[1], dirichlet_bc[1]) - - fem_2d = Tensor_spline_space( - [fem_1d_1, fem_1d_2], - polar_ck, - domain.cx[:, :, 0], - domain.cy[:, :, 0], - n_tor=n_tor, - basis_tor="i", - ) - - # load and analyze spectrum - omega2, U2_eig = xp.split(xp.load(spec_path), [1], axis=0) - omega2 = omega2.flatten() - - m_range_alfven = [args.m_l_alfvén, args.m_u_alfvén] - m_range_sound = [args.m_l_sound, args.m_u_sound] - - omegaA = params_mhd["B0"] / params_mhd["R0"] - - A, S = get_mhd_continua_2d( - fem_2d, - domain, - omega2, - U2_eig, - [min(m_range_alfven[0], m_range_sound[0]), max(m_range_alfven[1], m_range_sound[1])], - omegaA, - args.tol, - args.comp_sound, - ) - - # plot results - import matplotlib.pyplot as plt - - fig, ax = plt.subplots(2, 3) - fig.set_figheight(12) - fig.set_figwidth(14) - - etaplot = [xp.linspace(0.0, 1.0, 201), xp.linspace(0.0, 1.0, 101)] - - etaplot[0][0] += 1e-5 - - xplot = domain(etaplot[0], etaplot[1], 0.0)[0] - yplot = domain(etaplot[0], etaplot[1], 0.0)[1] - - # plot equilibrium profiles for (s, chi=0) - ax[0, 0].plot(etaplot[0], mhd_equil.b2_3(etaplot[0], 0.0, 0.0) / mhd_equil.b2_2(etaplot[0], 0.0, 0.0)) - ax[0, 1].plot(etaplot[0], mhd_equil.p_xyz(xplot[:, 0], 0.0, 0.0).squeeze()) - ax[0, 2].plot(etaplot[0], mhd_equil.n_xyz(xplot[:, 0], 0.0, 0.0).squeeze()) - - ax[0, 0].set_xlabel("$s$") - ax[0, 1].set_xlabel("$s$") - ax[0, 2].set_xlabel("$s$") - - ax[0, 0].set_ylabel("$q$") - ax[0, 1].set_ylabel("$p$") - ax[0, 2].set_ylabel("$n$") - - ax[0, 0].set_title("Safety factor") - ax[0, 1].set_title("Pressure") - ax[0, 2].set_title("Number density") - - # plot grid - domain_name = domain.__class__.__name__ - - xgrid = domain(fem_2d.el_b[0], fem_2d.el_b[1], 0.0) - - if "Torus" in domain_name or domain_name == "GVECunit" or domain_name == "Tokamak": - for i in range(xgrid[0].shape[0]): - ax[1, 0].plot(xgrid[0][i, :], xgrid[2][i, :], "tab:blue", alpha=0.5) - - for i in range(xgrid[0].shape[1]): - ax[1, 0].plot(xgrid[0][:, i], xgrid[2][:, i], "tab:blue", alpha=0.5) - - ax[1, 0].set_xlabel("x [m]") - ax[1, 0].set_ylabel("z [m]") - - else: - for i in range(xgrid[0].shape[0]): - ax[1, 0].plot(xgrid[0][i, :], xgrid[1][i, :], "tab:blue", alpha=0.5) - - for i in range(xgrid[0].shape[1]): - ax[1, 0].plot(xgrid[0][:, i], xgrid[1][:, i], "tab:blue", alpha=0.5) - - ax[1, 0].set_xlabel("x [m]") - ax[1, 0].set_ylabel("y [m]") - - ax[1, 0].set_title(r"Grid : $N_\mathrm{el}=$" + str(fem_2d.Nel[:2]), pad=10) - - # plot shear Alfvén continuum in range omega^2 = [0, omega_A^2] - for m in range(m_range_alfven[0], m_range_alfven[1] + 1): - ax[1, 1].plot(A[m][0], A[m][1], "+", label="m = " + str(m)) - - ax[1, 1].set_xlabel("$s$") - ax[1, 1].set_ylabel(r"$\omega^2$") - ax[1, 1].set_xlim((0.0, 1.0)) - ax[1, 1].set_ylim((0.0, omegaA**2 + 0.02 * omegaA**2)) - ax[1, 1].legend(fontsize=8) - ax[1, 1].set_title("Shear Alfvén continuum", pad=10) - ax[1, 1].set_xticks([0.0, 0.5, 1.0]) - - # plot shear Alfvén continuum in given range % of omega_A - for m in range(m_range_sound[0], m_range_sound[1] + 1): - ax[1, 2].plot(S[m][0], S[m][1], "+", label="m = " + str(m)) - - ax[1, 2].set_xlabel("$s$") - ax[1, 2].set_ylabel(r"$\omega^2$") - ax[1, 2].set_xlim((0.0, 1.0)) - ax[1, 2].set_ylim((0.0, 0.1 * omegaA**2)) - ax[1, 2].legend(fontsize=8) - ax[1, 2].set_title("Slow sound continuum", pad=10) - ax[1, 2].set_xticks([0.0, 0.5, 1.0]) - # ========================================================================= - - plt.subplots_adjust(wspace=0.4) - plt.subplots_adjust(hspace=0.5) - plt.show() diff --git a/src/struphy/eigenvalue_solvers/__init__.py b/src/struphy/eigenvalue_solvers/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/struphy/eigenvalue_solvers/derivatives.py b/src/struphy/eigenvalue_solvers/derivatives.py deleted file mode 100644 index 0e34cceb1..000000000 --- a/src/struphy/eigenvalue_solvers/derivatives.py +++ /dev/null @@ -1,164 +0,0 @@ -# coding: utf-8 -# -# Copyright 2021 Florian Holderied - -""" -Modules to assemble discrete derivatives. -""" - -import cunumpy as xp -import scipy.sparse as spa - - -# ================== 1d incident matrix ======================= -def grad_1d_matrix(spl_kind, NbaseN): - """ - Returns the 1d strong discrete gradient matrix (V0 --> V1) corresponding either periodic or clamped B-splines (without boundary conditions). - - Parameters - ---------- - spl_kind : boolean - periodic (True) or clamped (False) B-splines - - NbaseN : int - total number of basis functions in V0 - - Returns - ------- - grad : array_like - strong discrete gradient matrix - """ - - NbaseD = NbaseN - 1 + spl_kind - - grad = xp.zeros((NbaseD, NbaseN), dtype=float) - - for i in range(NbaseD): - grad[i, i] = -1.0 - grad[i, (i + 1) % NbaseN] = 1.0 - - return grad - - -# ===== discrete derivatives in one dimension ================= -def discrete_derivatives_1d(space): - """ - Returns discrete derivatives for a 1d B-spline space. - - Parameters - ---------- - space : spline_space_1d - 1d B-splines space - """ - - # 1D discrete derivative (full space) - G = spa.csr_matrix(grad_1d_matrix(space.spl_kind, space.NbaseN)) - - # apply boundary operators (reduced space) - G0 = space.B1.dot(G.dot(space.B0.T)) - - return G, G0 - - -# ===== discrete derivatives in three dimensions ============== -def discrete_derivatives_3d(space): - """ - Returns discrete derivatives for 2d and 3d B-spline spaces. - - Parameters - ---------- - space : tensor_spline_space - 2d or 3d tensor-product B-splines space - """ - - # discrete derivative in 3rd dimension - if space.dim == 3: - grad_1d_3 = space.spaces[2].G.copy() - else: - if space.n_tor == 0: - grad_1d_3 = 0 * spa.identity(1, format="csr") - else: - if space.basis_tor == "r": - grad_1d_3 = 2 * xp.pi * space.n_tor * spa.csr_matrix(xp.array([[0.0, 1.0], [-1.0, 0.0]])) - else: - grad_1d_3 = 1j * 2 * xp.pi * space.n_tor * spa.identity(1, format="csr") - - # standard tensor-product derivatives - if space.ck == -1: - # 1d derivatives and number of degrees of freedom in each direction - grad_1d_1 = space.spaces[0].G.copy() - grad_1d_2 = space.spaces[1].G.copy() - - n1 = grad_1d_1.shape[1] - n2 = grad_1d_2.shape[1] - n3 = grad_1d_3.shape[1] - - d1 = grad_1d_1.shape[0] - d2 = grad_1d_2.shape[0] - d3 = grad_1d_3.shape[0] - - # discrete grad (full space) - G1 = spa.kron(spa.kron(grad_1d_1, spa.identity(n2)), spa.identity(n3)) - G2 = spa.kron(spa.kron(spa.identity(n1), grad_1d_2), spa.identity(n3)) - G3 = spa.kron(spa.kron(spa.identity(n1), spa.identity(n2)), grad_1d_3) - - G = [[G1], [G2], [G3]] - G = spa.bmat(G, format="csr") - - # discrete curl (full space) - C12 = spa.kron(spa.kron(spa.identity(n1), spa.identity(d2)), grad_1d_3) - C13 = spa.kron(spa.kron(spa.identity(n1), grad_1d_2), spa.identity(d3)) - - C21 = spa.kron(spa.kron(spa.identity(d1), spa.identity(n2)), grad_1d_3) - C23 = spa.kron(spa.kron(grad_1d_1, spa.identity(n2)), spa.identity(d3)) - - C31 = spa.kron(spa.kron(spa.identity(d1), grad_1d_2), spa.identity(n3)) - C32 = spa.kron(spa.kron(grad_1d_1, spa.identity(d2)), spa.identity(n3)) - - C = [[None, -C12, C13], [C21, None, -C23], [-C31, C32, None]] - C = spa.bmat(C, format="csr") - - # discrete div (full space) - D1 = spa.kron(spa.kron(grad_1d_1, spa.identity(d2)), spa.identity(d3)) - D2 = spa.kron(spa.kron(spa.identity(d1), grad_1d_2), spa.identity(d3)) - D3 = spa.kron(spa.kron(spa.identity(d1), spa.identity(d2)), grad_1d_3) - - D = [[D1, D2, D3]] - D = spa.bmat(D, format="csr") - - # C^k polar derivatives - else: - # discrete grad (full space) - G1 = spa.kron(space.polar_splines.G1.copy(), spa.identity(grad_1d_3.shape[1])) - G2 = spa.kron(space.polar_splines.G2.copy(), spa.identity(grad_1d_3.shape[1])) - G3 = spa.kron(spa.identity(space.polar_splines.Nbase0), grad_1d_3) - - G = [[G1], [G2], [G3]] - G = spa.bmat(G, format="csr") - - # discrete curl (full space) - C12 = spa.kron(space.polar_splines.VC.copy(), spa.identity(grad_1d_3.shape[0])) - C21 = spa.kron(space.polar_splines.SC.copy(), spa.identity(grad_1d_3.shape[1])) - - C11_12 = -spa.kron(spa.identity(space.polar_splines.Nbase1C_2), grad_1d_3) - C11_21 = spa.kron(spa.identity(space.polar_splines.Nbase1C_1), grad_1d_3) - - C11 = spa.bmat([[None, C11_12], [C11_21, None]]) - - C = [[C11, C12], [C21, None]] - C = spa.bmat(C, format="csr") - - # discrete div (full space) - D1 = spa.kron(space.polar_splines.D1.copy(), spa.identity(grad_1d_3.shape[0])) - D2 = spa.kron(space.polar_splines.D2.copy(), spa.identity(grad_1d_3.shape[0])) - D3 = spa.kron(spa.identity(space.polar_splines.Nbase2), grad_1d_3) - - D = [[D1, D2, D3]] - D = spa.bmat(D, format="csr") - - # apply boundary operators - G0 = space.B1.dot(G.dot(space.B0.T)) - C0 = space.B2.dot(C.dot(space.B1.T)) - D0 = space.B3.dot(D.dot(space.B2.T)) - - return G, G0, C, C0, D, D0 diff --git a/src/struphy/eigenvalue_solvers/kernels_2d.py b/src/struphy/eigenvalue_solvers/kernels_2d.py deleted file mode 100644 index 5f86a40a0..000000000 --- a/src/struphy/eigenvalue_solvers/kernels_2d.py +++ /dev/null @@ -1,182 +0,0 @@ -# coding: utf-8 - -from pyccel.decorators import pure - - -def kernel_mass( - nel: "int[:]", - p: "int[:]", - nq: "int[:]", - ni: "int[:]", - nj: "int[:]", - w1: "float[:,:]", - w2: "float[:,:]", - bi1: "float[:,:,:,:]", - bi2: "float[:,:,:,:]", - bj1: "float[:,:,:,:]", - bj2: "float[:,:,:,:]", - ind_base1: "int[:,:]", - ind_base2: "int[:,:]", - mat: "float[:,:,:,:]", - mat_fun: "float[:,:,:,:]", -): - mat[:, :, :, :] = 0.0 - - # -- removed omp: #$ omp parallel private(ie1, ie2, il1, il2, jl1, jl2, value1, q1, q2, wvol, bi, bj) shared(mat) - # -- removed omp: #$ omp for reduction ( + : mat) - for ie1 in range(nel[0]): - for ie2 in range(nel[1]): - for il1 in range(p[0] + 1 - ni[0]): - for il2 in range(p[1] + 1 - ni[1]): - for jl1 in range(p[0] + 1 - nj[0]): - for jl2 in range(p[1] + 1 - nj[1]): - value1 = 0.0 - - for q1 in range(nq[0]): - for q2 in range(nq[1]): - wvol = w1[ie1, q1] * w2[ie2, q2] * mat_fun[ie1, q1, ie2, q2] - bi = bi1[ie1, il1, 0, q1] * bi2[ie2, il2, 0, q2] - bj = bj1[ie1, jl1, 0, q1] * bj2[ie2, jl2, 0, q2] - - value1 += wvol * bi * bj - - mat[ind_base1[ie1, il1], ind_base2[ie2, il2], p[0] + jl1 - il1, p[1] + jl2 - il2] += value1 - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -def kernel_inner( - nel: "int[:]", - n3: "int", - p: "int[:]", - nq: "int[:]", - ni: "int[:]", - w1: "float[:,:]", - w2: "float[:,:]", - bi1: "float[:,:,:,:]", - bi2: "float[:,:,:,:]", - ind_base1: "int[:,:]", - ind_base2: "int[:,:]", - mat: "float[:,:,:]", - mat_fun: "float[:,:,:,:,:]", -): - mat[:, :, :] = 0.0 - - # -- removed omp: #$ omp parallel private(ie1, ie2, ie3, il1, il2, value1, q1, q2, wvol, bi) shared(mat) - # -- removed omp: #$ omp for reduction ( + : mat) - for ie1 in range(nel[0]): - for ie2 in range(nel[1]): - for ie3 in range(n3): - for il1 in range(p[0] + 1 - ni[0]): - for il2 in range(p[1] + 1 - ni[1]): - value1 = 0.0 - - for q1 in range(nq[0]): - for q2 in range(nq[1]): - wvol = w1[ie1, q1] * w2[ie2, q2] * mat_fun[ie1, q1, ie2, q2, ie3] - bi = bi1[ie1, il1, 0, q1] * bi2[ie2, il2, 0, q2] - - value1 += wvol * bi - - mat[ind_base1[ie1, il1], ind_base2[ie2, il2], ie3] += value1 - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -def kernel_l2error( - nel: "int[:]", - p: "int[:]", - nq: "int[:]", - w1: "float[:,:]", - w2: "float[:,:]", - ni: "int[:]", - nj: "int[:]", - bi1: "float[:,:,:,:]", - bi2: "float[:,:,:,:]", - bj1: "float[:,:,:,:]", - bj2: "float[:,:,:,:]", - ind_basei1: "int[:,:]", - ind_basei2: "int[:,:]", - ind_basej1: "int[:,:]", - ind_basej2: "int[:,:]", - error: "float[:,:]", - mat_f1: "float[:,:,:,:]", - mat_f2: "float[:,:,:,:]", - c1: "float[:,:,:]", - c2: "float[:,:,:]", - mat_map: "float[:,:,:,:]", -): - # -- removed omp: #$ omp parallel private(ie1, ie2, q1, q2, wvol, bi, bj, il1, il2, jl1, jl2) - # -- removed omp: #$ omp for - for ie1 in range(nel[0]): - for ie2 in range(nel[1]): - # loop over quadrature points in element - for q1 in range(nq[0]): - for q2 in range(nq[1]): - wvol = w1[ie1, q1] * w2[ie2, q2] * mat_map[ie1, q1, ie2, q2] - - # evaluate discrete fields at quadrature point - bi = 0.0 - bj = 0.0 - - for il1 in range(p[0] + 1 - ni[0]): - for il2 in range(p[1] + 1 - ni[1]): - bi += ( - c1[ind_basei1[ie1, il1], ind_basei2[ie2, il2], 0] - * bi1[ie1, il1, 0, q1] - * bi2[ie2, il2, 0, q2] - ) - - for jl1 in range(p[0] + 1 - nj[0]): - for jl2 in range(p[1] + 1 - nj[1]): - bj += ( - c2[ind_basej1[ie1, jl1], ind_basej2[ie2, jl2], 0] - * bj1[ie1, jl1, 0, q1] - * bj2[ie2, jl2, 0, q2] - ) - - # compare this value to exact one and add contribution to error in element - error[ie1, ie2] += wvol * (bi - mat_f1[ie1, q1, ie2, q2]) * (bj - mat_f2[ie1, q1, ie2, q2]) - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -def kernel_evaluate_2form( - nel: "int[:]", - n3: "int", - p: "int[:]", - ns: "int[:]", - nq: "int[:]", - b_coeff: "float[:,:,:]", - ind_base1: "int[:,:]", - ind_base2: "int[:,:]", - bi1: "float[:,:,:,:]", - bi2: "float[:,:,:,:]", - b_eva: "float[:,:,:,:,:]", -): - b_eva[:, :, :, :, :] = 0.0 - - # -- removed omp: #$ omp parallel private(ie1, ie2, ie3, q1, q2, il1, il2) - # -- removed omp: #$ omp for - for ie1 in range(nel[0]): - for ie2 in range(nel[1]): - for ie3 in range(n3): - for q1 in range(nq[0]): - for q2 in range(nq[1]): - for il1 in range(p[0] + 1 - ns[0]): - for il2 in range(p[1] + 1 - ns[1]): - b_eva[ie1, q1, ie2, q2, ie3] += ( - b_coeff[ - ind_base1[ie1, il1], - ind_base2[ie2, il2], - ie3, - ] - * bi1[ie1, il1, 0, q1] - * bi2[ie2, il2, 0, q2] - ) - # -- removed omp: #$ omp end parallel - - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/kernels_3d.py b/src/struphy/eigenvalue_solvers/kernels_3d.py deleted file mode 100644 index 0d47768a4..000000000 --- a/src/struphy/eigenvalue_solvers/kernels_3d.py +++ /dev/null @@ -1,234 +0,0 @@ -# coding: utf-8 -# -# Copyright 2021 Florian Holderied (florian.holderied@ipp.mpg.de) - - -def kernel_mass( - nel: "int[:]", - p: "int[:]", - nq: "int[:]", - ni: "int[:]", - nj: "int[:]", - w1: "float[:,:]", - w2: "float[:,:]", - w3: "float[:,:]", - bi1: "float[:,:,:,:]", - bi2: "float[:,:,:,:]", - bi3: "float[:,:,:,:]", - bj1: "float[:,:,:,:]", - bj2: "float[:,:,:,:]", - bj3: "float[:,:,:,:]", - ind_base1: "int[:,:]", - ind_base2: "int[:,:]", - ind_base3: "int[:,:]", - mat: "float[:,:,:,:,:,:]", - mat_fun: "float[:,:,:,:,:,:]", -): - mat[:, :, :, :, :, :] = 0.0 - - # -- removed omp: #$ omp parallel private(ie1, ie2, ie3, il1, il2, il3, jl1, jl2, jl3, value1, q1, q2, q3, wvol, bi, bj) - # -- removed omp: #$ omp for reduction ( + : mat) - for ie1 in range(nel[0]): - for ie2 in range(nel[1]): - for ie3 in range(nel[2]): - for il1 in range(p[0] + 1 - ni[0]): - for il2 in range(p[1] + 1 - ni[1]): - for il3 in range(p[2] + 1 - ni[2]): - for jl1 in range(p[0] + 1 - nj[0]): - for jl2 in range(p[1] + 1 - nj[1]): - for jl3 in range(p[2] + 1 - nj[2]): - value1 = 0.0 - - for q1 in range(nq[0]): - for q2 in range(nq[1]): - for q3 in range(nq[2]): - wvol = ( - w1[ie1, q1] - * w2[ie2, q2] - * w3[ie3, q3] - * mat_fun[ie1, q1, ie2, q2, ie3, q3] - ) - bi = ( - bi1[ie1, il1, 0, q1] - * bi2[ie2, il2, 0, q2] - * bi3[ie3, il3, 0, q3] - ) - bj = ( - bj1[ie1, jl1, 0, q1] - * bj2[ie2, jl2, 0, q2] - * bj3[ie3, jl3, 0, q3] - ) - - value1 += wvol * bi * bj - - mat[ - ind_base1[ie1, il1], - ind_base2[ie2, il2], - ind_base3[ie3, il3], - p[0] + jl1 - il1, - p[1] + jl2 - il2, - p[2] + jl3 - il3, - ] += value1 - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -def kernel_inner( - nel: "int[:]", - p: "int[:]", - nq: "int[:]", - ni: "int[:]", - w1: "float[:,:]", - w2: "float[:,:]", - w3: "float[:,:]", - bi1: "float[:,:,:,:]", - bi2: "float[:,:,:,:]", - bi3: "float[:,:,:,:]", - ind_base1: "int[:,:]", - ind_base2: "int[:,:]", - ind_base3: "int[:,:]", - mat: "float[:,:,:]", - mat_fun: "float[:,:,:,:,:,:]", -): - mat[:, :, :] = 0.0 - - # -- removed omp: #$ omp parallel private(ie1, ie2, ie3, il1, il2, il3, value1, q1, q2, q3, wvol, bi) - # -- removed omp: #$ omp for reduction ( + : mat) - for ie1 in range(nel[0]): - for ie2 in range(nel[1]): - for ie3 in range(nel[2]): - for il1 in range(p[0] + 1 - ni[0]): - for il2 in range(p[1] + 1 - ni[1]): - for il3 in range(p[2] + 1 - ni[2]): - value1 = 0.0 - - for q1 in range(nq[0]): - for q2 in range(nq[1]): - for q3 in range(nq[2]): - wvol = ( - w1[ie1, q1] * w2[ie2, q2] * w3[ie3, q3] * mat_fun[ie1, q1, ie2, q2, ie3, q3] - ) - bi = bi1[ie1, il1, 0, q1] * bi2[ie2, il2, 0, q2] * bi3[ie3, il3, 0, q3] - - value1 += wvol * bi - - mat[ind_base1[ie1, il1], ind_base2[ie2, il2], ind_base3[ie3, il3]] += value1 - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -def kernel_l2error( - nel: "int[:]", - p: "int[:]", - nq: "int[:]", - w1: "float[:,:]", - w2: "float[:,:]", - w3: "float[:,:]", - ni: "int[:]", - nj: "int[:]", - bi1: "float[:,:,:,:]", - bi2: "float[:,:,:,:]", - bi3: "float[:,:,:,:]", - bj1: "float[:,:,:,:]", - bj2: "float[:,:,:,:]", - bj3: "float[:,:,:,:]", - ind_basei1: "int[:,:]", - ind_basei2: "int[:,:]", - ind_basei3: "int[:,:]", - ind_basej1: "int[:,:]", - ind_basej2: "int[:,:]", - ind_basej3: "int[:,:]", - error: "float[:,:,:]", - mat_f1: "float[:,:,:,:,:,:]", - mat_f2: "float[:,:,:,:,:,:]", - c1: "float[:,:,:]", - c2: "float[:,:,:]", - mat_map: "float[:,:,:,:,:,:]", -): - # -- removed omp: #$ omp parallel private(ie1, ie2, ie3, q1, q2, q3, wvol, bi, bj, il1, il2, il3, jl1, jl2, jl3) - # -- removed omp: #$ omp for - - # loop over all elements - for ie1 in range(nel[0]): - for ie2 in range(nel[1]): - for ie3 in range(nel[2]): - # loop over quadrature points in element - for q1 in range(nq[0]): - for q2 in range(nq[1]): - for q3 in range(nq[2]): - wvol = w1[ie1, q1] * w2[ie2, q2] * w3[ie3, q3] * mat_map[ie1, q1, ie2, q2, ie3, q3] - - # evaluate discrete fields at quadrature point - bi = 0.0 - bj = 0.0 - - for il1 in range(p[0] + 1 - ni[0]): - for il2 in range(p[1] + 1 - ni[1]): - for il3 in range(p[2] + 1 - ni[2]): - bi += ( - c1[ind_basei1[ie1, il1], ind_basei2[ie2, il2], ind_basei3[ie3, il3]] - * bi1[ie1, il1, 0, q1] - * bi2[ie2, il2, 0, q2] - * bi3[ie3, il3, 0, q3] - ) - - for jl1 in range(p[0] + 1 - nj[0]): - for jl2 in range(p[1] + 1 - nj[1]): - for jl3 in range(p[2] + 1 - nj[2]): - bj += ( - c2[ind_basej1[ie1, jl1], ind_basej2[ie2, jl2], ind_basej3[ie3, jl3]] - * bj1[ie1, jl1, 0, q1] - * bj2[ie2, jl2, 0, q2] - * bj3[ie3, jl3, 0, q3] - ) - - # compare this value to exact one and add contribution to error in element - error[ie1, ie2, ie3] += ( - wvol - * (bi - mat_f1[ie1, q1, ie2, q2, ie3, q3]) - * (bj - mat_f2[ie1, q1, ie2, q2, ie3, q3]) - ) - - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -def kernel_evaluate_2form( - nel: "int[:]", - p: "int[:]", - ns: "int[:]", - nq: "int[:]", - b_coeff: "float[:,:,:]", - ind_base1: "int[:,:]", - ind_base2: "int[:,:]", - ind_base3: "int[:,:]", - bi1: "float[:,:,:,:]", - bi2: "float[:,:,:,:]", - bi3: "float[:,:,:,:]", - b_eva: "float[:,:,:,:,:,:]", -): - b_eva[:, :, :, :, :, :] = 0.0 - - # -- removed omp: #$ omp parallel private(ie1, ie2, ie3, q1, q2, q3, il1, il2, il3) - # -- removed omp: #$ omp for - for ie1 in range(nel[0]): - for ie2 in range(nel[1]): - for ie3 in range(nel[2]): - for q1 in range(nq[0]): - for q2 in range(nq[1]): - for q3 in range(nq[2]): - for il1 in range(p[0] + 1 - ns[0]): - for il2 in range(p[1] + 1 - ns[1]): - for il3 in range(p[2] + 1 - ns[2]): - b_eva[ie1, q1, ie2, q2, ie3, q3] += ( - b_coeff[ind_base1[ie1, il1], ind_base2[ie2, il2], ind_base3[ie3, il3]] - * bi1[ie1, il1, 0, q1] - * bi2[ie2, il2, 0, q2] - * bi3[ie3, il3, 0, q3] - ) - # -- removed omp: #$ omp end parallel - - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/kernels_projectors_global.py b/src/struphy/eigenvalue_solvers/kernels_projectors_global.py deleted file mode 100644 index f01cefc1c..000000000 --- a/src/struphy/eigenvalue_solvers/kernels_projectors_global.py +++ /dev/null @@ -1,714 +0,0 @@ -from numpy import shape - - -# ========= kernel for integration in 1d ================== -def kernel_int_1d(nq1: "int", w1: "float[:]", mat_f: "float[:]") -> "float": - f_loc = 0.0 - - for q1 in range(nq1): - f_loc += w1[q1] * mat_f[q1] - - return f_loc - - -# ========= kernel for integration in 2d ================== -def kernel_int_2d(nq1: "int", nq2: "int", w1: "float[:]", w2: "float[:]", mat_f: "float[:,:]") -> "float": - f_loc = 0.0 - - for q1 in range(nq1): - for q2 in range(nq2): - f_loc += w1[q1] * w2[q2] * mat_f[q1, q2] - - return f_loc - - -# ========= kernel for integration in 3d ================== -def kernel_int_3d( - nq1: "int", - nq2: "int", - nq3: "int", - w1: "float[:]", - w2: "float[:]", - w3: "float[:]", - mat_f: "float[:,:,:]", -) -> "float": - f_loc = 0.0 - - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - f_loc += w1[q1] * w2[q2] * w3[q3] * mat_f[q1, q2, q3] - - return f_loc - - -# =========================================================================================================== -# 2d -# =========================================================================================================== - -# =========================================================================================================== -# line integrals -# =========================================================================================================== - - -# ========= kernel for integration along eta1 direction, reducing to a 2d array ============================ -def kernel_int_2d_eta1( - subs1: "int[:]", - subs_cum1: "int[:]", - w1: "float[:,:]", - mat_f: "float[:,:,:]", - f_int: "float[:,:]", -): - n1, n2 = shape(f_int) - - nq1 = shape(w1)[1] - - for i1 in range(n1): - for i2 in range(n2): - value = 0.0 - - for j1 in range(subs1[i1]): - for q1 in range(nq1): - value += w1[i1 + j1 + subs_cum1[i1], q1] * mat_f[i1 + j1 + subs_cum1[i1], q1, i2] - - f_int[i1, i2] = value - - -# ========= kernel for integration along eta2 direction, reducing to a 2d array ============================ -def kernel_int_2d_eta2( - subs2: "int[:]", - subs_cum2: "int[:]", - w2: "float[:,:]", - mat_f: "float[:,:,:]", - f_int: "float[:,:]", -): - n1, n2 = shape(f_int) - - nq2 = shape(w2)[1] - - for i1 in range(n1): - for i2 in range(n2): - value = 0.0 - - for j2 in range(subs2[i2]): - for q2 in range(nq2): - value += w2[i2 + j2 + subs_cum2[i2], q2] * mat_f[i1, i2 + j2 + subs_cum2[i2], q2] - - f_int[i1, i2] = value - - -# ========= kernel for integration along eta1 direction, reducing to a 2d array ============================ -def kernel_int_2d_eta1_old(w1: "float[:,:]", mat_f: "float[:,:,:]", f_int: "float[:,:]"): - ne1, nq1, n2 = shape(mat_f) - - for ie1 in range(ne1): - for i2 in range(n2): - f_int[ie1, i2] = 0.0 - - for q1 in range(nq1): - f_int[ie1, i2] += w1[ie1, q1] * mat_f[ie1, q1, i2] - - -# ========= kernel for integration along eta2 direction, reducing to a 2d array ============================ -def kernel_int_2d_eta2_old(w2: "float[:,:]", mat_f: "float[:,:,:]", f_int: "float[:,:]"): - n1, ne2, nq2 = shape(mat_f) - - for i1 in range(n1): - for ie2 in range(ne2): - f_int[i1, ie2] = 0.0 - - for q2 in range(nq2): - f_int[i1, ie2] += w2[ie2, q2] * mat_f[i1, ie2, q2] - - -# =========================================================================================================== -# surface integrals -# =========================================================================================================== - - -# ========= kernel for integration in eta1-eta2 plane, reducing to a 2d array ============================== -def kernel_int_2d_eta1_eta2( - subs1: "int[:]", - subs2: "int[:]", - subs_cum1: "int[:]", - subs_cum2: "int[:]", - w1: "float[:,:]", - w2: "float[:,:]", - mat_f: "float[:,:,:,:]", - f_int: "float[:,:]", -): - n1, n2 = shape(f_int) - - nq1 = shape(w1)[1] - nq2 = shape(w2)[1] - - for i1 in range(n1): - for i2 in range(n2): - value = 0.0 - - for j1 in range(subs1[i1]): - for j2 in range(subs2[i2]): - for q1 in range(nq1): - for q2 in range(nq2): - wvol = w1[i1 + j1 + subs_cum1[i1], q1] * w2[i2 + j2 + subs_cum2[i2], q2] - - value += wvol * mat_f[i1 + j1 + subs_cum1[i1], q1, i2 + j2 + subs_cum2[i2], q2] - - f_int[i1, i2] = value - - -# ========= kernel for integration in eta1-eta2 plane, reducing to a 2d array ======================= -def kernel_int_2d_eta1_eta2_old(w1: "float[:,:]", w2: "float[:,:]", mat_f: "float[:,:,:,:]", f_int: "float[:,:]"): - ne1, nq1, ne2, nq2 = shape(mat_f) - - for ie1 in range(ne1): - for ie2 in range(ne2): - f_int[ie1, ie2] = 0.0 - - for q1 in range(nq1): - for q2 in range(nq2): - f_int[ie1, ie2] += w1[ie1, q1] * w2[ie2, q2] * mat_f[ie1, q1, ie2, q2] - - -# =========================================================================================================== -# 3d -# =========================================================================================================== - -# =========================================================================================================== -# line integrals -# =========================================================================================================== - - -# ========= kernel for integration along eta1 direction, reducing to a 3d array ============================ -def kernel_int_3d_eta1( - subs1: "int[:]", - subs_cum1: "int[:]", - w1: "float[:,:]", - mat_f: "float[:,:,:,:]", - f_int: "float[:,:,:]", -): - n1, n2, n3 = shape(f_int) - - nq1 = shape(w1)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - value = 0.0 - - for j1 in range(subs1[i1]): - for q1 in range(nq1): - value += w1[i1 + j1 + subs_cum1[i1], q1] * mat_f[i1 + j1 + subs_cum1[i1], q1, i2, i3] - - f_int[i1, i2, i3] = value - - -def kernel_int_3d_eta1_transpose( - subs1: "int[:]", - subs_cum1: "int[:]", - w1: "float[:,:]", - f_int: "float[:,:,:]", - mat_f: "float[:,:,:,:]", -): - n1, n2, n3 = shape(f_int) - - nq1 = shape(w1)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - for j1 in range(subs1[i1]): - for q1 in range(nq1): - mat_f[i1 + j1 + subs_cum1[i1], q1, i2, i3] = w1[i1 + j1 + subs_cum1[i1], q1] * f_int[i1, i2, i3] - - -# ============================================================================================================ - - -# ========= kernel for integration along eta2 direction, reducing to a 3d array ============================ -def kernel_int_3d_eta2( - subs2: "int[:]", - subs_cum2: "int[:]", - w2: "float[:,:]", - mat_f: "float[:,:,:,:]", - f_int: "float[:,:,:]", -): - n1, n2, n3 = shape(f_int) - - nq2 = shape(w2)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - value = 0.0 - - for j2 in range(subs2[i2]): - for q2 in range(nq2): - value += w2[i2 + j2 + subs_cum2[i2], q2] * mat_f[i1, i2 + j2 + subs_cum2[i2], q2, i3] - - f_int[i1, i2, i3] = value - - -def kernel_int_3d_eta2_transpose( - subs2: "int[:]", - subs_cum2: "int[:]", - w2: "float[:,:]", - f_int: "float[:,:,:]", - mat_f: "float[:,:,:,:]", -): - n1, n2, n3 = shape(f_int) - - nq2 = shape(w2)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - for j2 in range(subs2[i2]): - for q2 in range(nq2): - mat_f[i1, i2 + j2 + subs_cum2[i2], q2, i3] = w2[i2 + j2 + subs_cum2[i2], q2] * f_int[i1, i2, i3] - - -# ============================================================================================================ - - -# ========= kernel for integration along eta3 direction, reducing to a 3d array ============================ -def kernel_int_3d_eta3( - subs3: "int[:]", - subs_cum3: "int[:]", - w3: "float[:,:]", - mat_f: "float[:,:,:,:]", - f_int: "float[:,:,:]", -): - n1, n2, n3 = shape(f_int) - - nq3 = shape(w3)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - value = 0.0 - - for j3 in range(subs3[i3]): - for q3 in range(nq3): - value += w3[i3 + j3 + subs_cum3[i3], q3] * mat_f[i1, i2, i3 + j3 + subs_cum3[i3], q3] - - f_int[i1, i2, i3] = value - - -def kernel_int_3d_eta3_transpose( - subs3: "int[:]", - subs_cum3: "int[:]", - w3: "float[:,:]", - f_int: "float[:,:,:]", - mat_f: "float[:,:,:,:]", -): - n1, n2, n3 = shape(f_int) - - nq3 = shape(w3)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - for j3 in range(subs3[i3]): - for q3 in range(nq3): - mat_f[i1, i2, i3 + j3 + subs_cum3[i3], q3] = w3[i3 + j3 + subs_cum3[i3], q3] * f_int[i1, i2, i3] - - -# ============================================================================================================ - - -# ========= kernel for integration along eta1 direction, reducing to a 3d array ============================ -def kernel_int_3d_eta1_old(w1: "float[:,:]", mat_f: "float[:,:,:,:]", f_int: "float[:,:,:]"): - ne1, nq1, n2, n3 = shape(mat_f) - - for ie1 in range(ne1): - for i2 in range(n2): - for i3 in range(n3): - f_int[ie1, i2, i3] = 0.0 - - for q1 in range(nq1): - f_int[ie1, i2, i3] += w1[ie1, q1] * mat_f[ie1, q1, i2, i3] - - -# ========= kernel for integration along eta2 direction, reducing to a 3d array ============================ -def kernel_int_3d_eta2_old(w2: "float[:,:]", mat_f: "float[:,:,:,:]", f_int: "float[:,:,:]"): - n1, ne2, nq2, n3 = shape(mat_f) - - for i1 in range(n1): - for ie2 in range(ne2): - for i3 in range(n3): - f_int[i1, ie2, i3] = 0.0 - - for q2 in range(nq2): - f_int[i1, ie2, i3] += w2[ie2, q2] * mat_f[i1, ie2, q2, i3] - - -# ========= kernel for integration along eta3 direction, reducing to a 3d array ============================ -def kernel_int_3d_eta3_old(w3: "float[:,:]", mat_f: "float[:,:,:,:]", f_int: "float[:,:,:]"): - n1, n2, ne3, nq3 = shape(mat_f) - - for i1 in range(n1): - for i2 in range(n2): - for ie3 in range(ne3): - f_int[i1, i2, ie3] = 0.0 - - for q3 in range(nq3): - f_int[i1, i2, ie3] += w3[ie3, q3] * mat_f[i1, i2, ie3, q3] - - -# =========================================================================================================== -# surface integrals -# =========================================================================================================== - - -# ========= kernel for integration in eta2-eta3 plane, reducing to a 3d array ============================== -def kernel_int_3d_eta2_eta3( - subs2: "int[:]", - subs3: "int[:]", - subs_cum2: "int[:]", - subs_cum3: "int[:]", - w2: "float[:,:]", - w3: "float[:,:]", - mat_f: "float[:,:,:,:,:]", - f_int: "float[:,:,:]", -): - n1, n2, n3 = shape(f_int) - - nq2 = shape(w2)[1] - nq3 = shape(w3)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - value = 0.0 - - for j2 in range(subs2[i2]): - for j3 in range(subs3[i3]): - for q2 in range(nq2): - for q3 in range(nq3): - wvol = w2[i2 + j2 + subs_cum2[i2], q2] * w3[i3 + j3 + subs_cum3[i3], q3] - - value += wvol * mat_f[i1, i2 + j2 + subs_cum2[i2], q2, i3 + j3 + subs_cum3[i3], q3] - - f_int[i1, i2, i3] = value - - -def kernel_int_3d_eta2_eta3_transpose( - subs2: "int[:]", - subs3: "int[:]", - subs_cum2: "int[:]", - subs_cum3: "int[:]", - w2: "float[:,:]", - w3: "float[:,:]", - f_int: "float[:,:,:]", - mat_f: "float[:,:,:,:,:]", -): - n1, n2, n3 = shape(f_int) - - nq2 = shape(w2)[1] - nq3 = shape(w3)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - for j2 in range(subs2[i2]): - for j3 in range(subs3[i3]): - for q2 in range(nq2): - for q3 in range(nq3): - wvol = w2[i2 + j2 + subs_cum2[i2], q2] * w3[i3 + j3 + subs_cum3[i3], q3] - - mat_f[i1, i2 + j2 + subs_cum2[i2], q2, i3 + j3 + subs_cum3[i3], q3] = ( - wvol * f_int[i1, i2, i3] - ) - - -# ========= kernel for integration in eta1-eta3 plane, reducing to a 3d array ============================== -def kernel_int_3d_eta1_eta3( - subs1: "int[:]", - subs3: "int[:]", - subs_cum1: "int[:]", - subs_cum3: "int[:]", - w1: "float[:,:]", - w3: "float[:,:]", - mat_f: "float[:,:,:,:,:]", - f_int: "float[:,:,:]", -): - n1, n2, n3 = shape(f_int) - - nq1 = shape(w1)[1] - nq3 = shape(w3)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - value = 0.0 - - for j1 in range(subs1[i1]): - for j3 in range(subs3[i3]): - for q1 in range(nq1): - for q3 in range(nq3): - wvol = w1[i1 + j1 + subs_cum1[i1], q1] * w3[i3 + j3 + subs_cum3[i3], q3] - - value += wvol * mat_f[i1 + j1 + subs_cum1[i1], q1, i2, i3 + j3 + subs_cum3[i3], q3] - - f_int[i1, i2, i3] = value - - -def kernel_int_3d_eta1_eta3_transpose( - subs1: "int[:]", - subs3: "int[:]", - subs_cum1: "int[:]", - subs_cum3: "int[:]", - w1: "float[:,:]", - w3: "float[:,:]", - f_int: "float[:,:,:]", - mat_f: "float[:,:,:,:,:]", -): - n1, n2, n3 = shape(f_int) - - nq1 = shape(w1)[1] - nq3 = shape(w3)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - for j1 in range(subs1[i1]): - for j3 in range(subs3[i3]): - for q1 in range(nq1): - for q3 in range(nq3): - wvol = w1[i1 + j1 + subs_cum1[i1], q1] * w3[i3 + j3 + subs_cum3[i3], q3] - - mat_f[i1 + j1 + subs_cum1[i1], q1, i2, i3 + j3 + subs_cum3[i3], q3] = ( - wvol * f_int[i1, i2, i3] - ) - - -# ========= kernel for integration in eta1-eta2 plane, reducing to a 3d array ============================== -def kernel_int_3d_eta1_eta2( - subs1: "int[:]", - subs2: "int[:]", - subs_cum1: "int[:]", - subs_cum2: "int[:]", - w1: "float[:,:]", - w2: "float[:,:]", - mat_f: "float[:,:,:,:,:]", - f_int: "float[:,:,:]", -): - n1, n2, n3 = shape(f_int) - - nq1 = shape(w1)[1] - nq2 = shape(w2)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - value = 0.0 - - for j1 in range(subs1[i1]): - for j2 in range(subs2[i2]): - for q1 in range(nq1): - for q2 in range(nq2): - wvol = w1[i1 + j1 + subs_cum1[i1], q1] * w2[i2 + j2 + subs_cum2[i2], q2] - - value += wvol * mat_f[i1 + j1 + subs_cum1[i1], q1, i2 + j2 + subs_cum2[i2], q2, i3] - - f_int[i1, i2, i3] = value - - -def kernel_int_3d_eta1_eta2_transpose( - subs1: "int[:]", - subs2: "int[:]", - subs_cum1: "int[:]", - subs_cum2: "int[:]", - w1: "float[:,:]", - w2: "float[:,:]", - f_int: "float[:,:,:]", - mat_f: "float[:,:,:,:,:]", -): - n1, n2, n3 = shape(f_int) - - nq1 = shape(w1)[1] - nq2 = shape(w2)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - for j1 in range(subs1[i1]): - for j2 in range(subs2[i2]): - for q1 in range(nq1): - for q2 in range(nq2): - wvol = w1[i1 + j1 + subs_cum1[i1], q1] * w2[i2 + j2 + subs_cum2[i2], q2] - - mat_f[i1 + j1 + subs_cum1[i1], q1, i2 + j2 + subs_cum2[i2], q2, i3] = ( - wvol * f_int[i1, i2, i3] - ) - - -# ========= kernel for integration in eta2-eta3 plane, reducing to a 3d array ============================== -def kernel_int_3d_eta2_eta3_old(w2: "float[:,:]", w3: "float[:,:]", mat_f: "float[:,:,:,:,:]", f_int: "float[:,:,:]"): - n1, ne2, nq2, ne3, nq3 = shape(mat_f) - - for i1 in range(n1): - for ie2 in range(ne2): - for ie3 in range(ne3): - f_int[i1, ie2, ie3] = 0.0 - - for q2 in range(nq2): - for q3 in range(nq3): - f_int[i1, ie2, ie3] += w2[ie2, q2] * w3[ie3, q3] * mat_f[i1, ie2, q2, ie3, q3] - - -# ========= kernel for integration eta1-eta3 plane, reducing to a 3d array ================================ -def kernel_int_3d_eta1_eta3_old(w1: "float[:,:]", w3: "float[:,:]", mat_f: "float[:,:,:,:,:]", f_int: "float[:,:,:]"): - ne1, nq1, n2, ne3, nq3 = shape(mat_f) - - for ie1 in range(ne1): - for i2 in range(n2): - for ie3 in range(ne3): - f_int[ie1, i2, ie3] = 0.0 - - for q1 in range(nq1): - for q3 in range(nq3): - f_int[ie1, i2, ie3] += w1[ie1, q1] * w3[ie3, q3] * mat_f[ie1, q1, i2, ie3, q3] - - -# ========= kernel for integration in eta1-eta2 plane, reducing to a 3d array ============================ -def kernel_int_3d_eta1_eta2_old(w1: "float[:,:]", w2: "float[:,:]", mat_f: "float[:,:,:,:,:]", f_int: "float[:,:,:]"): - ne1, nq1, ne2, nq2, n3 = shape(mat_f) - - for ie1 in range(ne1): - for ie2 in range(ne2): - for i3 in range(n3): - f_int[ie1, ie2, i3] = 0.0 - - for q1 in range(nq1): - for q2 in range(nq2): - f_int[ie1, ie2, i3] += w1[ie1, q1] * w2[ie2, q2] * mat_f[ie1, q1, ie2, q2, i3] - - -# =========================================================================================================== -# cell integrals -# =========================================================================================================== - - -# ========= kernel for integration in eta1-eta2-eta3 cell, reducing to a 3d array ============================== -def kernel_int_3d_eta1_eta2_eta3( - subs1: "int[:]", - subs2: "int[:]", - subs3: "int[:]", - subs_cum1: "int[:]", - subs_cum2: "int[:]", - subs_cum3: "int[:]", - w1: "float[:,:]", - w2: "float[:,:]", - w3: "float[:,:]", - mat_f: "float[:,:,:,:,:,:]", - f_int: "float[:,:,:]", -): - n1 = len(subs1) - n2 = len(subs2) - n3 = len(subs3) - - nq1 = shape(w1)[1] - nq2 = shape(w2)[1] - nq3 = shape(w3)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - value = 0.0 - - for j1 in range(subs1[i1]): - for j2 in range(subs2[i2]): - for j3 in range(subs3[i3]): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - wvol = ( - w1[i1 + j1 + subs_cum1[i1], q1] - * w2[i2 + j2 + subs_cum2[i2], q2] - * w3[i3 + j3 + subs_cum3[i3], q3] - ) - - value += ( - wvol - * mat_f[ - i1 + j1 + subs_cum1[i1], - q1, - i2 + j2 + subs_cum2[i2], - q2, - i3 + j3 + subs_cum3[i3], - q3, - ] - ) - - f_int[i1, i2, i3] = value - - -def kernel_int_3d_eta1_eta2_eta3_transpose( - subs1: "int[:]", - subs2: "int[:]", - subs3: "int[:]", - subs_cum1: "int[:]", - subs_cum2: "int[:]", - subs_cum3: "int[:]", - w1: "float[:,:]", - w2: "float[:,:]", - w3: "float[:,:]", - f_int: "float[:,:,:]", - mat_f: "float[:,:,:,:,:,:]", -): - n1 = len(subs1) - n2 = len(subs2) - n3 = len(subs3) - - nq1 = shape(w1)[1] - nq2 = shape(w2)[1] - nq3 = shape(w3)[1] - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - for j1 in range(subs1[i1]): - for j2 in range(subs2[i2]): - for j3 in range(subs3[i3]): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - wvol = ( - w1[i1 + j1 + subs_cum1[i1], q1] - * w2[i2 + j2 + subs_cum2[i2], q2] - * w3[i3 + j3 + subs_cum3[i3], q3] - ) - - mat_f[ - i1 + j1 + subs_cum1[i1], - q1, - i2 + j2 + subs_cum2[i2], - q2, - i3 + j3 + subs_cum3[i3], - q3, - ] = wvol * f_int[i1, i2, i3] - - -# ========= kernel for integration in eta1-eta2-eta3 cell, reducing to a 3d array ======================= -def kernel_int_3d_eta1_eta2_eta3_old( - w1: "float[:,:]", - w2: "float[:,:]", - w3: "float[:,:]", - mat_f: "float[:,:,:,:,:,:]", - f_int: "float[:,:,:]", -): - ne1, nq1, ne2, nq2, ne3, nq3 = shape(mat_f) - - for ie1 in range(ne1): - for ie2 in range(ne2): - for ie3 in range(ne3): - f_int[ie1, ie2, ie3] = 0.0 - - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - f_int[ie1, ie2, ie3] += ( - w1[ie1, q1] * w2[ie2, q2] * w3[ie3, q3] * mat_f[ie1, q1, ie2, q2, ie3, q3] - ) diff --git a/src/struphy/eigenvalue_solvers/kernels_projectors_global_mhd.py b/src/struphy/eigenvalue_solvers/kernels_projectors_global_mhd.py deleted file mode 100644 index ed196fdf1..000000000 --- a/src/struphy/eigenvalue_solvers/kernels_projectors_global_mhd.py +++ /dev/null @@ -1,1436 +0,0 @@ -from typing import Final - -from numpy import shape -from pyccel.decorators import pure - - -@pure -def matmul(a: "float[:,:]", b: "float[:,:]", c: "float[:,:]"): - """ - Performs the matrix-matrix product a*b and writes the result into c. - - Parameters - ---------- - a : array[float] - The first input array (matrix). - - b : array[float] - The second input array (matrix). - - c : array[float] - The output array (matrix) which is the result of the matrix-matrix product a.dot(b). - """ - - sh_a = shape(a) - sh_b = shape(b) - - if sh_a[0] == 0 or sh_a[1] == 0 or sh_b[0] == 0 or sh_b[1] == 0: - c[:, :] = 0.0 - else: - c[:, :] = 0.0 - for i in range(sh_a[0]): - for j in range(sh_b[1]): - for k in range(sh_a[1]): - c[i, j] += a[i, k] * b[k, j] - - -@pure -def sum_vec(a: "Final[float[:]]") -> float: - """ - Sum the elements of a 1D vector. - - Parameters - ---------- - a : array[float] - The 1d vector. - """ - - out = 0.0 - - sh_a = shape(a) - - for i in range(sh_a[0]): - out += a[i] - - return out - - -@pure -def min_vec(a: "Final[float[:]]") -> float: - """ - Compute the minimum a 1D vector. - - Parameters - ---------- - a : array[float] - The 1D vector. - """ - - out = a[0] - - sh_a = shape(a) - - for i in range(sh_a[0]): - if a[i] < out: - out = a[i] - - return out - - -@pure -def max_vec(a: "Final[float[:]]") -> float: - """ - Compute the maximum a 1D vector. - - Parameters - ---------- - a : array[float] - The 1D vector. - """ - - out = a[0] - - sh_a = shape(a) - - for i in range(sh_a[0]): - if a[i] > out: - out = a[i] - - return out - - -@pure -def max_vec_int(a: "Final[int[:]]") -> int: - """ - Compute the maximum a 1D vector. - - Parameters - ---------- - a : array[float] - The 1D vector. - """ - - out = a[0] - - sh_a = shape(a) - - for i in range(sh_a[0]): - if a[i] > out: - out = a[i] - - return out - - -# =========================================================================================================== -# 1d -# =========================================================================================================== - -# ============================================================================= - - -def rhs0_1d(row1: "int[:]", col1: "int[:]", bsp1: "float[:,:]", mat_eq: "float[:]", rhs: "float[:]"): - n_rows_1 = len(row1) - - for i1 in range(n_rows_1): - rhs[i1] = bsp1[row1[i1], col1[i1]] * mat_eq[row1[i1]] - - -# ============================================================================= -def rhs1_1d( - row1: "int[:]", - col1: "int[:]", - subs1: "int[:]", - subs_cum1: "int[:]", - wts1: "float[:,:]", - bsp1: "float[:,:,:]", - mat_eq: "float[:,:]", - rhs: "float[:]", -): - n_rows_1 = len(row1) - - nq1 = shape(wts1)[1] - - for i1 in range(n_rows_1): - value1 = 0.0 - - for j1 in range(subs1[row1[i1]]): - for q1 in range(nq1): - value1 += ( - wts1[row1[i1] + j1 + subs_cum1[row1[i1]], q1] - * bsp1[ - row1[i1] + j1 + subs_cum1[row1[i1]], - q1, - col1[i1], - ] - * mat_eq[row1[i1] + j1 + subs_cum1[row1[i1]], q1] - ) - - rhs[i1] = value1 - - -# ============================================================================= -def rhs0_f_1d( - indices1: "int[:,:]", - bsp11: "float[:,:]", - bsp12: "float[:,:]", - mat_eq: "float[:]", - f: "float[:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - rhs[:] = 0.0 - - for i1 in range(len(indices1[0])): - i = indices1[3, i1] - - rhs[i] += ( - f[indices1[0, i1]] - * bsp11[indices1[0, i1], indices1[1, i1]] - * bsp12[indices1[0, i1], indices1[2, i1]] - * mat_eq[indices1[0, i1]] - ) - - row[i] = indices1[1, i1] - col[i] = indices1[2, i1] - - -# ============================================================================= -def rhs1_f_1d( - indices1: "int[:,:]", - subs1: "int[:]", - subs_cum1: "int[:]", - wts1: "float[:,:]", - bsp11: "float[:,:,:]", - bsp12: "float[:,:,:]", - mat_eq: "float[:,:]", - f: "float[:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - nq1 = shape(wts1)[1] - - rhs[:] = 0.0 - - for i1 in range(len(indices1[0])): - value1 = 0.0 - - for j1 in range(subs1[indices1[0, i1]]): - for q1 in range(nq1): - value1 += ( - wts1[indices1[0, i1] + j1 + subs_cum1[indices1[0, i1]], q1] - * bsp11[ - indices1[0, i1] + j1 + subs_cum1[indices1[0, i1]], - q1, - indices1[1, i1], - ] - * bsp12[indices1[0, i1] + j1 + subs_cum1[indices1[0, i1]], q1, indices1[2, i1]] - * mat_eq[indices1[0, i1] + j1 + subs_cum1[indices1[0, i1]], q1] - ) - - i = indices1[3, i1] - - rhs[i] += f[indices1[0, i1]] * value1 - - row[i] = indices1[1, i1] - col[i] = indices1[2, i1] - - -# =========================================================================================================== -# 2d -# =========================================================================================================== - - -# ============================================================================= -def rhs0_2d( - row1: "int[:]", - row2: "int[:]", - col1: "int[:]", - col2: "int[:]", - bsp1: "float[:,:]", - bsp2: "float[:,:]", - mat_eq: "float[:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - n_rows_1 = len(row1) - n_rows_2 = len(row2) - - n1i, n1j = shape(bsp1) - n2i, n2j = shape(bsp2) - - for i1 in range(n_rows_1): - for i2 in range(n_rows_2): - i = n_rows_2 * i1 + i2 - - bsp = bsp1[row1[i1], col1[i1]] * bsp2[row2[i2], col2[i2]] - - rhs[i] = bsp * mat_eq[row1[i1], row2[i2]] - - row[i] = n2i * row1[i1] + row2[i2] - col[i] = n2j * col1[i1] + col2[i2] - - -# ============================================================================= -def rhs11_2d( - row1: "int[:]", - row2: "int[:]", - col1: "int[:]", - col2: "int[:]", - subs1: "int[:]", - subs_cum1: "int[:]", - wts1: "float[:,:]", - bsp1: "float[:,:,:]", - bsp2: "float[:,:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - mat_eq: "float[:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - n_rows_1 = len(row1) - n_rows_2 = len(row2) - - n1i = nbase_d[0] - n2i = nbase_n[1] - - n1j = shape(bsp1)[2] - n2j = shape(bsp2)[1] - - nq1 = shape(wts1)[1] - - for i1 in range(n_rows_1): - for i2 in range(n_rows_2): - value1 = 0.0 - - for j1 in range(subs1[row1[i1]]): - for q1 in range(nq1): - value1 += ( - wts1[row1[i1] + j1 + subs_cum1[row1[i1]], q1] - * bsp1[ - row1[i1] + j1 + subs_cum1[row1[i1]], - q1, - col1[i1], - ] - * mat_eq[row1[i1] + j1 + subs_cum1[row1[i1]], q1, row2[i2]] - ) - - i = n_rows_2 * i1 + i2 - - rhs[i] = value1 * bsp2[row2[i2], col2[i2]] - - row[i] = n2i * row1[i1] + row2[i2] - col[i] = n2j * col1[i1] + col2[i2] - - -# ============================================================================= -def rhs12_2d( - row1: "int[:]", - row2: "int[:]", - col1: "int[:]", - col2: "int[:]", - subs2: "int[:]", - subs_cum2: "int[:]", - wts2: "float[:,:]", - bsp1: "float[:,:]", - bsp2: "float[:,:,:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - mat_eq: "float[:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - n_rows_1 = len(row1) - n_rows_2 = len(row2) - - n1i = nbase_n[0] - n2i = nbase_d[1] - - n1j = shape(bsp1)[1] - n2j = shape(bsp2)[2] - - nq2 = shape(wts2)[1] - - for i1 in range(n_rows_1): - for i2 in range(n_rows_2): - value1 = 0.0 - - for j2 in range(subs2[row2[i2]]): - for q2 in range(nq2): - value1 += ( - wts2[row2[i2] + j2 + subs_cum2[row2[i2]], q2] - * bsp2[ - row2[i2] + j2 + subs_cum2[row2[i2]], - q2, - col2[i2], - ] - * mat_eq[row1[i1], row2[i2] + j2 + subs_cum2[row2[i2]], q2] - ) - - i = n_rows_2 * i1 + i2 - - rhs[i] = value1 * bsp1[row1[i1], col1[i1]] - - row[i] = n2i * row1[i1] + row2[i2] - col[i] = n2j * col1[i1] + col2[i2] - - -# ============================================================================= -def rhs2_2d( - row1: "int[:]", - row2: "int[:]", - col1: "int[:]", - col2: "int[:]", - subs1: "int[:]", - subs2: "int[:]", - subs_cum1: "int[:]", - subs_cum2: "int[:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - bsp1: "float[:,:,:]", - bsp2: "float[:,:,:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - mat_eq: "float[:,:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - n_rows_1 = len(row1) - n_rows_2 = len(row2) - - n1i = nbase_d[0] - n2i = nbase_d[1] - - n1j = shape(bsp1)[2] - n2j = shape(bsp2)[2] - - nq1 = shape(wts1)[1] - nq2 = shape(wts2)[1] - - for i1 in range(n_rows_1): - for i2 in range(n_rows_2): - value1 = 0.0 - - for j1 in range(subs1[row1[i1]]): - for j2 in range(subs2[row2[i2]]): - for q1 in range(nq1): - for q2 in range(nq2): - w_vol = ( - wts1[row1[i1] + j1 + subs_cum1[row1[i1]], q1] - * wts2[row2[i2] + j2 + subs_cum2[row2[i2]], q2] - ) - - basis = ( - bsp1[row1[i1] + j1 + subs_cum1[row1[i1]], q1, col1[i1]] - * bsp2[row2[i2] + j2 + subs_cum2[row2[i2]], q2, col2[i2]] - ) - - value1 += ( - w_vol - * basis - * mat_eq[ - row1[i1] + j1 + subs_cum1[row1[i1]], - q1, - row2[i2] + j2 + subs_cum2[row2[i2]], - q2, - ] - ) - - i = n_rows_2 * i1 + i2 - - rhs[i] = value1 - - row[i] = n2i * row1[i1] + row2[i2] - col[i] = n2j * col1[i1] + col2[i2] - - -# ============================================================================= -def rhs0_f_2d( - indices1: "int[:,:]", - indices2: "int[:,:]", - bsp11: "float[:,:]", - bsp12: "float[:,:]", - bsp21: "float[:,:]", - bsp22: "float[:,:]", - mat_eq: "float[:,:]", - f: "complex[:,:]", - rhs: "complex[:]", - row: "int[:]", - col: "int[:]", -): - nv1 = max_vec_int(indices1[3]) + 1 - nv2 = max_vec_int(indices2[3]) + 1 - - n1i = shape(bsp11)[1] - n2i = shape(bsp21)[1] - - n1j = shape(bsp12)[1] - n2j = shape(bsp22)[1] - - rhs[:] = 0.0 - - for i1 in range(len(indices1[0])): - for i2 in range(len(indices2[0])): - i = nv2 * indices1[3, i1] + indices2[3, i2] - - rhs[i] += ( - f[indices1[0, i1], indices2[0, i2]] - * mat_eq[indices1[0, i1], indices2[0, i2]] - * bsp11[ - indices1[0, i1], - indices1[1, i1], - ] - * bsp12[indices1[0, i1], indices1[2, i1]] - * bsp21[indices2[0, i2], indices2[1, i2]] - * bsp22[indices2[0, i2], indices2[2, i2]] - ) - - row[i] = n2i * indices1[1, i1] + indices2[1, i2] - col[i] = n2j * indices1[2, i1] + indices2[2, i2] - - -# ============================================================================= -def rhs11_f_2d( - indices1: "int[:,:]", - indices2: "int[:,:]", - subs1: "int[:]", - subs_cum1: "int[:]", - wts1: "float[:,:]", - bsp11: "float[:,:,:]", - bsp12: "float[:,:,:]", - bsp21: "float[:,:]", - bsp22: "float[:,:]", - mat_eq: "float[:,:,:]", - f: "complex[:,:]", - rhs: "complex[:]", - row: "int[:]", - col: "int[:]", -): - nq1 = shape(wts1)[1] - - nv1 = max_vec_int(indices1[3]) + 1 - nv2 = max_vec_int(indices2[3]) + 1 - - n1i = shape(bsp11)[2] - n2i = shape(bsp21)[1] - - n1j = shape(bsp12)[2] - n2j = shape(bsp22)[1] - - rhs[:] = 0.0 - - for i1 in range(len(indices1[0])): - for i2 in range(len(indices2[0])): - value1 = 0.0 - - for j1 in range(subs1[indices1[0, i1]]): - for q1 in range(nq1): - value1 += ( - wts1[indices1[0, i1] + j1 + subs_cum1[indices1[0, i1]], q1] - * bsp11[indices1[0, i1] + j1 + subs_cum1[indices1[0, i1]], q1, indices1[1, i1]] - * bsp12[indices1[0, i1] + j1 + subs_cum1[indices1[0, i1]], q1, indices1[2, i1]] - * mat_eq[indices1[0, i1] + j1 + subs_cum1[indices1[0, i1]], q1, indices2[0, i2]] - ) - - i = nv2 * indices1[3, i1] + indices2[3, i2] - - rhs[i] += ( - f[indices1[0, i1], indices2[0, i2]] - * value1 - * bsp21[indices2[0, i2], indices2[1, i2]] - * bsp22[indices2[0, i2], indices2[2, i2]] - ) - - row[i] = n2i * indices1[1, i1] + indices2[1, i2] - col[i] = n2j * indices1[2, i1] + indices2[2, i2] - - -# ============================================================================= -def rhs12_f_2d( - indices1: "int[:,:]", - indices2: "int[:,:]", - subs2: "int[:]", - subs_cum2: "int[:]", - wts2: "float[:,:]", - bsp11: "float[:,:]", - bsp12: "float[:,:]", - bsp21: "float[:,:,:]", - bsp22: "float[:,:,:]", - mat_eq: "float[:,:,:]", - f: "complex[:,:]", - rhs: "complex[:]", - row: "int[:]", - col: "int[:]", -): - nq2 = shape(wts2)[1] - - nv1 = max_vec_int(indices1[3]) + 1 - nv2 = max_vec_int(indices2[3]) + 1 - - n1i = shape(bsp11)[1] - n2i = shape(bsp21)[2] - - n1j = shape(bsp12)[1] - n2j = shape(bsp22)[2] - - rhs[:] = 0.0 - - for i1 in range(len(indices1[0])): - for i2 in range(len(indices2[0])): - value1 = 0.0 - - for j2 in range(subs2[indices2[0, i2]]): - for q2 in range(nq2): - value1 += ( - wts2[indices2[0, i2] + j2 + subs_cum2[indices2[0, i2]], q2] - * bsp21[indices2[0, i2] + j2 + subs_cum2[indices2[0, i2]], q2, indices2[1, i2]] - * bsp22[indices2[0, i2] + j2 + subs_cum2[indices2[0, i2]], q2, indices2[2, i2]] - * mat_eq[indices1[0, i1], indices2[0, i2] + j2 + subs_cum2[indices2[0, i2]], q2] - ) - - i = nv2 * indices1[3, i1] + indices2[3, i2] - - rhs[i] += ( - f[indices1[0, i1], indices2[0, i2]] - * value1 - * bsp11[indices1[0, i1], indices1[1, i1]] - * bsp12[indices1[0, i1], indices1[2, i1]] - ) - - row[i] = n2i * indices1[1, i1] + indices2[1, i2] - col[i] = n2j * indices1[2, i1] + indices2[2, i2] - - -# =========================================================================================================== -# 3d -# =========================================================================================================== - - -# ============================================================================= -def rhs0( - row1: "int[:]", - row2: "int[:]", - row3: "int[:]", - col1: "int[:]", - col2: "int[:]", - col3: "int[:]", - bsp1: "float[:,:]", - bsp2: "float[:,:]", - bsp3: "float[:,:]", - mat_eq: "float[:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - n_rows_1 = len(row1) - n_rows_2 = len(row2) - n_rows_3 = len(row3) - - n1i, n1j = shape(bsp1) - n2i, n2j = shape(bsp2) - n3i, n3j = shape(bsp3) - - # -- removed omp: #$ omp parallel private(i1, i2, i3, i, bsp) - # -- removed omp: #$ omp for - for i1 in range(n_rows_1): - for i2 in range(n_rows_2): - for i3 in range(n_rows_3): - i = n_rows_2 * n_rows_3 * i1 + n_rows_3 * i2 + i3 - - bsp = bsp1[row1[i1], col1[i1]] * bsp2[row2[i2], col2[i2]] * bsp3[row3[i3], col3[i3]] - - rhs[i] = bsp * mat_eq[row1[i1], row2[i2], row3[i3]] - - row[i] = n2i * n3i * row1[i1] + n3i * row2[i2] + row3[i3] - col[i] = n2j * n3j * col1[i1] + n3j * col2[i2] + col3[i3] - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================= -def rhs11( - row1: "int[:]", - row2: "int[:]", - row3: "int[:]", - col1: "int[:]", - col2: "int[:]", - col3: "int[:]", - subs1: "int[:]", - subs_cum1: "int[:]", - wts1: "float[:,:]", - bsp1: "float[:,:,:]", - bsp2: "float[:,:]", - bsp3: "float[:,:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - mat_eq: "float[:,:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - n_rows_1 = len(row1) - n_rows_2 = len(row2) - n_rows_3 = len(row3) - - n1i = nbase_d[0] - n2i = nbase_n[1] - n3i = nbase_n[2] - - n1j = shape(bsp1)[2] - n2j = shape(bsp2)[1] - n3j = shape(bsp3)[1] - - nq1 = shape(wts1)[1] - - # -- removed omp: #$ omp parallel private(i1, i2, i3, value1, j1, q1, i) - # -- removed omp: #$ omp for - for i1 in range(n_rows_1): - for i2 in range(n_rows_2): - for i3 in range(n_rows_3): - value1 = 0.0 - - for j1 in range(subs1[row1[i1]]): - for q1 in range(nq1): - value1 += ( - wts1[row1[i1] + j1 + subs_cum1[row1[i1]], q1] - * bsp1[ - row1[i1] + j1 + subs_cum1[row1[i1]], - q1, - col1[i1], - ] - * mat_eq[row1[i1] + j1 + subs_cum1[row1[i1]], q1, row2[i2], row3[i3]] - ) - - i = n_rows_2 * n_rows_3 * i1 + n_rows_3 * i2 + i3 - - rhs[i] = value1 * bsp2[row2[i2], col2[i2]] * bsp3[row3[i3], col3[i3]] - - row[i] = n2i * n3i * row1[i1] + n3i * row2[i2] + row3[i3] - col[i] = n2j * n3j * col1[i1] + n3j * col2[i2] + col3[i3] - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================= -def rhs12( - row1: "int[:]", - row2: "int[:]", - row3: "int[:]", - col1: "int[:]", - col2: "int[:]", - col3: "int[:]", - subs2: "int[:]", - subs_cum2: "int[:]", - wts2: "float[:,:]", - bsp1: "float[:,:]", - bsp2: "float[:,:,:]", - bsp3: "float[:,:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - mat_eq: "float[:,:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - n_rows_1 = len(row1) - n_rows_2 = len(row2) - n_rows_3 = len(row3) - - n1i = nbase_n[0] - n2i = nbase_d[1] - n3i = nbase_n[2] - - n1j = shape(bsp1)[1] - n2j = shape(bsp2)[2] - n3j = shape(bsp3)[1] - - nq2 = shape(wts2)[1] - - # -- removed omp: #$ omp parallel private(i1, i2, i3, value1, j2, q2, i) - # -- removed omp: #$ omp for - for i1 in range(n_rows_1): - for i2 in range(n_rows_2): - for i3 in range(n_rows_3): - value1 = 0.0 - - for j2 in range(subs2[row2[i2]]): - for q2 in range(nq2): - value1 += ( - wts2[row2[i2] + j2 + subs_cum2[row2[i2]], q2] - * bsp2[ - row2[i2] + j2 + subs_cum2[row2[i2]], - q2, - col2[i2], - ] - * mat_eq[row1[i1], row2[i2] + j2 + subs_cum2[row2[i2]], q2, row3[i3]] - ) - - i = n_rows_2 * n_rows_3 * i1 + n_rows_3 * i2 + i3 - - rhs[i] = value1 * bsp1[row1[i1], col1[i1]] * bsp3[row3[i3], col3[i3]] - - row[i] = n2i * n3i * row1[i1] + n3i * row2[i2] + row3[i3] - col[i] = n2j * n3j * col1[i1] + n3j * col2[i2] + col3[i3] - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================= -def rhs13( - row1: "int[:]", - row2: "int[:]", - row3: "int[:]", - col1: "int[:]", - col2: "int[:]", - col3: "int[:]", - subs3: "int[:]", - subs_cum3: "int[:]", - wts3: "float[:,:]", - bsp1: "float[:,:]", - bsp2: "float[:,:]", - bsp3: "float[:,:,:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - mat_eq: "float[:,:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - n_rows_1 = len(row1) - n_rows_2 = len(row2) - n_rows_3 = len(row3) - - n1i = nbase_n[0] - n2i = nbase_n[1] - n3i = nbase_d[2] - - n1j = shape(bsp1)[1] - n2j = shape(bsp2)[1] - n3j = shape(bsp3)[2] - - nq3 = shape(wts3)[1] - - # -- removed omp: #$ omp parallel private(i1, i2, i3, value1, j3, q3, i) - # -- removed omp: #$ omp for - for i1 in range(n_rows_1): - for i2 in range(n_rows_2): - for i3 in range(n_rows_3): - value1 = 0.0 - - for j3 in range(subs3[row3[i3]]): - for q3 in range(nq3): - value1 += ( - wts3[row3[i3] + j3 + subs_cum3[row3[i3]], q3] - * bsp3[ - row3[i3] + j3 + subs_cum3[row3[i3]], - q3, - col3[i3], - ] - * mat_eq[row1[i1], row2[i2], row3[i3] + j3 + subs_cum3[row3[i3]], q3] - ) - - i = n_rows_2 * n_rows_3 * i1 + n_rows_3 * i2 + i3 - - rhs[i] = value1 * bsp1[row1[i1], col1[i1]] * bsp2[row2[i2], col2[i2]] - - row[i] = n2i * n3i * row1[i1] + n3i * row2[i2] + row3[i3] - col[i] = n2j * n3j * col1[i1] + n3j * col2[i2] + col3[i3] - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================= -def rhs21( - row1: "int[:]", - row2: "int[:]", - row3: "int[:]", - col1: "int[:]", - col2: "int[:]", - col3: "int[:]", - subs2: "int[:]", - subs3: "int[:]", - subs_cum2: "int[:]", - subs_cum3: "int[:]", - wts2: "float[:,:]", - wts3: "float[:,:]", - bsp1: "float[:,:]", - bsp2: "float[:,:,:]", - bsp3: "float[:,:,:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - mat_eq: "float[:,:,:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - n_rows_1 = len(row1) - n_rows_2 = len(row2) - n_rows_3 = len(row3) - - n1i = nbase_n[0] - n2i = nbase_d[1] - n3i = nbase_d[2] - - n1j = shape(bsp1)[1] - n2j = shape(bsp2)[2] - n3j = shape(bsp3)[2] - - nq2 = shape(wts2)[1] - nq3 = shape(wts3)[1] - - # -- removed omp: #$ omp parallel private(i1, i2, i3, value1, j2, q2, j3, q3, w_vol, basis, i) - # -- removed omp: #$ omp for - for i1 in range(n_rows_1): - for i2 in range(n_rows_2): - for i3 in range(n_rows_3): - value1 = 0.0 - - for j2 in range(subs2[row2[i2]]): - for q2 in range(nq2): - for j3 in range(subs3[row3[i3]]): - for q3 in range(nq3): - w_vol = ( - wts2[row2[i2] + j2 + subs_cum2[row2[i2]], q2] - * wts3[row3[i3] + j3 + subs_cum3[row3[i3]], q3] - ) - - basis = ( - bsp2[row2[i2] + j2 + subs_cum2[row2[i2]], q2, col2[i2]] - * bsp3[row3[i3] + j3 + subs_cum3[row3[i3]], q3, col3[i3]] - ) - - value1 += ( - w_vol - * basis - * mat_eq[ - row1[i1], - row2[i2] + j2 + subs_cum2[row2[i2]], - q2, - row3[i3] + j3 + subs_cum3[row3[i3]], - q3, - ] - ) - - i = n_rows_2 * n_rows_3 * i1 + n_rows_3 * i2 + i3 - - rhs[i] = value1 * bsp1[row1[i1], col1[i1]] - - row[i] = n2i * n3i * row1[i1] + n3i * row2[i2] + row3[i3] - col[i] = n2j * n3j * col1[i1] + n3j * col2[i2] + col3[i3] - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================= -def rhs22( - row1: "int[:]", - row2: "int[:]", - row3: "int[:]", - col1: "int[:]", - col2: "int[:]", - col3: "int[:]", - subs1: "int[:]", - subs3: "int[:]", - subs_cum1: "int[:]", - subs_cum3: "int[:]", - wts1: "float[:,:]", - wts3: "float[:,:]", - bsp1: "float[:,:,:]", - bsp2: "float[:,:]", - bsp3: "float[:,:,:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - mat_eq: "float[:,:,:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - n_rows_1 = len(row1) - n_rows_2 = len(row2) - n_rows_3 = len(row3) - - n1i = nbase_d[0] - n2i = nbase_n[1] - n3i = nbase_d[2] - - n1j = shape(bsp1)[2] - n2j = shape(bsp2)[1] - n3j = shape(bsp3)[2] - - nq1 = shape(wts1)[1] - nq3 = shape(wts3)[1] - - # -- removed omp: #$ omp parallel private(i1, i2, i3, value1, j1, q1, j3, q3, w_vol, basis, i) - # -- removed omp: #$ omp for - for i1 in range(n_rows_1): - for i2 in range(n_rows_2): - for i3 in range(n_rows_3): - value1 = 0.0 - - for j1 in range(subs1[row1[i1]]): - for q1 in range(nq1): - for j3 in range(subs3[row3[i3]]): - for q3 in range(nq3): - w_vol = ( - wts1[row1[i1] + j1 + subs_cum1[row1[i1]], q1] - * wts3[row3[i3] + j3 + subs_cum3[row3[i3]], q3] - ) - - basis = ( - bsp1[row1[i1] + j1 + subs_cum1[row1[i1]], q1, col1[i1]] - * bsp3[row3[i3] + j3 + subs_cum3[row3[i3]], q3, col3[i3]] - ) - - value1 += ( - w_vol - * basis - * mat_eq[ - row1[i1] + j1 + subs_cum1[row1[i1]], - q1, - row2[i2], - row3[i3] + j3 + subs_cum3[row3[i3]], - q3, - ] - ) - - i = n_rows_2 * n_rows_3 * i1 + n_rows_3 * i2 + i3 - - rhs[i] = value1 * bsp2[row2[i2], col2[i2]] - - row[i] = n2i * n3i * row1[i1] + n3i * row2[i2] + row3[i3] - col[i] = n2j * n3j * col1[i1] + n3j * col2[i2] + col3[i3] - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================= -def rhs23( - row1: "int[:]", - row2: "int[:]", - row3: "int[:]", - col1: "int[:]", - col2: "int[:]", - col3: "int[:]", - subs1: "int[:]", - subs2: "int[:]", - subs_cum1: "int[:]", - subs_cum2: "int[:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - bsp1: "float[:,:,:]", - bsp2: "float[:,:,:]", - bsp3: "float[:,:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - mat_eq: "float[:,:,:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - n_rows_1 = len(row1) - n_rows_2 = len(row2) - n_rows_3 = len(row3) - - n1i = nbase_d[0] - n2i = nbase_d[1] - n3i = nbase_n[2] - - n1j = shape(bsp1)[2] - n2j = shape(bsp2)[2] - n3j = shape(bsp3)[1] - - nq1 = shape(wts1)[1] - nq2 = shape(wts2)[1] - - # -- removed omp: #$ omp parallel private(i1, i2, i3, value1, j1, q1, j2, q2, w_vol, basis, i) - # -- removed omp: #$ omp for - for i1 in range(n_rows_1): - for i2 in range(n_rows_2): - for i3 in range(n_rows_3): - value1 = 0.0 - - for j1 in range(subs1[row1[i1]]): - for q1 in range(nq1): - for j2 in range(subs2[row2[i2]]): - for q2 in range(nq2): - w_vol = ( - wts1[row1[i1] + j1 + subs_cum1[row1[i1]], q1] - * wts2[row2[i2] + j2 + subs_cum2[row2[i2]], q2] - ) - - basis = ( - bsp1[row1[i1] + j1 + subs_cum1[row1[i1]], q1, col1[i1]] - * bsp2[row2[i2] + j2 + subs_cum2[row2[i2]], q2, col2[i2]] - ) - - value1 += ( - w_vol - * basis - * mat_eq[ - row1[i1] + j1 + subs_cum1[row1[i1]], - q1, - row2[i2] + j2 + subs_cum2[row2[i2]], - q2, - row3[i3], - ] - ) - - i = n_rows_2 * n_rows_3 * i1 + n_rows_3 * i2 + i3 - - rhs[i] = value1 * bsp3[row3[i3], col3[i3]] - - row[i] = n2i * n3i * row1[i1] + n3i * row2[i2] + row3[i3] - col[i] = n2j * n3j * col1[i1] + n3j * col2[i2] + col3[i3] - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================= -def rhs3( - row1: "int[:]", - row2: "int[:]", - row3: "int[:]", - col1: "int[:]", - col2: "int[:]", - col3: "int[:]", - subs1: "int[:]", - subs2: "int[:]", - subs3: "int[:]", - subs_cum1: "int[:]", - subs_cum2: "int[:]", - subs_cum3: "int[:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", - bsp1: "float[:,:,:]", - bsp2: "float[:,:,:]", - bsp3: "float[:,:,:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - mat_eq: "float[:,:,:,:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - n_rows_1 = len(row1) - n_rows_2 = len(row2) - n_rows_3 = len(row3) - - n1i = nbase_d[0] - n2i = nbase_d[1] - n3i = nbase_d[2] - - n1j = shape(bsp1)[2] - n2j = shape(bsp2)[2] - n3j = shape(bsp3)[2] - - nq1 = shape(wts1)[1] - nq2 = shape(wts2)[1] - nq3 = shape(wts3)[1] - - # -- removed omp: #$ omp parallel private(i1, i2, i3, value1, j1, q1, j2, q2, j3, q3, w_vol, basis, i) - # -- removed omp: #$ omp for - for i1 in range(n_rows_1): - for i2 in range(n_rows_2): - for i3 in range(n_rows_3): - value1 = 0.0 - - for j1 in range(subs1[row1[i1]]): - for q1 in range(nq1): - for j2 in range(subs2[row2[i2]]): - for q2 in range(nq2): - for j3 in range(subs3[row3[i3]]): - for q3 in range(nq3): - w_vol = ( - wts1[row1[i1] + j1 + subs_cum1[row1[i1]], q1] - * wts2[ - row2[i2] + j2 + subs_cum2[row2[i2]], - q2, - ] - * wts3[row3[i3] + j3 + subs_cum3[row3[i3]], q3] - ) - - basis = ( - bsp1[row1[i1] + j1 + subs_cum1[row1[i1]], q1, col1[i1]] - * bsp2[ - row2[i2] + j2 + subs_cum2[row2[i2]], - q2, - col2[i2], - ] - * bsp3[row3[i3] + j3 + subs_cum3[row3[i3]], q3, col3[i3]] - ) - - value1 += ( - w_vol - * basis - * mat_eq[ - row1[i1] + j1 + subs_cum1[row1[i1]], - q1, - row2[i2] + j2 + subs_cum2[row2[i2]], - q2, - row3[i3] + j3 + subs_cum3[row3[i3]], - q3, - ] - ) - - i = n_rows_2 * n_rows_3 * i1 + n_rows_3 * i2 + i3 - - rhs[i] = value1 - - row[i] = n2i * n3i * row1[i1] + n3i * row2[i2] + row3[i3] - col[i] = n2j * n3j * col1[i1] + n3j * col2[i2] + col3[i3] - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================= -def rhs11_f( - indices1: "int[:,:]", - indices2: "int[:,:]", - indices3: "int[:,:]", - n_row_sub1: "int[:]", - sub1_cum: "int[:]", - wts1: "float[:,:]", - bsp11: "float[:,:,:]", - bsp12: "float[:,:,:]", - bsp21: "float[:,:]", - bsp22: "float[:,:]", - bsp31: "float[:,:]", - bsp32: "float[:,:]", - mat_eq: "float[:,:,:,:]", - f: "float[:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - nq1 = shape(wts1)[1] - - nv1 = max_vec_int(indices1[3]) + 1 - nv2 = max_vec_int(indices2[3]) + 1 - nv3 = max_vec_int(indices3[3]) + 1 - - n1i = shape(bsp11)[2] - n2i = shape(bsp21)[1] - n3i = shape(bsp31)[1] - - n1j = shape(bsp12)[2] - n2j = shape(bsp22)[1] - n3j = shape(bsp32)[1] - - counter1 = 0 - rhs[:] = 0.0 - - for i1 in range(len(indices1[0])): - for i2 in range(len(indices2[0])): - for i3 in range(len(indices3[0])): - value1 = 0.0 - - counter1 = sub1_cum[indices1[0, i1]] - - for j1 in range(n_row_sub1[indices1[0, i1]]): - for q1 in range(nq1): - value1 += ( - wts1[indices1[0, i1] + j1 + counter1, q1] - * bsp11[indices1[0, i1] + j1 + counter1, q1, indices1[1, i1]] - * bsp12[ - indices1[ - 0, - i1, - ] - + j1 - + counter1, - q1, - indices1[2, i1], - ] - * mat_eq[indices1[0, i1] + j1 + counter1, q1, indices2[0, i2], indices3[0, i3]] - ) - - i = nv2 * nv3 * indices1[3, i1] + nv3 * indices2[3, i2] + indices3[3, i3] - - rhs[i] += ( - f[indices1[0, i1], indices2[0, i2], indices3[0, i3]] - * value1 - * bsp21[indices2[0, i2], indices2[1, i2]] - * bsp22[indices2[0, i2], indices2[2, i2]] - * bsp31[ - indices3[0, i3], - indices3[1, i3], - ] - * bsp32[indices3[0, i3], indices3[2, i3]] - ) - - row[i] = n2i * n3i * indices1[1, i1] + n3i * indices2[1, i2] + indices3[1, i3] - col[i] = n2j * n3j * indices1[2, i1] + n3j * indices2[2, i2] + indices3[2, i3] - - -# ============================================================================= -def rhs12_f( - indices1: "int[:,:]", - indices2: "int[:,:]", - indices3: "int[:,:]", - n_row_sub2: "int[:]", - sub2_cum: "int[:]", - wts2: "float[:,:]", - bsp11: "float[:,:]", - bsp12: "float[:,:]", - bsp21: "float[:,:,:]", - bsp22: "float[:,:,:]", - bsp31: "float[:,:]", - bsp32: "float[:,:]", - mat_eq: "float[:,:,:,:]", - f: "float[:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - nq2 = shape(wts2)[1] - - nv1 = max_vec_int(indices1[3]) + 1 - nv2 = max_vec_int(indices2[3]) + 1 - nv3 = max_vec_int(indices3[3]) + 1 - - n1i = shape(bsp11)[1] - n2i = shape(bsp21)[2] - n3i = shape(bsp31)[1] - - n1j = shape(bsp12)[1] - n2j = shape(bsp22)[2] - n3j = shape(bsp32)[1] - - counter2 = 0 - rhs[:] = 0.0 - - for i1 in range(len(indices1[0])): - for i2 in range(len(indices2[0])): - for i3 in range(len(indices3[0])): - value1 = 0.0 - - counter2 = sub2_cum[indices2[0, i2]] - - for j2 in range(n_row_sub2[indices2[0, i2]]): - for q2 in range(nq2): - value1 += ( - wts2[indices2[0, i2] + j2 + counter2, q2] - * bsp21[indices2[0, i2] + j2 + counter2, q2, indices2[1, i2]] - * bsp22[ - indices2[ - 0, - i2, - ] - + j2 - + counter2, - q2, - indices2[2, i2], - ] - * mat_eq[indices1[0, i1], indices2[0, i2] + j2 + counter2, q2, indices3[0, i3]] - ) - - i = nv2 * nv3 * indices1[3, i1] + nv3 * indices2[3, i2] + indices3[3, i3] - - rhs[i] += ( - f[indices1[0, i1], indices2[0, i2], indices3[0, i3]] - * value1 - * bsp11[indices1[0, i1], indices1[1, i1]] - * bsp12[indices1[0, i1], indices1[2, i1]] - * bsp31[ - indices3[0, i3], - indices3[1, i3], - ] - * bsp32[indices3[0, i3], indices3[2, i3]] - ) - - row[i] = n2i * n3i * indices1[1, i1] + n3i * indices2[1, i2] + indices3[1, i3] - col[i] = n2j * n3j * indices1[2, i1] + n3j * indices2[2, i2] + indices3[2, i3] - - -# ============================================================================= -def rhs13_f( - indices1: "int[:,:]", - indices2: "int[:,:]", - indices3: "int[:,:]", - n_row_sub3: "int[:]", - sub3_cum: "int[:]", - wts3: "float[:,:]", - bsp11: "float[:,:]", - bsp12: "float[:,:]", - bsp21: "float[:,:]", - bsp22: "float[:,:]", - bsp31: "float[:,:,:]", - bsp32: "float[:,:,:]", - mat_eq: "float[:,:,:,:]", - f: "float[:,:,:]", - rhs: "float[:]", - row: "int[:]", - col: "int[:]", -): - nq3 = shape(wts3)[1] - - nv1 = max_vec_int(indices1[3]) + 1 - nv2 = max_vec_int(indices2[3]) + 1 - nv3 = max_vec_int(indices3[3]) + 1 - - n1i = shape(bsp11)[1] - n2i = shape(bsp21)[1] - n3i = shape(bsp31)[2] - - n1j = shape(bsp12)[1] - n2j = shape(bsp22)[1] - n3j = shape(bsp32)[2] - - counter3 = 0 - rhs[:] = 0.0 - - for i1 in range(len(indices1[0])): - for i2 in range(len(indices2[0])): - for i3 in range(len(indices3[0])): - value1 = 0.0 - - counter3 = sub3_cum[indices3[0, i3]] - - for j3 in range(n_row_sub3[indices3[0, i3]]): - for q3 in range(nq3): - value1 += ( - wts3[indices3[0, i3] + j3 + counter3, q3] - * bsp31[indices3[0, i3] + j3 + counter3, q3, indices3[1, i3]] - * bsp32[ - indices3[ - 0, - i3, - ] - + j3 - + counter3, - q3, - indices3[2, i3], - ] - * mat_eq[indices1[0, i1], indices2[0, i2], indices3[0, i3] + j3 + counter3, q3] - ) - - i = nv2 * nv3 * indices1[3, i1] + nv3 * indices2[3, i2] + indices3[3, i3] - - rhs[i] += ( - f[indices1[0, i1], indices2[0, i2], indices3[0, i3]] - * value1 - * bsp11[indices1[0, i1], indices1[1, i1]] - * bsp12[indices1[0, i1], indices1[2, i1]] - * bsp21[ - indices2[0, i2], - indices2[1, i2], - ] - * bsp22[indices2[0, i2], indices2[2, i2]] - ) - - row[i] = n2i * n3i * indices1[1, i1] + n3i * indices2[1, i2] + indices3[1, i3] - col[i] = n2j * n3j * indices1[2, i1] + n3j * indices2[2, i2] + indices3[2, i3] diff --git a/src/struphy/eigenvalue_solvers/legacy/MHD_eigenvalues_cylinder_1D.py b/src/struphy/eigenvalue_solvers/legacy/MHD_eigenvalues_cylinder_1D.py deleted file mode 100644 index a16b44e3d..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/MHD_eigenvalues_cylinder_1D.py +++ /dev/null @@ -1,749 +0,0 @@ -import cunumpy as xp -import scipy as sc -import scipy.sparse as spa -import scipy.special as sp - -import struphy.bsplines.bsplines as bsp -import struphy.eigenvalue_solvers.derivatives as der -import struphy.eigenvalue_solvers.kernels_projectors_global_mhd as ker -import struphy.eigenvalue_solvers.legacy.inner_products_1d as inner -import struphy.eigenvalue_solvers.mass_matrices_1d as mass -import struphy.eigenvalue_solvers.projectors_global as pro -import struphy.eigenvalue_solvers.spline_space as spl - - -# numerical solution of the general ideal MHD eigenvalue problem in a cylinder using 1d B-splines in radial direction -def solve_ev_problem(rho, B_phi, dB_phi, B_z, p, gamma, a, k, m, num_params, bcZ): - # 1d clamped B-spline space in [0, 1] - splines = spl.Spline_space_1d(num_params[0], num_params[1], False, num_params[2]) - - # mapping of radial coordinate from [0, 1] to [0, a] - r = lambda eta: a * eta - - # jacobian for integration - jac = lambda eta1: a * xp.ones(eta1.shape, dtype=float) - - # ========================== kinetic energy functional ============================== - # integrands (multiplied by -2/omega**2) - K_XX = lambda eta: rho(r(eta)) / r(eta) - K_VV = lambda eta: rho(r(eta)) * r(eta) - K_ZZ = lambda eta: rho(r(eta)) / r(eta) * (B_z(r(eta)) ** 2 + B_phi(r(eta)) ** 2) - - K_VZ = lambda eta: rho(r(eta)) * B_phi(r(eta)) - K_ZV = lambda eta: rho(r(eta)) * B_phi(r(eta)) - - # compute matrices - K_11 = mass.get_M(splines, 0, 0, K_XX, jac)[1:-1, 1:-1] - K_22 = mass.get_M(splines, 2, 2, K_VV, jac) - K_33 = mass.get_M(splines, 2, 2, K_ZZ, jac)[bcZ:, bcZ:] - - K_23 = mass.get_M(splines, 2, 2, K_VZ, jac)[:, bcZ:] - K_32 = mass.get_M(splines, 2, 2, K_ZV, jac)[bcZ:, :] - - K = spa.bmat([[K_11, None, None], [None, K_22, K_23], [None, K_32, K_33]]).toarray() - - ## test correct computation - # Bspline_A = Bsp.Bspline(splines.T, splines.p ) - # Bspline_B = Bsp.Bspline(splines.t, splines.p - 1) - # - # K_11_scipy = xp.zeros((splines.NbaseN, splines.NbaseN), dtype=float) - # K_22_scipy = xp.zeros((splines.NbaseD, splines.NbaseD), dtype=float) - # K_33_scipy = xp.zeros((splines.NbaseD, splines.NbaseD), dtype=float) - # K_23_scipy = xp.zeros((splines.NbaseD, splines.NbaseD), dtype=float) - # K_32_scipy = xp.zeros((splines.NbaseD, splines.NbaseD), dtype=float) - # - # for i in range(1, Bspline_A.N - 1): - # for j in range(1, Bspline_A.N - 1): - # integrand = lambda eta : a*K_XX(eta)*Bspline_A(eta, i)*Bspline_A(eta, j) - # K_11_scipy[i, j] = integrate.quad(integrand, 0., 1.)[0] - # - # for i in range(Bspline_B.N): - # for j in range(Bspline_B.N): - # integrand = lambda eta : a*K_VV(eta)*Bspline_B(eta, i)*Bspline_B(eta, j) - # K_22_scipy[i, j] = integrate.quad(integrand, 0., 1.)[0] - # - # if bcZ == 0: - # integrand = lambda eta : a*K_ZZ(eta)*Bspline_B(eta, i)*Bspline_B(eta, j) - # K_33_scipy[i, j] = integrate.quad(integrand, 0., 1.)[0] - # else: - # if i != 0 and j != 0: - # integrand = lambda eta : a*K_ZZ(eta)*Bspline_B(eta, i)*Bspline_B(eta, j) - # K_33_scipy[i, j] = integrate.quad(integrand, 0., 1.)[0] - # - # integrand = lambda eta : a*K_VZ(eta)*Bspline_B(eta, i)*Bspline_B(eta, j) - # K_23_scipy[i, j] = integrate.quad(integrand, 0., 1.)[0] - # - # integrand = lambda eta : a*K_ZV(eta)*Bspline_B(eta, i)*Bspline_B(eta, j) - # K_32_scipy[i, j] = integrate.quad(integrand, 0., 1.)[0] - - # assert xp.allclose(K_11.toarray(), K_11_scipy[1:-1, 1:-1]) - # assert xp.allclose(K_22.toarray(), K_22_scipy ) - # assert xp.allclose(K_33.toarray(), K_33_scipy[bcZ:, bcZ:]) - # assert xp.allclose(K_23.toarray(), K_23_scipy[ : , bcZ:]) - # assert xp.allclose(K_32.toarray(), K_32_scipy[bcZ:, :]) - - # ========================== potential energy functional =========================== - # integrands (multiplied by 2) - W_XX = ( - lambda eta: B_phi(r(eta)) ** 2 * m**2 / r(eta) ** 3 - + 2 * B_phi(r(eta)) ** 2 / r(eta) ** 3 - - 2 * B_phi(r(eta)) * dB_phi(r(eta)) / r(eta) ** 2 - + 2 * B_phi(r(eta)) * B_z(r(eta)) * k * m / r(eta) ** 2 - + B_z(r(eta)) ** 2 * k**2 / r(eta) - ) - - W_VV = ( - lambda eta: B_z(r(eta)) ** 2 * k**2 * r(eta) - + B_z(r(eta)) ** 2 * m**2 / r(eta) - + gamma * m**2 * p(r(eta)) / r(eta) - ) - - W_ZZ = ( - lambda eta: B_phi(r(eta)) ** 2 * gamma * m**2 * p(r(eta)) / r(eta) ** 3 - + 2 * B_phi(r(eta)) * B_z(r(eta)) * gamma * k * m * p(r(eta)) / r(eta) ** 2 - + B_z(r(eta)) ** 2 * gamma * k**2 * p(r(eta)) / r(eta) - ) - - W_dXdX = lambda eta: B_phi(r(eta)) ** 2 / r(eta) + B_z(r(eta)) ** 2 / r(eta) + gamma * p(r(eta)) / r(eta) - - W_XdX = lambda eta: -2 * B_phi(r(eta)) ** 2 / r(eta) ** 2 - W_dXX = lambda eta: -2 * B_phi(r(eta)) ** 2 / r(eta) ** 2 - - W_XV = lambda eta: 2 * B_phi(r(eta)) * B_z(r(eta)) * k / r(eta) - W_dXV = ( - lambda eta: -B_phi(r(eta)) * B_z(r(eta)) * k + B_z(r(eta)) ** 2 * m / r(eta) + gamma * m * p(r(eta)) / r(eta) - ) - - W_VX = lambda eta: 2 * B_phi(r(eta)) * B_z(r(eta)) * k / r(eta) - W_VdX = ( - lambda eta: -B_phi(r(eta)) * B_z(r(eta)) * k + B_z(r(eta)) ** 2 * m / r(eta) + gamma * m * p(r(eta)) / r(eta) - ) - - W_dXZ = lambda eta: B_phi(r(eta)) * gamma * m * p(r(eta)) / r(eta) ** 2 + B_z(r(eta)) * gamma * k * p(r(eta)) / r( - eta, - ) - W_ZdX = lambda eta: B_phi(r(eta)) * gamma * m * p(r(eta)) / r(eta) ** 2 + B_z(r(eta)) * gamma * k * p(r(eta)) / r( - eta, - ) - - W_VZ = lambda eta: B_phi(r(eta)) * gamma * m**2 * p(r(eta)) / r(eta) ** 2 + B_z(r(eta)) * gamma * k * m * p( - r(eta), - ) / r(eta) - W_ZV = lambda eta: B_phi(r(eta)) * gamma * m**2 * p(r(eta)) / r(eta) ** 2 + B_z(r(eta)) * gamma * k * m * p( - r(eta), - ) / r(eta) - - # compute matrices - W_11 = mass.get_M(splines, 0, 0, W_XX, jac)[1:-1, 1:-1] - W_11 += mass.get_M(splines, 1, 1, W_dXdX, jac)[1:-1, 1:-1] - W_11 += mass.get_M(splines, 1, 0, W_dXX, jac)[1:-1, 1:-1] - W_11 += mass.get_M(splines, 0, 1, W_XdX, jac)[1:-1, 1:-1] - - W_22 = mass.get_M(splines, 2, 2, W_VV, jac) - W_33 = mass.get_M(splines, 2, 2, W_ZZ, jac)[bcZ:, bcZ:] - - W_12 = mass.get_M(splines, 0, 2, W_XV, jac)[1:-1, :] - W_12 += mass.get_M(splines, 1, 2, W_dXV, jac)[1:-1, :] - - W_21 = mass.get_M(splines, 2, 0, W_VX, jac)[:, 1:-1] - W_21 += mass.get_M(splines, 2, 1, W_VdX, jac)[:, 1:-1] - - W_13 = mass.get_M(splines, 1, 2, W_dXZ, jac)[1:-1, bcZ:] - W_31 = mass.get_M(splines, 2, 1, W_ZdX, jac)[bcZ:, 1:-1] - - W_23 = mass.get_M(splines, 2, 2, W_VZ, jac)[:, bcZ:] - W_32 = mass.get_M(splines, 2, 2, W_ZV, jac)[bcZ:, :] - - # W_11[0, :] = 0.00000001 - # W_11[:, 0] = 0.00000001 - - # W_22[0, 0] = 0.00000001 - - W = spa.bmat([[W_11, W_12, W_13], [W_21, W_22, W_23], [W_31, W_32, W_33]]).toarray() - - # return W_22 - ## test correct computation - # W_11_scipy = xp.zeros((splines.NbaseN, splines.NbaseN), dtype=float) - # W_22_scipy = xp.zeros((splines.NbaseD, splines.NbaseD), dtype=float) - # W_33_scipy = xp.zeros((splines.NbaseD, splines.NbaseD), dtype=float) - # W_12_scipy = xp.zeros((splines.NbaseN, splines.NbaseD), dtype=float) - # W_21_scipy = xp.zeros((splines.NbaseD, splines.NbaseN), dtype=float) - # W_13_scipy = xp.zeros((splines.NbaseN, splines.NbaseD), dtype=float) - # W_31_scipy = xp.zeros((splines.NbaseD, splines.NbaseN), dtype=float) - # W_23_scipy = xp.zeros((splines.NbaseD, splines.NbaseD), dtype=float) - # W_32_scipy = xp.zeros((splines.NbaseD, splines.NbaseD), dtype=float) - # - # for i in range(1, Bspline_A.N - 1): - # for j in range(1, Bspline_A.N - 1): - # integrand = lambda eta : a * W_XX(eta) * Bspline_A(eta, i, 0) * Bspline_A(eta, j, 0) - # W_11_scipy[i, j] += integrate.quad(integrand, 0., 1.)[0] - # - # integrand = lambda eta : 1/a * W_dXdX(eta) * Bspline_A(eta, i, 1) * Bspline_A(eta, j, 1) - # W_11_scipy[i, j] += integrate.quad(integrand, 0., 1.)[0] - # - # integrand = lambda eta : W_dXX(eta) * Bspline_A(eta, i, 1) * Bspline_A(eta, j, 0) - # W_11_scipy[i, j] += integrate.quad(integrand, 0., 1.)[0] - # - # integrand = lambda eta : W_XdX(eta) * Bspline_A(eta, i, 0) * Bspline_A(eta, j, 1) - # W_11_scipy[i, j] += integrate.quad(integrand, 0., 1.)[0] - # - # assert xp.allclose(W_11.toarray(), W_11_scipy[1:-1, 1:-1]) - - # print(xp.allclose(K, K.T)) - # print(xp.allclose(W, W.T)) - - # solve eigenvalue problem omega**2*K*xi = W*xi - A = xp.linalg.inv(K).dot(W) - - omega2, XVZ_eig = xp.linalg.eig(A) - - # extract components - X_eig = XVZ_eig[: (splines.NbaseN - 2), :] - V_eig = XVZ_eig[(splines.NbaseN - 2) : (splines.NbaseN - 2 + splines.NbaseD), :] - Z_eig = XVZ_eig[(splines.NbaseN - 2 + splines.NbaseD) :, :] - - # add boundary conditions X(0) = X(1) = 0 - X_eig = xp.vstack((xp.zeros(X_eig.shape[1], dtype=float), X_eig, xp.zeros(X_eig.shape[1], dtype=float))) - - # add boundary condition Z(0) = 0 - if bcZ == 1: - Z_eig = xp.vstack((xp.zeros(Z_eig.shape[1], dtype=float), Z_eig)) - - return omega2, X_eig, V_eig, Z_eig - - -# numerical solution of the general ideal MHD eigenvalue problem in a cylinder using a 1d commuting diagram with B-splines in radial direction -def solve_ev_problem_FEEC(Rho, B_phi, dB_phi, B_z, dB_z, P, gamma, a, R0, n, m, num_params): - # 1d clamped B-spline space in [0, 1] - splines = spl.Spline_space_1d(num_params[0], num_params[1], False, num_params[2]) - proj = pro.projectors_global_1d(splines, num_params[3]) - GRAD = der.grad_1d_matrix(splines)[:, 1:-1] - GRAD_all = der.grad_1d_matrix(splines) - - # mapping of radial coordinate from [0, 1] to [0, a] - r = lambda eta: a * eta - - # components of metric tensor and Jacobian determinant - G_r = a**2 - G_phi = lambda eta: 4 * xp.pi**2 * r(eta) ** 2 - G_z = 4 * xp.pi**2 * R0**2 - J = lambda eta: 4 * xp.pi**2 * R0 * a * r(eta) - - # 2-from components of equilibrium magnetic field and its projection - B2_phi = lambda eta: 2 * xp.pi * R0 * a * B_phi(r(eta)) - B2_z = lambda eta: 2 * xp.pi * a * r(eta) * B_z(r(eta)) - - b2_eq_phi = xp.linalg.solve(proj.D.toarray(), proj.rhs_1(B2_phi)) - b2_eq_z = xp.append(xp.array([0.0]), xp.linalg.solve(proj.D.toarray()[1:, 1:], proj.rhs_1(B2_z)[1:])) - - # 3-form components of equilibrium density and pessure and its projection - Rho3 = lambda eta: J(eta) * Rho(r(eta)) - P3 = lambda eta: J(eta) * P(r(eta)) - - rho3_eq = xp.append(xp.array([0.0]), xp.linalg.solve(proj.D.toarray()[1:, 1:], proj.rhs_1(Rho3)[1:])) - p3_eq = xp.append(xp.array([0.0]), xp.linalg.solve(proj.D.toarray()[1:, 1:], proj.rhs_1(P3)[1:])) - - # 2-form components of initial velocity and its projection - U2_r = lambda eta: J(eta) * eta * (1 - eta) - - u2_r = proj.pi_0(U2_r) - u2_phi = -1 / (2 * xp.pi * m) * GRAD_all.dot(u2_r) - u2_z = xp.zeros(len(u2_phi), dtype=float) - - b2_r = xp.zeros(len(u2_r), dtype=float) - b2_phi = xp.zeros(len(u2_phi), dtype=float) - b2_z = xp.zeros(len(u2_z), dtype=float) - - p3 = xp.zeros(len(u2_z), dtype=float) - - # projection matrices - pi0_N_i, pi0_D_i, pi1_N_i, pi1_D_i = proj.projection_matrices_1d_reduced() - pi0_NN_i, pi0_DN_i, pi0_ND_i, pi0_DD_i, pi1_NN_i, pi1_DN_i, pi1_ND_i, pi1_DD_i = proj.projection_matrices_1d() - - # 1D collocation matrices for interpolation in format (point, global basis function) - x_int = xp.copy(proj.x_int) - - kind_splines = [False, True] - - basis_int_N = bsp.collocation_matrix(splines.T, splines.p, x_int, False, normalize=kind_splines[0]) - basis_int_D = bsp.collocation_matrix(splines.t, splines.p - 1, x_int, False, normalize=kind_splines[1]) - - # 1D integration sub-intervals, quadrature points and weights - if splines.p % 2 == 0: - x_his = xp.union1d(x_int, splines.el_b) - else: - x_his = xp.copy(x_int) - - pts, wts = bsp.quadrature_grid(x_his, proj.pts_loc, proj.wts_loc) - - # compute number of sub-intervals for integrations (even degree) - if splines.p % 2 == 0: - subs = 2 * xp.ones(proj.pts.shape[0], dtype=int) - - subs[: splines.p // 2] = 1 - subs[-splines.p // 2 :] = 1 - - # compute number of sub-intervals for integrations (odd degree) - else: - subs = xp.ones(proj.pts.shape[0], dtype=int) - - # evaluate basis functions on quadrature points in format (interval, local quad. point, global basis function) - basis_his_N = bsp.collocation_matrix(splines.T, splines.p, pts.flatten(), False, normalize=kind_splines[0]).reshape( - pts.shape[0], - pts.shape[1], - splines.NbaseN, - ) - basis_his_D = bsp.collocation_matrix( - splines.t, - splines.p - 1, - pts.flatten(), - False, - normalize=kind_splines[1], - ).reshape(pts.shape[0], pts.shape[1], splines.NbaseD) - - # shift first interpolation point away from pole - x_int[0] += 0.0001 - - return basis_his_D - - # ====== mass matrices ============================================================ - M3 = mass.get_M1(splines, mapping=J).toarray() - - M2_r = mass.get_M0(splines, mapping=lambda eta: G_r / J(eta)).toarray()[1:-1, 1:-1] - M2_phi = mass.get_M1(splines, mapping=lambda eta: J(eta) / G_phi(eta)).toarray() - M2_z = mass.get_M1(splines, mapping=lambda eta: J(eta) / G_z).toarray() - - # === matrices for curl of equilibrium field (with integration by parts) ========== - MB_12_eq = xp.empty((splines.NbaseN, splines.NbaseD), dtype=float) - MB_13_eq = xp.empty((splines.NbaseN, splines.NbaseD), dtype=float) - - MB_21_eq = xp.empty((splines.NbaseD, splines.NbaseN), dtype=float) - MB_31_eq = xp.empty((splines.NbaseD, splines.NbaseN), dtype=float) - - f_phi = xp.linalg.inv(proj.N.toarray()).T.dot(GRAD_all.T.dot(M2_phi.dot(b2_eq_phi))) - f_z = xp.linalg.inv(proj.N.toarray()).T.dot(GRAD_all.T.dot(M2_z.dot(b2_eq_z))) - - pi0_ND_phi = xp.empty(pi0_ND_i[3].max() + 1, dtype=float) - pi0_ND_z = xp.empty(pi0_ND_i[3].max() + 1, dtype=float) - - row_ND = xp.empty(pi0_ND_i[3].max() + 1, dtype=int) - col_ND = xp.empty(pi0_ND_i[3].max() + 1, dtype=int) - - pi0_DN_phi = xp.empty(pi0_DN_i[3].max() + 1, dtype=float) - pi0_DN_z = xp.empty(pi0_DN_i[3].max() + 1, dtype=float) - - row_DN = xp.empty(pi0_DN_i[3].max() + 1, dtype=int) - col_DN = xp.empty(pi0_DN_i[3].max() + 1, dtype=int) - - ker.rhs0_f_1d(pi0_ND_i, basis_int_N, basis_int_D, 1 / J(x_int), f_phi, pi0_ND_phi, row_ND, col_ND) - ker.rhs0_f_1d(pi0_ND_i, basis_int_N, basis_int_D, 1 / J(x_int), f_z, pi0_ND_z, row_ND, col_ND) - - ker.rhs0_f_1d(pi0_DN_i, basis_int_D, basis_int_N, 1 / J(x_int), f_phi, pi0_DN_phi, row_DN, col_DN) - ker.rhs0_f_1d(pi0_DN_i, basis_int_D, basis_int_N, 1 / J(x_int), f_z, pi0_DN_z, row_DN, col_DN) - - pi0_ND_phi = spa.csr_matrix((pi0_ND_phi, (row_ND, col_ND)), shape=(splines.NbaseN, splines.NbaseD)).toarray() - pi0_ND_z = spa.csr_matrix((pi0_ND_z, (row_ND, col_ND)), shape=(splines.NbaseN, splines.NbaseD)).toarray() - - pi0_DN_phi = spa.csr_matrix((pi0_DN_phi, (row_DN, col_DN)), shape=(splines.NbaseD, splines.NbaseN)).toarray() - pi0_DN_z = spa.csr_matrix((pi0_DN_z, (row_DN, col_DN)), shape=(splines.NbaseD, splines.NbaseN)).toarray() - - MB_12_eq[:, :] = -pi0_ND_phi - MB_13_eq[:, :] = -pi0_ND_z - - MB_21_eq[:, :] = -pi0_DN_phi - MB_31_eq[:, :] = -pi0_DN_z - - # === matrices for curl of equilibrium field (without integration by parts) ====== - MB_12_eq = xp.empty((splines.NbaseN, splines.NbaseD), dtype=float) - MB_13_eq = xp.empty((splines.NbaseN, splines.NbaseD), dtype=float) - - MB_21_eq = xp.empty((splines.NbaseD, splines.NbaseN), dtype=float) - MB_31_eq = xp.empty((splines.NbaseD, splines.NbaseN), dtype=float) - - cN = xp.empty(splines.NbaseN, dtype=float) - cD = xp.empty(splines.NbaseD, dtype=float) - - for j in range(splines.NbaseD): - cD[:] = 0.0 - cD[j] = 1.0 - - integrand2 = ( - lambda eta: splines.evaluate_D(eta, cD) / J(eta) * 2 * xp.pi * a * (B_phi(r(eta)) + r(eta) * dB_phi(r(eta))) - ) - integrand3 = lambda eta: splines.evaluate_D(eta, cD) / J(eta) * 2 * xp.pi * a * R0 * dB_z(r(eta)) - - MB_12_eq[:, j] = inner.inner_prod_V0(splines, integrand2) - MB_13_eq[:, j] = inner.inner_prod_V0(splines, integrand3) - - for j in range(splines.NbaseN): - cN[:] = 0.0 - cN[j] = 1.0 - - integrand2 = ( - lambda eta: splines.evaluate_N(eta, cN) / J(eta) * 2 * xp.pi * a * (B_phi(r(eta)) + r(eta) * dB_phi(r(eta))) - ) - integrand3 = lambda eta: splines.evaluate_N(eta, cN) / J(eta) * 2 * xp.pi * a * R0 * dB_z(r(eta)) - - MB_21_eq[:, j] = inner.inner_prod_V1(splines, integrand2) - MB_31_eq[:, j] = inner.inner_prod_V1(splines, integrand3) - - # ===== right-hand sides of projection matrices =============== - rhs0_N_phi = xp.empty(pi0_N_i[0].size, dtype=float) - rhs0_N_z = xp.empty(pi0_N_i[0].size, dtype=float) - - rhs1_D_phi = xp.empty(pi1_D_i[0].size, dtype=float) - rhs1_D_z = xp.empty(pi1_D_i[0].size, dtype=float) - - rhs0_N_pr = xp.empty(pi0_N_i[0].size, dtype=float) - rhs1_D_pr = xp.empty(pi1_D_i[0].size, dtype=float) - - rhs0_N_rho = xp.empty(pi0_N_i[0].size, dtype=float) - rhs1_D_rho = xp.empty(pi1_D_i[0].size, dtype=float) - - # ker.rhs0_1d(pi0_N_i[0], pi0_N_i[1], basis_int_N, splines.evaluate_D(x_int, b2_eq_phi)/J(x_int), rhs0_N_phi) - # ker.rhs0_1d(pi0_N_i[0], pi0_N_i[1], basis_int_N, splines.evaluate_D(x_int, b2_eq_z )/J(x_int), rhs0_N_z ) - # - # ker.rhs1_1d(pi1_D_i[0], pi1_D_i[1], subs, xp.append(0, xp.cumsum(subs - 1)[:-1]), wts, basis_his_D, (splines.evaluate_D(pts.flatten(), b2_eq_z )/J(pts.flatten())).reshape(pts.shape[0], pts.shape[1]), rhs1_D_z) - # ker.rhs1_1d(pi1_D_i[0], pi1_D_i[1], subs, xp.append(0, xp.cumsum(subs - 1)[:-1]), wts, basis_his_D, (splines.evaluate_D(pts.flatten(), b2_eq_phi)/J(pts.flatten())).reshape(pts.shape[0], pts.shape[1]), rhs1_D_phi) - # - # ker.rhs0_1d(pi0_N_i[0], pi0_N_i[1], basis_int_N, splines.evaluate_D(x_int, p3_eq)/J(x_int), rhs0_N_pr) - # temp = xp.empty(pi0_N_i[0].size, dtype=float) - # temp[:] = rhs0_N_pr - # ker.rhs1_1d(pi1_D_i[0], pi1_D_i[1], subs, xp.append(0, xp.cumsum(subs - 1)[:-1]), wts, basis_his_D, (splines.evaluate_D(pts.flatten(), p3_eq)/J(pts.flatten())).reshape(pts.shape[0], pts.shape[1]), rhs1_D_pr) - # - # ker.rhs0_1d(pi0_N_i[0], pi0_N_i[1], basis_int_N, splines.evaluate_D(x_int, rho3)/J(x_int), rhs0_N_rho) - # ker.rhs1_1d(pi1_D_i[0], pi1_D_i[1], subs, xp.append(0, xp.cumsum(subs - 1)[:-1]), wts, basis_his_D, (splines.evaluate_D(pts.flatten(), rho3)/J(pts.flatten())).reshape(pts.shape[0], pts.shape[1]), rhs1_D_rho) - - ker.rhs0_1d(pi0_N_i[0], pi0_N_i[1], basis_int_N, B2_phi(x_int) / J(x_int), rhs0_N_phi) - ker.rhs0_1d(pi0_N_i[0], pi0_N_i[1], basis_int_N, B2_z(x_int) / J(x_int), rhs0_N_z) - - ker.rhs1_1d( - pi1_D_i[0], - pi1_D_i[1], - subs, - xp.append(0, xp.cumsum(subs - 1)[:-1]), - wts, - basis_his_D, - (B2_phi(pts.flatten()) / J(pts.flatten())).reshape(pts.shape[0], pts.shape[1]), - rhs1_D_phi, - ) - - ker.rhs1_1d( - pi1_D_i[0], - pi1_D_i[1], - subs, - xp.append(0, xp.cumsum(subs - 1)[:-1]), - wts, - basis_his_D, - (B2_z(pts.flatten()) / J(pts.flatten())).reshape(pts.shape[0], pts.shape[1]), - rhs1_D_z, - ) - # ker.rhs1_1d(pi1_D_i[0], pi1_D_i[1], subs, xp.append(0, xp.cumsum(subs - 1)[:-1]), wts, basis_his_D, xp.ones(pts.shape, dtype=float), rhs1_D_z) - - ker.rhs0_1d(pi0_N_i[0], pi0_N_i[1], basis_int_N, P3(x_int) / J(x_int), rhs0_N_pr) - ker.rhs1_1d( - pi1_D_i[0], - pi1_D_i[1], - subs, - xp.append(0, xp.cumsum(subs - 1)[:-1]), - wts, - basis_his_D, - (P3(pts.flatten()) / J(pts.flatten())).reshape(pts.shape[0], pts.shape[1]), - rhs1_D_pr, - ) - - ker.rhs0_1d(pi0_N_i[0], pi0_N_i[1], basis_int_N, Rho3(x_int) / J(x_int), rhs0_N_rho) - ker.rhs1_1d( - pi1_D_i[0], - pi1_D_i[1], - subs, - xp.append(0, xp.cumsum(subs - 1)[:-1]), - wts, - basis_his_D, - (Rho3(pts.flatten()) / J(pts.flatten())).reshape(pts.shape[0], pts.shape[1]), - rhs1_D_rho, - ) - - rhs0_N_phi = spa.csr_matrix( - (rhs0_N_phi, (pi0_N_i[0], pi0_N_i[1])), - shape=(splines.NbaseN, splines.NbaseN), - ).toarray() - rhs0_N_z = spa.csr_matrix((rhs0_N_z, (pi0_N_i[0], pi0_N_i[1])), shape=(splines.NbaseN, splines.NbaseN)).toarray() - - rhs1_D_phi = spa.csr_matrix( - (rhs1_D_phi, (pi1_D_i[0], pi1_D_i[1])), - shape=(splines.NbaseD, splines.NbaseD), - ).toarray() - rhs1_D_z = spa.csr_matrix((rhs1_D_z, (pi1_D_i[0], pi1_D_i[1])), shape=(splines.NbaseD, splines.NbaseD)).toarray() - - # return rhs1_D_z - - rhs0_N_pr = spa.csr_matrix((rhs0_N_pr, (pi0_N_i[0], pi0_N_i[1])), shape=(splines.NbaseN, splines.NbaseN)).toarray() - rhs1_D_pr = spa.csr_matrix((rhs1_D_pr, (pi1_D_i[0], pi1_D_i[1])), shape=(splines.NbaseD, splines.NbaseD)).toarray() - - rhs0_N_rho = spa.csr_matrix( - (rhs0_N_rho, (pi0_N_i[0], pi0_N_i[1])), - shape=(splines.NbaseN, splines.NbaseN), - ).toarray() - rhs1_D_rho = spa.csr_matrix( - (rhs1_D_rho, (pi1_D_i[0], pi1_D_i[1])), - shape=(splines.NbaseD, splines.NbaseD), - ).toarray() - - pi0_N_phi = xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).dot(rhs0_N_phi[1:-1, 1:-1]) - pi0_N_z = xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).dot(rhs0_N_z[1:-1, 1:-1]) - - pi1_D_phi = xp.linalg.inv(proj.D.toarray()).dot(rhs1_D_phi) - pi1_D_z = xp.linalg.inv(proj.D.toarray()).dot(rhs1_D_z) - - pi0_N_pr = xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).dot(rhs0_N_pr[1:-1, 1:-1]) - pi1_D_pr = xp.linalg.inv(proj.D.toarray()).dot(rhs1_D_pr) - - pi0_N_rho = xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).dot(rhs0_N_rho[1:-1, 1:-1]) - pi1_D_rho = xp.linalg.inv(proj.D.toarray()).dot(rhs1_D_rho) - - # ======= matrices in strong induction equation ================ - # 11 block - I_11 = -2 * xp.pi * m * pi0_N_phi - 2 * xp.pi * n * pi0_N_z - - # 21 block and 31 block - I_21 = -GRAD.dot(pi0_N_phi) - I_31 = -GRAD.dot(pi0_N_z) - - # 22 block and 32 block - I_22 = 2 * xp.pi * n * pi1_D_z - I_32 = -2 * xp.pi * m * pi1_D_z - - # 23 block and 33 block - I_23 = -2 * xp.pi * n * pi1_D_phi - I_33 = 2 * xp.pi * m * pi1_D_phi - - # total - I_all = xp.block( - [ - [I_11, xp.zeros((len(u2_r) - 2, len(u2_phi))), xp.zeros((len(u2_r) - 2, len(u2_z) - 1))], - [I_21, I_22, I_23[:, 1:]], - [I_31[1:, :], I_32[1:, :], I_33[1:, 1:]], - ], - ) - - # ======= matrices in strong pressure equation ================ - P_1 = -GRAD.dot(pi0_N_pr) - (gamma - 1) * pi1_D_pr.dot(GRAD) - P_2 = -2 * xp.pi * m * gamma * pi1_D_pr - P_3 = -2 * xp.pi * n * gamma * pi1_D_pr - - P_all = xp.block([[P_1[1:, :], P_2[1:, :], P_3[1:, 1:]]]) - - # ========== matrices in weak momentum balance equation ====== - A_1 = 1 / 2 * (pi0_N_rho.T.dot(M2_r) + M2_r.dot(pi0_N_rho)) - A_2 = 1 / 2 * (pi1_D_rho.T.dot(M2_phi) + M2_phi.dot(pi1_D_rho)) - A_3 = 1 / 2 * (pi1_D_rho.T.dot(M2_z) + M2_z.dot(pi1_D_rho))[:, :] - - A_all = xp.block( - [ - [A_1, xp.zeros((A_1.shape[0], A_2.shape[1])), xp.zeros((A_1.shape[0], A_3.shape[1]))], - [xp.zeros((A_2.shape[0], A_1.shape[1])), A_2, xp.zeros((A_2.shape[0], A_3.shape[1]))], - [xp.zeros((A_3.shape[0], A_1.shape[1])), xp.zeros((A_3.shape[0], A_2.shape[1])), A_3], - ], - ) - - MB_11 = 2 * xp.pi * n * pi0_N_z.T.dot(M2_r) + 2 * xp.pi * m * pi0_N_phi.T.dot(M2_r) - MB_12 = pi0_N_phi.T.dot(GRAD.T.dot(M2_phi)) - MB_12_eq[1:-1, :] - MB_13 = pi0_N_z.T.dot(GRAD.T.dot(M2_z)) - MB_13_eq[1:-1, :] - MB_14 = GRAD.T.dot(M3) - - MB_21 = MB_21_eq[:, 1:-1] - MB_22 = -2 * xp.pi * n * pi1_D_z.T.dot(M2_phi) - MB_23 = 2 * xp.pi * m * pi1_D_z.T.dot(M2_z) - MB_24 = 2 * xp.pi * m * M3 - - MB_31 = MB_31_eq[:, 1:-1] - MB_32 = 2 * xp.pi * n * pi1_D_phi.T.dot(M2_phi) - MB_33 = -2 * xp.pi * m * pi1_D_phi.T.dot(M2_z) - MB_34 = 2 * xp.pi * n * M3 - - MB_b_all = xp.block( - [[MB_11, MB_12, MB_13[:, 1:]], [MB_21, MB_22, MB_23[:, 1:]], [MB_31[1:, :], MB_32[1:, :], MB_33[1:, 1:]]], - ) - MB_p_all = xp.block([[MB_14[:, 1:]], [MB_24[:, 1:]], [MB_34[1:, 1:]]]) - - ## ======= matrices in strong induction equation ================ - ## 11 block - # I_11 = xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).dot(-2*xp.pi*m*rhs0_N_phi[1:-1, 1:-1] - 2*xp.pi*n*rhs0_N_z[1:-1, 1:-1]) - # - ## 21 block and 31 block - # I_21 = -GRAD[: , 1:-1].dot(xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).dot(rhs0_N_phi[1:-1, 1:-1])) - # I_31 = -GRAD[1:, 1:-1].dot(xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).dot(rhs0_N_z[1:-1, 1:-1])) - # - ## 22 block and 32 block - # I_22 = 2*xp.pi*n*xp.linalg.inv(proj.D.toarray()[ :, :]).dot(rhs1_D_z[ :, :]) - # I_32 = -2*xp.pi*m*xp.linalg.inv(proj.D.toarray()[1:, 1:]).dot(rhs1_D_z[1:, :]) - # - ## 23 block and 33 block - # I_23 = -2*xp.pi*n*xp.linalg.inv(proj.D.toarray()[ :, :]).dot(rhs1_D_phi[ :, 1:]) - # I_33 = 2*xp.pi*m*xp.linalg.inv(proj.D.toarray()[1:, 1:]).dot(rhs1_D_phi[1:, 1:]) - # - # - ## ======= matrices in strong pressure equation ================ - # P_1 = -GRAD[1:, 1:-1].dot(xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).dot(rhs0_N_pr[1:-1, 1:-1])) - (gamma - 1)*xp.linalg.inv(proj.D.toarray()[1:, 1:]).dot(rhs1_D_pr[1:, :].dot(GRAD[:, 1:-1])) - # P_2 = -2*xp.pi*m*gamma*xp.linalg.inv(proj.D.toarray()[1:, 1:]).dot(rhs1_D_pr[1:, :]) - # P_3 = -2*xp.pi*n*gamma*xp.linalg.inv(proj.D.toarray()[1:, 1:]).dot(rhs1_D_pr[1:, 1:]) - # - # - ## ========== matrices in weak momentum balance equation ====== - # rhs0_N_rho = xp.empty(pi0_N_i[0].size, dtype=float) - # ker.rhs0_1d(pi0_N_i[0], pi0_N_i[1], basis_int_N, splines.evaluate_D(x_int, rho3)/J(x_int), rhs0_N_rho) - # - # - # rhs1_D_rho = xp.empty(pi1_D_i[0].size, dtype=float) - # ker.rhs1_1d(pi1_D_i[0], pi1_D_i[1], subs, xp.append(0, xp.cumsum(subs - 1)[:-1]), wts, basis_his_D, (splines.evaluate_D(pts.flatten(), rho3)/J(pts.flatten())).reshape(pts.shape[0], pts.shape[1]), rhs1_D_rho) - # - # - # - # A_1 = 1/2*(rhs0_N_rho[1:-1, 1:-1].T.dot(xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).T.dot(M2_r[1:-1, 1:-1])) + M2_r[1:-1, 1:-1].dot(xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).dot(rhs0_N_rho[1:-1, 1:-1]))) - # A_2 = 1/2*(rhs1_D_rho.T.dot(xp.linalg.inv(proj.D.toarray()[:, :]).T.dot(M2_phi)) + M2_phi.dot(xp.linalg.inv(proj.D.toarray()[:, :]).dot(rhs1_D_rho))) - # A_3 = 1/2*(rhs1_D_rho[1:, 1:].T.dot(xp.linalg.inv(proj.D.toarray()[1:, 1:]).T.dot(M2_z[1:, 1:])) + M2_z[1:, 1:].dot(xp.linalg.inv(proj.D.toarray()[1:, 1:]).dot(rhs1_D_rho[1:, 1:]))) - # - # - # MB_11 = 2*xp.pi*n*rhs0_N_z[1:-1, 1:-1].T.dot(xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).T.dot(M2_r[1:-1, 1:-1])) + 2*xp.pi*m*rhs0_N_phi[1:-1, 1:-1].T.dot(xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).T.dot(M2_r[1:-1, 1:-1])) - # - # MB_12 = rhs0_N_phi[1:-1, 1:-1].T.dot(xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).T.dot(GRAD[:, 1:-1].T.dot(M2_phi))) - # MB_13 = rhs0_N_z[1:-1, 1:-1].T.dot(xp.linalg.inv(proj.N.toarray()[1:-1, 1:-1]).T.dot(GRAD[1:, 1:-1].T.dot(M2_z[1:, 1:]))) - # - # MB_14 = GRAD[1:, 1:-1].T.dot(M3[1:, 1:]) - # - # - # MB_22 = -2*xp.pi*n*rhs1_D_z.T.dot(xp.linalg.inv(proj.D.toarray()).T.dot(M2_phi)) - # MB_23 = 2*xp.pi*m*rhs1_D_z[1:, :].T.dot(xp.linalg.inv(proj.D.toarray()[1:, 1:]).T.dot(M2_z[1:, 1:])) - # MB_24 = 2*xp.pi*m*M3[ :, 1:] - # - # MB_32 = 2*xp.pi*n*rhs1_D_phi[:, 1:].T.dot(xp.linalg.inv(proj.D.toarray()).T.dot(M2_phi)) - # MB_33 = -2*xp.pi*m*rhs1_D_phi[1:, 1:].T.dot(xp.linalg.inv(proj.D.toarray()[1:, 1:]).T.dot(M2_z[1:, 1:])) - # MB_34 = 2*xp.pi*n*M3[1:, 1:] - # - # - # ==== matrices in eigenvalue problem ======== - W_11 = MB_11.dot(I_11) + MB_12.dot(I_21) + MB_13.dot(I_31) + MB_14.dot(P_1) - W_12 = MB_12.dot(I_22) + MB_13.dot(I_32) + MB_14.dot(P_2) - W_13 = MB_12.dot(I_23) + MB_13.dot(I_33) + MB_14.dot(P_3) - - W_21 = MB_21.dot(I_11) + MB_22.dot(I_21) + MB_23.dot(I_31) + MB_24.dot(P_1) - W_22 = MB_22.dot(I_22) + MB_23.dot(I_32) + MB_24.dot(P_2) - W_23 = MB_22.dot(I_23) + MB_23.dot(I_33) + MB_24.dot(P_3) - - W_31 = MB_31.dot(I_11) + MB_32.dot(I_21) + MB_33.dot(I_31) + MB_34.dot(P_1) - W_32 = MB_32.dot(I_22) + MB_33.dot(I_32) + MB_34.dot(P_2) - W_33 = MB_32.dot(I_23) + MB_33.dot(I_33) + MB_34.dot(P_3) - - # W = xp.block([[W_11, W_12, W_13[:, 1:]], [W_21, W_22, W_23[:, 1:]], [W_31[1:, :], W_32[1:, :], W_33[1:, 1:]]]) - W = xp.block([[W_11, W_12, W_13[:, :]], [W_21, W_22, W_23[:, :]], [W_31[:, :], W_32[:, :], W_33[:, :]]]) - - # print(xp.allclose(K, K.T)) - # print(xp.allclose(W, W.T)) - - # solve eigenvalue problem omega**2*K*xi = W*xi - MAT = xp.linalg.inv(-A_all).dot(W) - - omega2, XYZ_eig = xp.linalg.eig(MAT) - # omega2, XYZ_eig = xp.linalg.eig(xp.linalg.inv(-A_all).dot(MB_b_all.dot(I_all) + MB_p_all.dot(P_all))) - - # extract components - X_eig = XYZ_eig[: (splines.NbaseN - 2), :] - Y_eig = XYZ_eig[(splines.NbaseN - 2) : (splines.NbaseN - 2 + splines.NbaseD), :] - Z_eig = XYZ_eig[(splines.NbaseN - 2 + splines.NbaseD) :, :] - - # add boundary conditions X(0) = X(1) = 0 - X_eig = xp.vstack((xp.zeros(X_eig.shape[1], dtype=float), X_eig, xp.zeros(X_eig.shape[1], dtype=float))) - - # add boundary condition Z(0) = 0 - Z_eig = xp.vstack((xp.zeros(Z_eig.shape[1], dtype=float), Z_eig)) - - return omega2, X_eig, Y_eig, Z_eig - - ## ========== matrices in initial value problem === - LHS = xp.block( - [ - [A_all, xp.zeros((A_all.shape[0], A_all.shape[1])), xp.zeros((A_all.shape[0], len(p3) - 1))], - [ - xp.zeros((A_all.shape[0], A_all.shape[1])), - xp.identity(A_all.shape[0]), - xp.zeros((A_all.shape[0], len(p3) - 1)), - ], - [ - xp.zeros((len(p3) - 1, A_all.shape[1])), - xp.zeros((len(p3) - 1, A_all.shape[1])), - xp.identity(len(p3) - 1), - ], - ], - ) - - RHS = xp.block( - [ - [xp.zeros((MB_b_all.shape[0], I_all.shape[1])), MB_b_all, MB_p_all], - [I_all, xp.zeros((I_all.shape[0], MB_b_all.shape[1])), xp.zeros((I_all.shape[0], MB_p_all.shape[1]))], - [P_all, xp.zeros((P_all.shape[0], MB_b_all.shape[1])), xp.zeros((P_all.shape[0], MB_p_all.shape[1]))], - ], - ) - - dt = 0.05 - T = 200.0 - Nt = int(T / dt) - - UPDATE = xp.linalg.inv(LHS - dt / 2 * RHS).dot(LHS + dt / 2 * RHS) - ##UPDATE = xp.linalg.inv(LHS).dot(LHS + dt*RHS) - # - # lambdas, eig_vecs = xp.linalg.eig(UPDATE) - - # return lambdas - # - # return lambdas - # - u2_r_all = xp.zeros((Nt + 1, len(u2_r)), dtype=float) - u2_phi_all = xp.zeros((Nt + 1, len(u2_phi)), dtype=float) - u2_z_all = xp.zeros((Nt + 1, len(u2_z)), dtype=float) - - b2_r_all = xp.zeros((Nt + 1, len(b2_r)), dtype=float) - b2_phi_all = xp.zeros((Nt + 1, len(b2_phi)), dtype=float) - b2_z_all = xp.zeros((Nt + 1, len(b2_z)), dtype=float) - - p3_all = xp.zeros((Nt + 1, len(p3)), dtype=float) - - # initialization - # u2_r_all[0, :] = u2_r - # u2_phi_all[0, :] = u2_phi - - u2_r_all[0, 1:-1] = xp.random.rand(len(u2_r) - 2) - p3_all[0, 1:] = xp.random.rand(len(p3) - 1) - - # time integration - for n in range(Nt): - old = xp.concatenate( - ( - u2_r_all[n, 1:-1], - u2_phi_all[n, :], - u2_z_all[n, 1:], - b2_r_all[n, 1:-1], - b2_phi_all[n, :], - b2_z_all[n, 1:], - p3_all[n, 1:], - ), - ) - new = UPDATE.dot(old) - - # extract components - unew, bnew, pnew = xp.split( - new, - [len(u2_r) - 2 + len(u2_phi) + len(u2_z) - 1, 2 * (len(u2_r) - 2 + len(u2_phi) + len(u2_z) - 1)], - ) - - u2_r_all[n + 1, :] = xp.array([0.0] + list(unew[: (splines.NbaseN - 2)]) + [0.0]) - u2_phi_all[n + 1, :] = unew[(splines.NbaseN - 2) : (splines.NbaseN - 2 + splines.NbaseD)] - u2_z_all[n + 1, :] = xp.array([0.0] + list(unew[(splines.NbaseN - 2 + splines.NbaseD) :])) - - b2_r_all[n + 1, :] = xp.array([0.0] + list(bnew[: (splines.NbaseN - 2)]) + [0.0]) - b2_phi_all[n + 1, :] = bnew[(splines.NbaseN - 2) : (splines.NbaseN - 2 + splines.NbaseD)] - b2_z_all[n + 1, :] = xp.array([0.0] + list(bnew[(splines.NbaseN - 2 + splines.NbaseD) :])) - - p3_all[n + 1, :] = xp.array([0.0] + list(pnew)) - - return u2_r_all, u2_phi_all, u2_z_all, b2_r_all, b2_phi_all, b2_z_all, p3_all, omega2 diff --git a/src/struphy/eigenvalue_solvers/legacy/__init__.py b/src/struphy/eigenvalue_solvers/legacy/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/struphy/eigenvalue_solvers/legacy/control_variates/__init__.py b/src/struphy/eigenvalue_solvers/legacy/control_variates/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/struphy/eigenvalue_solvers/legacy/control_variates/control_variate.py b/src/struphy/eigenvalue_solvers/legacy/control_variates/control_variate.py deleted file mode 100644 index a4b95eb06..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/control_variates/control_variate.py +++ /dev/null @@ -1,787 +0,0 @@ -# coding: utf-8 -# -# Copyright 2020 Florian Holderied (florian.holderied@ipp.mpg.de) - -""" -Class for control variates in delta-f method for current coupling scheme. -""" - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.feec.basics.kernels_3d as ker -import struphy.feec.control_variates.kernels_control_variate as ker_cv - - -class terms_control_variate: - """ - Contains method for computing the terms (B x jh_eq) and -(rhoh_eq * (B x U)). - - Parameters - ---------- - tensor_space_FEM : Tensor_spline_space - 3D tensor product B-spline space - - domain : domain - domain object defining the geometry - - basis_u : int - representation of MHD bulk velocity - """ - - def __init__(self, tensor_space_FEM, domain, basis_u): - self.space = tensor_space_FEM # 3D B-spline space - self.basis_u = basis_u # representation of MHD bulk velocity - - if self.basis_u == 0: - kind_fun_eq = [1, 2, 3, 4] - - elif self.basis_u == 2: - kind_fun_eq = [11, 12, 13, 14] - - # ========= evaluation of DF^(-1) * jh_eq_phys * |det(DF)| at quadrature points ========= - self.mat_jh1 = xp.empty( - ( - self.space.Nel[0], - self.space.n_quad[0], - self.space.Nel[1], - self.space.n_quad[1], - self.space.Nel[2], - self.space.n_quad[2], - ), - dtype=float, - ) - self.mat_jh2 = xp.empty( - ( - self.space.Nel[0], - self.space.n_quad[0], - self.space.Nel[1], - self.space.n_quad[1], - self.space.Nel[2], - self.space.n_quad[2], - ), - dtype=float, - ) - self.mat_jh3 = xp.empty( - ( - self.space.Nel[0], - self.space.n_quad[0], - self.space.Nel[1], - self.space.n_quad[1], - self.space.Nel[2], - self.space.n_quad[2], - ), - dtype=float, - ) - - ker_cv.kernel_evaluation_quad( - self.space.Nel, - self.space.n_quad, - self.space.pts[0], - self.space.pts[1], - self.space.pts[2], - self.mat_jh1, - kind_fun_eq[0], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - ker_cv.kernel_evaluation_quad( - self.space.Nel, - self.space.n_quad, - self.space.pts[0], - self.space.pts[1], - self.space.pts[2], - self.mat_jh2, - kind_fun_eq[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - ker_cv.kernel_evaluation_quad( - self.space.Nel, - self.space.n_quad, - self.space.pts[0], - self.space.pts[1], - self.space.pts[2], - self.mat_jh3, - kind_fun_eq[2], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - # ========= evaluation of nh_eq_phys * |det(DF)| at quadrature points =================== - self.mat_nh = xp.empty( - ( - self.space.Nel[0], - self.space.n_quad[0], - self.space.Nel[1], - self.space.n_quad[1], - self.space.Nel[2], - self.space.n_quad[2], - ), - dtype=float, - ) - - ker_cv.kernel_evaluation_quad( - self.space.Nel, - self.space.n_quad, - self.space.pts[0], - self.space.pts[1], - self.space.pts[2], - self.mat_nh, - kind_fun_eq[3], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - # =========== 2-form magnetic field at quadrature points ================================= - self.B2_1 = xp.empty( - ( - self.space.Nel[0], - self.space.n_quad[0], - self.space.Nel[1], - self.space.n_quad[1], - self.space.Nel[2], - self.space.n_quad[2], - ), - dtype=float, - ) - self.B2_2 = xp.empty( - ( - self.space.Nel[0], - self.space.n_quad[0], - self.space.Nel[1], - self.space.n_quad[1], - self.space.Nel[2], - self.space.n_quad[2], - ), - dtype=float, - ) - self.B2_3 = xp.empty( - ( - self.space.Nel[0], - self.space.n_quad[0], - self.space.Nel[1], - self.space.n_quad[1], - self.space.Nel[2], - self.space.n_quad[2], - ), - dtype=float, - ) - - # ================== correction matrices in step 1 ======================== - if self.basis_u == 0: - self.M12 = xp.empty( - ( - self.space.NbaseN[0], - self.space.NbaseN[1], - self.space.NbaseN[2], - 2 * self.space.p[0] + 1, - 2 * self.space.p[1] + 1, - 2 * self.space.p[2] + 1, - ), - dtype=float, - ) - self.M13 = xp.empty( - ( - self.space.NbaseN[0], - self.space.NbaseN[1], - self.space.NbaseN[2], - 2 * self.space.p[0] + 1, - 2 * self.space.p[1] + 1, - 2 * self.space.p[2] + 1, - ), - dtype=float, - ) - self.M23 = xp.empty( - ( - self.space.NbaseN[0], - self.space.NbaseN[1], - self.space.NbaseN[2], - 2 * self.space.p[0] + 1, - 2 * self.space.p[1] + 1, - 2 * self.space.p[2] + 1, - ), - dtype=float, - ) - - elif self.basis_u == 2: - self.M12 = xp.empty( - ( - self.space.NbaseN[0], - self.space.NbaseD[1], - self.space.NbaseD[2], - 2 * self.space.p[0] + 1, - 2 * self.space.p[1] + 1, - 2 * self.space.p[2] + 1, - ), - dtype=float, - ) - self.M13 = xp.empty( - ( - self.space.NbaseN[0], - self.space.NbaseD[1], - self.space.NbaseD[2], - 2 * self.space.p[0] + 1, - 2 * self.space.p[1] + 1, - 2 * self.space.p[2] + 1, - ), - dtype=float, - ) - self.M23 = xp.empty( - ( - self.space.NbaseD[0], - self.space.NbaseN[1], - self.space.NbaseD[2], - 2 * self.space.p[0] + 1, - 2 * self.space.p[1] + 1, - 2 * self.space.p[2] + 1, - ), - dtype=float, - ) - - # ==================== correction vectors in step 3 ======================= - if self.basis_u == 0: - self.F1 = xp.empty((self.space.NbaseN[0], self.space.NbaseN[1], self.space.NbaseN[2]), dtype=float) - self.F2 = xp.empty((self.space.NbaseN[0], self.space.NbaseN[1], self.space.NbaseN[2]), dtype=float) - self.F3 = xp.empty((self.space.NbaseN[0], self.space.NbaseN[1], self.space.NbaseN[2]), dtype=float) - - elif self.basis_u == 2: - self.F1 = xp.empty((self.space.NbaseN[0], self.space.NbaseD[1], self.space.NbaseD[2]), dtype=float) - self.F2 = xp.empty((self.space.NbaseD[0], self.space.NbaseN[1], self.space.NbaseD[2]), dtype=float) - self.F3 = xp.empty((self.space.NbaseD[0], self.space.NbaseD[1], self.space.NbaseN[2]), dtype=float) - - # ===== inner product in V0^3 resp. V2 of (B x jh_eq) - term ========== - def inner_prod_jh_eq(self, b1, b2, b3): - """ - Computes the inner product of the term - - (B x (DF^(-1) * jh_eq_phys) * |det(DF)|) (if MHD bulk velocity is a vector field) - (B x (DF^(-1) * jh_eq_phys) ) (if MHD bulk velocity is a 2-form) - - with each basis function in V0^3, respectively V2. - - Parameters - ---------- - b1 : array_like - the B-field FEM coefficients (1-component) - - b2 : array_like - the B-field FEM coefficients (2-component) - - b3 : array_like - the B-field FEM coefficients (3-component) - - Returns - ------- - F : array_like - inner products with each basis function in V0^3 resp. V2 - """ - - # evaluation of magnetic field at quadrature points - ker.kernel_evaluate_2form( - self.space.Nel, - self.space.p, - [0, 1, 1], - self.space.n_quad, - b1, - self.space.Nbase_2form[0], - self.space.basisN[0], - self.space.basisD[1], - self.space.basisD[2], - self.B2_1, - ) - ker.kernel_evaluate_2form( - self.space.Nel, - self.space.p, - [1, 0, 1], - self.space.n_quad, - b2, - self.space.Nbase_2form[1], - self.space.basisD[0], - self.space.basisN[1], - self.space.basisD[2], - self.B2_2, - ) - ker.kernel_evaluate_2form( - self.space.Nel, - self.space.p, - [1, 1, 0], - self.space.n_quad, - b3, - self.space.Nbase_2form[2], - self.space.basisD[0], - self.space.basisD[1], - self.space.basisN[2], - self.B2_3, - ) - - if self.basis_u == 0: - # assembly of F (1-component) - ker.kernel_inner( - self.space.Nel[0], - self.space.Nel[1], - self.space.Nel[2], - self.space.p[0], - self.space.p[1], - self.space.p[2], - self.space.n_quad[0], - self.space.n_quad[1], - self.space.n_quad[2], - 0, - 0, - 0, - self.space.wts[0], - self.space.wts[1], - self.space.wts[2], - self.space.basisN[0], - self.space.basisN[1], - self.space.basisN[2], - self.space.NbaseN[0], - self.space.NbaseN[1], - self.space.NbaseN[2], - self.F1, - self.B2_2 * self.mat_jh3 - self.B2_3 * self.mat_jh2, - ) - - # assembly of F (2-component) - ker.kernel_inner( - self.space.Nel[0], - self.space.Nel[1], - self.space.Nel[2], - self.space.p[0], - self.space.p[1], - self.space.p[2], - self.space.n_quad[0], - self.space.n_quad[1], - self.space.n_quad[2], - 0, - 0, - 0, - self.space.wts[0], - self.space.wts[1], - self.space.wts[2], - self.space.basisN[0], - self.space.basisN[1], - self.space.basisN[2], - self.space.NbaseN[0], - self.space.NbaseN[1], - self.space.NbaseN[2], - self.F2, - self.B2_3 * self.mat_jh1 - self.B2_1 * self.mat_jh3, - ) - - # assembly of F (3-component) - ker.kernel_inner( - self.space.Nel[0], - self.space.Nel[1], - self.space.Nel[2], - self.space.p[0], - self.space.p[1], - self.space.p[2], - self.space.n_quad[0], - self.space.n_quad[1], - self.space.n_quad[2], - 0, - 0, - 0, - self.space.wts[0], - self.space.wts[1], - self.space.wts[2], - self.space.basisN[0], - self.space.basisN[1], - self.space.basisN[2], - self.space.NbaseN[0], - self.space.NbaseN[1], - self.space.NbaseN[2], - self.F3, - self.B2_1 * self.mat_jh2 - self.B2_2 * self.mat_jh1, - ) - - elif self.basis_u == 2: - # assembly of F (1-component) - ker.kernel_inner( - self.space.Nel[0], - self.space.Nel[1], - self.space.Nel[2], - self.space.p[0], - self.space.p[1], - self.space.p[2], - self.space.n_quad[0], - self.space.n_quad[1], - self.space.n_quad[2], - 0, - 1, - 1, - self.space.wts[0], - self.space.wts[1], - self.space.wts[2], - self.space.basisN[0], - self.space.basisD[1], - self.space.basisD[2], - self.space.NbaseN[0], - self.space.NbaseD[1], - self.space.NbaseD[2], - self.F1, - self.B2_2 * self.mat_jh3 - self.B2_3 * self.mat_jh2, - ) - - # assembly of F (2-component) - ker.kernel_inner( - self.space.Nel[0], - self.space.Nel[1], - self.space.Nel[2], - self.space.p[0], - self.space.p[1], - self.space.p[2], - self.space.n_quad[0], - self.space.n_quad[1], - self.space.n_quad[2], - 1, - 0, - 1, - self.space.wts[0], - self.space.wts[1], - self.space.wts[2], - self.space.basisD[0], - self.space.basisN[1], - self.space.basisD[2], - self.space.NbaseD[0], - self.space.NbaseN[1], - self.space.NbaseD[2], - self.F2, - self.B2_3 * self.mat_jh1 - self.B2_1 * self.mat_jh3, - ) - - # assembly of F (3-component) - ker.kernel_inner( - self.space.Nel[0], - self.space.Nel[1], - self.space.Nel[2], - self.space.p[0], - self.space.p[1], - self.space.p[2], - self.space.n_quad[0], - self.space.n_quad[1], - self.space.n_quad[2], - 1, - 1, - 0, - self.space.wts[0], - self.space.wts[1], - self.space.wts[2], - self.space.basisD[0], - self.space.basisD[1], - self.space.basisN[2], - self.space.NbaseD[0], - self.space.NbaseD[1], - self.space.NbaseN[2], - self.F3, - self.B2_1 * self.mat_jh2 - self.B2_2 * self.mat_jh1, - ) - - return xp.concatenate((self.F1.flatten(), self.F2.flatten(), self.F3.flatten())) - - # ===== mass matrix in V0^3 resp. V2 of -(rhoh_eq * (B x U)) - term ======= - def mass_nh_eq(self, b1, b2, b3): - """ - Computes the mass matrix in V0^3 respectively V2 weighted with the term - - -(rhoh_eq_phys * |det(DF)| B x) (if MHD bulk velocity is a vector field) - -(rhoh_eq_phys / |det(DF)| B x) (if MHD bulk velocity is a 2-form) - - - Parameters - ---------- - b1 : array_like - the B-field FEM coefficients (1-component) - - b2 : array_like - the B-field FEM coefficients (2-component) - - b3 : array_like - the B-field FEM coefficients (3-component) - - Returns - ------- - M12 : 6D array - 12 block of weighted mass matrix - - M13 : 6D array - 13 block of weighted mass matrix - - M23 : 6D array - 23 block of weighted mass matrix - """ - - # evaluation of magnetic field at quadrature points - ker.kernel_evaluate_2form( - self.space.Nel, - self.space.p, - [0, 1, 1], - self.space.n_quad, - b1, - self.space.Nbase_2form[0], - self.space.basisN[0], - self.space.basisD[1], - self.space.basisD[2], - self.B2_1, - ) - ker.kernel_evaluate_2form( - self.space.Nel, - self.space.p, - [1, 0, 1], - self.space.n_quad, - b2, - self.space.Nbase_2form[1], - self.space.basisD[0], - self.space.basisN[1], - self.space.basisD[2], - self.B2_2, - ) - ker.kernel_evaluate_2form( - self.space.Nel, - self.space.p, - [1, 1, 0], - self.space.n_quad, - b3, - self.space.Nbase_2form[2], - self.space.basisD[0], - self.space.basisD[1], - self.space.basisN[2], - self.B2_3, - ) - - if self.basis_u == 0: - # assembly of M12 - ker.kernel_mass( - self.space.Nel[0], - self.space.Nel[1], - self.space.Nel[2], - self.space.p[0], - self.space.p[1], - self.space.p[2], - self.space.n_quad[0], - self.space.n_quad[1], - self.space.n_quad[2], - 0, - 0, - 0, - 0, - 0, - 0, - self.space.wts[0], - self.space.wts[1], - self.space.wts[2], - self.space.basisN[0], - self.space.basisN[1], - self.space.basisN[2], - self.space.basisN[0], - self.space.basisN[1], - self.space.basisN[2], - self.space.indN[0], - self.space.indN[1], - self.space.indN[2], - self.M12, - +self.mat_nh * self.B2_3, - ) - - # assembly of M13 - ker.kernel_mass( - self.space.Nel[0], - self.space.Nel[1], - self.space.Nel[2], - self.space.p[0], - self.space.p[1], - self.space.p[2], - self.space.n_quad[0], - self.space.n_quad[1], - self.space.n_quad[2], - 0, - 0, - 0, - 0, - 0, - 0, - self.space.wts[0], - self.space.wts[1], - self.space.wts[2], - self.space.basisN[0], - self.space.basisN[1], - self.space.basisN[2], - self.space.basisN[0], - self.space.basisN[1], - self.space.basisN[2], - self.space.indN[0], - self.space.indN[1], - self.space.indN[2], - self.M13, - -self.mat_nh * self.B2_2, - ) - - # assembly of M23 - ker.kernel_mass( - self.space.Nel[0], - self.space.Nel[1], - self.space.Nel[2], - self.space.p[0], - self.space.p[1], - self.space.p[2], - self.space.n_quad[0], - self.space.n_quad[1], - self.space.n_quad[2], - 0, - 0, - 0, - 0, - 0, - 0, - self.space.wts[0], - self.space.wts[1], - self.space.wts[2], - self.space.basisN[0], - self.space.basisN[1], - self.space.basisN[2], - self.space.basisN[0], - self.space.basisN[1], - self.space.basisN[2], - self.space.indN[0], - self.space.indN[1], - self.space.indN[2], - self.M23, - +self.mat_nh * self.B2_1, - ) - - elif self.basis_u == 2: - # assembly of M12 - ker.kernel_mass( - self.space.Nel[0], - self.space.Nel[1], - self.space.Nel[2], - self.space.p[0], - self.space.p[1], - self.space.p[2], - self.space.n_quad[0], - self.space.n_quad[1], - self.space.n_quad[2], - 0, - 1, - 1, - 1, - 0, - 1, - self.space.wts[0], - self.space.wts[1], - self.space.wts[2], - self.space.basisN[0], - self.space.basisD[1], - self.space.basisD[2], - self.space.basisD[0], - self.space.basisN[1], - self.space.basisD[2], - self.space.indN[0], - self.space.indD[1], - self.space.indD[2], - self.M12, - +self.mat_nh * self.B2_3, - ) - - # assembly of M13 - ker.kernel_mass( - self.space.Nel[0], - self.space.Nel[1], - self.space.Nel[2], - self.space.p[0], - self.space.p[1], - self.space.p[2], - self.space.n_quad[0], - self.space.n_quad[1], - self.space.n_quad[2], - 0, - 1, - 1, - 1, - 1, - 0, - self.space.wts[0], - self.space.wts[1], - self.space.wts[2], - self.space.basisN[0], - self.space.basisD[1], - self.space.basisD[2], - self.space.basisD[0], - self.space.basisD[1], - self.space.basisN[2], - self.space.indN[0], - self.space.indD[1], - self.space.indD[2], - self.M13, - -self.mat_nh * self.B2_2, - ) - - # assembly of M23 - ker.kernel_mass( - self.space.Nel[0], - self.space.Nel[1], - self.space.Nel[2], - self.space.p[0], - self.space.p[1], - self.space.p[2], - self.space.n_quad[0], - self.space.n_quad[1], - self.space.n_quad[2], - 1, - 0, - 1, - 1, - 1, - 0, - self.space.wts[0], - self.space.wts[1], - self.space.wts[2], - self.space.basisD[0], - self.space.basisN[1], - self.space.basisD[2], - self.space.basisD[0], - self.space.basisD[1], - self.space.basisN[2], - self.space.indD[0], - self.space.indN[1], - self.space.indD[2], - self.M23, - +self.mat_nh * self.B2_1, - ) - - # conversion to sparse matrix and return - return self.M12, self.M13, self.M23 diff --git a/src/struphy/eigenvalue_solvers/legacy/control_variates/kernels_control_variate.py b/src/struphy/eigenvalue_solvers/legacy/control_variates/kernels_control_variate.py deleted file mode 100644 index cd6ecff46..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/control_variates/kernels_control_variate.py +++ /dev/null @@ -1,188 +0,0 @@ -import struphy.geometry.mappings_3d as mapping -import struphy.pic.equilibrium_PIC as eq_pic - - -# ========================================================================================== -def fun( - eta1: float, - eta2: float, - eta3: float, - kind_fun: int, - kind_map: int, - params_map: "float[:]", - tn1: "float[:]", - tn2: "float[:]", - tn3: "float[:]", - pn: "int[:]", - nbase_n: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - # bulk velocity is a 0-form - if kind_fun == 1: - x = mapping.f(eta1, eta2, eta3, 1, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - y = mapping.f(eta1, eta2, eta3, 2, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - z = mapping.f(eta1, eta2, eta3, 3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - jhx = eq_pic.jhx_eq(x, y, z) - jhy = eq_pic.jhy_eq(x, y, z) - jhz = eq_pic.jhz_eq(x, y, z) - - detdf = mapping.det_df(eta1, eta2, eta3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - dfinv_11 = mapping.df_inv(eta1, eta2, eta3, 11, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - dfinv_12 = mapping.df_inv(eta1, eta2, eta3, 12, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - dfinv_13 = mapping.df_inv(eta1, eta2, eta3, 13, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - value = (dfinv_11 * jhx + dfinv_12 * jhy + dfinv_13 * jhz) * abs(detdf) - - elif kind_fun == 2: - x = mapping.f(eta1, eta2, eta3, 1, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - y = mapping.f(eta1, eta2, eta3, 2, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - z = mapping.f(eta1, eta2, eta3, 3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - jhx = eq_pic.jhx_eq(x, y, z) - jhy = eq_pic.jhy_eq(x, y, z) - jhz = eq_pic.jhz_eq(x, y, z) - - detdf = mapping.det_df(eta1, eta2, eta3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - dfinv_21 = mapping.df_inv(eta1, eta2, eta3, 21, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - dfinv_22 = mapping.df_inv(eta1, eta2, eta3, 22, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - dfinv_23 = mapping.df_inv(eta1, eta2, eta3, 23, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - value = (dfinv_21 * jhx + dfinv_22 * jhy + dfinv_23 * jhz) * abs(detdf) - - elif kind_fun == 3: - x = mapping.f(eta1, eta2, eta3, 1, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - y = mapping.f(eta1, eta2, eta3, 2, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - z = mapping.f(eta1, eta2, eta3, 3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - jhx = eq_pic.jhx_eq(x, y, z) - jhy = eq_pic.jhy_eq(x, y, z) - jhz = eq_pic.jhz_eq(x, y, z) - - detdf = mapping.det_df(eta1, eta2, eta3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - dfinv_31 = mapping.df_inv(eta1, eta2, eta3, 31, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - dfinv_32 = mapping.df_inv(eta1, eta2, eta3, 32, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - dfinv_33 = mapping.df_inv(eta1, eta2, eta3, 33, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - value = (dfinv_31 * jhx + dfinv_32 * jhy + dfinv_33 * jhz) * abs(detdf) - - elif kind_fun == 4: - x = mapping.f(eta1, eta2, eta3, 1, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - y = mapping.f(eta1, eta2, eta3, 2, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - z = mapping.f(eta1, eta2, eta3, 3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - detdf = mapping.det_df(eta1, eta2, eta3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - value = eq_pic.nh_eq_phys(x, y, z) * abs(detdf) - - # bulk velocity is a 2-form - if kind_fun == 11: - x = mapping.f(eta1, eta2, eta3, 1, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - y = mapping.f(eta1, eta2, eta3, 2, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - z = mapping.f(eta1, eta2, eta3, 3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - jhx = eq_pic.jhx_eq(x, y, z) - jhy = eq_pic.jhy_eq(x, y, z) - jhz = eq_pic.jhz_eq(x, y, z) - - dfinv_11 = mapping.df_inv(eta1, eta2, eta3, 11, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - dfinv_12 = mapping.df_inv(eta1, eta2, eta3, 12, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - dfinv_13 = mapping.df_inv(eta1, eta2, eta3, 13, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - value = dfinv_11 * jhx + dfinv_12 * jhy + dfinv_13 * jhz - - elif kind_fun == 12: - x = mapping.f(eta1, eta2, eta3, 1, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - y = mapping.f(eta1, eta2, eta3, 2, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - z = mapping.f(eta1, eta2, eta3, 3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - jhx = eq_pic.jhx_eq(x, y, z) - jhy = eq_pic.jhy_eq(x, y, z) - jhz = eq_pic.jhz_eq(x, y, z) - - dfinv_21 = mapping.df_inv(eta1, eta2, eta3, 21, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - dfinv_22 = mapping.df_inv(eta1, eta2, eta3, 22, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - dfinv_23 = mapping.df_inv(eta1, eta2, eta3, 23, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - value = dfinv_21 * jhx + dfinv_22 * jhy + dfinv_23 * jhz - - elif kind_fun == 13: - x = mapping.f(eta1, eta2, eta3, 1, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - y = mapping.f(eta1, eta2, eta3, 2, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - z = mapping.f(eta1, eta2, eta3, 3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - jhx = eq_pic.jhx_eq(x, y, z) - jhy = eq_pic.jhy_eq(x, y, z) - jhz = eq_pic.jhz_eq(x, y, z) - - dfinv_31 = mapping.df_inv(eta1, eta2, eta3, 31, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - dfinv_32 = mapping.df_inv(eta1, eta2, eta3, 32, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - dfinv_33 = mapping.df_inv(eta1, eta2, eta3, 33, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - value = dfinv_31 * jhx + dfinv_32 * jhy + dfinv_33 * jhz - - elif kind_fun == 14: - x = mapping.f(eta1, eta2, eta3, 1, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - y = mapping.f(eta1, eta2, eta3, 2, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - z = mapping.f(eta1, eta2, eta3, 3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - detdf = mapping.det_df(eta1, eta2, eta3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - value = eq_pic.nh_eq_phys(x, y, z) / abs(detdf) - - return value - - -# ========================================================================================== -def kernel_evaluation_quad( - nel: "int[:]", - nq: "int[:]", - eta1: "float[:,:]", - eta: "float[:,:]", - eta3: "float[:,:]", - mat_f: "float[:,:,:,:,:,:]", - kind_fun: int, - kind_map: int, - params_map: "float[:]", - tn1: "float[:]", - tn2: "float[:]", - tn3: "float[:]", - pn: "int[:]", - nbase_n: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3) - for ie1 in range(nel[0]): - for ie2 in range(nel[1]): - for ie3 in range(nel[2]): - for q1 in range(nq[0]): - for q2 in range(nq[1]): - for q3 in range(nq[2]): - mat_f[ie1, q1, ie2, q2, ie3, q3] = fun( - eta1[ie1, q1], - eta2[ie2, q2], - eta3[ie3, q3], - kind_fun, - kind_map, - params_map, - tn1, - tn2, - tn3, - pn, - nbase_n, - cx, - cy, - cz, - ) - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/__init__.py b/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fB_massless_control_variate.py b/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fB_massless_control_variate.py deleted file mode 100644 index 39156f985..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fB_massless_control_variate.py +++ /dev/null @@ -1,444 +0,0 @@ -import cunumpy as xp -import scipy.sparse as spa - -import struphy.feec.basics.kernels_3d as ker -import struphy.feec.control_variates.kinetic_extended.fB_massless_kernels_control_variate as ker_cv -import struphy.feec.control_variates.kinetic_extended.fnB_massless_cv_kernel_2 as ker_cv2 - - -def bv_right( - p, - indN, - indD, - Nel, - G_inv_11, - G_inv_12, - G_inv_13, - G_inv_22, - G_inv_23, - G_inv_33, - DFI_11, - DFI_12, - DFI_13, - DFI_21, - DFI_22, - DFI_23, - DFI_31, - DFI_32, - DFI_33, - df_det, - Jeqx, - Jeqy, - Jeqz, - temp_dft, - generate_weight1, - generate_weight2, - generate_weight3, - temp_twoform1, - temp_twoform2, - temp_twoform3, - b1, - b2, - b3, - uvalue, - b1value, - b2value, - b3value, - tensor_space_FEM, -): - r""" - Computes the matrix Q4_(ab,ij) = \int e^{-U} (DF^{-T}B)_{6-a-b} (Lambda^2_(a,i) x Lambda^2_(b,j))_{6-a-b} deta, no summatio over a,b!! a is not equal to b - 2-form space V2 = span(Lambda^2_(a,i)) with a in [1,2,3] and i in [1, N^2_a] - Number of basis functions is N2 = N2_1 + N2_2 + N2_3 - - ab is a 3x3 block matrix structure: skew-symmetric matrix, we compute elements 12, 31, 23 - M12 = Lambda^2_1 x Lambda^2_2 contracts with the 3rd component of DF^{-T}(B1, B2, B3) - M31 = Lambda^2_3 x Lambda^2_1 contracts with the 2nd component of DF^{-T}(B1, B2, B3) - M23 = Lambda^2_2 x Lambda^2_3 contracts with the 1st component of DF^{-T}(B1, B2, B3) - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - - Returns: - M: Q4 block matrix, csc sparse - """ - # ============= load information about B-splines ============= - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D splin degrees - nq1 = tensor_space_FEM.n_quad[0] - nq2 = tensor_space_FEM.n_quad[1] - nq3 = tensor_space_FEM.n_quad[2] - bn1 = tensor_space_FEM.basisN[0] - bn2 = tensor_space_FEM.basisN[1] - bn3 = tensor_space_FEM.basisN[2] - bd1 = tensor_space_FEM.basisD[0] - bd2 = tensor_space_FEM.basisD[1] - bd3 = tensor_space_FEM.basisD[2] - pts1 = tensor_space_FEM.pts[0] - pts2 = tensor_space_FEM.pts[1] - pts3 = tensor_space_FEM.pts[2] - wts1 = tensor_space_FEM.wts[0] - wts2 = tensor_space_FEM.wts[1] - wts3 = tensor_space_FEM.wts[2] - - ker_cv.bvright1( - G_inv_11, - G_inv_12, - G_inv_13, - G_inv_22, - G_inv_23, - G_inv_33, - indN[0], - indN[1], - indN[2], - indD[0], - indD[1], - indD[2], - Nel[0], - Nel[1], - Nel[2], - nq1, - nq2, - nq3, - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1value, - b2value, - b3value, - b1, - b2, - b3, - temp_dft, - generate_weight1, - generate_weight2, - generate_weight3, - bn1, - bn2, - bn3, - bd1, - bd2, - bd3, - ) - ker_cv.bvright2( - DFI_11, - DFI_12, - DFI_13, - DFI_21, - DFI_22, - DFI_23, - DFI_31, - DFI_32, - DFI_33, - df_det, - Jeqx, - Jeqy, - Jeqz, - Nel[0], - Nel[1], - Nel[2], - nq1, - nq2, - nq3, - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1value, - b2value, - b3value, - uvalue, - temp_dft, - generate_weight1, - generate_weight2, - generate_weight3, - pts1, - pts2, - pts3, - wts1, - wts2, - wts3, - ) - ker_cv.bvfinal( - indN[0], - indN[1], - indN[2], - indD[0], - indD[1], - indD[2], - Nel[0], - Nel[1], - Nel[2], - nq1, - nq2, - nq3, - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1value, - b2value, - b3value, - uvalue, - bn1, - bn2, - bn3, - bd1, - bd2, - bd3, - temp_twoform1, - temp_twoform2, - temp_twoform3, - ) - # ========================= C.T =========================== - return tensor_space_FEM.C.T.dot( - xp.concatenate((temp_twoform1.flatten(), temp_twoform2.flatten(), temp_twoform3.flatten())), - ) - - -def vv_right( - stage_index, - tol, - Np_loc, - LO_inv, - domain, - acc, - NbaseN, - NbaseD, - temp_particle, - p, - Nel, - tensor_space_FEM, - b1, - b2, - b3, - particles_loc, -): - r""" - Computes the matrix Q4_(ab,ij) = \int e^{-U} (DF^{-T}B)_{6-a-b} (Lambda^2_(a,i) x Lambda^2_(b,j))_{6-a-b} deta, no summatio over a,b!! a is not equal to b - 2-form space V2 = span(Lambda^2_(a,i)) with a in [1,2,3] and i in [1, N^2_a] - Number of basis functions is N2 = N2_1 + N2_2 + N2_3 - - ab is a 3x3 block matrix structure: skew-symmetric matrix, we compute elements 12, 31, 23 - M12 = Lambda^2_1 x Lambda^2_2 contracts with the 3rd component of DF^{-T}(B1, B2, B3) - M31 = Lambda^2_3 x Lambda^2_1 contracts with the 2nd component of DF^{-T}(B1, B2, B3) - M23 = Lambda^2_2 x Lambda^2_3 contracts with the 1st component of DF^{-T}(B1, B2, B3) - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - - Returns: - M: Q4 block matrix, csc sparse - """ - # =====we can just calculate 3 matrices===== - # ============= load information about B-splines ============= - if stage_index == 1: - ker_cv.vv( - tol, - acc.stage1_out_loc, - temp_particle, - b1, - b2, - b3, - LO_inv, - Np_loc, - NbaseN, - NbaseD, - Nel, - p, - tensor_space_FEM.T[0], - tensor_space_FEM.T[1], - tensor_space_FEM.T[2], - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif stage_index == 2: - ker_cv.vv( - tol, - acc.stage2_out_loc, - temp_particle, - b1, - b2, - b3, - LO_inv, - Np_loc, - NbaseN, - NbaseD, - Nel, - p, - tensor_space_FEM.T[0], - tensor_space_FEM.T[1], - tensor_space_FEM.T[2], - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif stage_index == 3: - ker_cv.vv( - tol, - acc.stage3_out_loc, - temp_particle, - b1, - b2, - b3, - LO_inv, - Np_loc, - NbaseN, - NbaseD, - Nel, - p, - tensor_space_FEM.T[0], - tensor_space_FEM.T[1], - tensor_space_FEM.T[2], - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - else: - ker_cv.vv( - tol, - acc.stage4_out_loc, - temp_particle, - b1, - b2, - b3, - LO_inv, - Np_loc, - NbaseN, - NbaseD, - Nel, - p, - tensor_space_FEM.T[0], - tensor_space_FEM.T[1], - tensor_space_FEM.T[2], - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - -def quadrature_density(gather, domain): - """ - Computes the matrix - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - Returns: - M: Q4 block matrix, csc sparse - """ - # =====we can just calculate 3 matrices===== - # ============= load information about B-splines ============= - - ker_cv2.quadrature_density( - gather.Nel, - gather.pts[0], - gather.pts[1], - gather.pts[2], - gather.n_quad, - gather.gather_quadrature, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - -def quadrature_grid(gather, domain): - """ - Computes the matrix - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - Returns: - M: Q4 block matrix, csc sparse - """ - # =====we can just calculate 3 matrices===== - # ============= load information about B-splines ============= - - ker_cv.grid_density( - gather.Nel, - gather.gather_grid, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) diff --git a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fB_massless_kernels_control_variate.py b/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fB_massless_kernels_control_variate.py deleted file mode 100644 index 7f15931ec..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fB_massless_kernels_control_variate.py +++ /dev/null @@ -1,719 +0,0 @@ -import input_run.equilibrium_PIC as equ_PIC - -import struphy.feec.basics.spline_evaluation_3d as eva -import struphy.feec.bsplines_kernels as bsp - -# import module for mapping evaluation -import struphy.geometry.mappings_3d as mapping3d -import struphy.geometry.mappings_3d_fast as mapping_fast - -# import module for matrix-matrix and matrix-vector multiplications -import struphy.linear_algebra.linalg_kernels as linalg - - -def grid_density( - Nel: "int[:]", - gather: "float[:,:,:]", - kind_map: int, - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - # ======================================================================= - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, x1, x2, x3) - for ie1 in range(Nel[0]): - for ie2 in range(Nel[1]): - for ie3 in range(Nel[2]): - # ========= physical domain ============= - x1 = mapping3d.f( - ie1 / Nel[0], - ie2 / Nel[2], - ie3 / Nel[2], - 1, - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - x2 = mapping3d.f( - ie1 / Nel[0], - ie2 / Nel[2], - ie3 / Nel[2], - 2, - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - x3 = mapping3d.f( - ie1 / Nel[0], - ie2 / Nel[2], - ie3 / Nel[2], - 3, - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - gather[ie1, ie2, ie3] += equ_PIC.nh_eq_phys(x1, x2, x3) - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ========================================================================================== -def bvright1( - G_inv_11: "float[:,:,:,:,:,:]", - G_inv_12: "float[:,:,:,:,:,:]", - G_inv_13: "float[:,:,:,:,:,:]", - G_inv_22: "float[:,:,:,:,:,:]", - G_inv_23: "float[:,:,:,:,:,:]", - G_inv_33: "float[:,:,:,:,:,:]", - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - b1: "float[:,:,:]", - b2: "float[:,:,:]", - b3: "float[:,:,:]", - dft: "float[:,:]", - generate_weight1: "float[:]", - generate_weight3: "float[:]", - Jeq: "float[:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", -): - # ====================================================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b1[iddx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] - ) - - b1value[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b2[idnx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] - ) - - b2value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * b3[idnx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] - ) - - b3value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, dft, generate_weight1, generate_weight3) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - dft[0, 0] = G_inv_11[ie1, ie2, ie3, q1, q2, q3] - dft[0, 1] = G_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[0, 2] = G_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[1, 0] = G_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[1, 1] = G_inv_22[ie1, ie2, ie3, q1, q2, q3] - dft[1, 2] = G_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 0] = G_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[2, 1] = G_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 2] = G_inv_33[ie1, ie2, ie3, q1, q2, q3] - generate_weight3[0] = b1value[ie1, ie2, ie3, q1, q2, q3] - generate_weight3[1] = b2value[ie1, ie2, ie3, q1, q2, q3] - generate_weight3[2] = b3value[ie1, ie2, ie3, q1, q2, q3] - linalg.matrix_vector(dft, generate_weight3, generate_weight1) - b1value[ie1, ie2, ie3, q1, q2, q3] = generate_weight1[0] - b2value[ie1, ie2, ie3, q1, q2, q3] = generate_weight1[1] - b3value[ie1, ie2, ie3, q1, q2, q3] = generate_weight1[2] - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def bvright2( - DFI_11: "float[:,:,:,:,:,:]", - DFI_12: "float[:,:,:,:,:,:]", - DFI_13: "float[:,:,:,:,:,:]", - DFI_21: "float[:,:,:,:,:,:]", - DFI_22: "float[:,:,:,:,:,:]", - DFI_23: "float[:,:,:,:,:,:]", - DFI_31: "float[:,:,:,:,:,:]", - DFI_32: "float[:,:,:,:,:,:]", - DFI_33: "float[:,:,:,:,:,:]", - df_det: "float[:,:,:,:,:,:]", - Jeqx: "float[:,:,:,:,:,:]", - Jeqy: "float[:,:,:,:,:,:]", - Jeqz: "float[:,:,:,:,:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - uvalue: "float[:,:,:,:,:,:]", - dft: "float[:,:]", - generate_weight1: "float[:]", - generate_weight3: "float[:]", - Jeq: "float[:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", -): - # ====================================================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, dft, detdet, generate_weight1, generate_weight3, Jeq) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - generate_weight1[0] = b1value[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[1] = b2value[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[2] = b3value[ie1, ie2, ie3, q1, q2, q3] - - dft[0, 0] = DFI_11[ie1, ie2, ie3, q1, q2, q3] - dft[0, 1] = DFI_12[ie1, ie2, ie3, q1, q2, q3] - dft[0, 2] = DFI_13[ie1, ie2, ie3, q1, q2, q3] - dft[1, 0] = DFI_21[ie1, ie2, ie3, q1, q2, q3] - dft[1, 1] = DFI_22[ie1, ie2, ie3, q1, q2, q3] - dft[1, 2] = DFI_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 0] = DFI_31[ie1, ie2, ie3, q1, q2, q3] - dft[2, 1] = DFI_32[ie1, ie2, ie3, q1, q2, q3] - dft[2, 2] = DFI_33[ie1, ie2, ie3, q1, q2, q3] - detdet = df_det[ie1, ie2, ie3, q1, q2, q3] * wts1[ie1, q1] * wts2[ie2, q2] * wts3[ie3, q3] - Jeq[0] = Jeqx[ie1, ie2, ie3, q1, q2, q3] - Jeq[1] = Jeqy[ie1, ie2, ie3, q1, q2, q3] - Jeq[2] = Jeqz[ie1, ie2, ie3, q1, q2, q3] - linalg.matrix_vector(dft, Jeq, generate_weight3) - - b1value[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * ( - generate_weight3[1] * generate_weight1[2] - - generate_weight3[2] * generate_weight1[1] - ) - ) - b2value[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * ( - generate_weight3[2] * generate_weight1[0] - - generate_weight3[0] * generate_weight1[2] - ) - ) - b3value[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * ( - generate_weight3[0] * generate_weight1[1] - - generate_weight3[1] * generate_weight1[0] - ) - ) - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def bvfinal( - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - uvalue: "float[:,:,:,:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - temp_final_1: "float[:,:,:]", - temp_final_2: "float[:,:,:]", - temp_final_3: "float[:,:,:]", -): - temp_final_1[:, :, :] = 0.0 - temp_final_2[:, :, :] = 0.0 - temp_final_3[:, :, :] = 0.0 - # ====================================================================================== - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_1) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(d3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - b1value[ie1, ie2, ie3, q1, q2, q3] - * bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - ) - - temp_final_1[idnx[ie1, il1], iddy[ie2, il2], iddz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_2) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - b2value[ie1, ie2, ie3, q1, q2, q3] - * bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - ) - - temp_final_2[iddx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_3) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(d1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - b3value[ie1, ie2, ie3, q1, q2, q3] - * bd1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - ) - - temp_final_3[iddx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================================================================================================================= - - -def vv( - tol: "float", - out_vector: "float[:,:]", - Jeq: "float[:]", - bb1: "float[:,:,:]", - bb2: "float[:,:,:]", - bb3: "float[:,:,:]", - gather_grid: "float[:,:,:]", - Np_loc: "int", - NbaseN: "int[:]", - NbaseD: "int[:]", - Nel: "int[:]", - p: "int[:]", - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - particles: "float[:,:]", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, zeros - - pn1 = p[0] - pn2 = p[1] - pn3 = p[2] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - pd3 = pn3 - 1 - - # p + 1 non-vanishing basis functions up tp degree p - b1 = empty((pn1 + 1, pn1 + 1), dtype=float) - b2 = empty((pn2 + 1, pn2 + 1), dtype=float) - b3 = empty((pn3 + 1, pn3 + 1), dtype=float) - - l1 = empty(pn1, dtype=float) - l2 = empty(pn2, dtype=float) - l3 = empty(pn3, dtype=float) - - r1 = empty(pn1, dtype=float) - r2 = empty(pn2, dtype=float) - r3 = empty(pn3, dtype=float) - - # scaling arrays for M-splines - d1 = empty(pn1, dtype=float) - d2 = empty(pn2, dtype=float) - d3 = empty(pn3, dtype=float) - # non-vanishing N-splines - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - # non-vanishing D-splines - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - vel2 = zeros(3, dtype=float) - vel = zeros(3, dtype=float) - dfinv = zeros((3, 3), dtype=float) - out_vector[:, :] = 0.0 - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = empty((3, 3), dtype=float) - fx = empty(3, dtype=float) - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (den_inv, ie1, ie2, ie3, disx, disy, disz, eta1, eta2, eta3, span1, span2, span3, ip, l1, l2, l3, r1, r2, r3, b1, b2, b3, d1, d2, d3, bn1, bn2, bn3, bd1, bd2, bd3, vel, vel2, dfinv, U_value, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, x1, x2, x3, Jeq) - for ip in range(Np_loc): - vel[:] = 0.0 - - eta1 = particles[0, ip] - eta2 = particles[1, ip] - eta3 = particles[2, ip] - span1 = int(eta1 * Nel[0]) + pn1 - span2 = int(eta2 * Nel[1]) + pn2 - span3 = int(eta3 * Nel[2]) + pn3 - - bsp.basis_funs_all(t1, pn1, eta1, span1, l1, r1, b1, d1) - bsp.basis_funs_all(t2, pn2, eta2, span2, l2, r2, b2, d2) - bsp.basis_funs_all(t3, pn3, eta3, span3, l3, r3, b3, d3) - bn1[:] = b1[pn1, :] - bd1[:] = b1[pd1, :pn1] * d1[:] - bn2[:] = b2[pn2, :] - bd2[:] = b2[pd2, :pn2] * d2[:] - bn3[:] = b3[pn3, :] - bd3[:] = b3[pd3, :pn3] * d3[:] - - vel[0] = eva.evaluation_kernel( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - NbaseD[0], - NbaseN[1], - NbaseN[2], - bb1, - ) - vel[1] = eva.evaluation_kernel( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - NbaseN[0], - NbaseD[1], - NbaseN[2], - bb2, - ) - vel[2] = eva.evaluation_kernel( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - NbaseN[0], - NbaseN[1], - NbaseD[2], - bb3, - ) - # ======= here we use the linear hat function =========== - ie1 = int(eta1 * Nel[0]) - ie2 = int(eta2 * Nel[1]) - ie3 = int(eta3 * Nel[2]) - disx = (eta1 - ie1 / Nel[0]) * Nel[0] - disy = (eta2 - ie2 / Nel[1]) * Nel[1] - disz = (eta3 - ie3 / Nel[2]) * Nel[2] - - U_value = gather_grid[ie1, ie2, ie3] * (1 - disx) * (1 - disy) * (1 - disz) - U_value += gather_grid[(ie1 + 1) % Nel[0], ie2, ie3] * disx * (1 - disy) * (1 - disz) - U_value += gather_grid[ie1, (ie2 + 1) % Nel[1], ie3] * (1 - disx) * disy * (1 - disz) - U_value += gather_grid[ie1, ie2, (ie3 + 1) % Nel[2]] * (1 - disx) * (1 - disy) * disz - U_value += gather_grid[ie1, (ie2 + 1) % Nel[1], (ie3 + 1) % Nel[2]] * (1 - disx) * disy * disz - U_value += gather_grid[(ie1 + 1) % Nel[0], ie2, (ie3 + 1) % Nel[2]] * disx * (1 - disy) * disz - U_value += gather_grid[(ie1 + 1) % Nel[0], (ie2 + 1) % Nel[1], ie3] * disx * disy * (1 - disz) - U_value += gather_grid[(ie1 + 1) % Nel[0], (ie2 + 1) % Nel[1], (ie3 + 1) % Nel[2]] * disx * disy * disz - - if abs(U_value) > tol: - den_inv = 1 / U_value - else: - den_inv = 0.0 - # ========= mapping evaluation ============= - span1f = int(eta1 * nelf[0]) + pf1 - span2f = int(eta2 * nelf[1]) + pf2 - span3f = int(eta3 * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - # ========================================= - vel2[0] = dfinv[0, 0] * vel[0] + dfinv[1, 0] * vel[1] + dfinv[2, 0] * vel[2] - vel2[1] = dfinv[0, 1] * vel[0] + dfinv[1, 1] * vel[1] + dfinv[2, 1] * vel[2] - vel2[2] = dfinv[0, 2] * vel[0] + dfinv[1, 2] * vel[1] + dfinv[2, 2] * vel[2] - - x1 = mapping3d.f(eta1, eta2, eta3, 1, kind_map, params_map, tf1, tf2, tf3, pf, nbasef, cx, cy, cz) - x2 = mapping3d.f(eta1, eta2, eta3, 2, kind_map, params_map, tf1, tf2, tf3, pf, nbasef, cx, cy, cz) - x3 = mapping3d.f(eta1, eta2, eta3, 3, kind_map, params_map, tf1, tf2, tf3, pf, nbasef, cx, cy, cz) - - Jeq[0] = equ_PIC.jhx_eq(x1, x2, x3) - Jeq[1] = equ_PIC.jhy_eq(x1, x2, x3) - Jeq[2] = equ_PIC.jhz_eq(x1, x2, x3) - - vel[0] = vel2[1] * Jeq[2] - vel2[2] * Jeq[1] - vel[1] = vel2[2] * Jeq[0] - vel2[0] * Jeq[2] - vel[2] = vel2[0] * Jeq[1] - vel2[1] * Jeq[0] - out_vector[0, ip] -= den_inv * vel[0] - out_vector[1, ip] -= den_inv * vel[1] - out_vector[2, ip] -= den_inv * vel[2] - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fnB_massless_control_variate.py b/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fnB_massless_control_variate.py deleted file mode 100644 index 5e9c04eb0..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fnB_massless_control_variate.py +++ /dev/null @@ -1,672 +0,0 @@ -import cunumpy as xp -import hylife.utilitis_FEEC.basics.kernels_3d as ker -import hylife.utilitis_FEEC.control_variates.fnB_massless_kernels_control_variate as ker_cv -import scipy.sparse as spa - - -def bv_pre(tol, n, LO_inv, tensor_space_FEM, p, Nel, idnx, idny, idnz): - r""" - Computes the matrix Q4_(ab,ij) = \int e^{-U} (DF^{-T}B)_{6-a-b} (Lambda^2_(a,i) x Lambda^2_(b,j))_{6-a-b} deta, no summatio over a,b!! a is not equal to b - 2-form space V2 = span(Lambda^2_(a,i)) with a in [1,2,3] and i in [1, N^2_a] - Number of basis functions is N2 = N2_1 + N2_2 + N2_3 - - ab is a 3x3 block matrix structure: skew-symmetric matrix, we compute elements 12, 31, 23 - M12 = Lambda^2_1 x Lambda^2_2 contracts with the 3rd component of DF^{-T}(B1, B2, B3) - M31 = Lambda^2_3 x Lambda^2_1 contracts with the 2nd component of DF^{-T}(B1, B2, B3) - M23 = Lambda^2_2 x Lambda^2_3 contracts with the 1st component of DF^{-T}(B1, B2, B3) - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - - Returns: - M: Q4 block matrix, csc sparse - """ - - ker_cv.bvpre( - tol, - Nel[0], - Nel[1], - Nel[2], - tensor_space_FEM.n_quad[0], - tensor_space_FEM.n_quad[1], - tensor_space_FEM.n_quad[2], - p[0], - p[1], - p[2], - LO_inv, - n, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - idnx, - idny, - idnz, - ) - - -def bv_right( - p, - indN, - indD, - Nel, - G_inv_11, - G_inv_12, - G_inv_13, - G_inv_22, - G_inv_23, - G_inv_33, - DFI_11, - DFI_12, - DFI_13, - DFI_21, - DFI_22, - DFI_23, - DFI_31, - DFI_32, - DFI_33, - df_det, - Jeqx, - Jeqy, - Jeqz, - temp_dft, - generate_weight1, - generate_weight2, - generate_weight3, - temp_twoform1, - temp_twoform2, - temp_twoform3, - b1, - b2, - b3, - uvalue, - b1value, - b2value, - b3value, - tensor_space_FEM, -): - r""" - Computes the matrix Q4_(ab,ij) = \int e^{-U} (DF^{-T}B)_{6-a-b} (Lambda^2_(a,i) x Lambda^2_(b,j))_{6-a-b} deta, no summatio over a,b!! a is not equal to b - 2-form space V2 = span(Lambda^2_(a,i)) with a in [1,2,3] and i in [1, N^2_a] - Number of basis functions is N2 = N2_1 + N2_2 + N2_3 - - ab is a 3x3 block matrix structure: skew-symmetric matrix, we compute elements 12, 31, 23 - M12 = Lambda^2_1 x Lambda^2_2 contracts with the 3rd component of DF^{-T}(B1, B2, B3) - M31 = Lambda^2_3 x Lambda^2_1 contracts with the 2nd component of DF^{-T}(B1, B2, B3) - M23 = Lambda^2_2 x Lambda^2_3 contracts with the 1st component of DF^{-T}(B1, B2, B3) - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - - Returns: - M: Q4 block matrix, csc sparse - """ - # ============= load information about B-splines ============= - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D splin degrees - nq1 = tensor_space_FEM.n_quad[0] - nq2 = tensor_space_FEM.n_quad[1] - nq3 = tensor_space_FEM.n_quad[2] - bn1 = tensor_space_FEM.basisN[0] - bn2 = tensor_space_FEM.basisN[1] - bn3 = tensor_space_FEM.basisN[2] - bd1 = tensor_space_FEM.basisD[0] - bd2 = tensor_space_FEM.basisD[1] - bd3 = tensor_space_FEM.basisD[2] - pts1 = tensor_space_FEM.pts[0] - pts2 = tensor_space_FEM.pts[1] - pts3 = tensor_space_FEM.pts[2] - wts1 = tensor_space_FEM.wts[0] - wts2 = tensor_space_FEM.wts[1] - wts3 = tensor_space_FEM.wts[2] - - ker_cv.bvright1( - G_inv_11, - G_inv_12, - G_inv_13, - G_inv_22, - G_inv_23, - G_inv_33, - indN[0], - indN[1], - indN[2], - indD[0], - indD[1], - indD[2], - Nel[0], - Nel[1], - Nel[2], - nq1, - nq2, - nq3, - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1value, - b2value, - b3value, - b1, - b2, - b3, - temp_dft, - generate_weight1, - generate_weight2, - generate_weight3, - bn1, - bn2, - bn3, - bd1, - bd2, - bd3, - ) - ker_cv.bvright2( - DFI_11, - DFI_12, - DFI_13, - DFI_21, - DFI_22, - DFI_23, - DFI_31, - DFI_32, - DFI_33, - df_det, - Jeqx, - Jeqy, - Jeqz, - Nel[0], - Nel[1], - Nel[2], - nq1, - nq2, - nq3, - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1value, - b2value, - b3value, - uvalue, - temp_dft, - generate_weight1, - generate_weight2, - generate_weight3, - pts1, - pts2, - pts3, - wts1, - wts2, - wts3, - ) - ker_cv.bvfinal( - indN[0], - indN[1], - indN[2], - indD[0], - indD[1], - indD[2], - Nel[0], - Nel[1], - Nel[2], - nq1, - nq2, - nq3, - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1value, - b2value, - b3value, - uvalue, - bn1, - bn2, - bn3, - bd1, - bd2, - bd3, - temp_twoform1, - temp_twoform2, - temp_twoform3, - ) - # ========================= C.T =========================== - return tensor_space_FEM.C.T.dot( - xp.concatenate((temp_twoform1.flatten(), temp_twoform2.flatten(), temp_twoform3.flatten())), - ) - - -def uv_right( - dft, - DFIT_11, - DFIT_12, - DFIT_13, - DFIT_21, - DFIT_22, - DFIT_23, - DFIT_31, - DFIT_32, - DFIT_33, - df_det, - Jeqx, - Jeqy, - Jeqz, - indN, - indD, - generate_weight1, - generate_weight2, - generate_weight3, - p, - Nel, - temp_final_0, - temp_final_1, - temp_final_2, - temp_final_3, - gradU1, - gradU2, - gradU3, - GRAD, - u, - uvalue, - b1value, - b2value, - b3value, - weight1, - weight2, - weight3, - tensor_space_FEM, -): - r""" - Computes the matrix Q4_(ab,ij) = \int e^{-U} (DF^{-T}B)_{6-a-b} (Lambda^2_(a,i) x Lambda^2_(b,j))_{6-a-b} deta, no summatio over a,b!! a is not equal to b - 2-form space V2 = span(Lambda^2_(a,i)) with a in [1,2,3] and i in [1, N^2_a] - Number of basis functions is N2 = N2_1 + N2_2 + N2_3 - - ab is a 3x3 block matrix structure: skew-symmetric matrix, we compute elements 12, 31, 23 - M12 = Lambda^2_1 x Lambda^2_2 contracts with the 3rd component of DF^{-T}(B1, B2, B3) - M31 = Lambda^2_3 x Lambda^2_1 contracts with the 2nd component of DF^{-T}(B1, B2, B3) - M23 = Lambda^2_2 x Lambda^2_3 contracts with the 1st component of DF^{-T}(B1, B2, B3) - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - - Returns: - M: Q4 block matrix, csc sparse - """ - # =====we can just calculate 3 matrices===== - # ============= load information about B-splines ============= - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D splin degrees - - ker_cv.uvpre( - indN[0], - indN[1], - indN[2], - Nel[0], - Nel[1], - Nel[2], - tensor_space_FEM.n_quad[0], - tensor_space_FEM.n_quad[1], - tensor_space_FEM.n_quad[2], - p[0], - p[1], - p[2], - uvalue, - u, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - ) - ker_cv.uvright( - DFIT_11, - DFIT_12, - DFIT_13, - DFIT_21, - DFIT_22, - DFIT_23, - DFIT_31, - DFIT_32, - DFIT_33, - df_det, - Jeqx, - Jeqy, - Jeqz, - generate_weight3, - indN[0], - indN[1], - indN[2], - indD[0], - indD[1], - indD[2], - Nel[0], - Nel[1], - Nel[2], - tensor_space_FEM.n_quad[0], - tensor_space_FEM.n_quad[1], - tensor_space_FEM.n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1value, - b2value, - b3value, - uvalue, - weight1, - weight2, - weight3, - gradU1, - gradU2, - gradU3, - dft, - generate_weight1, - generate_weight2, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - tensor_space_FEM.wts[0], - tensor_space_FEM.wts[1], - tensor_space_FEM.wts[2], - ) - ker_cv.uvfinal( - indN[0], - indN[1], - indN[2], - indD[0], - indD[1], - indD[2], - Nel[0], - Nel[1], - Nel[2], - tensor_space_FEM.n_quad[0], - tensor_space_FEM.n_quad[1], - tensor_space_FEM.n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - uvalue, - temp_final_0, - temp_final_1, - temp_final_2, - temp_final_3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - # ========================= C.T =========================== - temp_final = temp_final_0.flatten() + tensor_space_FEM.G.T.dot( - xp.concatenate((temp_final_1.flatten(), temp_final_2.flatten(), temp_final_3.flatten())), - ) - - return temp_final - - -def vv_right( - tol, - stage_index, - Np_loc, - u, - domain, - acc, - NbaseN, - NbaseD, - temp_particle, - p, - Nel, - tensor_space_FEM, - b1, - b2, - b3, - particles_loc, -): - r""" - Computes the matrix Q4_(ab,ij) = \int e^{-U} (DF^{-T}B)_{6-a-b} (Lambda^2_(a,i) x Lambda^2_(b,j))_{6-a-b} deta, no summatio over a,b!! a is not equal to b - 2-form space V2 = span(Lambda^2_(a,i)) with a in [1,2,3] and i in [1, N^2_a] - Number of basis functions is N2 = N2_1 + N2_2 + N2_3 - - ab is a 3x3 block matrix structure: skew-symmetric matrix, we compute elements 12, 31, 23 - M12 = Lambda^2_1 x Lambda^2_2 contracts with the 3rd component of DF^{-T}(B1, B2, B3) - M31 = Lambda^2_3 x Lambda^2_1 contracts with the 2nd component of DF^{-T}(B1, B2, B3) - M23 = Lambda^2_2 x Lambda^2_3 contracts with the 1st component of DF^{-T}(B1, B2, B3) - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - - Returns: - M: Q4 block matrix, csc sparse - """ - # =====we can just calculate 3 matrices===== - # ============= load information about B-splines ============= - if stage_index == 1: - ker_cv.vv( - tol, - acc.stage1_out_loc, - temp_particle, - b1, - b2, - b3, - u, - Np_loc, - NbaseN, - NbaseD, - Nel, - p, - tensor_space_FEM.T[0], - tensor_space_FEM.T[1], - tensor_space_FEM.T[2], - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif stage_index == 2: - ker_cv.vv( - tol, - acc.stage2_out_loc, - temp_particle, - b1, - b2, - b3, - u, - Np_loc, - NbaseN, - NbaseD, - Nel, - p, - tensor_space_FEM.T[0], - tensor_space_FEM.T[1], - tensor_space_FEM.T[2], - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif stage_index == 3: - ker_cv.vv( - tol, - acc.stage3_out_loc, - temp_particle, - b1, - b2, - b3, - u, - Np_loc, - NbaseN, - NbaseD, - Nel, - p, - tensor_space_FEM.T[0], - tensor_space_FEM.T[1], - tensor_space_FEM.T[2], - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - else: - ker_cv.vv( - tol, - acc.stage4_out_loc, - temp_particle, - b1, - b2, - b3, - u, - Np_loc, - NbaseN, - NbaseD, - Nel, - p, - tensor_space_FEM.T[0], - tensor_space_FEM.T[1], - tensor_space_FEM.T[2], - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - -def quadrature_density(gather, Nel, pts1, pts2, pts3, n_quad, domain): - """ - Computes the matrix - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - Returns: - M: Q4 block matrix, csc sparse - """ - # =====we can just calculate 3 matrices===== - # ============= load information about B-splines ============= - - ker_cv.quadrature_density( - Nel, - pts1, - pts2, - pts3, - n_quad, - gather, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - -def quadrature_grid(gather, Nel, domain): - """ - Computes the matrix - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - Returns: - M: Q4 block matrix, csc sparse - """ - # =====we can just calculate 3 matrices===== - # ============= load information about B-splines ============= - - ker_cv.grid_density( - Nel, - gather, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) diff --git a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fnB_massless_cv_kernel_2.py b/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fnB_massless_cv_kernel_2.py deleted file mode 100644 index 9e26773cd..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fnB_massless_cv_kernel_2.py +++ /dev/null @@ -1,87 +0,0 @@ -import hylife.geometry.mappings_3d as map3d -import input_run.equilibrium_PIC as equ_PIC - - -# =============== xvn substep ============================ -def quadrature_density( - Nel: "int[:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - n_quad: "int[:]", - gather: "float[:,:,:,:,:,:]", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - # ======================================================================= - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, il1, il2, il3, x1, x2, x3) - for ie1 in range(Nel[0]): - for ie2 in range(Nel[1]): - for ie3 in range(Nel[2]): - for il1 in range(n_quad[0]): - for il2 in range(n_quad[1]): - for il3 in range(n_quad[2]): - # ========= physical domain ============= - x1 = map3d.f( - pts1[ie1, il1], - pts2[ie2, il2], - pts3[ie3, il3], - 1, - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - x2 = map3d.f( - pts1[ie1, il1], - pts2[ie2, il2], - pts3[ie3, il3], - 2, - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - x3 = map3d.f( - pts1[ie1, il1], - pts2[ie2, il2], - pts3[ie3, il3], - 3, - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - gather[ie1, ie2, ie3, il1, il2, il3] += equ_PIC.nh_eq_phys(x1, x2, x3) - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fnB_massless_kernels_control_variate.py b/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fnB_massless_kernels_control_variate.py deleted file mode 100644 index 965a7af33..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/fnB_massless_kernels_control_variate.py +++ /dev/null @@ -1,766 +0,0 @@ -import hylife.geometry.mappings_3d as map3d -import hylife.geometry.mappings_3d_fast as mapping_fast -import hylife.linear_algebra.core as linalg -import hylife.utilitis_FEEC.basics.spline_evaluation_3d as eva -import hylife.utilitis_FEEC.bsplines_kernels as bsp -import input_run.equilibrium_PIC as equ_PIC - - -def grid_density( - Nel: "int[:]", - gather_grid: "float[:,:,:]", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - # ======================================================================= - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, x1, x2, x3) - for ie1 in range(Nel[0]): - for ie2 in range(Nel[1]): - for ie3 in range(Nel[2]): - # ========= physical domain ============= - x1 = map3d.f( - ie1 / Nel[0], - ie2 / Nel[2], - ie3 / Nel[2], - 1, - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - x2 = map3d.f( - ie1 / Nel[0], - ie2 / Nel[2], - ie3 / Nel[2], - 2, - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - x3 = map3d.f( - ie1 / Nel[0], - ie2 / Nel[2], - ie3 / Nel[2], - 3, - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - gather_grid[ie1, ie2, ie3] += equ_PIC.nh_eq_phys(x1, x2, x3) - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ============================================================================================================================================================================= -def vv( - tol: "float", - out_vector: "float[:,:]", - Jeq: "float[:]", - bb1: "float[:,:,:]", - bb2: "float[:,:,:]", - bb3: "float[:,:,:]", - n: "float[:,:,:]", - Np_loc: "int", - NbaseN: "int[:]", - NbaseD: "int[:]", - Nel: "int[:]", - p: "int[:]", - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - particles: "float[:,:]", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, zeros - - pn1 = p[0] - pn2 = p[1] - pn3 = p[2] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - pd3 = pn3 - 1 - - # p + 1 non-vanishing basis functions up tp degree p - b1 = empty((pn1 + 1, pn1 + 1), dtype=float) - b2 = empty((pn2 + 1, pn2 + 1), dtype=float) - b3 = empty((pn3 + 1, pn3 + 1), dtype=float) - - l1 = empty(pn1, dtype=float) - l2 = empty(pn2, dtype=float) - l3 = empty(pn3, dtype=float) - - r1 = empty(pn1, dtype=float) - r2 = empty(pn2, dtype=float) - r3 = empty(pn3, dtype=float) - - # scaling arrays for M-splines - d1 = empty(pn1, dtype=float) - d2 = empty(pn2, dtype=float) - d3 = empty(pn3, dtype=float) - # non-vanishing N-splines - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - # non-vanishing D-splines - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - vel2 = zeros(3, dtype=float) - vel = zeros(3, dtype=float) - dfinv = zeros((3, 3), dtype=float) - out_vector[:, :] = 0.0 - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = empty((3, 3), dtype=float) - fx = empty(3, dtype=float) - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (tt, eta1, eta2, eta3, span1, span2, span3, ip, l1, l2, l3, r1, r2, r3, b1, b2, b3, d1, d2, d3, bn1, bn2, bn3, bd1, bd2, bd3, vel, vel2, dfinv, U_value, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, x1, x2, x3, Jeq) - for ip in range(Np_loc): - vel[:] = 0.0 - - eta1 = particles[0, ip] - eta2 = particles[1, ip] - eta3 = particles[2, ip] - span1 = int(eta1 * Nel[0]) + pn1 - span2 = int(eta2 * Nel[1]) + pn2 - span3 = int(eta3 * Nel[2]) + pn3 - - bsp.basis_funs_all(t1, pn1, eta1, span1, l1, r1, b1, d1) - bsp.basis_funs_all(t2, pn2, eta2, span2, l2, r2, b2, d2) - bsp.basis_funs_all(t3, pn3, eta3, span3, l3, r3, b3, d3) - bn1[:] = b1[pn1, :] - bd1[:] = b1[pd1, :pn1] * d1[:] - bn2[:] = b2[pn2, :] - bd2[:] = b2[pd2, :pn2] * d2[:] - bn3[:] = b3[pn3, :] - bd3[:] = b3[pd3, :pn3] * d3[:] - - vel[0] = eva.evaluation_kernel( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - NbaseD[0], - NbaseN[1], - NbaseN[2], - bb1, - ) - vel[1] = eva.evaluation_kernel( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - NbaseN[0], - NbaseD[1], - NbaseN[2], - bb2, - ) - vel[2] = eva.evaluation_kernel( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - NbaseN[0], - NbaseN[1], - NbaseD[2], - bb3, - ) - - tt = eva.evaluation_kernel( - pn1, - pn2, - pn3, - bn1, - bn2, - bn3, - span1, - span2, - span3, - NbaseN[0], - NbaseN[1], - NbaseN[2], - n, - ) - if abs(tt) > tol: - U_value = 1.0 / tt - else: - U_value = 0.0 - # ========= mapping evaluation ============= - span1f = int(eta1 * nelf[0]) + pf1 - span2f = int(eta2 * nelf[1]) + pf2 - span3f = int(eta3 * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - # ========================================= - - linalg.matrix_vector(dfinv, vel, vel2) - - x1 = map3d.f(eta1, eta2, eta3, 1, kind_map, params_map, tf1, tf2, tf3, pf, nbasef, cx, cy, cz) - x2 = map3d.f(eta1, eta2, eta3, 2, kind_map, params_map, tf1, tf2, tf3, pf, nbasef, cx, cy, cz) - x3 = map3d.f(eta1, eta2, eta3, 3, kind_map, params_map, tf1, tf2, tf3, pf, nbasef, cx, cy, cz) - - Jeq[0] = equ_PIC.jhx_eq(x1, x2, x3) - Jeq[1] = equ_PIC.jhy_eq(x1, x2, x3) - Jeq[2] = equ_PIC.jhz_eq(x1, x2, x3) - - vel[0] = vel2[1] * Jeq[2] - vel2[2] * Jeq[1] - vel[1] = vel2[2] * Jeq[0] - vel2[0] * Jeq[2] - vel[2] = vel2[0] * Jeq[1] - vel2[1] * Jeq[0] - out_vector[0, ip] -= U_value * vel[0] - out_vector[1, ip] -= U_value * vel[1] - out_vector[2, ip] -= U_value * vel[2] - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ===================== bv substep ======================= - - -# ========================================================================================== -def bvpre( - tol: "float", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - uvalue: "float[:,:,:,:,:,:]", - n: "float[:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * n[idnx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] - ) - if abs(value) > tol: - uvalue[ie1, ie2, ie3, q1, q2, q3] = 1.0 / value - else: - uvalue[ie1, ie2, ie3, q1, q2, q3] = 0.0 - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== - - -def bvright1( - G_inv_11: "float[:,:,:,:,:,:]", - G_inv_12: "float[:,:,:,:,:,:]", - G_inv_13: "float[:,:,:,:,:,:]", - G_inv_22: "float[:,:,:,:,:,:]", - G_inv_23: "float[:,:,:,:,:,:]", - G_inv_33: "float[:,:,:,:,:,:]", - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - b1: "float[:,:,:]", - b2: "float[:,:,:]", - b3: "float[:,:,:]", - dft: "float[:,:]", - generate_weight1: "float[:]", - generate_weight3: "float[:]", - Jeq: "float[:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", -): - # ====================================================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b1[iddx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] - ) - - b1value[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b2[idnx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] - ) - - b2value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * b3[idnx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] - ) - - b3value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, dft, generate_weight1, generate_weight3) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - dft[0, 0] = G_inv_11[ie1, ie2, ie3, q1, q2, q3] - dft[0, 1] = G_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[0, 2] = G_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[1, 0] = G_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[1, 1] = G_inv_22[ie1, ie2, ie3, q1, q2, q3] - dft[1, 2] = G_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 0] = G_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[2, 1] = G_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 2] = G_inv_33[ie1, ie2, ie3, q1, q2, q3] - generate_weight3[0] = b1value[ie1, ie2, ie3, q1, q2, q3] - generate_weight3[1] = b2value[ie1, ie2, ie3, q1, q2, q3] - generate_weight3[2] = b3value[ie1, ie2, ie3, q1, q2, q3] - linalg.matrix_vector(dft, generate_weight3, generate_weight1) - b1value[ie1, ie2, ie3, q1, q2, q3] = generate_weight1[0] - b2value[ie1, ie2, ie3, q1, q2, q3] = generate_weight1[1] - b3value[ie1, ie2, ie3, q1, q2, q3] = generate_weight1[2] - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def bvright2( - DFI_11: "float[:,:,:,:,:,:]", - DFI_12: "float[:,:,:,:,:,:]", - DFI_13: "float[:,:,:,:,:,:]", - DFI_21: "float[:,:,:,:,:,:]", - DFI_22: "float[:,:,:,:,:,:]", - DFI_23: "float[:,:,:,:,:,:]", - DFI_31: "float[:,:,:,:,:,:]", - DFI_32: "float[:,:,:,:,:,:]", - DFI_33: "float[:,:,:,:,:,:]", - df_det: "float[:,:,:,:,:,:]", - Jeqx: "float[:,:,:,:,:,:]", - Jeqy: "float[:,:,:,:,:,:]", - Jeqz: "float[:,:,:,:,:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - uvalue: "float[:,:,:,:,:,:]", - dft: "float[:,:]", - generate_weight1: "float[:]", - generate_weight3: "float[:]", - Jeq: "float[:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", -): - # ====================================================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, dft, detdet, generate_weight1, generate_weight3, Jeq) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - generate_weight1[0] = b1value[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[1] = b2value[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[2] = b3value[ie1, ie2, ie3, q1, q2, q3] - - dft[0, 0] = DFI_11[ie1, ie2, ie3, q1, q2, q3] - dft[0, 1] = DFI_12[ie1, ie2, ie3, q1, q2, q3] - dft[0, 2] = DFI_13[ie1, ie2, ie3, q1, q2, q3] - dft[1, 0] = DFI_21[ie1, ie2, ie3, q1, q2, q3] - dft[1, 1] = DFI_22[ie1, ie2, ie3, q1, q2, q3] - dft[1, 2] = DFI_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 0] = DFI_31[ie1, ie2, ie3, q1, q2, q3] - dft[2, 1] = DFI_32[ie1, ie2, ie3, q1, q2, q3] - dft[2, 2] = DFI_33[ie1, ie2, ie3, q1, q2, q3] - detdet = df_det[ie1, ie2, ie3, q1, q2, q3] * wts1[ie1, q1] * wts2[ie2, q2] * wts3[ie3, q3] - Jeq[0] = Jeqx[ie1, ie2, ie3, q1, q2, q3] - Jeq[1] = Jeqy[ie1, ie2, ie3, q1, q2, q3] - Jeq[2] = Jeqz[ie1, ie2, ie3, q1, q2, q3] - linalg.matrix_vector(dft, Jeq, generate_weight3) - - b1value[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * ( - generate_weight3[1] * generate_weight1[2] - - generate_weight3[2] * generate_weight1[1] - ) - ) - b2value[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * ( - generate_weight3[2] * generate_weight1[0] - - generate_weight3[0] * generate_weight1[2] - ) - ) - b3value[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * ( - generate_weight3[0] * generate_weight1[1] - - generate_weight3[1] * generate_weight1[0] - ) - ) - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def bvfinal( - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - uvalue: "float[:,:,:,:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - temp_final_1: "float[:,:,:]", - temp_final_2: "float[:,:,:]", - temp_final_3: "float[:,:,:]", -): - temp_final_1[:, :, :] = 0.0 - temp_final_2[:, :, :] = 0.0 - temp_final_3[:, :, :] = 0.0 - # ====================================================================================== - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_1) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(d3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - b1value[ie1, ie2, ie3, q1, q2, q3] - * bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - ) - - temp_final_1[idnx[ie1, il1], iddy[ie2, il2], iddz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_2) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - b2value[ie1, ie2, ie3, q1, q2, q3] - * bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - ) - - temp_final_2[iddx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_3) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(d1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - b3value[ie1, ie2, ie3, q1, q2, q3] - * bd1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - ) - - temp_final_3[iddx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/massless_control_variate.py b/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/massless_control_variate.py deleted file mode 100644 index 3459ff7b2..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/massless_control_variate.py +++ /dev/null @@ -1,595 +0,0 @@ -import cunumpy as xp -import hylife.utilitis_FEEC.basics.kernels_3d as ker -import hylife.utilitis_FEEC.control_variates.massless_kernels_control_variate as ker_cv -import scipy.sparse as spa - - -def bv_pre(u, uvalue, tensor_space_FEM, p, Nel, idnx, idny, idnz): - r""" - Computes the matrix Q4_(ab,ij) = \int e^{-U} (DF^{-T}B)_{6-a-b} (Lambda^2_(a,i) x Lambda^2_(b,j))_{6-a-b} deta, no summatio over a,b!! a is not equal to b - 2-form space V2 = span(Lambda^2_(a,i)) with a in [1,2,3] and i in [1, N^2_a] - Number of basis functions is N2 = N2_1 + N2_2 + N2_3 - - ab is a 3x3 block matrix structure: skew-symmetric matrix, we compute elements 12, 31, 23 - M12 = Lambda^2_1 x Lambda^2_2 contracts with the 3rd component of DF^{-T}(B1, B2, B3) - M31 = Lambda^2_3 x Lambda^2_1 contracts with the 2nd component of DF^{-T}(B1, B2, B3) - M23 = Lambda^2_2 x Lambda^2_3 contracts with the 1st component of DF^{-T}(B1, B2, B3) - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - - Returns: - M: Q4 block matrix, csc sparse - """ - - ker_cv.bvpre( - Nel[0], - Nel[1], - Nel[2], - tensor_space_FEM.n_quad[0], - tensor_space_FEM.n_quad[1], - tensor_space_FEM.n_quad[2], - p[0], - p[1], - p[2], - uvalue, - u, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - idnx, - idny, - idnz, - ) - - -def bv_right( - p, - indN, - indD, - Nel, - G_inv_11, - G_inv_12, - G_inv_13, - G_inv_22, - G_inv_23, - G_inv_33, - DFI_11, - DFI_12, - DFI_13, - DFI_21, - DFI_22, - DFI_23, - DFI_31, - DFI_32, - DFI_33, - df_det, - Jeqx, - Jeqy, - Jeqz, - temp_dft, - generate_weight1, - generate_weight2, - generate_weight3, - temp_twoform1, - temp_twoform2, - temp_twoform3, - b1, - b2, - b3, - uvalue, - b1value, - b2value, - b3value, - tensor_space_FEM, -): - r""" - Computes the matrix Q4_(ab,ij) = \int e^{-U} (DF^{-T}B)_{6-a-b} (Lambda^2_(a,i) x Lambda^2_(b,j))_{6-a-b} deta, no summatio over a,b!! a is not equal to b - 2-form space V2 = span(Lambda^2_(a,i)) with a in [1,2,3] and i in [1, N^2_a] - Number of basis functions is N2 = N2_1 + N2_2 + N2_3 - - ab is a 3x3 block matrix structure: skew-symmetric matrix, we compute elements 12, 31, 23 - M12 = Lambda^2_1 x Lambda^2_2 contracts with the 3rd component of DF^{-T}(B1, B2, B3) - M31 = Lambda^2_3 x Lambda^2_1 contracts with the 2nd component of DF^{-T}(B1, B2, B3) - M23 = Lambda^2_2 x Lambda^2_3 contracts with the 1st component of DF^{-T}(B1, B2, B3) - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - - Returns: - M: Q4 block matrix, csc sparse - """ - # ============= load information about B-splines ============= - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D splin degrees - nq1 = tensor_space_FEM.n_quad[0] - nq2 = tensor_space_FEM.n_quad[1] - nq3 = tensor_space_FEM.n_quad[2] - bn1 = tensor_space_FEM.basisN[0] - bn2 = tensor_space_FEM.basisN[1] - bn3 = tensor_space_FEM.basisN[2] - bd1 = tensor_space_FEM.basisD[0] - bd2 = tensor_space_FEM.basisD[1] - bd3 = tensor_space_FEM.basisD[2] - pts1 = tensor_space_FEM.pts[0] - pts2 = tensor_space_FEM.pts[1] - pts3 = tensor_space_FEM.pts[2] - wts1 = tensor_space_FEM.wts[0] - wts2 = tensor_space_FEM.wts[1] - wts3 = tensor_space_FEM.wts[2] - - ker_cv.bvright1( - G_inv_11, - G_inv_12, - G_inv_13, - G_inv_22, - G_inv_23, - G_inv_33, - indN[0], - indN[1], - indN[2], - indD[0], - indD[1], - indD[2], - Nel[0], - Nel[1], - Nel[2], - nq1, - nq2, - nq3, - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1value, - b2value, - b3value, - b1, - b2, - b3, - temp_dft, - generate_weight1, - generate_weight2, - generate_weight3, - bn1, - bn2, - bn3, - bd1, - bd2, - bd3, - ) - ker_cv.bvright2( - DFI_11, - DFI_12, - DFI_13, - DFI_21, - DFI_22, - DFI_23, - DFI_31, - DFI_32, - DFI_33, - df_det, - Jeqx, - Jeqy, - Jeqz, - Nel[0], - Nel[1], - Nel[2], - nq1, - nq2, - nq3, - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1value, - b2value, - b3value, - uvalue, - temp_dft, - generate_weight1, - generate_weight2, - generate_weight3, - pts1, - pts2, - pts3, - wts1, - wts2, - wts3, - ) - ker_cv.bvfinal( - indN[0], - indN[1], - indN[2], - indD[0], - indD[1], - indD[2], - Nel[0], - Nel[1], - Nel[2], - nq1, - nq2, - nq3, - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1value, - b2value, - b3value, - uvalue, - bn1, - bn2, - bn3, - bd1, - bd2, - bd3, - temp_twoform1, - temp_twoform2, - temp_twoform3, - ) - # ========================= C.T =========================== - return tensor_space_FEM.C.T.dot( - xp.concatenate((temp_twoform1.flatten(), temp_twoform2.flatten(), temp_twoform3.flatten())), - ) - - -def uv_right( - dft, - DFI_11, - DFI_12, - DFI_13, - DFI_21, - DFI_22, - DFI_23, - DFI_31, - DFI_32, - DFI_33, - df_det, - Jeqx, - Jeqy, - Jeqz, - indN, - indD, - generate_weight1, - generate_weight2, - generate_weight3, - p, - Nel, - temp_final_0, - temp_final_1, - temp_final_2, - temp_final_3, - gradU1, - gradU2, - gradU3, - GRAD, - u, - uvalue, - b1value, - b2value, - b3value, - weight0, - weight1, - weight2, - weight3, - tensor_space_FEM, -): - r""" - Computes the matrix Q4_(ab,ij) = \int e^{-U} (DF^{-T}B)_{6-a-b} (Lambda^2_(a,i) x Lambda^2_(b,j))_{6-a-b} deta, no summatio over a,b!! a is not equal to b - 2-form space V2 = span(Lambda^2_(a,i)) with a in [1,2,3] and i in [1, N^2_a] - Number of basis functions is N2 = N2_1 + N2_2 + N2_3 - - ab is a 3x3 block matrix structure: skew-symmetric matrix, we compute elements 12, 31, 23 - M12 = Lambda^2_1 x Lambda^2_2 contracts with the 3rd component of DF^{-T}(B1, B2, B3) - M31 = Lambda^2_3 x Lambda^2_1 contracts with the 2nd component of DF^{-T}(B1, B2, B3) - M23 = Lambda^2_2 x Lambda^2_3 contracts with the 1st component of DF^{-T}(B1, B2, B3) - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - - Returns: - M: Q4 block matrix, csc sparse - """ - # =====we can just calculate 3 matrices===== - # ============= load information about B-splines ============= - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D splin degrees - - ker_cv.uvpre( - indN[0], - indN[1], - indN[2], - Nel[0], - Nel[1], - Nel[2], - tensor_space_FEM.n_quad[0], - tensor_space_FEM.n_quad[1], - tensor_space_FEM.n_quad[2], - p[0], - p[1], - p[2], - uvalue, - u, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - ) - ker_cv.uvright( - DFI_11, - DFI_12, - DFI_13, - DFI_21, - DFI_22, - DFI_23, - DFI_31, - DFI_32, - DFI_33, - df_det, - Jeqx, - Jeqy, - Jeqz, - generate_weight3, - indN[0], - indN[1], - indN[2], - indD[0], - indD[1], - indD[2], - Nel[0], - Nel[1], - Nel[2], - tensor_space_FEM.n_quad[0], - tensor_space_FEM.n_quad[1], - tensor_space_FEM.n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1value, - b2value, - b3value, - uvalue, - weight0, - weight1, - weight2, - weight3, - gradU1, - gradU2, - gradU3, - dft, - generate_weight1, - generate_weight2, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - tensor_space_FEM.wts[0], - tensor_space_FEM.wts[1], - tensor_space_FEM.wts[2], - ) - ker_cv.uvfinal( - indN[0], - indN[1], - indN[2], - indD[0], - indD[1], - indD[2], - Nel[0], - Nel[1], - Nel[2], - tensor_space_FEM.n_quad[0], - tensor_space_FEM.n_quad[1], - tensor_space_FEM.n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - weight0, - temp_final_0, - temp_final_1, - temp_final_2, - temp_final_3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - # ========================= C.T =========================== - temp_final = temp_final_0.flatten() + tensor_space_FEM.G.T.dot( - xp.concatenate((temp_final_1.flatten(), temp_final_2.flatten(), temp_final_3.flatten())), - ) - - return temp_final - - -def vv_right( - stage_index, - Np_loc, - u, - domain, - acc, - NbaseN, - NbaseD, - temp_particle, - p, - Nel, - tensor_space_FEM, - b1, - b2, - b3, - particles_loc, -): - r""" - Computes the matrix Q4_(ab,ij) = \int e^{-U} (DF^{-T}B)_{6-a-b} (Lambda^2_(a,i) x Lambda^2_(b,j))_{6-a-b} deta, no summatio over a,b!! a is not equal to b - 2-form space V2 = span(Lambda^2_(a,i)) with a in [1,2,3] and i in [1, N^2_a] - Number of basis functions is N2 = N2_1 + N2_2 + N2_3 - - ab is a 3x3 block matrix structure: skew-symmetric matrix, we compute elements 12, 31, 23 - M12 = Lambda^2_1 x Lambda^2_2 contracts with the 3rd component of DF^{-T}(B1, B2, B3) - M31 = Lambda^2_3 x Lambda^2_1 contracts with the 2nd component of DF^{-T}(B1, B2, B3) - M23 = Lambda^2_2 x Lambda^2_3 contracts with the 1st component of DF^{-T}(B1, B2, B3) - - Parameters: - Mab_kernel: ndarray - [b1, b2, b3]: coefficents of B - u: coefficients of U - tensor_space_FEM: STRUPHY 3D spline object - mapping: STRUPHY mapping type - - - - Returns: - M: Q4 block matrix, csc sparse - """ - # =====we can just calculate 3 matrices===== - # ============= load information about B-splines ============= - if stage_index == 1: - ker_cv.vv( - acc.stage1_out_loc, - temp_particle, - b1, - b2, - b3, - u, - Np_loc, - NbaseN, - NbaseD, - Nel, - p, - tensor_space_FEM.T[0], - tensor_space_FEM.T[1], - tensor_space_FEM.T[2], - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif stage_index == 2: - ker_cv.vv( - acc.stage2_out_loc, - temp_particle, - b1, - b2, - b3, - u, - Np_loc, - NbaseN, - NbaseD, - Nel, - p, - tensor_space_FEM.T[0], - tensor_space_FEM.T[1], - tensor_space_FEM.T[2], - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif stage_index == 3: - ker_cv.vv( - acc.stage3_out_loc, - temp_particle, - b1, - b2, - b3, - u, - Np_loc, - NbaseN, - NbaseD, - Nel, - p, - tensor_space_FEM.T[0], - tensor_space_FEM.T[1], - tensor_space_FEM.T[2], - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - else: - ker_cv.vv( - acc.stage4_out_loc, - temp_particle, - b1, - b2, - b3, - u, - Np_loc, - NbaseN, - NbaseD, - Nel, - p, - tensor_space_FEM.T[0], - tensor_space_FEM.T[1], - tensor_space_FEM.T[2], - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) diff --git a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/massless_cvker.py b/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/massless_cvker.py deleted file mode 100644 index 753967c78..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/massless_cvker.py +++ /dev/null @@ -1,257 +0,0 @@ -import hylife.geometry.mappings_3d as map3d -import hylife.geometry.mappings_3d_fast as mapping_fast -import hylife.linear_algebra.core as linalg -import hylife.utilitis_FEEC.basics.spline_evaluation_3d as eva -import hylife.utilitis_FEEC.bsplines_kernels as bsp -import input_run.equilibrium_PIC as equ_PIC - - -# ========================================================================================== -def bvright1( - G_inv_11: "float[:,:,:,:,:,:]", - G_inv_12: "float[:,:,:,:,:,:]", - G_inv_13: "float[:,:,:,:,:,:]", - G_inv_22: "float[:,:,:,:,:,:]", - G_inv_23: "float[:,:,:,:,:,:]", - G_inv_33: "float[:,:,:,:,:,:]", - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - b1: "float[:,:,:]", - b2: "float[:,:,:]", - b3: "float[:,:,:]", - dft: "float[:,:]", - generate_weight1: "float[:]", - generate_weight3: "float[:]", - Jeq: "float[:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", -): - # ====================================================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b1[iddx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] - ) - - b1value[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b2[idnx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] - ) - - b2value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * b3[idnx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] - ) - - b3value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, dft, generate_weight1, generate_weight3) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - dft[0, 0] = G_inv_11[ie1, ie2, ie3, q1, q2, q3] - dft[0, 1] = G_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[0, 2] = G_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[1, 0] = G_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[1, 1] = G_inv_22[ie1, ie2, ie3, q1, q2, q3] - dft[1, 2] = G_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 0] = G_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[2, 1] = G_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 2] = G_inv_33[ie1, ie2, ie3, q1, q2, q3] - generate_weight3[0] = b1value[ie1, ie2, ie3, q1, q2, q3] - generate_weight3[1] = b2value[ie1, ie2, ie3, q1, q2, q3] - generate_weight3[2] = b3value[ie1, ie2, ie3, q1, q2, q3] - linalg.matrix_vector(dft, generate_weight3, generate_weight1) - b1value[ie1, ie2, ie3, q1, q2, q3] = generate_weight1[0] - b2value[ie1, ie2, ie3, q1, q2, q3] = generate_weight1[1] - b3value[ie1, ie2, ie3, q1, q2, q3] = generate_weight1[2] - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def bvright2( - DFI_11: "float[:,:,:,:,:,:]", - DFI_12: "float[:,:,:,:,:,:]", - DFI_13: "float[:,:,:,:,:,:]", - DFI_21: "float[:,:,:,:,:,:]", - DFI_22: "float[:,:,:,:,:,:]", - DFI_23: "float[:,:,:,:,:,:]", - DFI_31: "float[:,:,:,:,:,:]", - DFI_32: "float[:,:,:,:,:,:]", - DFI_33: "float[:,:,:,:,:,:]", - df_det: "float[:,:,:,:,:,:]", - Jeqx: "float[:,:,:,:,:,:]", - Jeqy: "float[:,:,:,:,:,:]", - Jeqz: "float[:,:,:,:,:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - uvalue: "float[:,:,:,:,:,:]", - dft: "float[:,:]", - generate_weight1: "float[:]", - generate_weight3: "float[:]", - Jeq: "float[:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", -): - # ====================================================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, dft, detdet, generate_weight1, generate_weight3, Jeq) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - generate_weight1[0] = b1value[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[1] = b2value[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[2] = b3value[ie1, ie2, ie3, q1, q2, q3] - - dft[0, 0] = DFI_11[ie1, ie2, ie3, q1, q2, q3] - dft[0, 1] = DFI_12[ie1, ie2, ie3, q1, q2, q3] - dft[0, 2] = DFI_13[ie1, ie2, ie3, q1, q2, q3] - dft[1, 0] = DFI_21[ie1, ie2, ie3, q1, q2, q3] - dft[1, 1] = DFI_22[ie1, ie2, ie3, q1, q2, q3] - dft[1, 2] = DFI_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 0] = DFI_31[ie1, ie2, ie3, q1, q2, q3] - dft[2, 1] = DFI_32[ie1, ie2, ie3, q1, q2, q3] - dft[2, 2] = DFI_33[ie1, ie2, ie3, q1, q2, q3] - detdet = df_det[ie1, ie2, ie3, q1, q2, q3] * wts1[ie1, q1] * wts2[ie2, q2] * wts3[ie3, q3] - Jeq[0] = Jeqx[ie1, ie2, ie3, q1, q2, q3] - Jeq[1] = Jeqy[ie1, ie2, ie3, q1, q2, q3] - Jeq[2] = Jeqz[ie1, ie2, ie3, q1, q2, q3] - linalg.matrix_vector(dft, Jeq, generate_weight3) - - b1value[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * ( - generate_weight3[1] * generate_weight1[2] - - generate_weight3[2] * generate_weight1[1] - ) - ) - b2value[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * ( - generate_weight3[2] * generate_weight1[0] - - generate_weight3[0] * generate_weight1[2] - ) - ) - b3value[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * ( - generate_weight3[0] * generate_weight1[1] - - generate_weight3[1] * generate_weight1[0] - ) - ) - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/massless_kernels_control_variate.py b/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/massless_kernels_control_variate.py deleted file mode 100644 index bfff64b2a..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/control_variates/kinetic_extended/massless_kernels_control_variate.py +++ /dev/null @@ -1,1140 +0,0 @@ -import hylife.geometry.mappings_3d as map3d -import hylife.geometry.mappings_3d_fast as mapping_fast -import hylife.linear_algebra.core as linalg -import hylife.utilitis_FEEC.basics.spline_evaluation_3d as eva -import hylife.utilitis_FEEC.bsplines_kernels as bsp -import input_run.equilibrium_PIC as equ_PIC - - -# ========================================================================================== -def uvpre( - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - uvalue: "float[:,:,:,:,:,:]", - u: "float[:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", -): - from numpy import empty, exp, zeros - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * u[idnx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] - ) - - uvalue[ie1, ie2, ie3, q1, q2, q3] = exp(-value) - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def uvright( - DFI_11: "float[:,:,:,:,:,:]", - DFI_12: "float[:,:,:,:,:,:]", - DFI_13: "float[:,:,:,:,:,:]", - DFI_21: "float[:,:,:,:,:,:]", - DFI_22: "float[:,:,:,:,:,:]", - DFI_23: "float[:,:,:,:,:,:]", - DFI_31: "float[:,:,:,:,:,:]", - DFI_32: "float[:,:,:,:,:,:]", - DFI_33: "float[:,:,:,:,:,:]", - df_det: "float[:,:,:,:,:,:]", - Jeqx: "float[:,:,:,:,:,:]", - Jeqy: "float[:,:,:,:,:,:]", - Jeqz: "float[:,:,:,:,:,:]", - Jeq: "float[:]", - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - uvalue: "float[:,:,:,:,:,:]", - weight0: "float[:,:,:,:,:,:]", - weight1: "float[:,:,:,:,:,:]", - weight2: "float[:,:,:,:,:,:]", - weight3: "float[:,:,:,:,:,:]", - b1: "float[:,:,:]", - b2: "float[:,:,:]", - b3: "float[:,:,:]", - dft: "float[:,:]", - generate_weight1: "float[:]", - generate_weight3: "float[:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b1[iddx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] - ) - - b1value[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b2[idnx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] - ) - - b2value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * b3[idnx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] - ) - - b3value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, dft, detdet, generate_weight1, generate_weight3, Jeq) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - dft[0, 0] = DFI_11[ - ie1, - ie2, - ie3, - q1, - q2, - q3, - ] # mappings_analytical.df_inv(pts1[ie1, q1], pts2[ie2,q2], pts3[ie3,q3], kind_map, params_map, components[0, 0]) - dft[0, 1] = DFI_21[ - ie1, - ie2, - ie3, - q1, - q2, - q3, - ] # mappings_analytical.df_inv(pts1[ie1, q1], pts2[ie2,q2], pts3[ie3,q3], kind_map, params_map, components[0, 1]) - dft[0, 2] = DFI_31[ - ie1, - ie2, - ie3, - q1, - q2, - q3, - ] # mappings_analytical.df_inv(pts1[ie1, q1], pts2[ie2,q2], pts3[ie3,q3], kind_map, params_map, components[0, 2]) - dft[1, 0] = DFI_12[ - ie1, - ie2, - ie3, - q1, - q2, - q3, - ] # mappings_analytical.df_inv(pts1[ie1, q1], pts2[ie2,q2], pts3[ie3,q3], kind_map, params_map, components[1, 0]) - dft[1, 1] = DFI_22[ - ie1, - ie2, - ie3, - q1, - q2, - q3, - ] # mappings_analytical.df_inv(pts1[ie1, q1], pts2[ie2,q2], pts3[ie3,q3], kind_map, params_map, components[1, 1]) - dft[1, 2] = DFI_32[ - ie1, - ie2, - ie3, - q1, - q2, - q3, - ] # mappings_analytical.df_inv(pts1[ie1, q1], pts2[ie2,q2], pts3[ie3,q3], kind_map, params_map, components[1, 2]) - dft[2, 0] = DFI_13[ - ie1, - ie2, - ie3, - q1, - q2, - q3, - ] # mappings_analytical.df_inv(pts1[ie1, q1], pts2[ie2,q2], pts3[ie3,q3], kind_map, params_map, components[2, 0]) - dft[2, 1] = DFI_23[ - ie1, - ie2, - ie3, - q1, - q2, - q3, - ] # mappings_analytical.df_inv(pts1[ie1, q1], pts2[ie2,q2], pts3[ie3,q3], kind_map, params_map, components[2, 1]) - dft[2, 2] = DFI_33[ - ie1, - ie2, - ie3, - q1, - q2, - q3, - ] # mappings_analytical.df_inv(pts1[ie1, q1], pts2[ie2,q2], pts3[ie3,q3], kind_map, params_map, components[2, 2]) - detdet = df_det[ - ie1, - ie2, - ie3, - q1, - q2, - q3, - ] # mappings_analytical.det_df(pts1[ie1, q1], pts2[ie2,q2], pts3[ie3,q3], kind_map, params_map) - Jeq[0] = Jeqx[ie1, ie2, ie3, q1, q2, q3] - Jeq[1] = Jeqy[ie1, ie2, ie3, q1, q2, q3] - Jeq[2] = Jeqz[ie1, ie2, ie3, q1, q2, q3] - linalg.matrix_vector(dft, Jeq, generate_weight3) - weight1[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * generate_weight3[0] - * wts1[ie1, q1] - * wts2[ie2, q2] - * wts3[ie3, q3] - ) - weight2[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * generate_weight3[1] - * wts1[ie1, q1] - * wts2[ie2, q2] - * wts3[ie3, q3] - ) - weight3[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * generate_weight3[2] - * wts1[ie1, q1] - * wts2[ie2, q2] - * wts3[ie3, q3] - ) - weight0[ie1, ie2, ie3, q1, q2, q3] = ( - -uvalue[ie1, ie2, ie3, q1, q2, q3] - * ( - b1value[ie1, ie2, ie3, q1, q2, q3] * generate_weight3[0] - + b2value[ie1, ie2, ie3, q1, q2, q3] * generate_weight3[1] - + b3value[ie1, ie2, ie3, q1, q2, q3] * generate_weight3[2] - ) - * detdet - * wts1[ie1, q1] - * wts2[ie2, q2] - * wts3[ie3, q3] - ) - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def uvfinal( - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - weight1: "float[:,:,:,:,:,:]", - weight2: "float[:,:,:,:,:,:]", - weight3: "float[:,:,:,:,:,:]", - weight0: "float[:,:,:,:,:,:]", - temp_final_0: "float[:,:,:]", - temp_final_1: "float[:,:,:]", - temp_final_2: "float[:,:,:]", - temp_final_3: "float[:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", -): - temp_final_0[:, :, :] = 0.0 - temp_final_1[:, :, :] = 0.0 - temp_final_2[:, :, :] = 0.0 - temp_final_3[:, :, :] = 0.0 - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_0) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight0[ie1, ie2, ie3, q1, q2, q3] - * bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - ) - - temp_final_0[idnx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_1) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight1[ie1, ie2, ie3, q1, q2, q3] - * bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - ) - - temp_final_1[iddx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_2) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight2[ie1, ie2, ie3, q1, q2, q3] - * bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - ) - - temp_final_2[idnx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_3) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight3[ie1, ie2, ie3, q1, q2, q3] - * bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - ) - - temp_final_3[idnx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - -# ========================================================================================== -def bvpre( - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - uvalue: "float[:,:,:,:,:,:]", - u: "float[:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", -): - from numpy import exp - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * u[idnx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] - ) - - uvalue[ie1, ie2, ie3, q1, q2, q3] = exp(-value) - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def bvfinal( - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - uvalue: "float[:,:,:,:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - temp_final_1: "float[:,:,:]", - temp_final_2: "float[:,:,:]", - temp_final_3: "float[:,:,:]", -): - temp_final_1[:, :, :] = 0.0 - temp_final_2[:, :, :] = 0.0 - temp_final_3[:, :, :] = 0.0 - # ====================================================================================== - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_1) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(d3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - b1value[ie1, ie2, ie3, q1, q2, q3] - * bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - ) - - temp_final_1[idnx[ie1, il1], iddy[ie2, il2], iddz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_2) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - b2value[ie1, ie2, ie3, q1, q2, q3] - * bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - ) - - temp_final_2[iddx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_3) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(d1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - b3value[ie1, ie2, ie3, q1, q2, q3] - * bd1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - ) - - temp_final_3[iddx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================================================================================================================= -def vv( - out_vector: "float[:,:]", - Jeq: "float[:]", - bb1: "float[:,:,:]", - bb2: "float[:,:,:]", - bb3: "float[:,:,:]", - u: "float[:,:,:]", - Np_loc: "int", - NbaseN: "int[:]", - NbaseD: "int[:]", - Nel: "int[:]", - p: "int[:]", - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - particles: "float[:,:]", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - # can we set matrix as global variable, how data is sent in python? - from numpy import empty, exp, zeros - - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D spline degrees - - vel = zeros(3, dtype=float) - # - dfinv = zeros((3, 3), dtype=float) - - pn1 = p[0] - pn2 = p[1] - pn3 = p[2] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - pd3 = pn3 - 1 - - # p + 1 non-vanishing basis functions up tp degree p - b1 = empty((pn1 + 1, pn1 + 1), dtype=float) - b2 = empty((pn2 + 1, pn2 + 1), dtype=float) - b3 = empty((pn3 + 1, pn3 + 1), dtype=float) - - l1 = empty(pn1, dtype=float) - l2 = empty(pn2, dtype=float) - l3 = empty(pn3, dtype=float) - - r1 = empty(pn1, dtype=float) - r2 = empty(pn2, dtype=float) - r3 = empty(pn3, dtype=float) - - # scaling arrays for M-splines - d1 = empty(pn1, dtype=float) - d2 = empty(pn2, dtype=float) - d3 = empty(pn3, dtype=float) - # non-vanishing N-splines - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - # non-vanishing D-splines - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - vel2 = zeros(3, dtype=float) - x = zeros(3, dtype=float) - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = zeros((3, 3), dtype=float) - g = zeros((3, 3), dtype=float) - fx = zeros(3, dtype=float) - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (eta1, eta2, eta3, x, span1, span2, span3, ip, l1, l2, l3, r1, r2, r3, b1, b2, b3, d1, d2, d3, bn1, bn2, bn3, bd1, bd2, bd3, vel, vel2, dfinv, U_value, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, Jeq) - for ip in range(Np_loc): - vel[:] = 0.0 - - eta1 = particles[0, ip] - eta2 = particles[1, ip] - eta3 = particles[2, ip] - span1 = int(eta1 * Nel[0]) + pn1 - span2 = int(eta2 * Nel[1]) + pn2 - span3 = int(eta3 * Nel[2]) + pn3 - - bsp.basis_funs_all(t1, pn1, eta1, span1, l1, r1, b1, d1) - bsp.basis_funs_all(t2, pn2, eta2, span2, l2, r2, b2, d2) - bsp.basis_funs_all(t3, pn3, eta3, span3, l3, r3, b3, d3) - bn1[:] = b1[pn1, :] - bd1[:] = b1[pd1, :pn1] * d1[:] - bn2[:] = b2[pn2, :] - bd2[:] = b2[pd2, :pn2] * d2[:] - bn3[:] = b3[pn3, :] - bd3[:] = b3[pd3, :pn3] * d3[:] - - vel[0] = eva.evaluation_kernel( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - NbaseD[0], - NbaseN[1], - NbaseN[2], - bb1, - ) - vel[1] = eva.evaluation_kernel( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - NbaseN[0], - NbaseD[1], - NbaseN[2], - bb2, - ) - vel[2] = eva.evaluation_kernel( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - NbaseN[0], - NbaseN[1], - NbaseD[2], - bb3, - ) - - U_value = exp( - -eva.evaluation_kernel( - pn1, - pn2, - pn3, - bn1, - bn2, - bn3, - span1, - span2, - span3, - NbaseN[0], - NbaseN[1], - NbaseN[2], - u, - ), - ) - - # ========= mapping evaluation ============= - span1f = int(eta1 * nelf[0]) + pf1 - span2f = int(eta2 * nelf[1]) + pf2 - span3f = int(eta3 * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - # ========================================= - - vel2[0] = dfinv[0, 0] * vel[0] + dfinv[1, 0] * vel[1] + dfinv[2, 0] * vel[2] - vel2[1] = dfinv[0, 1] * vel[0] + dfinv[1, 1] * vel[1] + dfinv[2, 1] * vel[2] - vel2[2] = dfinv[0, 2] * vel[0] + dfinv[1, 2] * vel[1] + dfinv[2, 2] * vel[2] - - # ====== Jeq should be evaluated in physical domain - x[0] = map3d.f(eta1, eta2, eta3, 1, kind_map, params_map, tf1, tf2, tf3, pf, nbasef, cx, cy, cz) - x[1] = map3d.f(eta1, eta2, eta3, 2, kind_map, params_map, tf1, tf2, tf3, pf, nbasef, cx, cy, cz) - x[2] = map3d.f(eta1, eta2, eta3, 3, kind_map, params_map, tf1, tf2, tf3, pf, nbasef, cx, cy, cz) - Jeq[0] = equ_PIC.jhx_eq(x[0], x[1], x[2]) - Jeq[1] = equ_PIC.jhy_eq(x[0], x[1], x[2]) - Jeq[2] = equ_PIC.jhz_eq(x[0], x[1], x[2]) - vel[0] = vel2[1] * Jeq[2] - vel2[2] * Jeq[1] - vel[1] = vel2[2] * Jeq[0] - vel2[0] * Jeq[2] - vel[2] = vel2[0] * Jeq[1] - vel2[1] * Jeq[0] - out_vector[0, ip] -= U_value * vel[0] - out_vector[1, ip] -= U_value * vel[1] - out_vector[2, ip] -= U_value * vel[2] - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def bvright1( - G_inv_11: "float[:,:,:,:,:,:]", - G_inv_12: "float[:,:,:,:,:,:]", - G_inv_13: "float[:,:,:,:,:,:]", - G_inv_22: "float[:,:,:,:,:,:]", - G_inv_23: "float[:,:,:,:,:,:]", - G_inv_33: "float[:,:,:,:,:,:]", - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - b1: "float[:,:,:]", - b2: "float[:,:,:]", - b3: "float[:,:,:]", - dft: "float[:,:]", - generate_weight1: "float[:]", - generate_weight3: "float[:]", - Jeq: "float[:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", -): - # ====================================================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b1[iddx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] - ) - - b1value[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b2[idnx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] - ) - - b2value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * b3[idnx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] - ) - - b3value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, dft, generate_weight1, generate_weight3) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - dft[0, 0] = G_inv_11[ie1, ie2, ie3, q1, q2, q3] - dft[0, 1] = G_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[0, 2] = G_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[1, 0] = G_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[1, 1] = G_inv_22[ie1, ie2, ie3, q1, q2, q3] - dft[1, 2] = G_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 0] = G_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[2, 1] = G_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 2] = G_inv_33[ie1, ie2, ie3, q1, q2, q3] - generate_weight3[0] = b1value[ie1, ie2, ie3, q1, q2, q3] - generate_weight3[1] = b2value[ie1, ie2, ie3, q1, q2, q3] - generate_weight3[2] = b3value[ie1, ie2, ie3, q1, q2, q3] - linalg.matrix_vector(dft, generate_weight3, generate_weight1) - b1value[ie1, ie2, ie3, q1, q2, q3] = generate_weight1[0] - b2value[ie1, ie2, ie3, q1, q2, q3] = generate_weight1[1] - b3value[ie1, ie2, ie3, q1, q2, q3] = generate_weight1[2] - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def bvright2( - DFI_11: "float[:,:,:,:,:,:]", - DFI_12: "float[:,:,:,:,:,:]", - DFI_13: "float[:,:,:,:,:,:]", - DFI_21: "float[:,:,:,:,:,:]", - DFI_22: "float[:,:,:,:,:,:]", - DFI_23: "float[:,:,:,:,:,:]", - DFI_31: "float[:,:,:,:,:,:]", - DFI_32: "float[:,:,:,:,:,:]", - DFI_33: "float[:,:,:,:,:,:]", - df_det: "float[:,:,:,:,:,:]", - Jeqx: "float[:,:,:,:,:,:]", - Jeqy: "float[:,:,:,:,:,:]", - Jeqz: "float[:,:,:,:,:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - uvalue: "float[:,:,:,:,:,:]", - dft: "float[:,:]", - generate_weight1: "float[:]", - generate_weight3: "float[:]", - Jeq: "float[:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", -): - # ====================================================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, dft, detdet, generate_weight1, generate_weight3, Jeq) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - generate_weight1[0] = b1value[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[1] = b2value[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[2] = b3value[ie1, ie2, ie3, q1, q2, q3] - - dft[0, 0] = DFI_11[ie1, ie2, ie3, q1, q2, q3] - dft[0, 1] = DFI_12[ie1, ie2, ie3, q1, q2, q3] - dft[0, 2] = DFI_13[ie1, ie2, ie3, q1, q2, q3] - dft[1, 0] = DFI_21[ie1, ie2, ie3, q1, q2, q3] - dft[1, 1] = DFI_22[ie1, ie2, ie3, q1, q2, q3] - dft[1, 2] = DFI_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 0] = DFI_31[ie1, ie2, ie3, q1, q2, q3] - dft[2, 1] = DFI_32[ie1, ie2, ie3, q1, q2, q3] - dft[2, 2] = DFI_33[ie1, ie2, ie3, q1, q2, q3] - detdet = df_det[ie1, ie2, ie3, q1, q2, q3] * wts1[ie1, q1] * wts2[ie2, q2] * wts3[ie3, q3] - Jeq[0] = Jeqx[ie1, ie2, ie3, q1, q2, q3] - Jeq[1] = Jeqy[ie1, ie2, ie3, q1, q2, q3] - Jeq[2] = Jeqz[ie1, ie2, ie3, q1, q2, q3] - linalg.matrix_vector(dft, Jeq, generate_weight3) - - b1value[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * ( - generate_weight3[1] * generate_weight1[2] - - generate_weight3[2] * generate_weight1[1] - ) - ) - b2value[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * ( - generate_weight3[2] * generate_weight1[0] - - generate_weight3[0] * generate_weight1[2] - ) - ) - b3value[ie1, ie2, ie3, q1, q2, q3] = ( - detdet - * uvalue[ie1, ie2, ie3, q1, q2, q3] - * ( - generate_weight3[0] * generate_weight1[1] - - generate_weight3[1] * generate_weight1[0] - ) - ) - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/legacy/emw_operators.py b/src/struphy/eigenvalue_solvers/legacy/emw_operators.py deleted file mode 100755 index 9e8c95b3f..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/emw_operators.py +++ /dev/null @@ -1,226 +0,0 @@ -# coding: utf-8 -# -# Copyright 2021 Florian Holderied (florian.holderied@ipp.mpg.de) - -""" -Class for 2D/3D linear MHD projection operators. -""" - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.eigenvalue_solvers.kernels_3d as ker -import struphy.eigenvalue_solvers.legacy.mass_matrices_3d_pre as mass_3d_pre - - -class EMW_operators: - """ - Define the needed operator for the ceratain model - - Parameters - ---------- - domain : obj - Domain object. - - space : obj - Tensor_spline_space object. - - eq_MHD : obj - Equilibrium_mhd object. - - - Notes - ----- - Implemented operators - ===================================================== =========================== ===================== - operator dim of matrix verification method - ===================================================== =========================== ===================== - R1 = G B2 eps_ijk lambda_j^1 lambda_k^1 1/sqrt(g) R^{N^1 x N^1} r - ===================================================== =========================== ===================== - - """ - - # def __init__(self, space, equilibrium, domain, basis_e): - def __init__(self, DOMAIN, SPACES, EQUILIBRIUM=None): - # create objects - self.DOMAIN = DOMAIN - self.SPACES = SPACES - self.EQUILIBRIUM = EQUILIBRIUM - - self.dim_V1 = self.SPACES.Ntot_1form_cum[-1] - self.dim_V2 = self.SPACES.Ntot_2form_cum[-1] - - # Build the rotation operator - weight = [self.__weight_1, self.__weight_2, self.__weight_3] - self.__assemble_M1_cross(weight) - - # ================ Build the R1 operator ===================== - def __weight_1(self, eta1, eta2, eta3): - det_g = 1.0 / abs(self.DOMAIN.evaluate(eta1, eta2, eta3, "det_df")) - G_11 = self.DOMAIN.evaluate(eta1, eta2, eta3, "g_11") - G_12 = self.DOMAIN.evaluate(eta1, eta2, eta3, "g_12") - G_13 = self.DOMAIN.evaluate(eta1, eta2, eta3, "g_13") - B0_1 = self.EQUILIBRIUM.b2_eq_1(eta1, eta2, eta3) - B0_2 = self.EQUILIBRIUM.b2_eq_2(eta1, eta2, eta3) - B0_3 = self.EQUILIBRIUM.b2_eq_3(eta1, eta2, eta3) - return det_g * (G_11 * B0_1 + G_12 * B0_2 + G_13 * B0_3) - - def __weight_2(self, eta1, eta2, eta3): - det_g = 1.0 / abs(self.DOMAIN.evaluate(eta1, eta2, eta3, "det_df")) - G_21 = self.DOMAIN.evaluate(eta1, eta2, eta3, "g_21") - G_22 = self.DOMAIN.evaluate(eta1, eta2, eta3, "g_22") - G_23 = self.DOMAIN.evaluate(eta1, eta2, eta3, "g_23") - B0_1 = self.EQUILIBRIUM.b2_eq_1(eta1, eta2, eta3) - B0_2 = self.EQUILIBRIUM.b2_eq_2(eta1, eta2, eta3) - B0_3 = self.EQUILIBRIUM.b2_eq_3(eta1, eta2, eta3) - return det_g * (G_21 * B0_1 + G_22 * B0_2 + G_23 * B0_3) - - def __weight_3(self, eta1, eta2, eta3): - det_g = 1.0 / abs(self.DOMAIN.evaluate(eta1, eta2, eta3, "det_df")) - G_31 = self.DOMAIN.evaluate(eta1, eta2, eta3, "g_31") - G_32 = self.DOMAIN.evaluate(eta1, eta2, eta3, "g_32") - G_33 = self.DOMAIN.evaluate(eta1, eta2, eta3, "g_33") - B0_1 = self.EQUILIBRIUM.b2_eq_1(eta1, eta2, eta3) - B0_2 = self.EQUILIBRIUM.b2_eq_2(eta1, eta2, eta3) - B0_3 = self.EQUILIBRIUM.b2_eq_3(eta1, eta2, eta3) - return det_g * (G_31 * B0_1 + G_32 * B0_2 + G_33 * B0_3) - - def __assemble_M1_cross(self, weight): - """ - Assembles the 3D mass matrix with integrand - Lambda_1 x Lambda_1 * weight. - - Parameters - ---------- - self.SPACES : Tensor_spline_space - tensor product B-spline space for finite element spaces - - weight : callable - optional additional weight functions - """ - - p = self.SPACES.p # spline degrees - Nel = self.SPACES.Nel # number of elements - indN = self.SPACES.indN # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = self.SPACES.indD # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = self.SPACES.n_quad # number of quadrature points per element - pts = self.SPACES.pts # global quadrature points - wts = self.SPACES.wts # global quadrature weights - - basisN = self.SPACES.basisN # evaluated basis functions at quadrature points (N) - basisD = self.SPACES.basisD # evaluated basis functions at quadrature points (D) - - # indices and basis functions of components of a 1-form - ind = [ - [indD[0], indN[1], indN[2]], # DNN - [indN[0], indD[1], indN[2]], # NDN - [indN[0], indN[1], indD[2]], - ] # NND - - basis = [ - [basisD[0], basisN[1], basisN[2]], # DNN - [basisN[0], basisD[1], basisN[2]], # DNN - [basisN[0], basisN[1], basisD[2]], - ] # NND - - ns = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] - - # blocks of global mass matrix - M = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] - - for a in range(3): - for b in range(3): - Ni = self.SPACES.Nbase_1form[a] - Nj = self.SPACES.Nbase_1form[b] - - M[a][b] = xp.zeros((Ni[0], Ni[1], Ni[2], 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1), dtype=float) - - # evaluate metric tensor at quadrature points - if a == 1 and b == 2: - mat_w = weight[0](pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - elif a == 2 and b == 1: - mat_w = -weight[0](pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - - elif a == 2 and b == 0: - mat_w = weight[1](pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - elif a == 0 and b == 2: - mat_w = -weight[1](pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - elif a == 0 and b == 1: - mat_w = weight[2](pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - elif a == 1 and b == 0: - mat_w = -weight[2](pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - - if a != b: - mat_w = mat_w.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - ker.kernel_mass( - Nel[0], - Nel[1], - Nel[2], - p[0], - p[1], - p[2], - n_quad[0], - n_quad[1], - n_quad[2], - ns[a][0], - ns[a][1], - ns[a][2], - ns[b][0], - ns[b][1], - ns[b][2], - wts[0], - wts[1], - wts[2], - basis[a][0], - basis[a][1], - basis[a][2], - basis[b][0], - basis[b][1], - basis[b][2], - ind[a][0], - ind[a][1], - ind[a][2], - M[a][b], - mat_w, - ) - # convert to sparse matrix - indices = xp.indices((Ni[0], Ni[1], Ni[2], 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1)) - - shift = [xp.arange(Ni) - p for Ni, p in zip(Ni, p)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M[a][b] = spa.csr_matrix( - (M[a][b].flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M[a][b].eliminate_zeros() - - M = spa.bmat( - [[M[0][0], M[0][1], M[0][2]], [M[1][0], M[1][1], M[1][2]], [M[2][0], M[2][1], M[2][2]]], - format="csr", - ) - - self.R1_mat = -self.SPACES.E1_0.dot(M.dot(self.SPACES.E1_0.T)).tocsr() - - # ================ Set Operator ============================== - def set_Operators(self): - self.R1 = spa.linalg.LinearOperator((self.dim_V1, self.dim_V1), matvec=lambda x: self.R1_mat.dot(x)) - - # ================ Set Preconditioners ======================= - def set_Preconditioners(self, solver, drop_tol=1e-4, fill_fac=10.0): - """ - TODO - """ - - assert solver == "FFT", "Until now, only the FFT preconditioner is implemented!" - - if solver == "FFT": - self.M1_inv = mass_3d_pre.get_M1_PRE(self.SPACES, self.DOMAIN) diff --git a/src/struphy/eigenvalue_solvers/legacy/inner_products_1d.py b/src/struphy/eigenvalue_solvers/legacy/inner_products_1d.py deleted file mode 100644 index 0bf42397d..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/inner_products_1d.py +++ /dev/null @@ -1,112 +0,0 @@ -# coding: utf-8 -# -# Copyright 2020 Florian Holderied - -""" -Modules to compute inner products in 1d. -""" - -import cunumpy as xp -import scipy.sparse as spa - - -# ======= inner product in V0 ==================== -def inner_prod_V0(spline_space, fun, mapping=None): - """ - Computes the 1d inner product (N) of the given B-spline space of degree p with the function fun. - - Parameters - ---------- - spline_space : spline_space_1d - a 1d B-spline space - - mapping : callable - derivative of mapping df/dxi - - fun : callable - function for which the inner product with every basis function in V0 shall be computed - """ - - p = spline_space.p # spline degrees - Nel = spline_space.Nel # number of elements - NbaseN = spline_space.NbaseN # total number of basis functions (N) - - n_quad = spline_space.n_quad # number of quadrature points per element - pts = spline_space.pts # global quadrature points in format (element, local quad_point) - wts = spline_space.wts # global quadrature weights in format (element, local weight) - - basisN = spline_space.basisN # evaluated basis functions at quadrature points - - # evaluation of mapping at quadrature points - if mapping is None: - mat_map = xp.ones(pts.shape, dtype=float) - else: - mat_map = mapping(pts.flatten()).reshape(pts.shape) - - # evaluation of function at quadrature points - mat_f = fun(pts.flatten()).reshape(pts.shape) - - # assembly - F = xp.zeros(NbaseN, dtype=float) - - for ie in range(Nel): - for il in range(p + 1): - value = 0.0 - - for q in range(n_quad): - value += wts[ie, q] * basisN[ie, il, 0, q] * mat_f[ie, q] * mat_map[ie, q] - - F[(ie + il) % NbaseN] += value - - return F - - -# ======= inner product in V1 ==================== -def inner_prod_V1(spline_space, fun, mapping=None): - """ - Computes the 1d inner product (D) of the given B-spline space of degree p with the function fun. - - Parameters - ---------- - spline_space : spline_space_1d - a 1d B-spline space - - mapping : callable - derivative of mapping df/dxi - - fun : callable - function for which the inner product with every basis function in V1 shall be computed - """ - - p = spline_space.p # spline degrees - Nel = spline_space.Nel # number of elements - NbaseD = spline_space.NbaseD # total number of basis functions (N) - - n_quad = spline_space.n_quad # number of quadrature points per element - pts = spline_space.pts # global quadrature points in format (element, local quad_point) - wts = spline_space.wts # global quadrature weights in format (element, local weight) - - basisD = spline_space.basisD # evaluated basis functions at quadrature points - - # evaluation of mapping at quadrature points - if mapping is None: - mat_map = xp.ones(pts.shape, dtype=float) - else: - mat_map = 1 / mapping(pts.flatten()).reshape(pts.shape) - - # evaluation of function at quadrature points - mat_f = fun(pts.flatten()).reshape(pts.shape) - - # assembly - F = xp.zeros(NbaseD, dtype=float) - - for ie in range(Nel): - for il in range(p): - value = 0.0 - - for q in range(n_quad): - value += wts[ie, q] * basisD[ie, il, 0, q] * mat_f[ie, q] * mat_map[ie, q] - - F[(ie + il) % NbaseD] += value - - return F diff --git a/src/struphy/eigenvalue_solvers/legacy/inner_products_2d.py b/src/struphy/eigenvalue_solvers/legacy/inner_products_2d.py deleted file mode 100644 index 05df4725f..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/inner_products_2d.py +++ /dev/null @@ -1,338 +0,0 @@ -# coding: utf-8 -# -# Copyright 2020 Florian Holderied - -""" -Modules to compute inner products with given functions in 2D. -""" - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.eigenvalue_solvers.kernels_2d as ker - - -# ================ inner product in V0 =========================== -def inner_prod_V0(tensor_space_FEM, domain, fun): - """ - Assembles the 2D inner product [NN] * fun * |det(DF)| of the given tensor product B-spline space of bi-degree (p1, p2) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - fun : callable or xp.ndarray - the 0-form with which the inner products shall be computed (either callable or 2D array with values at quadrature points) - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of local non-vanishing basis functions in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points in format (element, local quad_point) - wts = tensor_space_FEM.wts # global quadrature weights in format (element, local weight) - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points - - # evaluation of |det(DF)| at eta3 = 0 and quadrature points in format (Nel1, nq1, Nel2, nq2) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), 0.0)) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # evaluation of given 0-form at quadrature points - mat_f = xp.empty((pts[0].size, pts[1].size), dtype=float) - - if callable(fun): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), indexing="ij") - mat_f[:, :] = fun(quad_mesh[0], quad_mesh[1], 0.0) - else: - mat_f[:, :] = fun - - # assembly - Ni = tensor_space_FEM.Nbase_0form - - F = xp.zeros((Ni[0], Ni[1]), dtype=float) - - mat_f = mat_f.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - ker.kernel_inner( - Nel[0], - Nel[1], - p[0], - p[1], - n_quad[0], - n_quad[1], - 0, - 0, - wts[0], - wts[1], - basisN[0], - basisN[1], - indN[0], - indN[1], - F, - mat_f * det_df, - ) - - return tensor_space_FEM.E0_0.dot(F.flatten()) - - -# ================ inner product in V1 =========================== -def inner_prod_V1(tensor_space_FEM, domain, fun): - """ - Assembles the 2D inner prodcut [DN, ND, NN] * |det(DF)| * G^(-1) * [fun_1, fun_2, fun_3] of the given tensor product B-spline space of bi-degree (p1, p2) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - fun : list of callables or xp.ndarrays - the 1-form components with which the inner products shall be computed (either list of 3 callables or 2D arrays with values at quadrature points) - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - # indices and basis functions of components of a 1-form - ind = [[indD[0], indN[1]], [indN[0], indD[1]], [indN[0], indN[1]]] - basis = [[basisD[0], basisN[1]], [basisN[0], basisD[1]], [basisN[0], basisN[1]]] - ns = [[1, 0], [0, 1], [0, 0]] - - # evaluation of |det(DF)| at eta3 = 0 and quadrature points in format (Nel1, nq1, Nel2, nq2) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), 0.0)) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # evaluation of G^(-1) at eta3 = 0 and quadrature points in format (3, 3, Nel1*nq1, Nel2*nq2) - g_inv = domain.metric_inv(pts[0].flatten(), pts[1].flatten(), 0.0) - - # 1-form components at quadrature points - mat_f = xp.empty((pts[0].size, pts[1].size), dtype=float) - - if callable(fun[0]): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), indexing="ij") - - # components of global inner product - F = [0, 0, 0] - - # assembly - for a in range(3): - Ni = tensor_space_FEM.Nbase_1form[a] - F[a] = xp.zeros((Ni[0], Ni[1]), dtype=float) - - mat_f[:, :] = 0.0 - - for b in range(3): - # evaluate g^ab * f_b at quadrature points - if callable(fun[b]): - mat_f += fun[b](quad_mesh[0], quad_mesh[1], 0.0) * g_inv[a, b] - else: - mat_f += fun[b] * g_inv[a, b] - - mat_f = mat_f.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - ker.kernel_inner( - Nel[0], - Nel[1], - p[0], - p[1], - n_quad[0], - n_quad[1], - ns[a][0], - ns[a][1], - wts[0], - wts[1], - basis[a][0], - basis[a][1], - ind[a][0], - ind[a][1], - F[a], - mat_f * det_df, - ) - - F1 = tensor_space_FEM.E1_pol_0.dot(xp.concatenate((F[0].flatten(), F[1].flatten()))) - F2 = tensor_space_FEM.E0_pol_0.dot(F[2].flatten()) - - return F1, F2 - - -# ================ inner product in V2 =========================== -def inner_prod_V2(tensor_space_FEM, domain, fun): - """ - Assembles the 2D inner product [ND, DN, DD] / |det(DF)| * G * [fun_1, fun_2, fun_3] of the given tensor product B-spline space of bi-degree (p1, p2) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - fun : list of callables or xp.ndarrays - the 2-form components with which the inner products shall be computed (either list of 3 callables or 2D arrays with values at quadrature points) - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - # indices and basis functions of components of a 2-form - ind = [[indN[0], indD[1]], [indD[0], indN[1]], [indD[0], indD[1]]] - basis = [[basisN[0], basisD[1]], [basisD[0], basisN[1]], [basisD[0], basisD[1]]] - ns = [[0, 1], [1, 0], [1, 1]] - - # evaluation of |det(DF)| at eta3 = 0 and quadrature points in format (Nel1, nq1, Nel2, nq2) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), 0.0)) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # evaluation of G at eta3 = 0 and quadrature points in format (3, 3, Nel1*nq1, Nel2*nq2) - g = domain.metric(pts[0].flatten(), pts[1].flatten(), 0.0) - - # 2-form components at quadrature points - mat_f = xp.empty((pts[0].size, pts[1].size), dtype=float) - - if callable(fun[0]): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), indexing="ij") - - # components of global inner product - F = [0, 0, 0] - - # assembly - for a in range(3): - Ni = tensor_space_FEM.Nbase_2form[a] - F[a] = xp.zeros((Ni[0], Ni[1]), dtype=float) - - mat_f[:, :] = 0.0 - - for b in range(3): - # evaluate g_ab * f_b at quadrature points - if callable(fun[b]): - mat_f += fun[b](quad_mesh[0], quad_mesh[1], 0.0) * g[a, b] - else: - mat_f += fun[b] * g[a, b] - - mat_f = mat_f.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - ker.kernel_inner( - Nel[0], - Nel[1], - p[0], - p[1], - n_quad[0], - n_quad[1], - ns[a][0], - ns[a][1], - wts[0], - wts[1], - basis[a][0], - basis[a][1], - ind[a][0], - ind[a][1], - F[a], - mat_f / det_df, - ) - - F1 = tensor_space_FEM.E2_pol_0.dot(xp.concatenate((F[0].flatten(), F[1].flatten()))) - F2 = tensor_space_FEM.E3_pol_0.dot(F[2].flatten()) - - return F1, F2 - - -# ================ inner product in V3 =========================== -def inner_prod_V3(tensor_space_FEM, domain, fun): - """ - Assembles the 2D inner product [DD] * fun / |det(DF)| of the given tensor product B-spline space of bi-degree (p1, p2) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - fun : callable or xp.ndarray - the 3-form component with which the inner products shall be computed (either callable or 2D array with values at quadrature points) - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indD = ( - tensor_space_FEM.indD - ) # global indices of local non-vanishing basis functions in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points in format (element, local quad_point) - wts = tensor_space_FEM.wts # global quadrature weights in format (element, local weight) - - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points - - # evaluation of |det(DF)| at eta3 = 0 and quadrature points in format (Nel1, nq1, Nel2, nq2) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), 0.0)) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # evaluation of given 3-form at quadrature points - mat_f = xp.empty((pts[0].size, pts[1].size), dtype=float) - - if callable(fun): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), indexing="ij") - mat_f[:, :] = fun(quad_mesh[0], quad_mesh[1], 0.0) - else: - mat_f[:, :] = fun - - # assembly - Ni = tensor_space_FEM.Nbase_3form - - F = xp.zeros((Ni[0], Ni[1]), dtype=float) - - mat_f = mat_f.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - ker.kernel_inner( - Nel[0], - Nel[1], - p[0], - p[1], - n_quad[0], - n_quad[1], - 1, - 1, - wts[0], - wts[1], - basisD[0], - basisD[1], - indD[0], - indD[1], - F, - mat_f / det_df, - ) - - return tensor_space_FEM.E3_0.dot(F.flatten()) diff --git a/src/struphy/eigenvalue_solvers/legacy/inner_products_3d.py b/src/struphy/eigenvalue_solvers/legacy/inner_products_3d.py deleted file mode 100644 index 20d95c05c..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/inner_products_3d.py +++ /dev/null @@ -1,360 +0,0 @@ -# coding: utf-8 -# -# Copyright 2020 Florian Holderied - -""" -Modules to compute inner products with given functions in 3D. -""" - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.eigenvalue_solvers.kernels_3d as ker - - -# ================ inner product in V0 =========================== -def inner_prod_V0(tensor_space_FEM, domain, fun): - """ - Assembles the 3D inner product [NNN] * fun * |det(DF)| of the given tensor product B-spline space of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - fun : callable or xp.ndarray - the 0-form with which the inner products shall be computed (either callable or 3D array with values at quadrature points) - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of local non-vanishing basis functions in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points in format (element, local quad_point) - wts = tensor_space_FEM.wts # global quadrature weights in format (element, local weight) - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points - - # evaluation of |det(DF)| at quadrature points in format (Nel1, nq1, Nel2, nq2, Nel3, nq3) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), pts[2].flatten())) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # evaluation of given 0-form at quadrature points - mat_f = xp.empty((pts[0].size, pts[1].size, pts[2].size), dtype=float) - - if callable(fun): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), pts[2].flatten(), indexing="ij") - mat_f[:, :, :] = fun(quad_mesh[0], quad_mesh[1], quad_mesh[2]) - else: - mat_f[:, :, :] = fun - - # assembly - Ni = tensor_space.Nbase_0form - - F = xp.zeros((Ni[0], Ni[1], Ni[2]), dtype=float) - - mat_f = mat_f.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - ker.kernel_inner( - Nel[0], - Nel[1], - Nel[2], - p[0], - p[1], - p[2], - n_quad[0], - n_quad[1], - n_quad[2], - 0, - 0, - 0, - wts[0], - wts[1], - wts[2], - basisN[0], - basisN[1], - basisN[2], - indN[0], - indN[1], - indN[2], - F, - mat_f * det_df, - ) - - return tensor_space_FEM.E0_0.dot(F.flatten()) - - -# ================ inner product in V1 =========================== -def inner_prod_V1(tensor_space_FEM, domain, fun): - """ - Assembles the 3D inner prodcut [DNN, NDN, NND] * |det(DF)| * G^(-1) * [fun_1, fun_2, fun_3] of the given tensor product B-spline space of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - fun : list of callables or xp.ndarrays - the 1-form components with which the inner products shall be computed (either list of 3 callables or 3D arrays with values at quadrature points) - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - # basis functions of components of a 1-form - ind = [[indD[0], indN[1], indN[2]], [indN[0], indD[1], indN[2]], [indN[0], indN[1], indD[2]]] - basis = [[basisD[0], basisN[1], basisN[2]], [basisN[0], basisD[1], basisN[2]], [basisN[0], basisN[1], basisD[2]]] - ns = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] - - # evaluation of |det(DF)| at quadrature points in format (Nel1, nq1, Nel2, nq2, Nel3, nq3) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), pts[2].flatten())) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # evaluation of G^(-1) at quadrature points in format (3, 3, Nel1*nq1, Nel2*nq2, Nel3*nq3) - g_inv = domain.metric_inv(pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - - # 1-form components at quadrature points - mat_f = xp.empty((pts[0].size, pts[1].size, pts[2].size), dtype=float) - - if callable(fun[0]): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), pts[2].flatten(), indexing="ij") - - # components of global inner product - F = [0, 0, 0] - - # assembly - for a in range(3): - Ni = tensor_space_FEM.Nbase_1form[a] - - F[a] = xp.zeros((Ni[0], Ni[1], Ni[2]), dtype=float) - - mat_f[:, :, :] = 0.0 - - for b in range(3): - # evaluate g^ab * f_b at quadrature points - if callable(fun[b]): - mat_f += fun[b](quad_mesh[0], quad_mesh[1], quad_mesh[2]) * g_inv[a, b] - else: - mat_f += fun[b] * g_inv[a, b] - - mat_f = mat_f.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - ker.kernel_inner( - Nel[0], - Nel[1], - Nel[2], - p[0], - p[1], - p[2], - n_quad[0], - n_quad[1], - n_quad[2], - ns[a][0], - ns[a][1], - ns[a][2], - wts[0], - wts[1], - wts[2], - basis[a][0], - basis[a][1], - basis[a][2], - ind[a][0], - ind[a][1], - ind[a][2], - F[a], - mat_f * det_df, - ) - - return tensor_space_FEM.E1_0.dot(xp.concatenate((F[0].flatten(), F[1].flatten(), F[2].flatten()))) - - -# ================ inner product in V2 =========================== -def inner_prod_V2(tensor_space_FEM, domain, fun): - """ - Assembles the 3D inner prodcut [NDD, DND, DDN] / |det(DF)| * G * [fun_1, fun_2, fun_3] of the given tensor product B-spline space of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - fun : list of callables or xp.ndarrays - the 2-form components with which the inner products shall be computed (either list of 3 callables or 3D arrays with values at quadrature points) - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - # basis functions of components of a 2-form - ind = [[indN[0], indD[1], indD[2]], [indD[0], indN[1], indD[2]], [indD[0], indD[1], indN[2]]] - basis = [[basisN[0], basisD[1], basisD[2]], [basisD[0], basisN[1], basisD[2]], [basisD[0], basisD[1], basisN[2]]] - ns = [[0, 1, 1], [1, 0, 1], [1, 1, 0]] - - # evaluation of |det(DF)| at quadrature points in format (Nel1, nq1, Nel2, nq2, Nel3, nq3) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), pts[2].flatten())) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # evaluation of G at quadrature points in format (3, 3, Nel1*nq1, Nel2*nq2, Nel3*nq3) - g = domain.metric(pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - - # 2-form components at quadrature points - mat_f = xp.empty((pts[0].size, pts[1].size, pts[2].size), dtype=float) - - if callable(fun[0]): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), pts[2].flatten(), indexing="ij") - - # components of global inner product - F = [0, 0, 0] - - # assembly - for a in range(3): - Ni = tensor_space_FEM.Nbase_2form[a] - - F[a] = xp.zeros((Ni[0], Ni[1], Ni[2]), dtype=float) - - mat_f[:, :, :] = 0.0 - - for b in range(3): - # evaluate g_ab * f_b at quadrature points - if callable(fun[b]): - mat_f += fun[b](quad_mesh[0], quad_mesh[1], quad_mesh[2]) * g[a, b] - else: - mat_f += fun[b] * g[a, b] - - mat_f = mat_f.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - ker.kernel_inner( - Nel[0], - Nel[1], - Nel[2], - p[0], - p[1], - p[2], - n_quad[0], - n_quad[1], - n_quad[2], - ns[a][0], - ns[a][1], - ns[a][2], - wts[0], - wts[1], - wts[2], - basis[a][0], - basis[a][1], - basis[a][2], - ind[a][0], - ind[a][1], - ind[a][2], - F[a], - mat_f / det_df, - ) - - return tensor_space_FEM.E2_0.dot(xp.concatenate((F[0].flatten(), F[1].flatten(), F[2].flatten()))) - - -# ================ inner product in V3 =========================== -def inner_prod_V3(tensor_space_FEM, domain, fun): - """ - Assembles the 3D inner prodcut [DDD] * fun / |det(DF)| of the given tensor product B-spline space of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - fun : callable or xp.ndarray - the 3-form component with which the inner products shall be computed (either callable or 3D array with values at quadrature points) - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indD = ( - tensor_space_FEM.indD - ) # global indices of local non-vanishing basis functions in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points in format (element, local quad_point) - wts = tensor_space_FEM.wts # global quadrature weights in format (element, local weight) - - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points - - # evaluation of |det(DF)| at quadrature points in format (Nel1, nq1, Nel2, nq2, Nel3, nq3) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), pts[2].flatten())) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # evaluation of given 3-form at quadrature points - mat_f = xp.empty((pts[0].size, pts[1].size, pts[2].size), dtype=float) - - if callable(fun): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), pts[2].flatten(), indexing="ij") - mat_f[:, :, :] = fun(quad_mesh[0], quad_mesh[1], quad_mesh[2]) - else: - mat_f[:, :, :] = fun - - # assembly - Ni = tensor_space.Nbase_3form - - F = xp.zeros((Ni[0], Ni[1], Ni[2]), dtype=float) - - ker.kernel_inner( - Nel[0], - Nel[1], - Nel[2], - p[0], - p[1], - p[2], - n_quad[0], - n_quad[1], - n_quad[2], - 1, - 1, - 1, - wts[0], - wts[1], - wts[2], - basisD[0], - basisD[1], - basisD[2], - indD[0], - indD[1], - indD[2], - F, - mat_f / det_df, - ) - - return tensor_space_FEM.E3_0.dot(F.flatten()) diff --git a/src/struphy/eigenvalue_solvers/legacy/l2_error_1d.py b/src/struphy/eigenvalue_solvers/legacy/l2_error_1d.py deleted file mode 100644 index d568d3207..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/l2_error_1d.py +++ /dev/null @@ -1,112 +0,0 @@ -# coding: utf-8 -# -# Copyright 2020 Florian Holderied - -""" -Modules to compute L2-errors in 1d. -""" - -import cunumpy as xp -import scipy.sparse as spa - - -# ======= error in V0 ==================== -def l2_error_V0(spline_space, mapping, coeff, fun): - """ - Computes the 1d L2 - error (N) of the given B-spline space of degree p with coefficients coeff with the function fun. - - Parameters - ---------- - spline_space : Spline_space_1d - a 1d B-spline space - - mapping : callable - derivative of mapping df/dxi - - coeff : array_like - coefficients of the spline space - - fun : callable - function for which the error shall be computed - """ - - p = spline_space.p # spline degrees - Nel = spline_space.Nel # number of elements - NbaseN = spline_space.NbaseN # total number of basis functions (N) - - n_quad = spline_space.n_quad # number of quadrature points per element - pts = spline_space.pts # global quadrature points in format (element, local quad_point) - wts = spline_space.wts # global quadrature weights in format (element, local weight) - - basisN = spline_space.basisN # evaluated basis functions at quadrature points - - # evaluation of mapping at quadrature points - mat_map = mapping(pts) - - # evaluation of function at quadrature points - mat_f = fun(pts) - - # assembly - error = xp.zeros(Nel, dtype=float) - - for ie in range(Nel): - for q in range(n_quad): - bi = 0.0 - - for il in range(p + 1): - bi += coeff[(ie + il) % NbaseN] * basisN[ie, il, 0, q] - - error[ie] += wts[ie, q] * (bi - mat_f[ie, q]) ** 2 - - return xp.sqrt(error.sum()) - - -# ======= error in V1 ==================== -def l2_error_V1(spline_space, mapping, coeff, fun): - """ - Computes the 1d L2 - error (D) of the given B-spline space of degree p with coefficients coeff with the function fun. - - Parameters - ---------- - spline_space : Spline_space_1d - a 1d B-spline space - - mapping : callable - derivative of mapping df/dxi - - coeff : array_like - coefficients of the spline space - - fun : callable - function for which the error shall be computed - """ - - p = spline_space.p # spline degrees - Nel = spline_space.Nel # number of elements - NbaseD = spline_space.NbaseD # total number of basis functions (N) - - n_quad = spline_space.n_quad # number of quadrature points per element - pts = spline_space.pts # global quadrature points in format (element, local quad_point) - wts = spline_space.wts # global quadrature weights in format (element, local weight) - - basisD = spline_space.basisD # evaluated basis functions at quadrature points - - # evaluation of mapping at quadrature points - mat_map = 1 / mapping(pts) - - # evaluation of function at quadrature points - mat_f = fun(pts) - - # assembly - error = xp.zeros(Nel, dtype=float) - - for ie in range(Nel): - for q in range(n_quad): - bi = 0.0 - - for il in range(p): - bi += coeff[(ie + il) % NbaseD] * basisD[ie, il, 0, q] - - error[ie] += wts[ie, q] * (bi - mat_f[ie, q]) ** 2 - - return xp.sqrt(error.sum()) diff --git a/src/struphy/eigenvalue_solvers/legacy/l2_error_2d.py b/src/struphy/eigenvalue_solvers/legacy/l2_error_2d.py deleted file mode 100644 index 452dd570b..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/l2_error_2d.py +++ /dev/null @@ -1,590 +0,0 @@ -# coding: utf-8 -# -# Copyright 2021 Florian Holderied - -""" -Modules to compute L2-errors of discrete p-forms with analytical forms in 2D. -""" - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.eigenvalue_solvers.kernels_2d as ker - - -# ======= error in V0 ==================== -def l2_error_V0(tensor_space_FEM, domain, f0, c0, method="standard"): - """ - Computes the 2D L2-error of (fun - fun_h) of the analytical function fun with the discrete function fun_h living in a 2D tensor product B-spline space of bi-degree (p1, p2) within a computational domain defined by the given object "domain" from hylife.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - f0 : callable or xp.ndarray - the 0-form with which the error shall be computed - - c0 : array_like - the FEM coefficients of the discrete 0-form - - method : string - method used to compute the error (standard : integrals are computed with matrix-vector products, else: kernel is used) - - Returns - ------- - error : int - the L2-error of the discrete form - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of local non-vanishing basis functions in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points in format (element, local quad_point) - wts = tensor_space_FEM.wts # global quadrature weights in format (element, local weight) - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points - - # extract coefficients to tensor-product space - if c0.ndim == 1: - c0 = tensor_space_FEM.extract_0(c0) - - assert c0.ndim == 3 - - # evaluation of |det(DF)| at quadrature points - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), 0.0)) - - # evaluation of exact 0-form at quadrature points - if callable(f0): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), indexing="ij") - f0 = f0(quad_mesh[0], quad_mesh[1], 0.0) - - if method == "standard": - # evaluation of discrete 0-form at quadrature points - f0_h = tensor_space_FEM.evaluate_NN(pts[0].flatten(), pts[1].flatten(), xp.array([0.0]), c0, "V0")[:, :, 0] - - # compute error - error = 0.0 - - integrand = (f0_h - f0) ** 2 * det_df - error += integrand.dot(wts[1].flatten()).dot(wts[0].flatten()) - - else: - # compute error in each element - error = xp.zeros(Nel[:2], dtype=float) - - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - [0, 0], - [0, 0], - basisN[0], - basisN[1], - basisN[0], - basisN[1], - indN[0], - indN[1], - indN[0], - indN[1], - error, - f0.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - f0.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - c0, - c0, - det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - ) - - error = error.sum() - - return xp.sqrt(error) - - -# ======= error in V1 ==================== -def l2_error_V1(tensor_space_FEM, domain, f1, c1, method="standard"): - """ - Computes the 2D L2-error of (fun - fun_h) of the analytical function fun with the discrete function fun_h living in a 2D tensor product B-spline space of bi-degree (p1, p2) within a computational domain defined by the given object "domain" from hylife.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - f1 : list of callables or xp.ndarrays - the three 1-form components with which the error shall be computed - - c1 : list of array_like - the FEM coefficients of the discrete components - - method : string - method used to compute the error (standard : integrals are computed with matrix-vector products, else: kernel is used) - - Returns - ------- - error : int - the L2-error of the discrete form - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - # extract cicients to tensor-product space - c1_1, c1_2, c1_3 = tensor_space_FEM.extract_1(c1) - - # evaluation of G^(-1)*|det(DF)| at quadrature points - metric_coeffs = domain.metric_inv(pts[0].flatten(), pts[1].flatten(), 0.0) - metric_coeffs *= abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), 0.0)) - - # evaluation of exact 1-form components at quadrature points - if callable(f1[0]): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), indexing="ij") - f1_1 = f1[0](quad_mesh[0], quad_mesh[1], 0.0) - f1_2 = f1[1](quad_mesh[0], quad_mesh[1], 0.0) - f1_3 = f1[2](quad_mesh[0], quad_mesh[1], 0.0) - - if method == "standard": - # evaluation of discrete 1-form components at quadrature points - f1_h_1 = tensor_space_FEM.evaluate_DN(pts[0].flatten(), pts[1].flatten(), xp.array([0.0]), c1_1, "V1")[:, :, 0] - f1_h_2 = tensor_space_FEM.evaluate_ND(pts[0].flatten(), pts[1].flatten(), xp.array([0.0]), c1_2, "V1")[:, :, 0] - f1_h_3 = tensor_space_FEM.evaluate_NN(pts[0].flatten(), pts[1].flatten(), xp.array([0.0]), c1_3, "V1")[:, :, 0] - - # compute error - error = 0.0 - - # 1 * d_f1 * G^11 * |det(DF)| * d_f1 - integrand = (f1_h_1 - f1_1) * metric_coeffs[0, 0] * (f1_h_1 - f1_1) - error += 1 * integrand.dot(wts[1].flatten()).dot(wts[0].flatten()) - - # 2 * d_f1 * G^12 * |det(DF)| * d_f2 - integrand = (f1_h_1 - f1_1) * metric_coeffs[0, 1] * (f1_h_2 - f1_2) - error += 2 * integrand.dot(wts[1].flatten()).dot(wts[0].flatten()) - - # 1 * d_f2 * G^22 * |det(DF)| * d_f2 - integrand = (f1_h_2 - f1_2) * metric_coeffs[1, 1] * (f1_h_2 - f1_2) - error += 1 * integrand.dot(wts[1].flatten()).dot(wts[0].flatten()) - - # 1 * d_f3 * G^33 * |det(DF)| * d_f3 - integrand = (f1_h_3 - f1_3) * metric_coeffs[2, 2] * (f1_h_3 - f1_3) - error += 1 * integrand.dot(wts[1].flatten()).dot(wts[0].flatten()) - - else: - # compute error in each element - error = xp.zeros(Nel[:2], dtype=float) - - # 1 * d_f1 * G^11 * |det(DF)| * d_f1 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - [1, 0], - [1, 0], - basisD[0], - basisN[1], - basisD[0], - basisN[1], - indD[0], - indN[1], - indD[0], - indN[1], - error, - f1_1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - f1_1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - c1_1, - c1_1, - 1 * metric_coeffs[0, 0].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - ) - - # 2 * d_f1 * G^12 * |det(DF)| * d_f2 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - [1, 0], - [0, 1], - basisD[0], - basisN[1], - basisN[0], - basisD[1], - indD[0], - indN[1], - indN[0], - indD[1], - error, - f1_1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - f1_2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - c1_1, - c1_2, - 2 * metric_coeffs[0, 1].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - ) - - # 1 * d_f2 * G^22 * |det(DF)| * d_f2 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - [0, 1], - [0, 1], - basisN[0], - basisD[1], - basisN[0], - basisD[1], - indN[0], - indD[1], - indN[0], - indD[1], - error, - f1_2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - f1_2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - c1_2, - c1_2, - 1 * metric_coeffs[1, 1].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - ) - - # 1 * d_f3 * G^33 * |det(DF)| * d_f3 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - [0, 0], - [0, 0], - basisN[0], - basisN[1], - basisN[0], - basisN[1], - indN[0], - indN[1], - indN[0], - indN[1], - error, - f1_3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - f1_3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - c1_3, - c1_3, - 1 * metric_coeffs[2, 2].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - ) - - error = error.sum() - - return xp.sqrt(error) - - -# ======= error in V2 ==================== -def l2_error_V2(tensor_space_FEM, domain, f2, c2, method="standard"): - """ - Computes the 2D L2-error of (fun - fun_h) of the analytical function fun with the discrete function fun_h living in a 2D tensor product B-spline space of bi-degree (p1, p2) within a computational domain defined by the given object "domain" from hylife.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - f2 : list of callables or xp.ndarrays - the three 2-form components with which the error shall be computed - - c2 : list of array_like - the FEM coefficients of the discrete components - - method : string - method used to compute the error (standard : integrals are computed with matrix-vector products, else: kernel is used) - - Returns - ------- - error : int - the L2-error of the discrete form - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - # extract coefficients to tensor-product space - c2_1, c2_2, c2_3 = tensor_space_FEM.extract_2(c2) - - # evaluation of G/|det(DF)| at quadrature points - metric_coeffs = domain.metric(pts[0].flatten(), pts[1].flatten(), 0.0) - metric_coeffs /= abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), 0.0)) - - # evaluation of exact 2-form components at quadrature points - if callable(f2[0]): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), indexing="ij") - f2_1 = f2[0](quad_mesh[0], quad_mesh[1], 0.0) - f2_2 = f2[1](quad_mesh[0], quad_mesh[1], 0.0) - f2_3 = f2[2](quad_mesh[0], quad_mesh[1], 0.0) - - if method == "standard": - # evaluation of discrete 2-form components at quadrature points - f2_h_1 = tensor_space_FEM.evaluate_ND(pts[0].flatten(), pts[1].flatten(), xp.array([0.0]), c2_1, "V2")[:, :, 0] - f2_h_2 = tensor_space_FEM.evaluate_DN(pts[0].flatten(), pts[1].flatten(), xp.array([0.0]), c2_2, "V2")[:, :, 0] - f2_h_3 = tensor_space_FEM.evaluate_DD(pts[0].flatten(), pts[1].flatten(), xp.array([0.0]), c2_3, "V2")[:, :, 0] - - # compute error - error = 0.0 - - # 1 * d_f1 * G_11 / |det(DF)| * d_f1 - integrand = (f2_h_1 - f2_1) * metric_coeffs[0, 0] * (f2_h_1 - f2_1) - error += 1 * integrand.dot(wts[1].flatten()).dot(wts[0].flatten()) - - # 2 * d_f1 * G_12 / |det(DF)| * d_f2 - integrand = (f2_h_1 - f2_1) * metric_coeffs[0, 1] * (f2_h_2 - f2_2) - error += 2 * integrand.dot(wts[1].flatten()).dot(wts[0].flatten()) - - # 1 * d_f2 * G_22 / |det(DF)| * d_f2 - integrand = (f2_h_2 - f2_2) * metric_coeffs[1, 1] * (f2_h_2 - f2_2) - error += 1 * integrand.dot(wts[1].flatten()).dot(wts[0].flatten()) - - # 1 * d_f3 * G_33 / |det(DF)| * d_f3 - integrand = (f2_h_3 - f2_3) * metric_coeffs[2, 2] * (f2_h_3 - f2_3) - error += 1 * integrand.dot(wts[1].flatten()).dot(wts[0].flatten()) - - else: - # compute error in each element - error = xp.zeros(Nel[:2], dtype=float) - - # 1 * d_f1 * G_11 / |det(DF)| * d_f1 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - [0, 1], - [0, 1], - basisN[0], - basisD[1], - basisN[0], - basisD[1], - indN[0], - indD[1], - indN[0], - indD[1], - error, - f2_1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - f2_1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - c2_1, - c2_1, - 1 * metric_coeffs[0, 0].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - ) - - # 2 * d_f1 * G_12 / |det(DF)| * d_f2 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - [0, 1], - [1, 0], - basisN[0], - basisD[1], - basisD[0], - basisN[1], - indN[0], - indD[1], - indD[0], - indN[1], - error, - f2_1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - f2_2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - c2_1, - c2_2, - 2 * metric_coeffs[0, 1].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - ) - - # 1 * d_f2 * G_22 / |det(DF)| * d_f2 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - [1, 0], - [1, 0], - basisD[0], - basisN[1], - basisD[0], - basisN[1], - indD[0], - indN[1], - indD[0], - indN[1], - error, - f2_2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - f2_2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - c2_2, - c2_2, - 1 * metric_coeffs[1, 1].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - ) - - # 1 * d_f3 * G_33 / |det(DF)| * d_f3 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - [1, 1], - [1, 1], - basisD[0], - basisD[1], - basisD[0], - basisD[1], - indD[0], - indD[1], - indD[0], - indD[1], - error, - f2_3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - f2_3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - c2_3, - c2_3, - 1 * metric_coeffs[2, 2].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - ) - - error = error.sum() - - return xp.sqrt(error) - - -# ======= error in V3 ==================== -def l2_error_V3(tensor_space_FEM, domain, f3, c3, method="standard"): - """ - Computes the 2D L2-error of (fun - fun_h) of the analytical function fun with the discrete function fun_h living in a 2D tensor product B-spline space of bi-degree (p1, p2) within a computational domain defined by the given object "domain" from hylife.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - f3 : callable or xp.ndarray - the 3-form component with which the error shall be computed - - c3 : array_like - the FEM coefficients of the discrete function - - method : string - method used to compute the error (standard : integrals are computed with matrix-vector products, else: kernel is used) - - Returns - ------- - error : int - the L2-error of the discrete form - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indD = ( - tensor_space_FEM.indD - ) # global indices of local non-vanishing basis functions in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points in format (element, local quad_point) - wts = tensor_space_FEM.wts # global quadrature weights in format (element, local weight) - - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points - - # extract c3icients to tensor-product space - if c3.ndim == 1: - c3 = tensor_space_FEM.extract_3(c3) - - assert c3.ndim == 3 - - # evaluation of |det(DF)| at quadrature points - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), 0.0)) - - # evaluation of exact 3-form at quadrature points - if callable(f3): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), indexing="ij") - f3 = f3(quad_mesh[0], quad_mesh[1], 0.0) - - if method == "standard": - # evaluation of discrete 3-form at quadrature points - f3_h = tensor_space_FEM.evaluate_DD(pts[0].flatten(), pts[1].flatten(), xp.array([0.0]), c3, "V3")[:, :, 0] - - # compute error - error = 0.0 - - integrand = (f3_h - f3) ** 2 / det_df - error += integrand.dot(wts[1].flatten()).dot(wts[0].flatten()) - - else: - # compute error in each element - error = xp.zeros(Nel[:2], dtype=float) - - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - [1, 1], - [1, 1], - basisD[0], - basisD[1], - basisD[0], - basisD[1], - indD[0], - indD[1], - indD[0], - indD[1], - error, - f3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - f3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - c3, - c3, - 1 / det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]), - ) - - error = error.sum() - - return xp.sqrt(error) diff --git a/src/struphy/eigenvalue_solvers/legacy/l2_error_3d.py b/src/struphy/eigenvalue_solvers/legacy/l2_error_3d.py deleted file mode 100644 index 7553e3a83..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/l2_error_3d.py +++ /dev/null @@ -1,622 +0,0 @@ -# coding: utf-8 -# -# Copyright 2020 Florian Holderied - -""" -Modules to compute L2-errors of discrete p-forms with analytical forms in 3D. -""" - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.eigenvalue_solvers.kernels_3d as ker - - -# ======= error in V0 ==================== -def l2_error_V0(tensor_space_FEM, domain, fun, coeff): - """ - Computes the 3D L2-error of (fun - fun_h) of the analytical function fun with the discrete function fun_h living in a 3D tensor product B-spline space of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from hylife.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - fun : callable or xp.ndarray - the 0-form with which the error shall be computed - - coeff : array_like - the FEM coefficients of the discrete 0-form - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of local non-vanishing basis functions in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points in format (element, local quad_point) - wts = tensor_space_FEM.wts # global quadrature weights in format (element, local weight) - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points - - # extract coefficients to tensor-product space - if coeff.ndim == 1: - coeff = tensor_space_FEM.extract_0(coeff) - - assert coeff.ndim == 3 - - # evaluation of |det(DF)| at quadrature points - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), pts[2].flatten())) - - # evaluation of given 0-form at quadrature points - mat_f = xp.empty((pts[0].size, pts[1].size, pts[2].size), dtype=float) - - if callable(fun): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), pts[2].flatten(), indexing="ij") - mat_f[:, :, :] = fun(quad_mesh[0], quad_mesh[1], quad_mesh[2]) - else: - mat_f[:, :, :] = fun - - # compute error - error = xp.zeros(Nel, dtype=float) - - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [0, 0, 0], - [0, 0, 0], - basisN[0], - basisN[1], - basisN[2], - basisN[0], - basisN[1], - basisN[2], - indN[0], - indN[1], - indN[2], - indN[0], - indN[1], - indN[2], - error, - mat_f.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff, - coeff, - det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - return xp.sqrt(error.sum()) - - -# ======= error in V1 ==================== -def l2_error_V1(tensor_space_FEM, domain, fun, coeff): - """ - Computes the 3D L2-error of (fun - fun_h) of the analytical function fun with the discrete function fun_h living in a 3D tensor product B-spline space of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from hylife.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - fun : list of callables or xp.ndarrays - the three 1-form components with which the error shall be computed - - coeff : list of array_like - the FEM coefficients of the discrete components - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - # extract coefficients to tensor-product space - coeff1, coeff2, coeff3 = tensor_space_FEM.extract_1(coeff) - - # evaluation of G^(-1)*|det(DF)| at quadrature points - metric_coeffs = domain.metric_inv(pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - metric_coeffs *= abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), pts[2].flatten())) - - # evaluation of given 1-form components at quadrature points - mat_f1 = xp.empty((pts[0].size, pts[1].size, pts[2].size), dtype=float) - mat_f2 = xp.empty((pts[0].size, pts[1].size, pts[2].size), dtype=float) - mat_f3 = xp.empty((pts[0].size, pts[1].size, pts[2].size), dtype=float) - - if callable(fun[0]): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), pts[2].flatten(), indexing="ij") - mat_f1[:, :, :] = fun[0](quad_mesh[0], quad_mesh[1], quad_mesh[2]) - mat_f2[:, :, :] = fun[1](quad_mesh[0], quad_mesh[1], quad_mesh[2]) - mat_f3[:, :, :] = fun[2](quad_mesh[0], quad_mesh[1], quad_mesh[2]) - else: - mat_f1[:, :, :] = fun[0] - mat_f2[:, :, :] = fun[1] - mat_f3[:, :, :] = fun[2] - - # compute error - error = xp.zeros(Nel, dtype=float) - - # 1 * f1 * G^11 * |det(DF)| * f1 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [1, 0, 0], - [1, 0, 0], - basisD[0], - basisN[1], - basisN[2], - basisD[0], - basisN[1], - basisN[2], - [indD[0], indN[1], indN[2]], - [indD[0], indN[1], indN[2]], - error, - mat_f1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff1, - coeff1, - 1 * metric_coeffs[0, 0].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - # 2 * f1 * G^12 * |det(DF)| * f2 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [1, 0, 0], - [0, 1, 0], - basisD[0], - basisN[1], - basisN[2], - basisN[0], - basisD[1], - basisN[2], - [indD[0], indN[1], indN[2]], - [indN[0], indD[1], indN[2]], - error, - mat_f1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff1, - coeff2, - 2 * metric_coeffs[0, 1].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - # 2 * f1 * G^13 * |det(DF)| * f3 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [1, 0, 0], - [0, 0, 1], - basisD[0], - basisN[1], - basisN[2], - basisN[0], - basisN[1], - basisD[2], - [indD[0], indN[1], indN[2]], - [indN[0], indN[1], indD[2]], - error, - mat_f1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff1, - coeff3, - 2 * metric_coeffs[0, 2].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - # 1 * f2 * G^22 * |det(DF)| * f2 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [0, 1, 0], - [0, 1, 0], - basisN[0], - basisD[1], - basisN[2], - basisN[0], - basisD[1], - basisN[2], - [indN[0], indD[1], indN[2]], - [indN[0], indD[1], indN[2]], - error, - mat_f2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff2, - coeff2, - 1 * metric_coeffs[1, 1].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - # 2 * f2 * G^23 * |det(DF)| * f3 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [0, 1, 0], - [0, 0, 1], - basisN[0], - basisD[1], - basisN[2], - basisN[0], - basisN[1], - basisD[2], - [indN[0], indD[1], indN[2]], - [indN[0], indN[1], indD[2]], - error, - mat_f2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff2, - coeff3, - 2 * metric_coeffs[1, 2].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - # 1 * f3 * G^33 * |det(DF)| * f3 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [0, 0, 1], - [0, 0, 1], - basisN[0], - basisN[1], - basisD[2], - basisN[0], - basisN[1], - basisD[2], - [indN[0], indN[1], indD[2]], - [indN[0], indN[1], indD[2]], - error, - mat_f3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff3, - coeff3, - 1 * metric_coeffs[2, 2].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - return xp.sqrt(error.sum()) - - -# ======= error in V2 ==================== -def l2_error_V2(tensor_space_FEM, domain, fun, coeff): - """ - Computes the 3D L2-error of (fun - fun_h) of the analytical function fun with the discrete function fun_h living in a 3D tensor product B-spline space of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from hylife.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - fun : list of callables or xp.ndarrays - the three 2-form components with which the error shall be computed - - coeff : list of array_like - the FEM coefficients of the discrete components - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - # extract coefficients to tensor-product space - coeff1, coeff2, coeff3 = tensor_space_FEM.extract_2(coeff) - - # evaluation of G/|det(DF)| at quadrature points in format (Nel1, nq1, Nel2, nq2, Nel3, nq3) - metric_coeffs = domain.metric(pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - metric_coeffs /= abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), pts[2].flatten())) - - # evaluation of given 2-form components at quadrature points - mat_f1 = xp.empty((pts[0].size, pts[1].size, pts[2].size), dtype=float) - mat_f2 = xp.empty((pts[0].size, pts[1].size, pts[2].size), dtype=float) - mat_f3 = xp.empty((pts[0].size, pts[1].size, pts[2].size), dtype=float) - - if callable(fun[0]): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), pts[2].flatten(), indexing="ij") - mat_f1[:, :, :] = fun[0](quad_mesh[0], quad_mesh[1], quad_mesh[2]) - mat_f2[:, :, :] = fun[1](quad_mesh[0], quad_mesh[1], quad_mesh[2]) - mat_f3[:, :, :] = fun[2](quad_mesh[0], quad_mesh[1], quad_mesh[2]) - else: - mat_f1[:, :, :] = fun[0] - mat_f2[:, :, :] = fun[1] - mat_f3[:, :, :] = fun[2] - - # compute error - error = xp.zeros(Nel, dtype=float) - - # 1 * f1 * G_11 / |det(DF)| * f1 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [0, 1, 1], - [0, 1, 1], - basisN[0], - basisD[1], - basisD[2], - basisN[0], - basisD[1], - basisD[2], - [indN[0], indD[1], indD[2]], - [indN[0], indD[1], indD[2]], - error, - mat_f1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff1, - coeff1, - 1 * metric_coeffs[0, 0].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - # 2 * f1 * G_12 / |det(DF)| * f2 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [0, 1, 1], - [1, 0, 1], - basisN[0], - basisD[1], - basisD[2], - basisD[0], - basisN[1], - basisD[2], - [indN[0], indD[1], indD[2]], - [indD[0], indN[1], indD[2]], - error, - mat_f1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff1, - coeff2, - 2 * metric_coeffs[0, 1].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - # 2 * f1 * G_13 / |det(DF)| * f3 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [0, 1, 1], - [1, 1, 0], - basisN[0], - basisD[1], - basisD[2], - basisD[0], - basisD[1], - basisN[2], - [indN[0], indD[1], indD[2]], - [indD[0], indD[1], indN[2]], - error, - mat_f1.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff1, - coeff3, - 2 * metric_coeffs[0, 2].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - # 1 * f2 * G_22 / |det(DF)| * f2 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [1, 0, 1], - [1, 0, 1], - basisD[0], - basisN[1], - basisD[2], - basisD[0], - basisN[1], - basisD[2], - [indD[0], indN[1], indD[2]], - [indD[0], indN[1], indD[2]], - error, - mat_f2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff2, - coeff2, - 1 * metric_coeffs[1, 1].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - # 2 * f2 * G_23 / |det(DF)| * f3 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [1, 0, 1], - [1, 1, 0], - basisD[0], - basisN[1], - basisD[2], - basisD[0], - basisD[1], - basisN[2], - [indD[0], indN[1], indD[2]], - [indD[0], indD[1], indN[2]], - error, - mat_f2.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff2, - coeff3, - 2 * metric_coeffs[1, 2].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - # 1 * f3 * G_33 / |det(DF)| * f3 - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [1, 1, 0], - [1, 1, 0], - basisD[0], - basisD[1], - basisN[2], - basisD[0], - basisD[1], - basisN[2], - [indD[0], indD[1], indN[2]], - [indD[0], indD[1], indN[2]], - error, - mat_f3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f3.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff3, - coeff3, - 1 * metric_coeffs[2, 2].reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - return xp.sqrt(error.sum()) - - -# ======= error in V3 ==================== -def l2_error_V3(tensor_space_FEM, domain, fun, coeff): - """ - Computes the 3D L2-error of (fun - fun_h) of the analytical function fun with the discrete function fun_h living in a 3D tensor product B-spline space of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from hylife.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - fun : callable or xp.ndarray - the 3-form component with which the error shall be computed - - coeff : array_like - the FEM coefficients of the discrete function - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points in format (element, local quad_point) - wts = tensor_space_FEM.wts # global quadrature weights in format (element, local weight) - - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points - - # extract coefficients to tensor-product space - if coeff.ndim == 1: - coeff = tensor_space_FEM.extract_3(coeff) - - assert coeff.ndim == 3 - - # evaluation of |det(DF)| at quadrature points - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), pts[2].flatten())) - - # evaluation of given 3-form component at quadrature points - mat_f = xp.empty((pts[0].size, pts[1].size, pts[2].size), dtype=float) - - if callable(fun): - quad_mesh = xp.meshgrid(pts[0].flatten(), pts[1].flatten(), pts[2].flatten(), indexing="ij") - mat_f[:, :, :] = fun(quad_mesh[0], quad_mesh[1], quad_mesh[2]) - else: - mat_f[:, :, :] = fun - - # compute error - error = xp.zeros(Nel, dtype=float) - - ker.kernel_l2error( - Nel, - p, - n_quad, - wts[0], - wts[1], - wts[2], - [1, 1, 1], - [1, 1, 1], - basisD[0], - basisD[1], - basisD[2], - basisD[0], - basisD[1], - basisD[2], - indD[0], - indD[1], - indD[2], - indD[0], - indD[1], - indD[2], - error, - mat_f.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - mat_f.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - coeff, - coeff, - 1 / det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]), - ) - - return xp.sqrt(error.sum()) diff --git a/src/struphy/eigenvalue_solvers/legacy/mass_matrices_3d_pre.py b/src/struphy/eigenvalue_solvers/legacy/mass_matrices_3d_pre.py deleted file mode 100644 index 82514ec04..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/mass_matrices_3d_pre.py +++ /dev/null @@ -1,393 +0,0 @@ -# coding: utf-8 -# -# Copyright 2021 Florian Holderied (florian.holderied@ipp.mpg.de) - -""" -Modules to obtain preconditioners for mass matrices in 3D. -""" - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.eigenvalue_solvers.spline_space as spl -import struphy.linear_algebra.linalg_kron as linkron - - -# ================ inverse mass matrix in V0 =========================== -def get_M0_PRE(tensor_space_FEM, domain): - """ - TODO - """ - - # 1d spaces for pre-conditioning with fft: - Nel_pre = [tensor_space_FEM.spaces[0].NbaseN, tensor_space_FEM.spaces[1].NbaseN, tensor_space_FEM.spaces[2].NbaseN] - spl_kind_pre = [True, True, True] - spaces_pre = [ - spl.Spline_space_1d(Nel, p, spl_kind, nq_el) - for Nel, p, spl_kind, nq_el in zip(Nel_pre, tensor_space_FEM.p, spl_kind_pre, tensor_space_FEM.n_quad) - ] - - # tensor product mass matrices for pre-conditioning - # spaces_pre[0].set_extraction_operators() - # spaces_pre[1].set_extraction_operators() - # spaces_pre[2].set_extraction_operators() - - spaces_pre[0].assemble_M0(lambda eta: (domain.params[1] - domain.params[0]) * xp.ones(eta.shape, dtype=float)) - spaces_pre[1].assemble_M0(lambda eta: (domain.params[3] - domain.params[2]) * xp.ones(eta.shape, dtype=float)) - spaces_pre[2].assemble_M0(lambda eta: (domain.params[5] - domain.params[4]) * xp.ones(eta.shape, dtype=float)) - - c_pre = [spaces_pre[0].M0.toarray()[:, 0], spaces_pre[1].M0.toarray()[:, 0], spaces_pre[2].M0.toarray()[:, 0]] - - return spa.linalg.LinearOperator( - shape=tensor_space_FEM.M0.shape, - matvec=lambda x: (linkron.kron_fftsolve_3d(c_pre, x.reshape(Nel_pre[0], Nel_pre[1], Nel_pre[2]))).flatten(), - ) - - -# ================ inverse mass matrix in V1 =========================== -def get_M1_PRE(tensor_space_FEM, domain): - """ - TODO - """ - - # 1d spaces for pre-conditioning with fft: - Nel_pre = [tensor_space_FEM.spaces[0].NbaseN, tensor_space_FEM.spaces[1].NbaseN, tensor_space_FEM.spaces[2].NbaseN] - spl_kind_pre = [True, True, True] - spaces_pre = [ - spl.Spline_space_1d(Nel, p, spl_kind, nq_el) - for Nel, p, spl_kind, nq_el in zip(Nel_pre, tensor_space_FEM.p, spl_kind_pre, tensor_space_FEM.n_quad) - ] - - # tensor product mass matrices for pre-conditioning of the three diagonal blocks - # spaces_pre[0].set_extraction_operators() - # spaces_pre[1].set_extraction_operators() - # spaces_pre[2].set_extraction_operators() - - spaces_pre[0].assemble_M0(lambda eta: (domain.params[1] - domain.params[0]) * xp.ones(eta.shape, dtype=float)) - spaces_pre[1].assemble_M0(lambda eta: (domain.params[3] - domain.params[2]) * xp.ones(eta.shape, dtype=float)) - spaces_pre[2].assemble_M0(lambda eta: (domain.params[5] - domain.params[4]) * xp.ones(eta.shape, dtype=float)) - - spaces_pre[0].assemble_M1(lambda eta: 1 / (domain.params[1] - domain.params[0]) * xp.ones(eta.shape, dtype=float)) - spaces_pre[1].assemble_M1(lambda eta: 1 / (domain.params[3] - domain.params[2]) * xp.ones(eta.shape, dtype=float)) - spaces_pre[2].assemble_M1(lambda eta: 1 / (domain.params[5] - domain.params[4]) * xp.ones(eta.shape, dtype=float)) - - c11_pre = [spaces_pre[0].M1.toarray()[:, 0], spaces_pre[1].M0.toarray()[:, 0], spaces_pre[2].M0.toarray()[:, 0]] - c22_pre = [spaces_pre[0].M0.toarray()[:, 0], spaces_pre[1].M1.toarray()[:, 0], spaces_pre[2].M0.toarray()[:, 0]] - c33_pre = [spaces_pre[0].M0.toarray()[:, 0], spaces_pre[1].M0.toarray()[:, 0], spaces_pre[2].M1.toarray()[:, 0]] - - def solve(x): - x1, x2, x3 = xp.split(x, 3) - - x1 = x1.reshape(Nel_pre[0], Nel_pre[1], Nel_pre[2]) - x2 = x2.reshape(Nel_pre[0], Nel_pre[1], Nel_pre[2]) - x3 = x3.reshape(Nel_pre[0], Nel_pre[1], Nel_pre[2]) - - r1 = linkron.kron_fftsolve_3d(c11_pre, x1).flatten() - r2 = linkron.kron_fftsolve_3d(c22_pre, x2).flatten() - r3 = linkron.kron_fftsolve_3d(c33_pre, x3).flatten() - - return xp.concatenate((r1, r2, r3)) - - return spa.linalg.LinearOperator(shape=tensor_space_FEM.M1.shape, matvec=solve) - - -# ================ inverse mass matrix in V2 =========================== -def get_M2_PRE(tensor_space_FEM, domain): - """ - TODO - """ - - # 1d spaces for pre-conditioning with fft: - Nel_pre = [tensor_space_FEM.spaces[0].NbaseN, tensor_space_FEM.spaces[1].NbaseN, tensor_space_FEM.spaces[2].NbaseN] - spl_kind_pre = [True, True, True] - spaces_pre = [ - spl.Spline_space_1d(Nel, p, spl_kind, nq_el) - for Nel, p, spl_kind, nq_el in zip(Nel_pre, tensor_space_FEM.p, spl_kind_pre, tensor_space_FEM.n_quad) - ] - - # tensor product mass matrices for pre-conditioning of the three diagonal blocks - # spaces_pre[0].set_extraction_operators() - # spaces_pre[1].set_extraction_operators() - # spaces_pre[2].set_extraction_operators() - - spaces_pre[0].assemble_M0(lambda eta: (domain.params[1] - domain.params[0]) * xp.ones(eta.shape, dtype=float)) - spaces_pre[1].assemble_M0(lambda eta: (domain.params[3] - domain.params[2]) * xp.ones(eta.shape, dtype=float)) - spaces_pre[2].assemble_M0(lambda eta: (domain.params[5] - domain.params[4]) * xp.ones(eta.shape, dtype=float)) - - spaces_pre[0].assemble_M1(lambda eta: 1 / (domain.params[1] - domain.params[0]) * xp.ones(eta.shape, dtype=float)) - spaces_pre[1].assemble_M1(lambda eta: 1 / (domain.params[3] - domain.params[2]) * xp.ones(eta.shape, dtype=float)) - spaces_pre[2].assemble_M1(lambda eta: 1 / (domain.params[5] - domain.params[4]) * xp.ones(eta.shape, dtype=float)) - - c11_pre = [spaces_pre[0].M0.toarray()[:, 0], spaces_pre[1].M1.toarray()[:, 0], spaces_pre[2].M1.toarray()[:, 0]] - c22_pre = [spaces_pre[0].M1.toarray()[:, 0], spaces_pre[1].M0.toarray()[:, 0], spaces_pre[2].M1.toarray()[:, 0]] - c33_pre = [spaces_pre[0].M1.toarray()[:, 0], spaces_pre[1].M1.toarray()[:, 0], spaces_pre[2].M0.toarray()[:, 0]] - - def solve(x): - x1, x2, x3 = xp.split(x, 3) - - x1 = x1.reshape(Nel_pre[0], Nel_pre[1], Nel_pre[2]) - x2 = x2.reshape(Nel_pre[0], Nel_pre[1], Nel_pre[2]) - x3 = x3.reshape(Nel_pre[0], Nel_pre[1], Nel_pre[2]) - - r1 = linkron.kron_fftsolve_3d(c11_pre, x1).flatten() - r2 = linkron.kron_fftsolve_3d(c22_pre, x2).flatten() - r3 = linkron.kron_fftsolve_3d(c33_pre, x3).flatten() - - return xp.concatenate((r1, r2, r3)) - - return spa.linalg.LinearOperator(shape=tensor_space_FEM.M2.shape, matvec=solve) - - -# ================ inverse mass matrix in V3 =========================== -def get_M3_PRE(tensor_space_FEM, domain): - """ - TODO - """ - - # 1d spaces for pre-conditioning with fft: - Nel_pre = [tensor_space_FEM.spaces[0].NbaseN, tensor_space_FEM.spaces[1].NbaseN, tensor_space_FEM.spaces[2].NbaseN] - spl_kind_pre = [True, True, True] - spaces_pre = [ - spl.Spline_space_1d(Nel, p, spl_kind, nq_el) - for Nel, p, spl_kind, nq_el in zip(Nel_pre, tensor_space_FEM.p, spl_kind_pre, tensor_space_FEM.n_quad) - ] - - # tensor product mass matrices for pre-conditioning - # spaces_pre[0].set_extraction_operators() - # spaces_pre[1].set_extraction_operators() - # spaces_pre[2].set_extraction_operators() - - spaces_pre[0].assemble_M1(lambda eta: 1 / (domain.params[1] - domain.params[0]) * xp.ones(eta.shape, dtype=float)) - spaces_pre[1].assemble_M1(lambda eta: 1 / (domain.params[3] - domain.params[2]) * xp.ones(eta.shape, dtype=float)) - spaces_pre[2].assemble_M1(lambda eta: 1 / (domain.params[5] - domain.params[4]) * xp.ones(eta.shape, dtype=float)) - - c_pre = [spaces_pre[0].M1.toarray()[:, 0], spaces_pre[1].M1.toarray()[:, 0], spaces_pre[2].M1.toarray()[:, 0]] - - return spa.linalg.LinearOperator( - shape=tensor_space_FEM.M3.shape, - matvec=lambda x: (linkron.kron_fftsolve_3d(c_pre, x.reshape(Nel_pre[0], Nel_pre[1], Nel_pre[2]))).flatten(), - ) - - -# ================ inverse mass matrix in V0^3 =========================== -def get_Mv_PRE(tensor_space_FEM, domain): - """ - TODO - """ - - # 1d spaces for pre-conditioning with fft: - Nel_pre = [tensor_space_FEM.spaces[0].NbaseN, tensor_space_FEM.spaces[1].NbaseN, tensor_space_FEM.spaces[2].NbaseN] - spl_kind_pre = [True, True, True] - spaces_pre = [ - spl.Spline_space_1d(Nel, p, spl_kind, nq_el) - for Nel, p, spl_kind, nq_el in zip(Nel_pre, tensor_space_FEM.p, spl_kind_pre, tensor_space_FEM.n_quad) - ] - - # tensor product mass matrices for pre-conditioning of the three diagonal blocks - # spaces_pre[0].set_extraction_operators() - # spaces_pre[1].set_extraction_operators() - # spaces_pre[2].set_extraction_operators() - - spaces_pre[0].assemble_M0(lambda eta: domain.params[0] ** 3 * xp.ones(eta.shape, dtype=float)) - spaces_pre[1].assemble_M0(lambda eta: domain.params[1] * xp.ones(eta.shape, dtype=float)) - spaces_pre[2].assemble_M0(lambda eta: domain.params[2] * xp.ones(eta.shape, dtype=float)) - - c11_pre = [spaces_pre[0].M0.toarray()[:, 0], spaces_pre[1].M0.toarray()[:, 0], spaces_pre[2].M0.toarray()[:, 0]] - - spaces_pre[0].assemble_M0(lambda eta: domain.params[0] * xp.ones(eta.shape, dtype=float)) - spaces_pre[1].assemble_M0(lambda eta: domain.params[1] ** 3 * xp.ones(eta.shape, dtype=float)) - spaces_pre[2].assemble_M0(lambda eta: domain.params[2] * xp.ones(eta.shape, dtype=float)) - - c22_pre = [spaces_pre[0].M0.toarray()[:, 0], spaces_pre[1].M0.toarray()[:, 0], spaces_pre[2].M0.toarray()[:, 0]] - - spaces_pre[0].assemble_M0(lambda eta: domain.params[0] * xp.ones(eta.shape, dtype=float)) - spaces_pre[1].assemble_M0(lambda eta: domain.params[1] * xp.ones(eta.shape, dtype=float)) - spaces_pre[2].assemble_M0(lambda eta: domain.params[2] ** 3 * xp.ones(eta.shape, dtype=float)) - - c33_pre = [spaces_pre[0].M0.toarray()[:, 0], spaces_pre[1].M0.toarray()[:, 0], spaces_pre[2].M0.toarray()[:, 0]] - - def solve(x): - x1, x2, x3 = xp.split(x, 3) - - x1 = x1.reshape(Nel_pre[0], Nel_pre[1], Nel_pre[2]) - x2 = x2.reshape(Nel_pre[0], Nel_pre[1], Nel_pre[2]) - x3 = x3.reshape(Nel_pre[0], Nel_pre[1], Nel_pre[2]) - - r1 = linkron.kron_fftsolve_3d(c11_pre, x1).flatten() - r2 = linkron.kron_fftsolve_3d(c22_pre, x2).flatten() - r3 = linkron.kron_fftsolve_3d(c33_pre, x3).flatten() - - return xp.concatenate((r1, r2, r3)) - - return spa.linalg.LinearOperator(shape=tensor_space_FEM.Mv.shape, matvec=solve) - - -# ==== inverse mass matrix in V0 (with boundary conditions) with decomposition poloidal x toroidal ==== -def get_M0_PRE_3(tensor_space_FEM, mats_pol=None): - """ - TODO - """ - - if mats_pol is None: - mat = tensor_space_FEM.B0_pol.dot(tensor_space_FEM.M0_pol_mat.dot(tensor_space_FEM.B0_pol.T)) - else: - mat = mats_pol - - # LU decomposition of poloidal mass matrix - M0_pol_0_LU = spa.linalg.splu(mat.tocsc()) - - # vector defining the circulant mass matrix in toroidal direction - tor_vec0 = tensor_space_FEM.M0_tor.toarray()[:, 0] - - def solve(x): - x = x.reshape(tensor_space_FEM.E0_pol_0.shape[0], tensor_space_FEM.NbaseN[2]) - - r = linkron.kron_fftsolve_2d(M0_pol_0_LU, tor_vec0, x).flatten() - - return r - - return spa.linalg.LinearOperator(shape=tensor_space_FEM.M0_0.shape, matvec=solve) - - -# ==== inverse mass matrix in V1 (with boundary conditions) with decomposition poloidal x toroidal ==== -def get_M1_PRE_3(tensor_space_FEM, mats_pol=None): - """ - TODO - """ - - if mats_pol is None: - mat = [ - tensor_space_FEM.B1_pol.dot(tensor_space_FEM.M1_pol_mat[0].dot(tensor_space_FEM.B1_pol.T)), - tensor_space_FEM.B0_pol.dot(tensor_space_FEM.M1_pol_mat[1].dot(tensor_space_FEM.B0_pol.T)), - ] - else: - mat = mats_pol - - # LU decomposition of poloidal mass matrix - M1_pol_0_11_LU = spa.linalg.splu(mat[0].tocsc()) - M1_pol_0_22_LU = spa.linalg.splu(mat[1].tocsc()) - - # vectors defining the circulant mass matrices in toroidal direction - tor_vec0 = tensor_space_FEM.M0_tor.toarray()[:, 0] - tor_vec1 = tensor_space_FEM.M1_tor.toarray()[:, 0] - - def solve(x): - x1 = x[: tensor_space_FEM.E1_pol_0.shape[0] * tensor_space_FEM.NbaseN[2]].reshape( - tensor_space_FEM.E1_pol_0.shape[0], - tensor_space_FEM.NbaseN[2], - ) - x2 = x[tensor_space_FEM.E1_pol_0.shape[0] * tensor_space_FEM.NbaseN[2] :].reshape( - tensor_space_FEM.E0_pol_0.shape[0], - tensor_space_FEM.NbaseD[2], - ) - - r1 = linkron.kron_fftsolve_2d(M1_pol_0_11_LU, tor_vec0, x1).flatten() - r2 = linkron.kron_fftsolve_2d(M1_pol_0_22_LU, tor_vec1, x2).flatten() - - return xp.concatenate((r1, r2)) - - return spa.linalg.LinearOperator(shape=tensor_space_FEM.M1_0.shape, matvec=solve) - - -# ==== inverse mass matrix in V2 (with boundary conditions) with decomposition poloidal x toroidal ==== -def get_M2_PRE_3(tensor_space_FEM, mats_pol=None): - """ - TODO - """ - - if mats_pol is None: - mat = [ - tensor_space_FEM.B2_pol.dot(tensor_space_FEM.M2_pol_mat[0].dot(tensor_space_FEM.B2_pol.T)), - tensor_space_FEM.B3_pol.dot(tensor_space_FEM.M2_pol_mat[1].dot(tensor_space_FEM.B3_pol.T)), - ] - else: - mat = mats_pol - - # LU decomposition of poloidal mass matrix - M2_pol_0_11_LU = spa.linalg.splu(mat[0].tocsc()) - M2_pol_0_22_LU = spa.linalg.splu(mat[1].tocsc()) - - # vectors defining the circulant mass matrices in toroidal direction - tor_vec0 = tensor_space_FEM.M0_tor.toarray()[:, 0] - tor_vec1 = tensor_space_FEM.M1_tor.toarray()[:, 0] - - def solve(x): - x1 = x[: tensor_space_FEM.E2_pol_0.shape[0] * tensor_space_FEM.NbaseD[2]].reshape( - tensor_space_FEM.E2_pol_0.shape[0], - tensor_space_FEM.NbaseD[2], - ) - x2 = x[tensor_space_FEM.E2_pol_0.shape[0] * tensor_space_FEM.NbaseD[2] :].reshape( - tensor_space_FEM.E3_pol_0.shape[0], - tensor_space_FEM.NbaseN[2], - ) - - r1 = linkron.kron_fftsolve_2d(M2_pol_0_11_LU, tor_vec1, x1).flatten() - r2 = linkron.kron_fftsolve_2d(M2_pol_0_22_LU, tor_vec0, x2).flatten() - - return xp.concatenate((r1, r2)) - - return spa.linalg.LinearOperator(shape=tensor_space_FEM.M2_0.shape, matvec=solve) - - -# ==== inverse mass matrix in V3 (with boundary conditions) with decomposition poloidal x toroidal ==== -def get_M3_PRE_3(tensor_space_FEM, mats_pol=None): - """ - TODO - """ - - if mats_pol is None: - mat = tensor_space_FEM.B3_pol.dot(tensor_space_FEM.M3_pol_mat.dot(tensor_space_FEM.B3_pol.T)) - else: - mat = mats_pol - - # LU decomposition of poloidal mass matrix - M3_pol_0_LU = spa.linalg.splu(mat.tocsc()) - - # vector defining the circulant mass matrix in toroidal direction - tor_vec1 = tensor_space_FEM.M1_tor.toarray()[:, 0] - - def solve(x): - x = x.reshape(tensor_space_FEM.E3_pol_0.shape[0], tensor_space_FEM.NbaseD[2]) - - r = linkron.kron_fftsolve_2d(M3_pol_0_LU, tor_vec1, x).flatten() - - return spa.linalg.LinearOperator(shape=tensor_space_FEM.M3_0.shape, matvec=solve) - - -# ==== inverse mass matrix in V0^3 (with boundary conditions) with decomposition poloidal x toroidal ==== -def get_Mv_PRE_3(tensor_space_FEM, mats_pol=None): - """ - TODO - """ - - if mats_pol is None: - mat = [ - tensor_space_FEM.Bv_pol.dot(tensor_space_FEM.Mv_pol_mat[0].dot(tensor_space_FEM.Bv_pol.T)), - tensor_space_FEM.Mv_pol_mat[1], - ] - else: - mat = mats_pol - - # LU decomposition of poloidal mass matrix - Mv_pol_0_11_LU = spa.linalg.splu(mat[0].tocsc()) - Mv_pol_0_22_LU = spa.linalg.splu(mat[1].tocsc()) - - # vectors defining the circulant mass matrices in toroidal direction - tor_vec0 = tensor_space_FEM.M0_tor.toarray()[:, 0] - - def solve(x): - x1 = x[: tensor_space_FEM.Ev_pol_0.shape[0] * tensor_space_FEM.NbaseN[2]].reshape( - tensor_space_FEM.Ev_pol_0.shape[0], - tensor_space_FEM.NbaseN[2], - ) - x2 = x[tensor_space_FEM.Ev_pol_0.shape[0] * tensor_space_FEM.NbaseN[2] :].reshape( - tensor_space_FEM.E0_pol.shape[0], - tensor_space_FEM.NbaseN[2], - ) - - r1 = linkron.kron_fftsolve_2d(Mv_pol_0_11_LU, tor_vec0, x1).flatten() - r2 = linkron.kron_fftsolve_2d(Mv_pol_0_22_LU, tor_vec0, x2).flatten() - - return xp.concatenate((r1, r2)) - - return spa.linalg.LinearOperator(shape=tensor_space_FEM.Mv_0.shape, matvec=solve) diff --git a/src/struphy/eigenvalue_solvers/legacy/massless_operators/__init__.py b/src/struphy/eigenvalue_solvers/legacy/massless_operators/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_arrays.py b/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_arrays.py deleted file mode 100644 index 65faf9209..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_arrays.py +++ /dev/null @@ -1,815 +0,0 @@ -import time -import timeit - -import cunumpy as xp -import scipy.sparse as spa -from psydac.ddm.mpi import mpi as MPI - -import struphy.geometry.mappings_3d as mapping3d -import struphy.geometry.mappings_3d_fast as mapping_fast -import struphy.linear_algebra.linalg_kernels as linalg - - -class Temp_arrays: - """ - Class for arrays predefined before the time loops - - Parameters - --------- - TENSOR_SPACE_FEM : tensor_spline_space-tensor product B-spline space - DOMAIN : : class of Domain - control : control variate or not - mpi_comm : environment of mpi processes - """ - - def __init__(self, TENSOR_SPACE_FEM, DOMAIN, control, mpi_comm): - self.Nel = TENSOR_SPACE_FEM.Nel - self.NbaseN = TENSOR_SPACE_FEM.NbaseN # number of basis functions (N) - self.NbaseD = TENSOR_SPACE_FEM.NbaseD # number of basis functions (D) - self.DOMAIN = DOMAIN - self.TENSOR_SPACE_FEM = TENSOR_SPACE_FEM - self.n_quad = TENSOR_SPACE_FEM.n_quad - self.mpi_rank = mpi_comm.Get_rank() - self.N_0form = TENSOR_SPACE_FEM.Nbase_0form - self.N_1form = TENSOR_SPACE_FEM.Nbase_1form - self.N_2form = TENSOR_SPACE_FEM.Nbase_2form - self.N_3form = TENSOR_SPACE_FEM.Nbase_3form - - self.Ntot_0form = TENSOR_SPACE_FEM.Ntot_0form - self.Ntot_1form = TENSOR_SPACE_FEM.Ntot_1form - self.Ntot_2form = TENSOR_SPACE_FEM.Ntot_2form - - self.b1_old = xp.empty(TENSOR_SPACE_FEM.Nbase_1form[0], dtype=float) - self.b2_old = xp.empty(TENSOR_SPACE_FEM.Nbase_1form[1], dtype=float) - self.b3_old = xp.empty(TENSOR_SPACE_FEM.Nbase_1form[2], dtype=float) - - self.b1_iter = xp.empty(TENSOR_SPACE_FEM.Nbase_1form[0], dtype=float) - self.b2_iter = xp.empty(TENSOR_SPACE_FEM.Nbase_1form[1], dtype=float) - self.b3_iter = xp.empty(TENSOR_SPACE_FEM.Nbase_1form[2], dtype=float) - - self.temp_dft = xp.empty((3, 3), dtype=float) - self.temp_generate_weight1 = xp.empty(3, dtype=float) - self.temp_generate_weight2 = xp.empty(3, dtype=float) - self.temp_generate_weight3 = xp.empty(3, dtype=float) - - self.zerosform_temp_long = xp.empty(TENSOR_SPACE_FEM.Ntot_0form, dtype=float) - self.oneform_temp1_long = xp.empty(TENSOR_SPACE_FEM.Ntot_1form[0], dtype=float) - self.oneform_temp2_long = xp.empty(TENSOR_SPACE_FEM.Ntot_1form[1], dtype=float) - self.oneform_temp3_long = xp.empty(TENSOR_SPACE_FEM.Ntot_1form[2], dtype=float) - - self.oneform_temp_long = xp.empty( - TENSOR_SPACE_FEM.Ntot_1form[0] + TENSOR_SPACE_FEM.Ntot_1form[1] + TENSOR_SPACE_FEM.Ntot_1form[2], - dtype=float, - ) - - self.twoform_temp1_long = xp.empty(TENSOR_SPACE_FEM.Ntot_2form[0], dtype=float) - self.twoform_temp2_long = xp.empty(TENSOR_SPACE_FEM.Ntot_2form[1], dtype=float) - self.twoform_temp3_long = xp.empty(TENSOR_SPACE_FEM.Ntot_2form[2], dtype=float) - - self.twoform_temp_long = xp.empty( - TENSOR_SPACE_FEM.Ntot_2form[0] + TENSOR_SPACE_FEM.Ntot_2form[1] + TENSOR_SPACE_FEM.Ntot_2form[2], - dtype=float, - ) - - self.temp_twoform1 = xp.empty(TENSOR_SPACE_FEM.Nbase_2form[0], dtype=float) - self.temp_twoform2 = xp.empty(TENSOR_SPACE_FEM.Nbase_2form[1], dtype=float) - self.temp_twoform3 = xp.empty(TENSOR_SPACE_FEM.Nbase_2form[2], dtype=float) - - # arrays used to store intermidaite values - self.form_0_flatten = xp.empty(self.Ntot_0form, dtype=float) - - self.form_1_1_flatten = xp.empty(self.Ntot_1form[0], dtype=float) - self.form_1_2_flatten = xp.empty(self.Ntot_1form[1], dtype=float) - self.form_1_3_flatten = xp.empty(self.Ntot_1form[2], dtype=float) - - self.form_1_tot_flatten = xp.empty(self.Ntot_1form[0] + self.Ntot_1form[1] + self.Ntot_1form[2], dtype=float) - - self.form_2_1_flatten = xp.empty(self.Ntot_2form[0], dtype=float) - self.form_2_2_flatten = xp.empty(self.Ntot_2form[1], dtype=float) - self.form_2_3_flatten = xp.empty(self.Ntot_2form[2], dtype=float) - - self.form_2_tot_flatten = xp.empty(self.Ntot_2form[0] + self.Ntot_2form[1] + self.Ntot_2form[2], dtype=float) - - self.bulkspeed_loc = xp.zeros((3, self.Nel[0], self.Nel[1], self.Nel[2]), dtype=float) - self.temperature_loc = xp.zeros((3, self.Nel[0], self.Nel[1], self.Nel[2]), dtype=float) - self.bulkspeed = xp.zeros((3, self.Nel[0], self.Nel[1], self.Nel[2]), dtype=float) - if self.mpi_rank == 0: - temperature = xp.zeros((3, self.Nel[0], self.Nel[1], self.Nel[2]), dtype=float) - else: - temperature = None - - # values of magnetic fields at all quadrature points - self.LO_inv = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - - self.LO_b1 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.LO_b2 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.LO_b3 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - # values of weights (used in the linear operators) - self.LO_w1 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.LO_w2 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.LO_w3 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - # values of a function (given its finite element coefficients) at all quadrature points - self.LO_r1 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.LO_r2 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.LO_r3 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - # values of determinant of Jacobi matrix of the map at all quadrature points - self.df_det = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - # when using delta f method, the values of current equilibrium at all quadrature points - if control: - self.Jeqx = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.Jeqy = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.Jeqz = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - # values of DF and inverse of DF at all quadrature points - self.DF_11 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DF_12 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DF_13 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DF_21 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DF_22 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DF_23 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DF_31 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DF_32 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DF_33 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - - self.DFI_11 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFI_12 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFI_13 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFI_21 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFI_22 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFI_23 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFI_31 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFI_32 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFI_33 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - - self.DFIT_11 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFIT_12 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFIT_13 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFIT_21 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFIT_22 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFIT_23 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFIT_31 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFIT_32 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.DFIT_33 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - - self.G_inv_11 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.G_inv_12 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.G_inv_13 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - - self.G_inv_22 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - self.G_inv_23 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - - self.G_inv_33 = xp.empty( - ( - self.Nel[0], - self.Nel[1], - self.Nel[2], - TENSOR_SPACE_FEM.n_quad[0], - TENSOR_SPACE_FEM.n_quad[1], - TENSOR_SPACE_FEM.n_quad[2], - ), - dtype=float, - ) - - self.temp_particle = xp.empty(3, dtype=float) - # initialization of DF and its inverse - # ================ for mapping evaluation ================== - # spline degrees - pf1 = DOMAIN.p[0] - pf2 = DOMAIN.p[1] - pf3 = DOMAIN.p[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = xp.empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = xp.empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = xp.empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = xp.empty(pf1, dtype=float) - l2f = xp.empty(pf2, dtype=float) - l3f = xp.empty(pf3, dtype=float) - - r1f = xp.empty(pf1, dtype=float) - r2f = xp.empty(pf2, dtype=float) - r3f = xp.empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = xp.empty(pf1, dtype=float) - d2f = xp.empty(pf2, dtype=float) - d3f = xp.empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = xp.empty(pf1 + 1, dtype=float) - der2f = xp.empty(pf2 + 1, dtype=float) - der3f = xp.empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = xp.empty((3, 3), dtype=float) - fx = xp.empty(3, dtype=float) - ginv = xp.empty((3, 3), dtype=float) - dfinv = xp.empty((3, 3), dtype=float) - - for ie1 in range(self.Nel[0]): - for ie2 in range(self.Nel[1]): - for ie3 in range(self.Nel[2]): - for q1 in range(TENSOR_SPACE_FEM.n_quad[0]): - for q2 in range(TENSOR_SPACE_FEM.n_quad[1]): - for q3 in range(TENSOR_SPACE_FEM.n_quad[2]): - span1f = int(TENSOR_SPACE_FEM.pts[0][ie1, q1] * DOMAIN.NbaseN[0]) + pf1 - span2f = int(TENSOR_SPACE_FEM.pts[1][ie2, q2] * DOMAIN.NbaseN[1]) + pf2 - span3f = int(TENSOR_SPACE_FEM.pts[2][ie3, q3] * DOMAIN.NbaseN[2]) + pf3 - # evaluate Jacobian matrix - mapping_fast.df_all( - DOMAIN.kind_map, - DOMAIN.params, - DOMAIN.T[0], - DOMAIN.T[1], - DOMAIN.T[2], - DOMAIN.p, - DOMAIN.NbaseN, - span1f, - span2f, - span3f, - DOMAIN.cx, - DOMAIN.cy, - DOMAIN.cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - self.TENSOR_SPACE_FEM.pts[0][ie1, q1], - self.TENSOR_SPACE_FEM.pts[1][ie2, q2], - self.TENSOR_SPACE_FEM.pts[2][ie3, q3], - df, - fx, - 0, - ) - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - # evaluate metric tensor - mapping_fast.g_inv_all(dfinv, ginv) - # evaluate Jacobian determinant - det_number = abs(linalg.det(df)) - - self.DFI_11[ie1, ie2, ie3, q1, q2, q3] = dfinv[0, 0] - self.DFI_12[ie1, ie2, ie3, q1, q2, q3] = dfinv[0, 1] - self.DFI_13[ie1, ie2, ie3, q1, q2, q3] = dfinv[0, 2] - self.DFI_21[ie1, ie2, ie3, q1, q2, q3] = dfinv[1, 0] - self.DFI_22[ie1, ie2, ie3, q1, q2, q3] = dfinv[1, 1] - self.DFI_23[ie1, ie2, ie3, q1, q2, q3] = dfinv[1, 2] - self.DFI_31[ie1, ie2, ie3, q1, q2, q3] = dfinv[2, 0] - self.DFI_32[ie1, ie2, ie3, q1, q2, q3] = dfinv[2, 1] - self.DFI_33[ie1, ie2, ie3, q1, q2, q3] = dfinv[2, 2] - - self.DFIT_11[ie1, ie2, ie3, q1, q2, q3] = dfinv[0, 0] - self.DFIT_12[ie1, ie2, ie3, q1, q2, q3] = dfinv[1, 0] - self.DFIT_13[ie1, ie2, ie3, q1, q2, q3] = dfinv[2, 0] - self.DFIT_21[ie1, ie2, ie3, q1, q2, q3] = dfinv[0, 1] - self.DFIT_22[ie1, ie2, ie3, q1, q2, q3] = dfinv[1, 1] - self.DFIT_23[ie1, ie2, ie3, q1, q2, q3] = dfinv[2, 1] - self.DFIT_31[ie1, ie2, ie3, q1, q2, q3] = dfinv[0, 2] - self.DFIT_32[ie1, ie2, ie3, q1, q2, q3] = dfinv[1, 2] - self.DFIT_33[ie1, ie2, ie3, q1, q2, q3] = dfinv[2, 2] - - self.DF_11[ie1, ie2, ie3, q1, q2, q3] = df[0, 0] - self.DF_12[ie1, ie2, ie3, q1, q2, q3] = df[0, 1] - self.DF_13[ie1, ie2, ie3, q1, q2, q3] = df[0, 2] - self.DF_21[ie1, ie2, ie3, q1, q2, q3] = df[1, 0] - self.DF_22[ie1, ie2, ie3, q1, q2, q3] = df[1, 1] - self.DF_23[ie1, ie2, ie3, q1, q2, q3] = df[1, 2] - self.DF_31[ie1, ie2, ie3, q1, q2, q3] = df[2, 0] - self.DF_32[ie1, ie2, ie3, q1, q2, q3] = df[2, 1] - self.DF_33[ie1, ie2, ie3, q1, q2, q3] = df[2, 2] - - self.G_inv_11[ie1, ie2, ie3, q1, q2, q3] = ginv[0, 0] - self.G_inv_12[ie1, ie2, ie3, q1, q2, q3] = ginv[0, 1] - self.G_inv_13[ie1, ie2, ie3, q1, q2, q3] = ginv[0, 2] - - self.G_inv_22[ie1, ie2, ie3, q1, q2, q3] = ginv[1, 1] - self.G_inv_23[ie1, ie2, ie3, q1, q2, q3] = ginv[1, 2] - - self.G_inv_33[ie1, ie2, ie3, q1, q2, q3] = ginv[2, 2] - - self.df_det[ie1, ie2, ie3, q1, q2, q3] = det_number - - if control: - x1 = mapping3d.f( - TENSOR_SPACE_FEM.pts[0][ie1, q1], - TENSOR_SPACE_FEM.pts[1][ie2, q2], - TENSOR_SPACE_FEM.pts[2][ie3, q3], - 1, - DOMAIN.kind_map, - DOMAIN.params, - DOMAIN.T[0], - DOMAIN.T[1], - DOMAIN.T[2], - DOMAIN.p, - DOMAIN.NbaseN, - DOMAIN.cx, - DOMAIN.cy, - DOMAIN.cz, - ) - x2 = mapping3d.f( - TENSOR_SPACE_FEM.pts[0][ie1, q1], - TENSOR_SPACE_FEM.pts[1][ie2, q2], - TENSOR_SPACE_FEM.pts[2][ie3, q3], - 2, - DOMAIN.kind_map, - DOMAIN.params, - DOMAIN.T[0], - DOMAIN.T[1], - DOMAIN.T[2], - DOMAIN.p, - DOMAIN.NbaseN, - DOMAIN.cx, - DOMAIN.cy, - DOMAIN.cz, - ) - x3 = mapping3d.f( - TENSOR_SPACE_FEM.pts[0][ie1, q1], - TENSOR_SPACE_FEM.pts[1][ie2, q2], - TENSOR_SPACE_FEM.pts[2][ie3, q3], - 3, - DOMAIN.kind_map, - DOMAIN.params, - DOMAIN.T[0], - DOMAIN.T[1], - DOMAIN.T[2], - DOMAIN.p, - DOMAIN.NbaseN, - DOMAIN.cx, - DOMAIN.cy, - DOMAIN.cz, - ) - Jeqx[ie1, ie2, ie3, q1, q2, q3] = equ_PIC.jhx_eq(x1, x2, x3) - Jeqy[ie1, ie2, ie3, q1, q2, q3] = equ_PIC.jhy_eq(x1, x2, x3) - Jeqz[ie1, ie2, ie3, q1, q2, q3] = equ_PIC.jhz_eq(x1, x2, x3) diff --git a/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_bb_kernel.py b/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_bb_kernel.py deleted file mode 100644 index 509c73380..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_bb_kernel.py +++ /dev/null @@ -1,457 +0,0 @@ -import struphy.linear_algebra.linalg_kernels as linalg - - -# ========================================================================================== -def right_hand( - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - right_1: "float[:,:,:,:,:,:]", - right_2: "float[:,:,:,:,:,:]", - right_3: "float[:,:,:,:,:,:]", - temp_vector_1: "float[:,:,:]", - temp_vector_2: "float[:,:,:]", - temp_vector_3: "float[:,:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(d3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * temp_vector_1[idnx[ie1, il1], iddy[ie2, il2], iddz[ie3, il3]] - ) - - right_1[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * temp_vector_2[iddx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] - ) - - right_2[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * temp_vector_3[iddx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] - ) - - right_3[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def bvalue( - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1: "float[:,:,:]", - b2: "float[:,:,:]", - b3: "float[:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - temp_vector_1: "float[:,:,:]", - temp_vector_2: "float[:,:,:]", - temp_vector_3: "float[:,:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b1[iddx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] - ) - - b1value[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b2[idnx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] - ) - - b2value[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * b3[idnx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] - ) - - b3value[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def weight( - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - right_1: "float[:,:,:,:,:,:]", - right_2: "float[:,:,:,:,:,:]", - right_3: "float[:,:,:,:,:,:]", - weight1: "float[:,:,:,:,:,:]", - weight2: "float[:,:,:,:,:,:]", - weight3: "float[:,:,:,:,:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - weight1[ie1, ie2, ie3, q1, q2, q3] = ( - b2value[ie1, ie2, ie3, q1, q2, q3] * right_3[ie1, ie2, ie3, q1, q2, q3] - - b3value[ie1, ie2, ie3, q1, q2, q3] * right_2[ie1, ie2, ie3, q1, q2, q3] - ) - weight2[ie1, ie2, ie3, q1, q2, q3] = ( - b3value[ie1, ie2, ie3, q1, q2, q3] * right_1[ie1, ie2, ie3, q1, q2, q3] - - b1value[ie1, ie2, ie3, q1, q2, q3] * right_3[ie1, ie2, ie3, q1, q2, q3] - ) - weight3[ie1, ie2, ie3, q1, q2, q3] = ( - b1value[ie1, ie2, ie3, q1, q2, q3] * right_2[ie1, ie2, ie3, q1, q2, q3] - - b2value[ie1, ie2, ie3, q1, q2, q3] * right_1[ie1, ie2, ie3, q1, q2, q3] - ) - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ========================================================================================== -def final( - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - weight1: "float[:,:,:,:,:,:]", - weight2: "float[:,:,:,:,:,:]", - weight3: "float[:,:,:,:,:,:]", - temp_final_1: "float[:,:,:]", - temp_final_2: "float[:,:,:]", - temp_final_3: "float[:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", -): - temp_final_1[:, :, :] = 0.0 - temp_final_2[:, :, :] = 0.0 - temp_final_3[:, :, :] = 0.0 - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_1) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(d3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight1[ie1, ie2, ie3, q1, q2, q3] - * bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - ) - - temp_final_1[idnx[ie1, il1], iddy[ie2, il2], iddz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_2) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight2[ie1, ie2, ie3, q1, q2, q3] - * bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - ) - - temp_final_2[iddx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_3) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(d1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight3[ie1, ie2, ie3, q1, q2, q3] - * bd1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - ) - - temp_final_3[iddx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def right_bwvalue( - G_inv_11: "float[:,:,:,:,:,:]", - G_inv_12: "float[:,:,:,:,:,:]", - G_inv_13: "float[:,:,:,:,:,:]", - G_inv_22: "float[:,:,:,:,:,:]", - G_inv_23: "float[:,:,:,:,:,:]", - G_inv_33: "float[:,:,:,:,:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - dft: "float[:,:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", - generate_weight1: "float[:]", - generate_weight2: "float[:]", - generate_weight3: "float[:]", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - uvalue: "float[:,:,:,:,:,:]", - weight1: "float[:,:,:,:,:,:]", - weight2: "float[:,:,:,:,:,:]", - weight3: "float[:,:,:,:,:,:]", - right_1: "float[:,:,:,:,:,:]", - right_2: "float[:,:,:,:,:,:]", - right_3: "float[:,:,:,:,:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, dft, generate_weight1, generate_weight3, temp) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - dft[0, 0] = G_inv_11[ie1, ie2, ie3, q1, q2, q3] - dft[0, 1] = G_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[0, 2] = G_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[1, 0] = G_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[1, 1] = G_inv_22[ie1, ie2, ie3, q1, q2, q3] - dft[1, 2] = G_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 0] = G_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[2, 1] = G_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 2] = G_inv_33[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[0] = b1value[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[1] = b2value[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[2] = b3value[ie1, ie2, ie3, q1, q2, q3] - temp = uvalue[ie1, ie2, ie3, q1, q2, q3] * wts1[ie1, q1] * wts2[ie2, q2] * wts3[ie3, q3] - linalg.matrix_vector(dft, generate_weight1, generate_weight3) - b1value[ie1, ie2, ie3, q1, q2, q3] = generate_weight3[0] * temp - b2value[ie1, ie2, ie3, q1, q2, q3] = generate_weight3[1] * temp - b3value[ie1, ie2, ie3, q1, q2, q3] = ( - generate_weight3[2] * temp - ) # we here multilying uvalue and weights into b1, b2, b3 - weight1[ie1, ie2, ie3, q1, q2, q3] = temp * ( - generate_weight3[1] * right_3[ie1, ie2, ie3, q1, q2, q3] - - generate_weight3[2] * right_2[ie1, ie2, ie3, q1, q2, q3] - ) - weight2[ie1, ie2, ie3, q1, q2, q3] = temp * ( - generate_weight3[2] * right_1[ie1, ie2, ie3, q1, q2, q3] - - generate_weight3[0] * right_3[ie1, ie2, ie3, q1, q2, q3] - ) - weight3[ie1, ie2, ie3, q1, q2, q3] = temp * ( - generate_weight3[0] * right_2[ie1, ie2, ie3, q1, q2, q3] - - generate_weight3[1] * right_1[ie1, ie2, ie3, q1, q2, q3] - ) - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_bv_kernel.py b/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_bv_kernel.py deleted file mode 100644 index e477940e6..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_bv_kernel.py +++ /dev/null @@ -1,788 +0,0 @@ -import struphy.linear_algebra.linalg_kernels as linalg - - -# ========================================================================================== -def prepre( - df_det: "float[:,:,:,:,:,:]", - G_inv_11: "float[:,:,:,:,:,:]", - G_inv_12: "float[:,:,:,:,:,:]", - G_inv_13: "float[:,:,:,:,:,:]", - G_inv_22: "float[:,:,:,:,:,:]", - G_inv_23: "float[:,:,:,:,:,:]", - G_inv_33: "float[:,:,:,:,:,:]", - N_index_x: "int[:,:]", - N_index_y: "int[:,:]", - N_index_z: "int[:,:]", - D_index_x: "int[:,:]", - D_index_y: "int[:,:]", - D_index_z: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - uvalue: "float[:,:,:,:,:,:]", - b1: "float[:,:,:]", - b2: "float[:,:,:]", - b3: "float[:,:,:]", - dft: "float[:,:]", - generate_weight1: "float[:]", - generate_weight3: "float[:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", -): - # ====uvalue is given from other function=========== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b1[D_index_x[ie1, il1], N_index_y[ie2, il2], N_index_z[ie3, il3]] - ) - - b1value[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b2[N_index_x[ie1, il1], D_index_y[ie2, il2], N_index_z[ie3, il3]] - ) - - b2value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * b3[N_index_x[ie1, il1], N_index_y[ie2, il2], D_index_z[ie3, il3]] - ) - - b3value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, dft, detdet, generate_weight1, generate_weight3) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - dft[0, 0] = G_inv_11[ie1, ie2, ie3, q1, q2, q3] - dft[0, 1] = G_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[0, 2] = G_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[1, 0] = G_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[1, 1] = G_inv_22[ie1, ie2, ie3, q1, q2, q3] - dft[1, 2] = G_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 0] = G_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[2, 1] = G_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 2] = G_inv_33[ie1, ie2, ie3, q1, q2, q3] - detdet = df_det[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[0] = ( - b1value[ie1, ie2, ie3, q1, q2, q3] - * wts1[ie1, q1] - * wts2[ie2, q2] - * wts3[ie3, q3] - * detdet - ) - generate_weight1[1] = ( - b2value[ie1, ie2, ie3, q1, q2, q3] - * wts1[ie1, q1] - * wts2[ie2, q2] - * wts3[ie3, q3] - * detdet - ) - generate_weight1[2] = ( - b3value[ie1, ie2, ie3, q1, q2, q3] - * wts1[ie1, q1] - * wts2[ie2, q2] - * wts3[ie3, q3] - * detdet - ) - linalg.matrix_vector(dft, generate_weight1, generate_weight3) - b1value[ie1, ie2, ie3, q1, q2, q3] = generate_weight3[0] * uvalue[ie1, ie2, ie3, q1, q2, q3] - b2value[ie1, ie2, ie3, q1, q2, q3] = generate_weight3[1] * uvalue[ie1, ie2, ie3, q1, q2, q3] - b3value[ie1, ie2, ie3, q1, q2, q3] = generate_weight3[2] * uvalue[ie1, ie2, ie3, q1, q2, q3] - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def right_hand2( - N_index_x: "int[:,:]", - N_index_y: "int[:,:]", - N_index_z: "int[:,:]", - D_index_x: "int[:,:]", - D_index_y: "int[:,:]", - D_index_z: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - right_1: "float[:,:,:,:,:,:]", - right_2: "float[:,:,:,:,:,:]", - right_3: "float[:,:,:,:,:,:]", - temp_vector_1: "float[:,:,:]", - temp_vector_2: "float[:,:,:]", - temp_vector_3: "float[:,:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(d3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * temp_vector_1[ - N_index_x[ie1, il1], - D_index_y[ie2, il2], - D_index_z[ie3, il3], - ] - ) - - right_1[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * temp_vector_2[ - D_index_x[ie1, il1], - N_index_y[ie2, il2], - D_index_z[ie3, il3], - ] - ) - - right_2[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * temp_vector_3[ - D_index_x[ie1, il1], - D_index_y[ie2, il2], - N_index_z[ie3, il3], - ] - ) - - right_3[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ========================================================================================== -def right_hand1( - N_index_x: "int[:,:]", - N_index_y: "int[:,:]", - N_index_z: "int[:,:]", - D_index_x: "int[:,:]", - D_index_y: "int[:,:]", - D_index_z: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - right_1: "float[:,:,:,:,:,:]", - right_2: "float[:,:,:,:,:,:]", - right_3: "float[:,:,:,:,:,:]", - temp_vector_1: "float[:,:,:]", - temp_vector_2: "float[:,:,:]", - temp_vector_3: "float[:,:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * temp_vector_1[ - D_index_x[ie1, il1], - N_index_y[ie2, il2], - N_index_z[ie3, il3], - ] - ) - - right_1[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * temp_vector_2[ - N_index_x[ie1, il1], - D_index_y[ie2, il2], - N_index_z[ie3, il3], - ] - ) - - right_2[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * temp_vector_3[ - N_index_x[ie1, il1], - N_index_y[ie2, il2], - D_index_z[ie3, il3], - ] - ) - - right_3[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ========================================================================================== -def weight_2( - DF_inv_11: "float[:,:,:,:,:,:]", - DF_inv_12: "float[:,:,:,:,:,:]", - DF_inv_13: "float[:,:,:,:,:,:]", - DF_inv_21: "float[:,:,:,:,:,:]", - DF_inv_22: "float[:,:,:,:,:,:]", - DF_inv_23: "float[:,:,:,:,:,:]", - DF_inv_31: "float[:,:,:,:,:,:]", - DF_inv_32: "float[:,:,:,:,:,:]", - DF_inv_33: "float[:,:,:,:,:,:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - dft: "float[:,:]", - generate_weight1: "float[:]", - generate_weight3: "float[:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - right_1: "float[:,:,:,:,:,:]", - right_2: "float[:,:,:,:,:,:]", - right_3: "float[:,:,:,:,:,:]", - weight1: "float[:,:,:,:,:,:]", - weight2: "float[:,:,:,:,:,:]", - weight3: "float[:,:,:,:,:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, dft, generate_weight1, generate_weight3) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - dft[0, 0] = DF_inv_11[ie1, ie2, ie3, q1, q2, q3] - dft[0, 1] = DF_inv_21[ie1, ie2, ie3, q1, q2, q3] - dft[0, 2] = DF_inv_31[ie1, ie2, ie3, q1, q2, q3] - dft[1, 0] = DF_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[1, 1] = DF_inv_22[ie1, ie2, ie3, q1, q2, q3] - dft[1, 2] = DF_inv_32[ie1, ie2, ie3, q1, q2, q3] - dft[2, 0] = DF_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[2, 1] = DF_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 2] = DF_inv_33[ie1, ie2, ie3, q1, q2, q3] - - generate_weight1[0] = -( - b2value[ie1, ie2, ie3, q1, q2, q3] * right_3[ie1, ie2, ie3, q1, q2, q3] - - b3value[ie1, ie2, ie3, q1, q2, q3] * right_2[ie1, ie2, ie3, q1, q2, q3] - ) - generate_weight1[1] = -( - b3value[ie1, ie2, ie3, q1, q2, q3] * right_1[ie1, ie2, ie3, q1, q2, q3] - - b1value[ie1, ie2, ie3, q1, q2, q3] * right_3[ie1, ie2, ie3, q1, q2, q3] - ) - generate_weight1[2] = -( - b1value[ie1, ie2, ie3, q1, q2, q3] * right_2[ie1, ie2, ie3, q1, q2, q3] - - b2value[ie1, ie2, ie3, q1, q2, q3] * right_1[ie1, ie2, ie3, q1, q2, q3] - ) - linalg.matrix_vector(dft, generate_weight1, generate_weight3) - weight1[ie1, ie2, ie3, q1, q2, q3] = generate_weight3[ - 0 - ] # -(b2value[ie1,ie2,ie3,q1,q2,q3] * right_3[ie1,ie2,ie3,q1,q2,q3] - b3value[ie1,ie2,ie3,q1,q2,q3] * right_2[ie1,ie2,ie3,q1,q2,q3]) - weight2[ie1, ie2, ie3, q1, q2, q3] = generate_weight3[ - 1 - ] # -(b3value[ie1,ie2,ie3,q1,q2,q3] * right_1[ie1,ie2,ie3,q1,q2,q3] - b1value[ie1,ie2,ie3,q1,q2,q3] * right_3[ie1,ie2,ie3,q1,q2,q3]) - weight3[ie1, ie2, ie3, q1, q2, q3] = generate_weight3[ - 2 - ] # -(b1value[ie1,ie2,ie3,q1,q2,q3] * right_2[ie1,ie2,ie3,q1,q2,q3] - b2value[ie1,ie2,ie3,q1,q2,q3] * right_1[ie1,ie2,ie3,q1,q2,q3]) - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def weight_1( - DF_inv_11: "float[:,:,:,:,:,:]", - DF_inv_12: "float[:,:,:,:,:,:]", - DF_inv_13: "float[:,:,:,:,:,:]", - DF_inv_21: "float[:,:,:,:,:,:]", - DF_inv_22: "float[:,:,:,:,:,:]", - DF_inv_23: "float[:,:,:,:,:,:]", - DF_inv_31: "float[:,:,:,:,:,:]", - DF_inv_32: "float[:,:,:,:,:,:]", - DF_inv_33: "float[:,:,:,:,:,:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - dft: "float[:,:]", - generate_weight1: "float[:]", - generate_weight3: "float[:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - right_1: "float[:,:,:,:,:,:]", - right_2: "float[:,:,:,:,:,:]", - right_3: "float[:,:,:,:,:,:]", - weight1: "float[:,:,:,:,:,:]", - weight2: "float[:,:,:,:,:,:]", - weight3: "float[:,:,:,:,:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, dft, generate_weight1, generate_weight3) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - dft[0, 0] = DF_inv_11[ie1, ie2, ie3, q1, q2, q3] - dft[0, 1] = DF_inv_12[ie1, ie2, ie3, q1, q2, q3] - dft[0, 2] = DF_inv_13[ie1, ie2, ie3, q1, q2, q3] - dft[1, 0] = DF_inv_21[ie1, ie2, ie3, q1, q2, q3] - dft[1, 1] = DF_inv_22[ie1, ie2, ie3, q1, q2, q3] - dft[1, 2] = DF_inv_23[ie1, ie2, ie3, q1, q2, q3] - dft[2, 0] = DF_inv_31[ie1, ie2, ie3, q1, q2, q3] - dft[2, 1] = DF_inv_32[ie1, ie2, ie3, q1, q2, q3] - dft[2, 2] = DF_inv_33[ie1, ie2, ie3, q1, q2, q3] - - generate_weight1[0] = right_1[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[1] = right_2[ie1, ie2, ie3, q1, q2, q3] - generate_weight1[2] = right_3[ie1, ie2, ie3, q1, q2, q3] - linalg.matrix_vector(dft, generate_weight1, generate_weight3) - weight1[ie1, ie2, ie3, q1, q2, q3] = ( - b2value[ie1, ie2, ie3, q1, q2, q3] * generate_weight3[2] - - b3value[ie1, ie2, ie3, q1, q2, q3] * generate_weight3[1] - ) - weight2[ie1, ie2, ie3, q1, q2, q3] = ( - b3value[ie1, ie2, ie3, q1, q2, q3] * generate_weight3[0] - - b1value[ie1, ie2, ie3, q1, q2, q3] * generate_weight3[2] - ) - weight3[ie1, ie2, ie3, q1, q2, q3] = ( - b1value[ie1, ie2, ie3, q1, q2, q3] * generate_weight3[1] - - b2value[ie1, ie2, ie3, q1, q2, q3] * generate_weight3[0] - ) - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def final_left( - N_index_x: "int[:,:]", - N_index_y: "int[:,:]", - N_index_z: "int[:,:]", - D_index_x: "int[:,:]", - D_index_y: "int[:,:]", - D_index_z: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - weight1: "float[:,:,:,:,:,:]", - weight2: "float[:,:,:,:,:,:]", - weight3: "float[:,:,:,:,:,:]", - temp_final_1: "float[:,:,:]", - temp_final_2: "float[:,:,:]", - temp_final_3: "float[:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", -): - temp_final_1[:, :, :] = 0.0 - temp_final_2[:, :, :] = 0.0 - temp_final_3[:, :, :] = 0.0 - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_1) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(d3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight1[ie1, ie2, ie3, q1, q2, q3] - * bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - ) - - temp_final_1[N_index_x[ie1, il1], D_index_y[ie2, il2], D_index_z[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_2) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight2[ie1, ie2, ie3, q1, q2, q3] - * bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - ) - - temp_final_2[D_index_x[ie1, il1], N_index_y[ie2, il2], D_index_z[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_3) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(d1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight3[ie1, ie2, ie3, q1, q2, q3] - * bd1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - ) - - temp_final_3[D_index_x[ie1, il1], D_index_y[ie2, il2], N_index_z[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def final_right( - N_index_x: "int[:,:]", - N_index_y: "int[:,:]", - N_index_z: "int[:,:]", - D_index_x: "int[:,:]", - D_index_y: "int[:,:]", - D_index_z: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - weight1: "float[:,:,:,:,:,:]", - weight2: "float[:,:,:,:,:,:]", - weight3: "float[:,:,:,:,:,:]", - temp_final_1: "float[:,:,:]", - temp_final_2: "float[:,:,:]", - temp_final_3: "float[:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", -): - temp_final_1[:, :, :] = 0.0 - temp_final_2[:, :, :] = 0.0 - temp_final_3[:, :, :] = 0.0 - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_1) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight1[ie1, ie2, ie3, q1, q2, q3] - * bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - ) - - temp_final_1[D_index_x[ie1, il1], N_index_y[ie2, il2], N_index_z[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_2) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight2[ie1, ie2, ie3, q1, q2, q3] - * bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - ) - - temp_final_2[N_index_x[ie1, il1], D_index_y[ie2, il2], N_index_z[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_3) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight3[ie1, ie2, ie3, q1, q2, q3] - * bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - ) - - temp_final_3[N_index_x[ie1, il1], N_index_y[ie2, il2], D_index_z[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_massless_linear_operators.py b/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_massless_linear_operators.py deleted file mode 100644 index bdf01bf8b..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_massless_linear_operators.py +++ /dev/null @@ -1,2621 +0,0 @@ -import time - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.feec.massless_operators.fB_bb_kernel as bb_kernel -import struphy.feec.massless_operators.fB_bv_kernel as bv_kernel -import struphy.feec.massless_operators.fB_vv_kernel as vv_kernel - - -class Massless_linear_operators: - """ - Linear operators in substep vv, bb, and bv of fB formulation - Parameters - ---------- - DOMAIN : obj, - Domain object from geometry/domain_3d. - - SPACES : obj, - FEEC self.SPACES., store information of tensor products of B-splines - - KIN : obj, - obj storing information of particles - """ - - def __init__(self, SPACES, DOMAIN, KIN): - self.indN = SPACES.indN - self.indD = SPACES.indD - self.Np_loc = KIN.Np_loc - self.Np = KIN.Np - self.Ntot_1form = SPACES.Ntot_1form - self.Ntot_2form = SPACES.Ntot_2form - self.Nel = SPACES.Nel - self.n_quad = SPACES.n_quad - self.p = SPACES.p - self.d = [self.p[0] - 1, self.p[1] - 1, self.p[2] - 1] - self.basisN = SPACES.basisN - self.basisD = SPACES.basisD - self.Nbase_2form = SPACES.Nbase_2form - self.Ntot_2form = SPACES.Ntot_2form - self.Nbase_1form = SPACES.Nbase_1form - self.Ntot_1form = SPACES.Ntot_1form - self.Nel = SPACES.Nel - self.NbaseN = SPACES.NbaseN - self.NbaseD = SPACES.NbaseD - - def linearoperator_step_vv(self, M2_PRE, M2, M1_PRE, M1, TEMP, ACC_VV): - """ - This function is used in substep vv with L2 projector. - """ - - dft = xp.empty((3, 3), dtype=float) - generate_weight1 = xp.zeros(3, dtype=float) - generate_weight2 = xp.zeros(3, dtype=float) - generate_weight3 = xp.zeros(3, dtype=float) - # =========================inverse of M1 =========================== - ACC_VV.temp1[:], ACC_VV.temp2[:], ACC_VV.temp3[:] = xp.split( - spa.linalg.cg( - M1, - 1.0 / self.Np * xp.concatenate((ACC_VV.vec1.flatten(), ACC_VV.vec2.flatten(), ACC_VV.vec3.flatten())), - tol=10 ** (-14), - M=M1_PRE, - )[0], - [self.Ntot_2form[0], self.Ntot_2form[0] + self.Ntot_2form[1]], - ) - ACC_VV.one_form1[:, :, :] = ACC_VV.temp1.reshape(self.Nbase_1form[0]) - ACC_VV.one_form2[:, :, :] = ACC_VV.temp2.reshape(self.Nbase_1form[1]) - ACC_VV.one_form3[:, :, :] = ACC_VV.temp3.reshape(self.Nbase_1form[2]) - - # ==========================Qvv * vector ============================ - vv_kernel.right_hand( - self.indN[0], - self.indN[1], - self.indN[2], - self.indD[0], - self.indD[1], - self.indD[2], - self.Nel[0], - self.Nel[1], - self.Nel[2], - self.n_quad[0], - self.n_quad[1], - self.n_quad[2], - self.p[0], - self.p[1], - self.p[2], - self.d[0], - self.d[1], - self.d[2], - self.basisN[0], - self.basisN[1], - self.basisN[2], - self.basisD[0], - self.basisD[1], - self.basisD[2], - TEMP.LO_r1, - TEMP.LO_r2, - TEMP.LO_r3, - ACC_VV.one_form1, - ACC_VV.one_form2, - ACC_VV.one_form3, - ) - - vv_kernel.weight( - self.Nel[0], - self.Nel[1], - self.Nel[2], - self.n_quad[0], - self.n_quad[1], - self.n_quad[2], - TEMP.LO_b1, - TEMP.LO_b2, - TEMP.LO_b3, - TEMP.LO_r1, - TEMP.LO_r2, - TEMP.LO_r3, - TEMP.LO_w1, - TEMP.LO_w2, - TEMP.LO_w3, - ) - - vv_kernel.final( - self.indN[0], - self.indN[1], - self.indN[2], - self.indD[0], - self.indD[1], - self.indD[2], - self.Nel[0], - self.Nel[1], - self.Nel[2], - self.n_quad[0], - self.n_quad[1], - self.n_quad[2], - self.p[0], - self.p[1], - self.p[2], - self.d[0], - self.d[1], - self.d[2], - TEMP.LO_w1, - TEMP.LO_w2, - TEMP.LO_w3, - ACC_VV.one_form1, - ACC_VV.one_form2, - ACC_VV.one_form3, - self.basisN[0], - self.basisN[1], - self.basisN[2], - self.basisD[0], - self.basisD[1], - self.basisD[2], - ) - - # =========================inverse of M1 =========================== - ACC_VV.temp1[:], ACC_VV.temp2[:], ACC_VV.temp3[:] = xp.split( - spa.linalg.cg( - M1, - xp.concatenate((ACC_VV.one_form1.flatten(), ACC_VV.one_form2.flatten(), ACC_VV.one_form3.flatten())), - tol=10 ** (-14), - M=M1_PRE, - )[0], - [self.Ntot_1form[0], self.Ntot_1form[0] + self.Ntot_1form[1]], - ) - ACC_VV.coe1[:, :, :] = ACC_VV.temp1.reshape(self.Nbase_1form[0]) - ACC_VV.coe2[:, :, :] = ACC_VV.temp2.reshape(self.Nbase_1form[1]) - ACC_VV.coe3[:, :, :] = ACC_VV.temp3.reshape(self.Nbase_1form[2]) - - def local_linearoperator_step_vv(indN, indD, ACC_VV, M2_PRE, M2, Np, TEMP): - """ - This function is used in substep vv with local projector - """ - # ============= load information about B-splines ============= - p = ACC_VV.p # spline degrees - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D splin degrees - Nel = ACC_VV.Nel # number of elements - n_quad = ACC_VV.tensor_space_FEM.n_quad # number of quadrature points per element - basisN = ACC_VV.tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = ACC_VV.tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - # ========================== - vv_kernel.right_hand( - indN[0], - indN[1], - indN[2], - indD[0], - indD[1], - indD[2], - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - basisN[0], - basisN[1], - basisN[2], - basisD[0], - basisD[1], - basisD[2], - TEMP.right_1, - TEMP.right_2, - TEMP.right_3, - ACC_VV.vec1, - ACC_VV.vec2, - ACC_VV.vec3, - ) - - vv_kernel.weight( - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - TEMP.b1value, - TEMP.b2value, - TEMP.b3value, - TEMP.right_1, - TEMP.right_2, - TEMP.right_3, - TEMP.weight1, - TEMP.weight2, - TEMP.weight3, - ) - - vv_kernel.final( - indN[0], - indN[1], - indN[2], - indD[0], - indD[1], - indD[2], - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - TEMP.weight1, - TEMP.weight2, - TEMP.weight3, - ACC_VV.one_form1, - ACC_VV.one_form2, - ACC_VV.one_form3, - basisN[0], - basisN[1], - basisN[2], - basisD[0], - basisD[1], - basisD[2], - ) - - ACC_VV.coe1[:, :, :] = ACC_VV.one_form1 - ACC_VV.coe2[:, :, :] = ACC_VV.one_form2 - ACC_VV.coe3[:, :, :] = ACC_VV.one_form3 - - def linearoperator_pre_step_vv( - self, - tensor_space_FEM, - df_det, - DFIT_11, - DFIT_12, - DFIT_13, - DFIT_21, - DFIT_22, - DFIT_23, - DFIT_31, - DFIT_32, - DFIT_33, - M2_PRE, - M2, - b1, - b2, - b3, - weight1, - weight2, - weight3, - right_1, - right_2, - right_3, - uvalue, - b1value, - b2value, - b3value, - ): - """ - This function is used in substep vv with L2 projector or local projector. - """ - # =====we can just calculate 3 matrices===== - # ============= load information about B-splines ============= - p = tensor_space_FEM.p # spline degrees - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D splin degrees - Nel = tensor_space_FEM.Nel # number of elements - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - indN = tensor_space_FEM.indN - indD = tensor_space_FEM.indD - - dft = xp.empty((3, 3), dtype=float) - generate_weight1 = xp.zeros(3, dtype=float) - generate_weight2 = xp.zeros(3, dtype=float) - generate_weight3 = xp.zeros(3, dtype=float) - - vv_kernel.prepre( - indN[0], - indN[1], - indN[2], - indD[0], - indD[1], - indD[2], - df_det, - DFIT_11, - DFIT_12, - DFIT_13, - DFIT_21, - DFIT_22, - DFIT_23, - DFIT_31, - DFIT_32, - DFIT_33, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1value, - b2value, - b3value, - uvalue, - b1, - b2, - b3, - dft, - generate_weight1, - generate_weight3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - pts[0], - pts[1], - pts[2], - wts[0], - wts[1], - wts[2], - ) - - def gather(self, index, dt, acc, tensor_space_FEM, domain, particles_loc, Np_loc, Np): - """ - This function is used in substep vv with scatter-gather algorithm. - """ - if index == 1: - vv_kernel.piecewise_gather( - 0.0, - acc.index_shapex, - acc.index_shapey, - acc.index_shapez, - acc.index_diffx, - acc.index_diffy, - acc.index_diffz, - acc.p_shape, - acc.p_size, - acc.n_quad, - tensor_space_FEM.pts[0], - tensor_space_FEM.pts[2], - tensor_space_FEM.pts[2], - tensor_space_FEM.Nel, - particles_loc, - Np_loc, - Np, - acc.gather1_loc, - acc.gather2_loc, - acc.gather3_loc, - acc.mid_particles, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif index == 2: - vv_kernel.piecewise_gather( - 0.5 * dt, - acc.index_shapex, - acc.index_shapey, - acc.index_shapez, - acc.index_diffx, - acc.index_diffy, - acc.index_diffz, - acc.p_shape, - acc.p_size, - acc.n_quad, - tensor_space_FEM.pts[0], - tensor_space_FEM.pts[2], - tensor_space_FEM.pts[2], - tensor_space_FEM.Nel, - particles_loc, - Np_loc, - Np, - acc.gather1_loc, - acc.gather2_loc, - acc.gather3_loc, - acc.stage1_out_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif index == 3: - vv_kernel.piecewise_gather( - 0.5 * dt, - acc.index_shapex, - acc.index_shapey, - acc.index_shapez, - acc.index_diffx, - acc.index_diffy, - acc.index_diffz, - acc.p_shape, - acc.p_size, - acc.n_quad, - tensor_space_FEM.pts[0], - tensor_space_FEM.pts[2], - tensor_space_FEM.pts[2], - tensor_space_FEM.Nel, - particles_loc, - Np_loc, - Np, - acc.gather1_loc, - acc.gather2_loc, - acc.gather3_loc, - acc.stage2_out_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - else: - vv_kernel.piecewise_gather( - dt, - acc.index_shapex, - acc.index_shapey, - acc.index_shapez, - acc.index_diffx, - acc.index_diffy, - acc.index_diffz, - acc.p_shape, - acc.p_size, - acc.n_quad, - tensor_space_FEM.pts[0], - tensor_space_FEM.pts[2], - tensor_space_FEM.pts[2], - tensor_space_FEM.Nel, - particles_loc, - Np_loc, - Np, - acc.gather1_loc, - acc.gather2_loc, - acc.gather3_loc, - acc.stage3_out_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - def scatter_gather_weight(self, acc, tensor_space_FEM, b1value, b2value, b3value): - vv_kernel.weight( - tensor_space_FEM.Nel[0], - tensor_space_FEM.Nel[1], - tensor_space_FEM.Nel[2], - acc.n_quad[0], - acc.n_quad[1], - acc.n_quad[2], - b1value, - b2value, - b3value, - acc.gather1, - acc.gather2, - acc.gather3, - acc.weight1, - acc.weight2, - acc.weight3, - ) - - def scatter(self, index, acc, tensor_space_FEM, domain, particles_loc, Np_loc, Np): - """ - This function is used in substep vv with scatter-gather algorithm. - """ - if index == 1: - vv_kernel.piecewise_scatter( - acc.index_shapex, - acc.index_shapey, - acc.index_shapez, - acc.index_diffx, - acc.index_diffy, - acc.index_diffz, - acc.p_shape, - acc.p_size, - acc.stage1_out_loc, - tensor_space_FEM.Nel, - Np_loc, - Np, - acc.weight1, - acc.weight2, - acc.weight3, - tensor_space_FEM.pts[0], - tensor_space_FEM.pts[1], - tensor_space_FEM.pts[2], - tensor_space_FEM.n_quad, - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif index == 2: - vv_kernel.piecewise_scatter( - acc.index_shapex, - acc.index_shapey, - acc.index_shapez, - acc.index_diffx, - acc.index_diffy, - acc.index_diffz, - acc.p_shape, - acc.p_size, - acc.stage2_out_loc, - tensor_space_FEM.Nel, - Np_loc, - Np, - acc.weight1, - acc.weight2, - acc.weight3, - tensor_space_FEM.pts[0], - tensor_space_FEM.pts[1], - tensor_space_FEM.pts[2], - tensor_space_FEM.n_quad, - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif index == 3: - vv_kernel.piecewise_scatter( - acc.index_shapex, - acc.index_shapey, - acc.index_shapez, - acc.index_diffx, - acc.index_diffy, - acc.index_diffz, - acc.p_shape, - acc.p_size, - acc.stage3_out_loc, - tensor_space_FEM.Nel, - Np_loc, - Np, - acc.weight1, - acc.weight2, - acc.weight3, - tensor_space_FEM.pts[0], - tensor_space_FEM.pts[1], - tensor_space_FEM.pts[2], - tensor_space_FEM.n_quad, - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - else: - vv_kernel.piecewise_scatter( - acc.index_shapex, - acc.index_shapey, - acc.index_shapez, - acc.index_diffx, - acc.index_diffy, - acc.index_diffz, - acc.p_shape, - acc.p_size, - acc.stage4_out_loc, - tensor_space_FEM.Nel, - Np_loc, - Np, - acc.weight1, - acc.weight2, - acc.weight3, - tensor_space_FEM.pts[0], - tensor_space_FEM.pts[1], - tensor_space_FEM.pts[2], - tensor_space_FEM.n_quad, - particles_loc, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - def linearoperator_step3( - self, - twoform_temp1_long, - twoform_temp2_long, - twoform_temp3_long, - temp_vector_1, - temp_vector_2, - temp_vector_3, - idn, - idd, - tensor_space_FEM, - dt, - input_vector, - b1, - b2, - b3, - weight1, - weight2, - weight3, - right_1, - right_2, - right_3, - uvalue, - b1value, - b2value, - b3value, - ): - """ - This function is used in substep bb. - """ - # ============= load information about B-splines ============= - p = tensor_space_FEM.p # spline degrees - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D spline degrees - Nel = tensor_space_FEM.Nel # number of elements - NbaseN = tensor_space_FEM.NbaseN # total number of basis functions (N) - NbaseD = tensor_space_FEM.NbaseD # total number of basis functions (D) - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - Ntot_2form = tensor_space_FEM.Ntot_2form - Nbase_2form = tensor_space_FEM.Nbase_2form - - dft = xp.empty((3, 3), dtype=float) - generate_weight1 = xp.empty(3, dtype=float) - generate_weight2 = xp.empty(3, dtype=float) - generate_weight3 = xp.empty(3, dtype=float) - - # ================================================================== - # ========================= C =========================== - # time1 = time.time() - twoform_temp1_long[:], twoform_temp2_long[:], twoform_temp3_long[:] = xp.split( - tensor_space_FEM.C.dot(input_vector), - [Ntot_2form[0], Ntot_2form[0] + Ntot_2form[1]], - ) - temp_vector_1[:, :, :] = twoform_temp1_long.reshape(Nbase_2form[0]) - temp_vector_2[:, :, :] = twoform_temp2_long.reshape(Nbase_2form[1]) - temp_vector_3[:, :, :] = twoform_temp3_long.reshape(Nbase_2form[2]) - # time2 = time.time() - # print('curl_time', time2 - time1) - # ==========================Q5 * vector ============================ - time1 = time.time() - bb_kernel.right_hand( - idn[0], - idn[1], - idn[2], - idd[0], - idd[1], - idd[2], - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - right_1, - right_2, - right_3, - temp_vector_1, - temp_vector_2, - temp_vector_3, - ) - time2 = time.time() - # print('right_hand_time', time2 - time1) - # time1 = time.time() - bb_kernel.weight( - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - b1value, - b2value, - b3value, - right_1, - right_2, - right_3, - weight1, - weight2, - weight3, - ) - # time2 = time.time() - # print('weight_time', time2 - time1) - # time1 = time.time() - bb_kernel.final( - idn[0], - idn[1], - idn[2], - idd[0], - idd[1], - idd[2], - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - temp_vector_1, - temp_vector_2, - temp_vector_3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - # time2 = time.time() - # print('time_final', time2 - time1) - # ========================= C.T =========================== - # time1 = time.time() - temp_final = tensor_space_FEM.M1.dot(input_vector) - dt / 2.0 * tensor_space_FEM.C.T.dot( - xp.concatenate((temp_vector_1.flatten(), temp_vector_2.flatten(), temp_vector_3.flatten())), - ) - # time2 = time.time() - # print('second_curl_time', time2 - time1) - # print('gmres_number', 1) - return temp_final - - def linearoperator_pre_step3(self, LO_inv, tensor_space_FEM): - """ - This function is used in substep bb. - """ - # ============= load information about B-splines ============= - p = tensor_space_FEM.p # spline degrees - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D spline degrees - Nel = tensor_space_FEM.Nel # number of elements - NbaseN = tensor_space_FEM.NbaseN # total number of basis functions (N) - NbaseD = tensor_space_FEM.NbaseD # total number of basis functions (D) - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - bb_kernel.pre( - tensor_space_FEM.indN[0], - tensor_space_FEM.indN[1], - tensor_space_FEM.indN[2], - tensor_space_FEM.indD[0], - tensor_space_FEM.indD[1], - tensor_space_FEM.indD[2], - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - LO_inv, - basisN[0], - basisN[1], - basisN[2], - ) - - def linearoperator_right_step3( - self, - twoform_temp1_long, - twoform_temp2_long, - twoform_temp3_long, - temp_vector_1, - temp_vector_2, - temp_vector_3, - idn, - idd, - tensor_space_FEM, - G_inv_11, - G_inv_12, - G_inv_13, - G_inv_22, - G_inv_23, - G_inv_33, - dt, - input_vector, - b1, - b2, - b3, - weight1, - weight2, - weight3, - right_1, - right_2, - right_3, - uvalue, - b1value, - b2value, - b3value, - ): - """ - This function is used in substep bb. - """ - # ============= load information about B-splines ============= - p = tensor_space_FEM.p # spline degrees - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D splin degrees - Nel = tensor_space_FEM.Nel # number of elements - NbaseN = tensor_space_FEM.NbaseN # total number of basis functions (N) - NbaseD = tensor_space_FEM.NbaseD # total number of basis functions (D) - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - Ntot_2form = tensor_space_FEM.Ntot_2form - Nbase_2form = tensor_space_FEM.Nbase_2form - - dft = xp.empty((3, 3), dtype=float) - generate_weight1 = xp.empty(3, dtype=float) - generate_weight2 = xp.empty(3, dtype=float) - generate_weight3 = xp.empty(3, dtype=float) - - # ================================================================== - # ========================= C =========================== - twoform_temp1_long[:], twoform_temp2_long[:], twoform_temp3_long[:] = xp.split( - tensor_space_FEM.C.dot(input_vector), - [Ntot_2form[0], Ntot_2form[0] + Ntot_2form[1]], - ) - temp_vector_1[:, :, :] = twoform_temp1_long.reshape(Nbase_2form[0]) - temp_vector_2[:, :, :] = twoform_temp2_long.reshape(Nbase_2form[1]) - temp_vector_3[:, :, :] = twoform_temp3_long.reshape(Nbase_2form[2]) - # ==========================Q5 * vector ============================ - # time1 = time.time() - bb_kernel.right_hand( - idn[0], - idn[1], - idn[2], - idd[0], - idd[1], - idd[2], - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - right_1, - right_2, - right_3, - temp_vector_1, - temp_vector_2, - temp_vector_3, - ) - # time2 = time.time() - # print('right_hand_bb', time2 - time1) - # time1 = time.time() - bb_kernel.bvalue( - idn[0], - idn[1], - idn[2], - idd[0], - idd[1], - idd[2], - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1, - b2, - b3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - b1value, - b2value, - b3value, - temp_vector_1, - temp_vector_2, - temp_vector_3, - ) - # time2 = time.time() - # print('bvalue_time_bb', time2 - time1) - # time1 = time.time() - bb_kernel.right_bwvalue( - G_inv_11, - G_inv_12, - G_inv_13, - G_inv_22, - G_inv_23, - G_inv_33, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - dft, - pts[0], - pts[1], - pts[2], - wts[0], - wts[1], - wts[2], - generate_weight1, - generate_weight2, - generate_weight3, - b1value, - b2value, - b3value, - uvalue, - weight1, - weight2, - weight3, - right_1, - right_2, - right_3, - ) - # time2 = time.time() - # print('bwvalue_time_bb', time2 - time1) - # time1 = time.time() - bb_kernel.final( - idn[0], - idn[1], - idn[2], - idd[0], - idd[1], - idd[2], - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - temp_vector_1, - temp_vector_2, - temp_vector_3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - # time2 = time.time() - # print('final_bb', time2 - time1) - # ========================= C.T =========================== - temp_final = tensor_space_FEM.M1.dot(input_vector) + dt / 2.0 * tensor_space_FEM.C.T.dot( - xp.concatenate((temp_vector_1.flatten(), temp_vector_2.flatten(), temp_vector_3.flatten())), - ) - - return temp_final - - # ========================================================================================================== - def substep4_linear_operator( - self, - acc, - dft, - generate_weight1, - generate_weight3, - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - M1, - M1_PRE, - CURL, - mat, - input, - tensor_space_FEM, - Ntot_2form, - Ntot_1form, - Nbase_2form, - Nbase_1form, - weight1, - weight2, - weight3, - right_1, - right_2, - right_3, - b1value, - b2value, - b3value, - dt, - kind_map, - params_map, - ): - """ - This function is used in substep bv with L2 projector. - """ - # input: b1value, b2value, b3value (as weight), bb1, bb2, bb3 (as right hand vector) - - p = tensor_space_FEM.p # spline degrees - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D spline degrees - Nel = tensor_space_FEM.Nel # number of elements - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - # ========================================== - acc.twoform_temp1_long[:], acc.twoform_temp2_long[:], acc.twoform_temp3_long[:] = xp.split( - tensor_space_FEM.C.dot(input), - [Ntot_2form[0], Ntot_2form[0] + Ntot_2form[1]], - ) - acc.twoform_temp1[:, :, :] = acc.twoform_temp1_long.reshape(Nbase_2form[0]) - acc.twoform_temp2[:, :, :] = acc.twoform_temp2_long.reshape(Nbase_2form[1]) - acc.twoform_temp3[:, :, :] = acc.twoform_temp3_long.reshape(Nbase_2form[2]) - bv_kernel.right_hand2( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - right_1, - right_2, - right_3, - acc.twoform_temp1, - acc.twoform_temp2, - acc.twoform_temp3, - ) - bv_kernel.weight_2( - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - pts[0], - pts[1], - pts[2], - dft, - generate_weight1, - generate_weight3, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - b1value, - b2value, - b3value, - right_1, - right_2, - right_3, - weight1, - weight2, - weight3, - ) - bv_kernel.final_right( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - acc.oneform_temp1, - acc.oneform_temp2, - acc.oneform_temp3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - acc.oneform_temp_long[:] = spa.linalg.gmres( - M1, - xp.concatenate((acc.oneform_temp1.flatten(), acc.oneform_temp2.flatten(), acc.oneform_temp3.flatten())), - tol=10 ** (-10), - M=M1_PRE, - )[0] - - acc.oneform_temp1_long[:], acc.oneform_temp2_long[:], acc.oneform_temp3_long[:] = xp.split( - spa.linalg.gmres(M1, mat.dot(acc.oneform_temp_long), tol=10 ** (-10), M=M1_PRE)[0], - [Ntot_1form[0], Ntot_1form[0] + Ntot_1form[1]], - ) - acc.oneform_temp1[:, :, :] = acc.oneform_temp1_long.reshape(Nbase_1form[0]) - acc.oneform_temp2[:, :, :] = acc.oneform_temp2_long.reshape(Nbase_1form[1]) - acc.oneform_temp3[:, :, :] = acc.oneform_temp3_long.reshape(Nbase_1form[2]) - bv_kernel.right_hand1( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - right_1, - right_2, - right_3, - acc.oneform_temp1, - acc.oneform_temp2, - acc.oneform_temp3, - ) - bv_kernel.weight_1( - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - pts[0], - pts[1], - pts[2], - dft, - generate_weight1, - generate_weight3, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - b1value, - b2value, - b3value, - right_1, - right_2, - right_3, - weight1, - weight2, - weight3, - ) - bv_kernel.final_left( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - acc.twoform_temp1, - acc.twoform_temp2, - acc.twoform_temp3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - - return M1.dot(input) + dt**2 / 4.0 * tensor_space_FEM.C.T.dot( - xp.concatenate((acc.twoform_temp1.flatten(), acc.twoform_temp2.flatten(), acc.twoform_temp3.flatten())), - ) - - # ========================================================================================================== - def substep4_linear_operator_right( - self, - acc, - dft, - generate_weight1, - generate_weight3, - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - M1, - M1_PRE, - CURL, - mat, - bb1, - bb2, - bb3, - tensor_space_FEM, - Ntot_2form, - Ntot_1form, - Nbase_2form, - Nbase_1form, - weight1, - weight2, - weight3, - right_1, - right_2, - right_3, - b1value, - b2value, - b3value, - vec, - dt, - kind_map, - params_map, - ): - """ - This function is used in substep bv with L2 projector. - """ - - p = tensor_space_FEM.p # spline degrees - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D spline degrees - Nel = tensor_space_FEM.Nel # number of elements - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - # ========================================== - acc.twoform_temp1_long[:], acc.twoform_temp2_long[:], acc.twoform_temp3_long[:] = xp.split( - CURL.dot(xp.concatenate((bb1.flatten(), bb2.flatten(), bb3.flatten()))), - [Ntot_2form[0], Ntot_2form[0] + Ntot_2form[1]], - ) - acc.twoform_temp1[:, :, :] = acc.twoform_temp1_long.reshape(Nbase_2form[0]) - acc.twoform_temp2[:, :, :] = acc.twoform_temp2_long.reshape(Nbase_2form[1]) - acc.twoform_temp3[:, :, :] = acc.twoform_temp3_long.reshape(Nbase_2form[2]) - - bv_kernel.right_hand2( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - right_1, - right_2, - right_3, - acc.twoform_temp1, - acc.twoform_temp2, - acc.twoform_temp3, - ) - bv_kernel.weight_2( - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - pts[0], - pts[1], - pts[2], - dft, - generate_weight1, - generate_weight3, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - b1value, - b2value, - b3value, - right_1, - right_2, - right_3, - weight1, - weight2, - weight3, - ) - bv_kernel.final_right( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - acc.oneform_temp1, - acc.oneform_temp2, - acc.oneform_temp3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - acc.oneform_temp_long[:] = mat.dot( - spa.linalg.gmres( - M1, - xp.concatenate((acc.oneform_temp1.flatten(), acc.oneform_temp2.flatten(), acc.oneform_temp3.flatten())), - tol=10 ** (-10), - M=M1_PRE, - )[0], - ) - - acc.oneform_temp1_long[:], acc.oneform_temp2_long[:], acc.oneform_temp3_long[:] = xp.split( - spa.linalg.gmres(M1, dt**2.0 / 4.0 * acc.oneform_temp_long + dt * vec, tol=10 ** (-10), M=M1_PRE)[0], - [Ntot_1form[0], Ntot_1form[0] + Ntot_1form[1]], - ) - acc.oneform_temp1[:, :, :] = acc.oneform_temp1_long.reshape(Nbase_1form[0]) - acc.oneform_temp2[:, :, :] = acc.oneform_temp2_long.reshape(Nbase_1form[1]) - acc.oneform_temp3[:, :, :] = acc.oneform_temp3_long.reshape(Nbase_1form[2]) - bv_kernel.right_hand1( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - right_1, - right_2, - right_3, - acc.oneform_temp1, - acc.oneform_temp2, - acc.oneform_temp3, - ) - bv_kernel.weight_1( - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - pts[0], - pts[1], - pts[2], - dft, - generate_weight1, - generate_weight3, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - b1value, - b2value, - b3value, - right_1, - right_2, - right_3, - weight1, - weight2, - weight3, - ) - bv_kernel.final_left( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - acc.twoform_temp1, - acc.twoform_temp2, - acc.twoform_temp3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - - return M1.dot(xp.concatenate((bb1.flatten(), bb2.flatten(), bb3.flatten()))) - CURL.T.dot( - xp.concatenate((acc.twoform_temp1.flatten(), acc.twoform_temp2.flatten(), acc.twoform_temp3.flatten())), - ) - - # ========================================================================================================== - def substep4_pre( - self, - df_det, - dft, - generate_weight1, - generate_weight3, - G_inv_11, - G_inv_12, - G_inv_13, - G_inv_22, - G_inv_23, - G_inv_33, - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - bb1, - bb2, - bb3, - tensor_space_FEM, - b1value, - b2value, - b3value, - uvalue, - kind_map, - params_map, - ): - """ - This function is used in substep bv L2 projector or local projector. - """ - p = tensor_space_FEM.p # spline degrees - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D spline degrees - Nel = tensor_space_FEM.Nel # number of elements - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - bv_kernel.prepre( - df_det, - G_inv_11, - G_inv_12, - G_inv_13, - G_inv_22, - G_inv_23, - G_inv_33, - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - b1value, - b2value, - b3value, - uvalue, - bb1, - bb2, - bb3, - dft, - generate_weight1, - generate_weight3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - pts[0], - pts[1], - pts[2], - wts[0], - wts[1], - wts[2], - ) - - # ========================================================================================================== - def substep4_pusher_field( - self, - acc, - dft, - generate_weight1, - generate_weight3, - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - M1, - M1_PRE, - CURL, - mat, - bb1, - bb2, - bb3, - tensor_space_FEM, - Ntot_2form, - Nbase_2form, - Nbase_1form, - weight1, - weight2, - weight3, - right_1, - right_2, - right_3, - b1value, - b2value, - b3value, - vec, - dt, - kind_map, - params_map, - ): - """ - This function is used in substep bv with L2 projector. - """ - - p = tensor_space_FEM.p # spline degrees - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D spline degrees - Nel = tensor_space_FEM.Nel # number of elements - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - # ========================================== - acc.twoform_temp1_long[:], acc.twoform_temp2_long[:], acc.twoform_temp3_long[:] = xp.split( - CURL.dot(xp.concatenate((bb1.flatten(), bb2.flatten(), bb3.flatten()))), - [Ntot_2form[0], Ntot_2form[0] + Ntot_2form[1]], - ) - acc.twoform_temp1[:, :, :] = acc.twoform_temp1_long.reshape(Nbase_2form[0]) - acc.twoform_temp2[:, :, :] = acc.twoform_temp2_long.reshape(Nbase_2form[1]) - acc.twoform_temp3[:, :, :] = acc.twoform_temp3_long.reshape(Nbase_2form[2]) - bv_kernel.right_hand2( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - right_1, - right_2, - right_3, - acc.twoform_temp1, - acc.twoform_temp2, - acc.twoform_temp3, - ) - bv_kernel.weight_2( - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - pts[0], - pts[1], - pts[2], - dft, - generate_weight1, - generate_weight3, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - b1value, - b2value, - b3value, - right_1, - right_2, - right_3, - weight1, - weight2, - weight3, - ) - bv_kernel.final_right( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - acc.oneform_temp1, - acc.oneform_temp2, - acc.oneform_temp3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - - return spa.linalg.cg( - M1, - xp.concatenate((acc.oneform_temp1.flatten(), acc.oneform_temp2.flatten(), acc.oneform_temp3.flatten())), - tol=10 ** (-13), - M=M1_PRE, - )[0] - - # ========================================================================================================== - def substep4_localproj_linear_operator( - self, - acc, - dft, - generate_weight1, - generate_weight3, - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - M1, - M1_PRE, - CURL, - mat, - input, - tensor_space_FEM, - Ntot_2form, - Ntot_1form, - Nbase_2form, - Nbase_1form, - weight1, - weight2, - weight3, - right_1, - right_2, - right_3, - b1value, - b2value, - b3value, - dt, - kind_map, - params_map, - ): - """ - This function is used in substep bv with local projector. - """ - - p = tensor_space_FEM.p # spline degrees - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D spline degrees - Nel = tensor_space_FEM.Nel # number of elements - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - # ========================================== - acc.twoform_temp1_long[:], acc.twoform_temp2_long[:], acc.twoform_temp3_long[:] = xp.split( - tensor_space_FEM.C.dot(input), - [Ntot_2form[0], Ntot_2form[0] + Ntot_2form[1]], - ) - acc.twoform_temp1[:, :, :] = acc.twoform_temp1_long.reshape(Nbase_2form[0]) - acc.twoform_temp2[:, :, :] = acc.twoform_temp2_long.reshape(Nbase_2form[1]) - acc.twoform_temp3[:, :, :] = acc.twoform_temp3_long.reshape(Nbase_2form[2]) - bv_kernel.right_hand2( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - right_1, - right_2, - right_3, - acc.twoform_temp1, - acc.twoform_temp2, - acc.twoform_temp3, - ) - bv_kernel.weight_2( - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - pts[0], - pts[1], - pts[2], - dft, - generate_weight1, - generate_weight3, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - b1value, - b2value, - b3value, - right_1, - right_2, - right_3, - weight1, - weight2, - weight3, - ) - bv_kernel.final_right( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - acc.oneform_temp1, - acc.oneform_temp2, - acc.oneform_temp3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - - acc.oneform_temp1_long[:], acc.oneform_temp2_long[:], acc.oneform_temp3_long[:] = xp.split( - mat.dot( - xp.concatenate((acc.oneform_temp1.flatten(), acc.oneform_temp2.flatten(), acc.oneform_temp3.flatten())), - ), - [Ntot_1form[0], Ntot_1form[0] + Ntot_1form[1]], - ) - - acc.oneform_temp1[:, :, :] = acc.oneform_temp1_long.reshape(Nbase_1form[0]) - acc.oneform_temp2[:, :, :] = acc.oneform_temp2_long.reshape(Nbase_1form[1]) - acc.oneform_temp3[:, :, :] = acc.oneform_temp3_long.reshape(Nbase_1form[2]) - bv_kernel.right_hand1( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - right_1, - right_2, - right_3, - acc.oneform_temp1, - acc.oneform_temp2, - acc.oneform_temp3, - ) - bv_kernel.weight_1( - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - pts[0], - pts[1], - pts[2], - dft, - generate_weight1, - generate_weight3, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - b1value, - b2value, - b3value, - right_1, - right_2, - right_3, - weight1, - weight2, - weight3, - ) - bv_kernel.final_left( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - acc.twoform_temp1, - acc.twoform_temp2, - acc.twoform_temp3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - - return M1.dot(input) + dt**2 / 4.0 * tensor_space_FEM.C.T.dot( - xp.concatenate((acc.twoform_temp1.flatten(), acc.twoform_temp2.flatten(), acc.twoform_temp3.flatten())), - ) - - # ========================================================================================================== - def substep4_localproj_linear_operator_right( - self, - acc, - dft, - generate_weight1, - generate_weight3, - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - M1, - M1_PRE, - CURL, - mat, - bb1, - bb2, - bb3, - tensor_space_FEM, - Ntot_2form, - Ntot_1form, - Nbase_2form, - Nbase_1form, - weight1, - weight2, - weight3, - right_1, - right_2, - right_3, - b1value, - b2value, - b3value, - vec, - dt, - kind_map, - params_map, - ): - """ - This function is used in substep bv with local projector. - """ - - p = tensor_space_FEM.p # spline degrees - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D spline degrees - Nel = tensor_space_FEM.Nel # number of elements - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - # ========================================== - acc.twoform_temp1_long[:], acc.twoform_temp2_long[:], acc.twoform_temp3_long[:] = xp.split( - CURL.dot(xp.concatenate((bb1.flatten(), bb2.flatten(), bb3.flatten()))), - [Ntot_2form[0], Ntot_2form[0] + Ntot_2form[1]], - ) - acc.twoform_temp1[:, :, :] = acc.twoform_temp1_long.reshape(Nbase_2form[0]) - acc.twoform_temp2[:, :, :] = acc.twoform_temp2_long.reshape(Nbase_2form[1]) - acc.twoform_temp3[:, :, :] = acc.twoform_temp3_long.reshape(Nbase_2form[2]) - - bv_kernel.right_hand2( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - right_1, - right_2, - right_3, - acc.twoform_temp1, - acc.twoform_temp2, - acc.twoform_temp3, - ) - bv_kernel.weight_2( - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - pts[0], - pts[1], - pts[2], - dft, - generate_weight1, - generate_weight3, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - b1value, - b2value, - b3value, - right_1, - right_2, - right_3, - weight1, - weight2, - weight3, - ) - bv_kernel.final_right( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - acc.oneform_temp1, - acc.oneform_temp2, - acc.oneform_temp3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - acc.oneform_temp_long[:] = mat.dot( - xp.concatenate((acc.oneform_temp1.flatten(), acc.oneform_temp2.flatten(), acc.oneform_temp3.flatten())), - ) - - acc.oneform_temp1_long[:], acc.oneform_temp2_long[:], acc.oneform_temp3_long[:] = xp.split( - (dt**2.0 / 4.0 * acc.oneform_temp_long + dt * vec), - [Ntot_1form[0], Ntot_1form[0] + Ntot_1form[1]], - ) - - acc.oneform_temp1[:, :, :] = acc.oneform_temp1_long.reshape(Nbase_1form[0]) - acc.oneform_temp2[:, :, :] = acc.oneform_temp2_long.reshape(Nbase_1form[1]) - acc.oneform_temp3[:, :, :] = acc.oneform_temp3_long.reshape(Nbase_1form[2]) - bv_kernel.right_hand1( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - right_1, - right_2, - right_3, - acc.oneform_temp1, - acc.oneform_temp2, - acc.oneform_temp3, - ) - bv_kernel.weight_1( - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - pts[0], - pts[1], - pts[2], - dft, - generate_weight1, - generate_weight3, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - b1value, - b2value, - b3value, - right_1, - right_2, - right_3, - weight1, - weight2, - weight3, - ) - bv_kernel.final_left( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - acc.twoform_temp1, - acc.twoform_temp2, - acc.twoform_temp3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - - return M1.dot(xp.concatenate((bb1.flatten(), bb2.flatten(), bb3.flatten()))) - CURL.T.dot( - xp.concatenate((acc.twoform_temp1.flatten(), acc.twoform_temp2.flatten(), acc.twoform_temp3.flatten())), - ) - - # ========================================================================================================== - def substep4_localproj_pusher_field( - self, - acc, - dft, - generate_weight1, - generate_weight3, - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - M1, - M1_PRE, - CURL, - mat, - bb1, - bb2, - bb3, - tensor_space_FEM, - Ntot_2form, - Nbase_2form, - Nbase_1form, - weight1, - weight2, - weight3, - right_1, - right_2, - right_3, - b1value, - b2value, - b3value, - vec, - dt, - kind_map, - params_map, - ): - """ - This function is used in substep bv with local projector. - """ - - p = tensor_space_FEM.p # spline degrees - d = [p[0] - 1, p[1] - 1, p[2] - 1] # D spline degrees - Nel = tensor_space_FEM.Nel # number of elements - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - # ========================================== - acc.twoform_temp1_long[:], acc.twoform_temp2_long[:], acc.twoform_temp3_long[:] = xp.split( - CURL.dot(xp.concatenate((bb1.flatten(), bb2.flatten(), bb3.flatten()))), - [Ntot_2form[0], Ntot_2form[0] + Ntot_2form[1]], - ) - acc.twoform_temp1[:, :, :] = acc.twoform_temp1_long.reshape(Nbase_2form[0]) - acc.twoform_temp2[:, :, :] = acc.twoform_temp2_long.reshape(Nbase_2form[1]) - acc.twoform_temp3[:, :, :] = acc.twoform_temp3_long.reshape(Nbase_2form[2]) - bv_kernel.right_hand2( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - right_1, - right_2, - right_3, - acc.twoform_temp1, - acc.twoform_temp2, - acc.twoform_temp3, - ) - bv_kernel.weight_2( - DF_inv_11, - DF_inv_12, - DF_inv_13, - DF_inv_21, - DF_inv_22, - DF_inv_23, - DF_inv_31, - DF_inv_32, - DF_inv_33, - pts[0], - pts[1], - pts[2], - dft, - generate_weight1, - generate_weight3, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - b1value, - b2value, - b3value, - right_1, - right_2, - right_3, - weight1, - weight2, - weight3, - ) - bv_kernel.final_right( - N_index_x, - N_index_y, - N_index_z, - D_index_x, - D_index_y, - D_index_z, - Nel[0], - Nel[1], - Nel[2], - n_quad[0], - n_quad[1], - n_quad[2], - p[0], - p[1], - p[2], - d[0], - d[1], - d[2], - weight1, - weight2, - weight3, - acc.oneform_temp1, - acc.oneform_temp2, - acc.oneform_temp3, - tensor_space_FEM.basisN[0], - tensor_space_FEM.basisN[1], - tensor_space_FEM.basisN[2], - tensor_space_FEM.basisD[0], - tensor_space_FEM.basisD[1], - tensor_space_FEM.basisD[2], - ) - - return xp.concatenate((acc.oneform_temp1.flatten(), acc.oneform_temp2.flatten(), acc.oneform_temp3.flatten())) diff --git a/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_vv_kernel.py b/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_vv_kernel.py deleted file mode 100644 index 1ef3376dc..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/massless_operators/fB_vv_kernel.py +++ /dev/null @@ -1,824 +0,0 @@ -import cunumpy as xp -from numpy import empty, exp, floor, zeros - -import struphy.bsplines.bsplines_kernels as bsp -import struphy.geometry.mappings_kernels as mapping_fast -import struphy.linear_algebra.linalg_kernels as linalg - - -# ========================================================================================== -def right_hand( - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - right_1: "float[:,:,:,:,:,:]", - right_2: "float[:,:,:,:,:,:]", - right_3: "float[:,:,:,:,:,:]", - temp_vector_1: "float[:,:,:]", - temp_vector_2: "float[:,:,:]", - temp_vector_3: "float[:,:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * temp_vector_1[iddx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] - ) - - right_1[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * temp_vector_2[idnx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] - ) - - right_2[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * temp_vector_3[idnx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] - ) - - right_3[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ========================================================================================== -def weight( - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - right_1: "float[:,:,:,:,:,:]", - right_2: "float[:,:,:,:,:,:]", - right_3: "float[:,:,:,:,:,:]", - weight1: "float[:,:,:,:,:,:]", - weight2: "float[:,:,:,:,:,:]", - weight3: "float[:,:,:,:,:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - weight1[ie1, ie2, ie3, q1, q2, q3] = ( - b2value[ie1, ie2, ie3, q1, q2, q3] * right_3[ie1, ie2, ie3, q1, q2, q3] - - b3value[ie1, ie2, ie3, q1, q2, q3] * right_2[ie1, ie2, ie3, q1, q2, q3] - ) - weight2[ie1, ie2, ie3, q1, q2, q3] = ( - b3value[ie1, ie2, ie3, q1, q2, q3] * right_1[ie1, ie2, ie3, q1, q2, q3] - - b1value[ie1, ie2, ie3, q1, q2, q3] * right_3[ie1, ie2, ie3, q1, q2, q3] - ) - weight3[ie1, ie2, ie3, q1, q2, q3] = ( - b1value[ie1, ie2, ie3, q1, q2, q3] * right_2[ie1, ie2, ie3, q1, q2, q3] - - b2value[ie1, ie2, ie3, q1, q2, q3] * right_1[ie1, ie2, ie3, q1, q2, q3] - ) - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def final( - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - weight1: "float[:,:,:,:,:,:]", - weight2: "float[:,:,:,:,:,:]", - weight3: "float[:,:,:,:,:,:]", - temp_final_1: "float[:,:,:]", - temp_final_2: "float[:,:,:]", - temp_final_3: "float[:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", -): - temp_final_1[:, :, :] = 0.0 - temp_final_2[:, :, :] = 0.0 - temp_final_3[:, :, :] = 0.0 - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_1) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight1[ie1, ie2, ie3, q1, q2, q3] - * bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - ) - - temp_final_1[iddx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_2) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight2[ie1, ie2, ie3, q1, q2, q3] - * bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - ) - - temp_final_2[idnx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : temp_final_3) private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value = 0.0 - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value += ( - weight3[ie1, ie2, ie3, q1, q2, q3] - * bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - ) - - temp_final_3[idnx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] += value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================== -def prepre( - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - det_df: "float[:,:,:,:,:,:]", - DFIT_11: "float[:,:,:,:,:,:]", - DFIT_12: "float[:,:,:,:,:,:]", - DFIT_13: "float[:,:,:,:,:,:]", - DFIT_21: "float[:,:,:,:,:,:]", - DFIT_22: "float[:,:,:,:,:,:]", - DFIT_23: "float[:,:,:,:,:,:]", - DFIT_31: "float[:,:,:,:,:,:]", - DFIT_32: "float[:,:,:,:,:,:]", - DFIT_33: "float[:,:,:,:,:,:]", - nel1: "int", - nel2: "int", - nel3: "int", - nq1: "int", - nq2: "int", - nq3: "int", - p1: "int", - p2: "int", - p3: "int", - d1: "int", - d2: "int", - d3: "int", - b1value: "float[:,:,:,:,:,:]", - b2value: "float[:,:,:,:,:,:]", - b3value: "float[:,:,:,:,:,:]", - uvalue: "float[:,:,:,:,:,:]", - b1: "float[:,:,:]", - b2: "float[:,:,:]", - b3: "float[:,:,:]", - dft: "float[:,:]", - generate_weight1: "float[:]", - generate_weight3: "float[:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", -): - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(d1 + 1): - for il2 in range(p2 + 1): - for il3 in range(p3 + 1): - value += ( - bd1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b1[iddx[ie1, il1], idny[ie2, il2], idnz[ie3, il3]] - ) - - b1value[ie1, ie2, ie3, q1, q2, q3] = value - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(d2 + 1): - for il3 in range(p3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bd2[ie2, il2, 0, q2] - * bn3[ie3, il3, 0, q3] - * b2[idnx[ie1, il1], iddy[ie2, il2], idnz[ie3, il3]] - ) - - b2value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, il1, il2, il3, value) - - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - value = 0.0 - for il1 in range(p1 + 1): - for il2 in range(p2 + 1): - for il3 in range(d3 + 1): - value += ( - bn1[ie1, il1, 0, q1] - * bn2[ie2, il2, 0, q2] - * bd3[ie3, il3, 0, q3] - * b3[idnx[ie1, il1], idny[ie2, il2], iddz[ie3, il3]] - ) - - b3value[ie1, ie2, ie3, q1, q2, q3] = value - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ie1, ie2, ie3, q1, q2, q3, detdet) - for ie1 in range(nel1): - for ie2 in range(nel2): - for ie3 in range(nel3): - for q1 in range(nq1): - for q2 in range(nq2): - for q3 in range(nq3): - detdet = wts1[ie1, q1] * wts2[ie2, q2] * wts3[ie3, q3] * uvalue[ie1, ie2, ie3, q1, q2, q3] - - b1value[ie1, ie2, ie3, q1, q2, q3] = b1value[ie1, ie2, ie3, q1, q2, q3] * detdet - b2value[ie1, ie2, ie3, q1, q2, q3] = b2value[ie1, ie2, ie3, q1, q2, q3] * detdet - b3value[ie1, ie2, ie3, q1, q2, q3] = b3value[ie1, ie2, ie3, q1, q2, q3] * detdet - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# =================================================================================================================== -def piecewise_gather( - ddt: "float", - index_shapex: "int[:]", - index_shapey: "int[:]", - index_shapez: "int[:]", - index_diffx: "int", - index_diffy: "int", - index_diffz: "int", - p_shape: "int[:]", - p_size: "float[:]", - n_quad: "int[:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - Nel: "int[:]", - particles: "float[:,:]", - Np_loc: "int", - Np: "int", - gather_1: "float[:,:,:,:,:,:]", - gather_2: "float[:,:,:,:,:,:]", - gather_3: "float[:,:,:,:,:,:]", - mid_particles: "float[:,:]", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - gather_1[:, :, :, :, :, :] = 0.0 - gather_2[:, :, :, :, :, :] = 0.0 - gather_3[:, :, :, :, :, :] = 0.0 - vel = zeros(3, dtype=float) - # ========================== - cell_left = empty(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - - temp1 = zeros(3, dtype=float) - temp4 = zeros(3, dtype=float) - - compact = zeros(3, dtype=float) - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = empty((3, 3), dtype=float) - fx = empty(3, dtype=float) - # ========================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : gather_1, gather_2, gather_3) private (ip, eta1, eta2, eta3, ie1, ie2, ie3, vel, weight_p, point_left, point_right, cell_left, cell_number1, cell_number2, cell_number3, il1, il2 ,il3, q1, q2, q3, temp1, temp4, value_x, value_y, value_z, ww, index1, index2, index3, preindex1, preindex2, preindex3, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, det_df) - - for ip in range(Np_loc): - eta1 = particles[0, ip] - eta2 = particles[1, ip] - eta3 = particles[2, ip] - - ie1 = int(eta1 * Nel[0]) - ie2 = int(eta2 * Nel[1]) - ie3 = int(eta3 * Nel[2]) - - vel[0] = particles[3, ip] + ddt * mid_particles[0, ip] - vel[1] = particles[4, ip] + ddt * mid_particles[1, ip] - vel[2] = particles[5, ip] + ddt * mid_particles[2, ip] - weight_p = particles[6, ip] / (p_size[0] * p_size[1] * p_size[2]) / Np # note we need to multiply cell size - - # the points here are still not put in the periodic box [0, 1] x [0, 1] x [0, 1] - point_left[0] = eta1 - 0.5 * compact[0] - point_right[0] = eta1 + 0.5 * compact[0] - point_left[1] = eta2 - 0.5 * compact[1] - point_right[1] = eta2 + 0.5 * compact[1] - point_left[2] = eta3 - 0.5 * compact[2] - point_right[2] = eta3 + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number1 = int(int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1) - cell_number2 = int(int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1) - cell_number3 = int(int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1) - - # ====================================== - for il1 in range(cell_number1): - for il2 in range(cell_number2): - for il3 in range(cell_number3): - for q1 in range(n_quad[0]): - for q2 in range(n_quad[1]): - for q3 in range(n_quad[2]): - temp1[0] = (cell_left[0] + il1) / Nel[0] + pts1[ - 0, - q1, - ] # quadrature points in the cell x direction - temp4[0] = abs(temp1[0] - eta1) - compact[0] / 2.0 # if > 0, result is 0 - - temp1[1] = (cell_left[1] + il2) / Nel[1] + pts2[0, q2] - temp4[1] = abs(temp1[1] - eta2) - compact[1] / 2.0 # if > 0, result is 0 - - temp1[2] = (cell_left[2] + il3) / Nel[2] + pts3[0, q3] - temp4[2] = abs(temp1[2] - eta3) - compact[2] / 2.0 # if > 0, result is 0 - - if temp4[0] < 0.0 and temp4[1] < 0.0 and temp4[2] < 0.0: - value_x = bsp.piecewise(p_shape[0], p_size[0], temp1[0] - eta1) - value_y = bsp.piecewise(p_shape[1], p_size[1], temp1[1] - eta2) - value_z = bsp.piecewise(p_shape[2], p_size[2], temp1[2] - eta3) - - # ========= mapping evaluation ============= - span1f = int(temp1[0] % 1.0 * nelf[0]) + pf[0] - span2f = int(temp1[1] % 1.0 * nelf[1]) + pf[1] - span3f = int(temp1[2] % 1.0 * nelf[2]) + pf[2] - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - temp1[0] % 1.0, - temp1[1] % 1.0, - temp1[2] % 1.0, - df, - fx, - 0, - ) - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - ww = weight_p * value_x * value_y * value_z / det_df - - preindex1 = int(cell_left[0] + il1 + index_diffx) - preindex2 = int(cell_left[1] + il2 + index_diffy) - preindex3 = int(cell_left[2] + il3 + index_diffz) - index1 = index_shapex[preindex1] - index2 = index_shapey[preindex2] - index3 = index_shapez[preindex3] - - gather_1[index1, index2, index3, q1, q2, q3] += vel[0] * ww - gather_2[index1, index2, index3, q1, q2, q3] += vel[1] * ww - gather_3[index1, index2, index3, q1, q2, q3] += vel[2] * ww - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ================================================================================================================== -def piecewise_scatter( - index_shapex: "int[:]", - index_shapey: "int[:]", - index_shapez: "int[:]", - index_diffx: "int", - index_diffy: "int", - index_diffz: "int", - p_shape: "int[:]", - p_size: "float[:]", - RK_vector: "float[:,:]", - Nel: "int[:]", - Np_loc: "int", - Np: "int", - weight_1: "float[:,:,:,:,:,:]", - weight_2: "float[:,:,:,:,:,:]", - weight_3: "float[:,:,:,:,:,:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - n_quad: "int[:]", - particles: "float[:,:]", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - vel = zeros(3, dtype=float) - - dfinv = zeros((3, 3), dtype=float) - dfinv_t = zeros((3, 3), dtype=float) - cell_left = empty(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - - temp1 = zeros(3, dtype=float) - temp2 = zeros(3, dtype=float) - temp3 = empty(3, dtype=int) - temp4 = zeros(3, dtype=float) - - compact = zeros(3, dtype=float) - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = empty((3, 3), dtype=float) - fx = empty(3, dtype=float) - # ========================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ip, eta1, eta2, eta3, weight_p, point_left, point_right, cell_left, cell_number1, cell_number2, cell_number3, il1, il2, il3, q1, q2, q3, temp1, temp4, value_x, value_y, value_z, ww, index1, index2, index3, preindex1, preindex2, preindex3, vel, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, det_df) - - for ip in range(Np_loc): - eta1 = particles[0, ip] - eta2 = particles[1, ip] - eta3 = particles[2, ip] - - vel[:] = 0.0 - - weight_p = particles[6, ip] / (p_size[0] * p_size[1] * p_size[2]) / Np - # the points here are still not put in the periodic box [0, 1] x [0, 1] x [0, 1] - point_left[0] = eta1 - 0.5 * compact[0] - point_right[0] = eta1 + 0.5 * compact[0] - point_left[1] = eta2 - 0.5 * compact[1] - point_right[1] = eta2 + 0.5 * compact[1] - point_left[2] = eta3 - 0.5 * compact[2] - point_right[2] = eta3 + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number1 = int(int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1) - cell_number2 = int(int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1) - cell_number3 = int(int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1) - - # ====================================== - for il1 in range(cell_number1): - for il2 in range(cell_number2): - for il3 in range(cell_number3): - for q1 in range(n_quad[0]): - for q2 in range(n_quad[1]): - for q3 in range(n_quad[2]): - temp1[0] = (cell_left[0] + il1) / Nel[0] + pts1[ - 0, - q1, - ] # quadrature points in the cell x direction - temp4[0] = abs(temp1[0] - eta1) - compact[0] / 2 # if > 0, result is 0 - - temp1[1] = (cell_left[1] + il2) / Nel[1] + pts2[0, q2] - temp4[1] = abs(temp1[1] - eta2) - compact[1] / 2 # if > 0, result is 0 - - temp1[2] = (cell_left[2] + il3) / Nel[2] + pts3[0, q3] - temp4[2] = abs(temp1[2] - eta3) - compact[2] / 2 # if > 0, result is 0 - - if temp4[0] < 0 and temp4[1] < 0 and temp4[2] < 0: - value_x = bsp.piecewise(p_shape[0], p_size[0], temp1[0] - eta1) - value_y = bsp.piecewise(p_shape[1], p_size[1], temp1[1] - eta2) - value_z = bsp.piecewise(p_shape[2], p_size[2], temp1[2] - eta3) - - # ========= mapping evaluation ============= - span1f = int(temp1[0] % 1.0 * nelf[0]) + pf[0] - span2f = int(temp1[1] % 1.0 * nelf[1]) + pf[1] - span3f = int(temp1[2] % 1.0 * nelf[2]) + pf[2] - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - temp1[0] % 1.0, - temp1[1] % 1.0, - temp1[2] % 1.0, - df, - fx, - 0, - ) - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - ww = value_x * value_y * value_z / det_df / (p_size[0] * p_size[1] * p_size[2]) - - preindex1 = int(cell_left[0] + il1 + index_diffx) - preindex2 = int(cell_left[1] + il2 + index_diffy) - preindex3 = int(cell_left[2] + il3 + index_diffz) - index1 = index_shapex[preindex1] - index2 = index_shapey[preindex2] - index3 = index_shapez[preindex3] - - vel[0] += ww * weight_1[index1, index2, index3, q1, q2, q3] - vel[1] += ww * weight_2[index1, index2, index3, q1, q2, q3] - vel[2] += ww * weight_3[index1, index2, index3, q1, q2, q3] - - RK_vector[0, ip] = vel[0] - RK_vector[1, ip] = vel[1] - RK_vector[2, ip] = vel[2] - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/legacy/mhd_operators_MF.py b/src/struphy/eigenvalue_solvers/legacy/mhd_operators_MF.py deleted file mode 100644 index 560314458..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/mhd_operators_MF.py +++ /dev/null @@ -1,3205 +0,0 @@ -import cunumpy as xp -import scipy.sparse as spa - -from struphy.eigenvalue_solvers.projectors_global import Projectors_tensor_3d -from struphy.eigenvalue_solvers.spline_space import Tensor_spline_space -from struphy.linear_algebra.linalg_kron import kron_matvec_3d, kron_solve_3d - - -# ================================================================================================= -class projectors_dot_x: - """ - Caclulate the product of vector 'x' with the several kinds of projection matrices. - Global projectors based on tensor product are used. - - Parameters - ---------- - space : obj - Tensor_spline_space object. - - eq_MHD : obj - Equilibrium_mhd object (pullbacks must be enabled). - - Notes - ----- - Implemented operators (transpose also implemented) with - - * MHD with velocity (up) as 1-form: - ===================================================== =========================== ===================== - operator dim of matrix verification method - ===================================================== =========================== ===================== - Q1 = pi_2[rho_eq * G_inv * lambda^1] R^{N^2 x N^1} comparison test with basic projector - W1 = pi_1[rho_eq / g_sqrt * lambda^1] R^{N^1 x N^1} identity test - U1 = pi_2[g_sqrt * G_inv * lambda^1] R^{N^2 x N^1} comparison test with basic projector - P1 = pi_1[j_eq / g_sqrt * lambda^2] R^{N^1 x N^2} comparison test with basic projector - S1 = pi_2[p_eq * G_inv * lambda^1] R^{N^2 x N^1} comparison test with basic projector - S10 = pi_1[p_eq * lambda^1] R^{N^1 x N^1} identity test - K1 = pi_3[p_eq / g_sqrt * lambda^3] R^{N^3 x N^3} identity test - K10 = pi_0[p_eq * lambda^0] R^{N^0 x N^0} identity test - T1 = pi_1[B_eq * G_inv * lambda^1] R^{N^1 x N^1} comparison test with basic projector - X1 = pi_0[DF^-T * lambda^1] R^{N^0 x 3 x N^1} comparison test with basic projector - ===================================================== =========================== ===================== - - * MHD with velocity (up) as 2-form: - ===================================================== ================= ===================== - operator dim of matrx verification method - ===================================================== ================= ===================== - Q2 = pi_2[rho_eq / g_sqrt * lambda^2] R^{N^2 x N^2} identity test - T2 = pi_1[B_eq / g_sqrt * lambda^2] R^{N^1 x N^2} comparison test with basic projector - P2 = pi_2[G_inv * j_eq * lambda^2] R^{N^2 x N^2} comparison test with basic projector - S2 = pi_2[p_eq / g_sqrt * lambda^2] R^{N^2 x N^2} identity test - K2 = pi_3[p_eq / g_sqrt * lambda^3] R^{N^3 x N^3} identity test - X2 = pi_0[DF / g_sqrt * lambda^2] R^{N^0 x 3 x N^2} comparison test with basic projector - Z20 = pi_1[G / g_sqrt * lambda^2] R^{N^1 x N^2} comparison test with basic projector - Y20 = pi_3[g_sqrt * lambda^0] R^{N^3 x N^0} comparison test with basic projector - S20 = pi_1[p_eq * G / g_sqrt * lambda^2] R^{N^1 x N^2} comparison test with basic projector - ===================================================== ================= ===================== - """ - - def __init__(self, space, eq_MHD): - self.space = space - self.eq_MHD = eq_MHD - - self.dim_0 = self.space.Ntot_0form - self.dim_1 = self.space.Ntot_1form_cum[-1] - self.dim_2 = self.space.Ntot_2form_cum[-1] - self.dim_3 = self.space.Ntot_3form - # self.M1 = self.space.M1 - # self.M2 = self.space.M2 - self.NbaseN = self.space.NbaseN - self.NbaseD = self.space.NbaseD - - # self.basis_u = basis_u - # self.basis_p = basis_p - - # Interpolation matrices - # self.N_1 = self.proj_eta1.N - # self.N_2 = self.proj_eta2.N - # self.N_3 = self.proj_eta3.N - - self.N_1 = self.space.spaces[0].projectors.I - self.N_2 = self.space.spaces[1].projectors.I - self.N_3 = self.space.spaces[2].projectors.I - - # Histopolation matrices - # self.D_1 = self.proj_eta1.D - # self.D_2 = self.proj_eta2.D - # self.D_3 = self.proj_eta3.D - - self.D_1 = self.space.spaces[0].projectors.H - self.D_2 = self.space.spaces[1].projectors.H - self.D_3 = self.space.spaces[2].projectors.H - - # Collocation matrices for different point sets - self.pts0_N_1 = self.space.spaces[0].projectors.N_int - self.pts0_N_2 = self.space.spaces[1].projectors.N_int - self.pts0_N_3 = self.space.spaces[2].projectors.N_int - - self.pts0_D_1 = self.space.spaces[0].projectors.D_int - self.pts0_D_2 = self.space.spaces[1].projectors.D_int - self.pts0_D_3 = self.space.spaces[2].projectors.D_int - - self.pts1_N_1 = self.space.spaces[0].projectors.N_pts - self.pts1_N_2 = self.space.spaces[1].projectors.N_pts - self.pts1_N_3 = self.space.spaces[2].projectors.N_pts - - self.pts1_D_1 = self.space.spaces[0].projectors.D_pts - self.pts1_D_2 = self.space.spaces[1].projectors.D_pts - self.pts1_D_3 = self.space.spaces[2].projectors.D_pts - - # assert xp.allclose(self.N_1.toarray(), self.pts0_N_1.toarray(), atol=1e-14) - # assert xp.allclose(self.N_2.toarray(), self.pts0_N_2.toarray(), atol=1e-14) - # assert xp.allclose(self.N_3.toarray(), self.pts0_N_3.toarray(), atol=1e-14) - - # ===== call equilibrium_mhd values at the projection points ===== - # projection points - self.pts_PI_0 = self.space.projectors.pts_PI["0"] - self.pts_PI_11 = self.space.projectors.pts_PI["11"] - self.pts_PI_12 = self.space.projectors.pts_PI["12"] - self.pts_PI_13 = self.space.projectors.pts_PI["13"] - self.pts_PI_21 = self.space.projectors.pts_PI["21"] - self.pts_PI_22 = self.space.projectors.pts_PI["22"] - self.pts_PI_23 = self.space.projectors.pts_PI["23"] - self.pts_PI_3 = self.space.projectors.pts_PI["3"] - - # p0_eq - self.p0_eq_0 = self.space.projectors.eval_for_PI("0", self.eq_MHD.p0) - self.p0_eq_11 = self.space.projectors.eval_for_PI("11", self.eq_MHD.p0) - self.p0_eq_12 = self.space.projectors.eval_for_PI("12", self.eq_MHD.p0) - self.p0_eq_13 = self.space.projectors.eval_for_PI("13", self.eq_MHD.p0) - - # p3_eq - self.p3_eq_21 = self.space.projectors.eval_for_PI("21", self.eq_MHD.p3) - self.p3_eq_22 = self.space.projectors.eval_for_PI("22", self.eq_MHD.p3) - self.p3_eq_23 = self.space.projectors.eval_for_PI("23", self.eq_MHD.p3) - self.p3_eq_3 = self.space.projectors.eval_for_PI("3", self.eq_MHD.p3) - - # n3_eq - self.n3_eq_11 = self.space.projectors.eval_for_PI("11", self.eq_MHD.n3) - self.n3_eq_12 = self.space.projectors.eval_for_PI("12", self.eq_MHD.n3) - self.n3_eq_13 = self.space.projectors.eval_for_PI("13", self.eq_MHD.n3) - self.n3_eq_21 = self.space.projectors.eval_for_PI("21", self.eq_MHD.n3) - self.n3_eq_22 = self.space.projectors.eval_for_PI("22", self.eq_MHD.n3) - self.n3_eq_23 = self.space.projectors.eval_for_PI("23", self.eq_MHD.n3) - - # b2_eq - self.b2_eq_11_1 = self.space.projectors.eval_for_PI("11", self.eq_MHD.b2_1) - self.b2_eq_12_1 = self.space.projectors.eval_for_PI("12", self.eq_MHD.b2_1) - self.b2_eq_13_1 = self.space.projectors.eval_for_PI("13", self.eq_MHD.b2_1) - self.b2_eq_11_2 = self.space.projectors.eval_for_PI("11", self.eq_MHD.b2_2) - self.b2_eq_12_2 = self.space.projectors.eval_for_PI("12", self.eq_MHD.b2_2) - self.b2_eq_13_2 = self.space.projectors.eval_for_PI("13", self.eq_MHD.b2_2) - self.b2_eq_11_3 = self.space.projectors.eval_for_PI("11", self.eq_MHD.b2_3) - self.b2_eq_12_3 = self.space.projectors.eval_for_PI("12", self.eq_MHD.b2_3) - self.b2_eq_13_3 = self.space.projectors.eval_for_PI("13", self.eq_MHD.b2_3) - - # j2_eq - self.j2_eq_11_1 = self.space.projectors.eval_for_PI("11", self.eq_MHD.j2_1) - self.j2_eq_12_1 = self.space.projectors.eval_for_PI("12", self.eq_MHD.j2_1) - self.j2_eq_13_1 = self.space.projectors.eval_for_PI("13", self.eq_MHD.j2_1) - self.j2_eq_11_2 = self.space.projectors.eval_for_PI("11", self.eq_MHD.j2_2) - self.j2_eq_12_2 = self.space.projectors.eval_for_PI("12", self.eq_MHD.j2_2) - self.j2_eq_13_2 = self.space.projectors.eval_for_PI("13", self.eq_MHD.j2_2) - self.j2_eq_11_3 = self.space.projectors.eval_for_PI("11", self.eq_MHD.j2_3) - self.j2_eq_12_3 = self.space.projectors.eval_for_PI("12", self.eq_MHD.j2_3) - self.j2_eq_13_3 = self.space.projectors.eval_for_PI("13", self.eq_MHD.j2_3) - self.j2_eq_21_1 = self.space.projectors.eval_for_PI("21", self.eq_MHD.j2_1) - self.j2_eq_22_1 = self.space.projectors.eval_for_PI("22", self.eq_MHD.j2_1) - self.j2_eq_23_1 = self.space.projectors.eval_for_PI("23", self.eq_MHD.j2_1) - self.j2_eq_21_2 = self.space.projectors.eval_for_PI("21", self.eq_MHD.j2_2) - self.j2_eq_22_2 = self.space.projectors.eval_for_PI("22", self.eq_MHD.j2_2) - self.j2_eq_23_2 = self.space.projectors.eval_for_PI("23", self.eq_MHD.j2_2) - self.j2_eq_21_3 = self.space.projectors.eval_for_PI("21", self.eq_MHD.j2_3) - self.j2_eq_22_3 = self.space.projectors.eval_for_PI("22", self.eq_MHD.j2_3) - self.j2_eq_23_3 = self.space.projectors.eval_for_PI("23", self.eq_MHD.j2_3) - - # g_sqrt - self.det_df_0 = self.eq_MHD.domain.jacobian_det(self.pts_PI_0[0], self.pts_PI_0[1], self.pts_PI_0[2]) - self.det_df_11 = self.eq_MHD.domain.jacobian_det(self.pts_PI_11[0], self.pts_PI_11[1], self.pts_PI_11[2]) - self.det_df_12 = self.eq_MHD.domain.jacobian_det(self.pts_PI_12[0], self.pts_PI_12[1], self.pts_PI_12[2]) - self.det_df_13 = self.eq_MHD.domain.jacobian_det(self.pts_PI_13[0], self.pts_PI_13[1], self.pts_PI_13[2]) - self.det_df_21 = self.eq_MHD.domain.jacobian_det(self.pts_PI_21[0], self.pts_PI_21[1], self.pts_PI_21[2]) - self.det_df_22 = self.eq_MHD.domain.jacobian_det(self.pts_PI_22[0], self.pts_PI_22[1], self.pts_PI_22[2]) - self.det_df_23 = self.eq_MHD.domain.jacobian_det(self.pts_PI_23[0], self.pts_PI_23[1], self.pts_PI_23[2]) - self.det_df_3 = self.eq_MHD.domain.jacobian_det(self.pts_PI_3[0], self.pts_PI_3[1], self.pts_PI_3[2]) - - # G - self.g_11 = self.eq_MHD.domain.metric(self.pts_PI_11[0], self.pts_PI_11[1], self.pts_PI_11[2]) - self.g_12 = self.eq_MHD.domain.metric(self.pts_PI_12[0], self.pts_PI_12[1], self.pts_PI_12[2]) - self.g_13 = self.eq_MHD.domain.metric(self.pts_PI_13[0], self.pts_PI_13[1], self.pts_PI_13[2]) - - # self.g_21 = self.eq_MHD.domain.metric(self.pts_PI_21[0], self.pts_PI_21[1], self.pts_PI_21[2]) - # self.g_22 = self.eq_MHD.domain.metric(self.pts_PI_22[0], self.pts_PI_22[1], self.pts_PI_22[2]) - # self.g_23 = self.eq_MHD.domain.metric(self.pts_PI_23[0], self.pts_PI_23[1], self.pts_PI_23[2]) - - # G_inv - self.g_inv_11 = self.eq_MHD.domain.metric_inv(self.pts_PI_11[0], self.pts_PI_11[1], self.pts_PI_11[2]) - self.g_inv_12 = self.eq_MHD.domain.metric_inv(self.pts_PI_12[0], self.pts_PI_12[1], self.pts_PI_12[2]) - self.g_inv_13 = self.eq_MHD.domain.metric_inv(self.pts_PI_13[0], self.pts_PI_13[1], self.pts_PI_13[2]) - - self.g_inv_21 = self.eq_MHD.domain.metric_inv(self.pts_PI_21[0], self.pts_PI_21[1], self.pts_PI_21[2]) - self.g_inv_22 = self.eq_MHD.domain.metric_inv(self.pts_PI_22[0], self.pts_PI_22[1], self.pts_PI_22[2]) - self.g_inv_23 = self.eq_MHD.domain.metric_inv(self.pts_PI_23[0], self.pts_PI_23[1], self.pts_PI_23[2]) - - # DF^-1 - self.df_inv_0 = self.eq_MHD.domain.jacobian_inv(self.pts_PI_0[0], self.pts_PI_0[1], self.pts_PI_0[2]) - - # DF - self.df_0 = self.eq_MHD.domain.jacobian(self.pts_PI_0[0], self.pts_PI_0[1], self.pts_PI_0[2]) - - # # Operator A - # if self.basis_u == 1: - # self.A = spa.linalg.LinearOperator((self.dim_1, self.dim_1), matvec = lambda x : (self.M1.dot(self.W1_dot(x)) + self.transpose_W1_dot(self.M1.dot(x))) / 2 ) - # self.A_mat = spa.csc_matrix(self.A.dot(xp.identity(self.dim_1))) - - # elif self.basis_u == 2: - # self.A = spa.linalg.LinearOperator((self.dim_2, self.dim_2), matvec = lambda x : (self.M2.dot(self.Q2_dot(x)) + self.transpose_Q2_dot(self.M2.dot(x))) / 2 ) - # self.A_mat = spa.csc_matrix(self.A.dot(xp.identity(self.dim_2))) - - # self.A_inv = spa.linalg.inv(self.A_mat) - - ######################################## - ########## 1-form formulation ########## - ######################################## - # ================================================================== - def Q1_dot(self, x): - """ - Matrix-vector product Q1.x - - Parameters - ---------- - x : xp.array - dim R^{N^1} - - Returns - ---------- - res : xp.array - dim R^{N^2} - - Notes - ----- - Q1 = pi_2[rho_eq * G_inv * lambda^1] in R^{N^2 x N^1} - - Q1.x = I_2( R_2 ( F_Q1.x)) - - I_2 ... inverse inter/histopolation matrix (tensor product) - - R_2 ... compute DOFs from function values at point set pts_ijk - - F_Q1[ijk, mno] = rho_eq(pts_ijk) * G_inv(pts_ijk) * lambda^1_mno(pts_ijk) - - * spline evaluation (at V_2 point sets) - * [int, his, his] points: {greville[0], quad_pts[1], quad_pts[2]} - * [his, int, his] points: {quad_pts[0], greville[1], quad_pts[2]} - * [his, his, int] points: {quad_pts[0], quad_pts[1], greville[2]} - - * Components of F_Q1: - * evaluated at [int, his, his] : (D, N, N) * G_inv_11 * rho_eq + (N, D, N) * G_inv_12 * rho_eq + (N, N, D) * G_inv_13 * rho_eq - * evaluated at [his, int, his] : (D, N, N) * G_inv_21 * rho_eq + (N, D, N) * G_inv_22 * rho_eq + (N, N, D) * G_inv_23 * rho_eq - * evaluated at [his, his, int] : (D, N, N) * G_inv_31 * rho_eq + (N, D, N) * G_inv_32 * rho_eq + (N, N, D) * G_inv_33 * rho_eq - """ - - # x dim check - # x should be R{N^1} - # assert len(x) == self.tensor_spl.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - # assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - # assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - # assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - # xi1 - mat_f_11 = kron_matvec_3d([self.pts0_D_1, self.pts1_N_2, self.pts1_N_3], x_loc[0]) - mat_f_12 = kron_matvec_3d([self.pts0_N_1, self.pts1_D_2, self.pts1_N_3], x_loc[1]) - mat_f_13 = kron_matvec_3d([self.pts0_N_1, self.pts1_N_2, self.pts1_D_3], x_loc[2]) - - # xi2 - mat_f_21 = kron_matvec_3d([self.pts1_D_1, self.pts0_N_2, self.pts1_N_3], x_loc[0]) - mat_f_22 = kron_matvec_3d([self.pts1_N_1, self.pts0_D_2, self.pts1_N_3], x_loc[1]) - mat_f_23 = kron_matvec_3d([self.pts1_N_1, self.pts0_N_2, self.pts1_D_3], x_loc[2]) - - # xi3 - mat_f_31 = kron_matvec_3d([self.pts1_D_1, self.pts1_N_2, self.pts0_N_3], x_loc[0]) - mat_f_32 = kron_matvec_3d([self.pts1_N_1, self.pts1_D_2, self.pts0_N_3], x_loc[1]) - mat_f_33 = kron_matvec_3d([self.pts1_N_1, self.pts1_N_2, self.pts0_D_3], x_loc[2]) - - mat_f_11_c = mat_f_11 * self.n3_eq_21 * self.g_inv_21[0, 0] - mat_f_12_c = mat_f_12 * self.n3_eq_21 * self.g_inv_21[0, 1] - mat_f_13_c = mat_f_13 * self.n3_eq_21 * self.g_inv_21[0, 2] - mat_f_21_c = mat_f_21 * self.n3_eq_22 * self.g_inv_22[1, 0] - mat_f_22_c = mat_f_22 * self.n3_eq_22 * self.g_inv_22[1, 1] - mat_f_23_c = mat_f_23 * self.n3_eq_22 * self.g_inv_22[1, 2] - mat_f_31_c = mat_f_31 * self.n3_eq_23 * self.g_inv_23[2, 0] - mat_f_32_c = mat_f_32 * self.n3_eq_23 * self.g_inv_23[2, 1] - mat_f_33_c = mat_f_33 * self.n3_eq_23 * self.g_inv_23[2, 2] - - mat_f_1_c = mat_f_11_c + mat_f_12_c + mat_f_13_c - mat_f_2_c = mat_f_21_c + mat_f_22_c + mat_f_23_c - mat_f_3_c = mat_f_31_c + mat_f_32_c + mat_f_33_c - - # ========== Step 2 : R( F(x) ) ==========# - # integration over quadrature points - # xi1 : DOF_1_{i,j,k} = sum_{m} w_{i,m} * mat_f_1_{i,m,j,k} - DOF_1 = self.space.projectors.dofs("21", mat_f_1_c) - - # xi2 : DOF_2_{i,j,k} = sum_{m} w_{j,m} * mat_f_2_{i,j,m,k} - DOF_2 = self.space.projectors.dofs("22", mat_f_2_c) - - # xi3 : DOF_3_{i,j,k} = sum_{m} w_{k,m} * mat_f_3_{i,j,k,m} - DOF_3 = self.space.projectors.dofs("23", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # xi1 : inter(xi1)-histo(xi2)-histo(xi3)-polation. - res_1 = self.space.projectors.PI_mat("21", DOF_1) - - # xi2 : histo(xi1)-inter(xi2)-histo(xi3)-polation. - res_2 = self.space.projectors.PI_mat("22", DOF_2) - - # xi3 : histo(xi1)-histo(xi2)-inter(xi3)-polation. - res_3 = self.space.projectors.PI_mat("23", DOF_3) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ================================================================== - def transpose_Q1_dot(self, x): - """ - Matrix-vector product Q1.T.x - - Parameters - ---------- - x : xp.array - dim R^{N^2} - - Returns - ---------- - res : xp.array - dim R^{N^1} - - Notes - ----- - Q1.x = I_2( R_2 ( F_Q1.x)) - - Q1.T.x = F_Q1.T( R_2.T ( I_2.T.x)) - - See Q1_dot for more info. - """ - - # x dim check - # x should be R{N^2} - # assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - # assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - # assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - # assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # step1 : I.T(x) - # xi1 : transpose of inter(xi1)-histo(xi2)-histo(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.N_1.T, self.D_2.T, self.D_3.T], x_loc[0]) - - # xi2 : transpose of histo(xi1)-inter(xi2)-histo(xi3)-polati on. - mat_dofs_2 = kron_solve_3d([self.D_1.T, self.N_2.T, self.D_3.T], x_loc[1]) - - # xi3 : transpose of histo(xi1)-histo(xi2)-inter(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.D_1.T, self.D_2.T, self.N_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - # transpose of integration over quadrature points - # xi1 - mat_f_1 = self.space.projectors.dofs_T("21", mat_dofs_1) - - # xi2 - mat_f_2 = self.space.projectors.dofs_T("22", mat_dofs_2) - - # xi3 - mat_f_3 = self.space.projectors.dofs_T("23", mat_dofs_3) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_11_c = mat_f_1 * self.n3_eq_21 * self.g_inv_21[0, 0] - mat_f_12_c = mat_f_1 * self.n3_eq_21 * self.g_inv_21[0, 1] - mat_f_13_c = mat_f_1 * self.n3_eq_21 * self.g_inv_21[0, 2] - mat_f_21_c = mat_f_2 * self.n3_eq_22 * self.g_inv_22[1, 0] - mat_f_22_c = mat_f_2 * self.n3_eq_22 * self.g_inv_22[1, 1] - mat_f_23_c = mat_f_2 * self.n3_eq_22 * self.g_inv_22[1, 2] - mat_f_31_c = mat_f_3 * self.n3_eq_23 * self.g_inv_23[2, 0] - mat_f_32_c = mat_f_3 * self.n3_eq_23 * self.g_inv_23[2, 1] - mat_f_33_c = mat_f_3 * self.n3_eq_23 * self.g_inv_23[2, 2] - - res_11 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_N_2.T, self.pts1_N_3.T], mat_f_11_c) - res_12 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_D_2.T, self.pts1_N_3.T], mat_f_12_c) - res_13 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_N_2.T, self.pts1_D_3.T], mat_f_13_c) - - res_21 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_N_2.T, self.pts1_N_3.T], mat_f_21_c) - res_22 = kron_matvec_3d([self.pts1_N_1.T, self.pts0_D_2.T, self.pts1_N_3.T], mat_f_22_c) - res_23 = kron_matvec_3d([self.pts1_N_1.T, self.pts0_N_2.T, self.pts1_D_3.T], mat_f_23_c) - - res_31 = kron_matvec_3d([self.pts1_D_1.T, self.pts1_N_2.T, self.pts0_N_3.T], mat_f_31_c) - res_32 = kron_matvec_3d([self.pts1_N_1.T, self.pts1_D_2.T, self.pts0_N_3.T], mat_f_32_c) - res_33 = kron_matvec_3d([self.pts1_N_1.T, self.pts1_N_2.T, self.pts0_D_3.T], mat_f_33_c) - - res_1 = res_11 + res_21 + res_31 - res_2 = res_12 + res_22 + res_32 - res_3 = res_13 + res_23 + res_33 - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # =================================================================== - def W1_dot(self, x): - """ - Matrix-vector product W1.x - - Parameters - ---------- - x : xp.array - dim R^{N^1} - - Returns - ---------- - res : xp.array - dim R^{N^1} - - Notes - ----- - W1 = pi_1[rho_eq / g_sqrt * lambda^1] in R{N^1 x N^1} - - W1.x = I_1( R_1 ( F_W1.x)) - - I_1 ... inverse inter/histopolation matrix (tensor product) - - R_1 ... compute DOFs from function values at point set pts_ijk - - F_W1[ijk,mno] = rho_eq(pts_ijk) / g_sqrt(pts_ijk) * lambda^1_mno(pts_ijk) - - * spline evaluation (at V_1 point sets) - * [his, int, int] points: {quad_pts[0], greville[1], greville[2]} - * [int, his, int] points: {greville[0], quad_pts[1], greville[2]} - * [int, int, his] points: {greville[0], greville[1], quad_pts[2]} - - * Components of F_W1: - * evaluated at [his, int, int] : (D, N, N) * rho_eq / g_sqrt - * evaluated at [int, his, int] : (N, D, N) * rho_eq / g_sqrt - * evaluated at [int, int, his] : (N, N, D) * rho_eq / g_sqrt - """ - # x dim check - # x should be R{N^1} - # assert len(x) == self.space.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - # assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - # assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - # assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - mat_f_1 = kron_matvec_3d([self.pts1_D_1, self.pts0_N_2, self.pts0_N_3], x_loc[0]) - mat_f_2 = kron_matvec_3d([self.pts0_N_1, self.pts1_D_2, self.pts0_N_3], x_loc[1]) - mat_f_3 = kron_matvec_3d([self.pts0_N_1, self.pts0_N_2, self.pts1_D_3], x_loc[2]) - - mat_f_1_c = mat_f_1 * self.n3_eq_11 / self.det_df_11 - mat_f_2_c = mat_f_2 * self.n3_eq_12 / self.det_df_12 - mat_f_3_c = mat_f_3 * self.n3_eq_13 / self.det_df_13 - - # ========== Step 2 : R( F(x) ) ==========# - # integration over quadrature points - # xi1 : DOF_1_{i,j,k} = sum_{m} w_{i,m} * mat_f_1_{i,m,j,k} - DOF_1 = self.space.projectors.dofs("11", mat_f_1_c) - - # xi2 : DOF_2_{i,j,k} = sum_{m} w_{j,m} * mat_f_2_{i,j,m,k} - DOF_2 = self.space.projectors.dofs("12", mat_f_2_c) - - # xi3 : DOF_3_{i,j,k} = sum_{m} w_{k,m} * mat_f_3_{i,j,k,m} - DOF_3 = self.space.projectors.dofs("13", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # xi1 : histo(xi1)-inter(xi2)-inter(xi3)-polation. - res_1 = self.space.projectors.PI_mat("11", DOF_1) - - # xi2 : inter(xi1)-histo(xi2)-inter(xi3)-polation. - res_2 = self.space.projectors.PI_mat("12", DOF_2) - - # xi3 : inter(xi1)-inter(xi2)-histo(xi3)-polation. - res_3 = self.space.projectors.PI_mat("13", DOF_3) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # =================================================================== - def transpose_W1_dot(self, x): - """ - Matrix-vector product W1.T.x - - Parameters - ---------- - x : xp.array - dim R{N^1} - - Returns - ---------- - res : xp.array - dim R{N^1} - - Notes - ----- - W1.x = I_1( R_1 ( F_W1.x)) - - W1.T.x = F_W1.T( R_1.T ( I_1.T.x)) - - See W1_dot for more details. - """ - # x dim check - # x should be R{N^1} - # assert len(x) == self.space.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - # assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - # assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - # assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # step1 : I.T(x) - # xi1 : transpose of histo(xi1)-inter(xi2)-inter(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.D_1.T, self.N_2.T, self.N_3.T], x_loc[0]) - - # xi2 : transpose of inter(xi1)-histo(xi2)-inter(xi3)-polation. - mat_dofs_2 = kron_solve_3d([self.N_1.T, self.D_2.T, self.N_3.T], x_loc[1]) - - # xi3 : transpose of inter(xi1)-inter(xi2)-histo(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.N_1.T, self.N_2.T, self.D_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - # transpose of integration over quadrature points - # xi1 : mat_f_1_{i,m,j,k} = w_{i,m} * DOF_1_{i,j,k} - mat_f_1 = self.space.projectors.dofs_T("11", mat_dofs_1) - - # xi2 : mat_f_2_{i,j,m,k} = w_{j,m} * DOF_2_{i,j,k} - mat_f_2 = self.space.projectors.dofs_T("12", mat_dofs_2) - - # xi3 : mat_f_2_{i,j,k,m} = w_{k,m} * DOF_3_{i,j,k} - mat_f_3 = self.space.projectors.dofs_T("13", mat_dofs_3) - - mat_f_1_c = mat_f_1 * self.n3_eq_11 / self.det_df_11 - mat_f_2_c = mat_f_2 * self.n3_eq_12 / self.det_df_12 - mat_f_3_c = mat_f_3 * self.n3_eq_13 / self.det_df_13 - - res_1 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_N_2.T, self.pts0_N_3.T], mat_f_1_c) - res_2 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_D_2.T, self.pts0_N_3.T], mat_f_2_c) - res_3 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_N_2.T, self.pts1_D_3.T], mat_f_3_c) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def U1_dot(self, x): - """ - Matrix-vector product U1.x - - Parameters - ---------- - x : xp.array - dim R^{N^1} - - Returns - ---------- - res : xp.array - dim R^{N^2} - - Notes - ----- - U1 = pi_2[g_sqrt * G_inv * lambda^1] in R^{N^2 x N^1} - - U1.x = I_2( R_2 ( F_U1.x)) - - I_2 ... inverse inter/histopolation matrix (tensor product) - - R_2 ... compute DOFs from function values at point set pts_ijk - - F_U1[ijk, mno] = g_sqrt(pts_ijk) * G_inv(pts_ijk) * lambda^1_mno(pts_ijk) - - * spline evaluation (at V_2 point sets) - * [int, his, his] points: {greville[0], quad_pts[1], quad_pts[2]} - * [his, int, his] points: {quad_pts[0], greville[1], quad_pts[2]} - * [his, his, int] points: {quad_pts[0], quad_pts[1], greville[2]} - - * Components of F_U1: - * evaluated at [int, his, his] : (D, N, N) * G_inv_11 * g_sqrt + (N, D, N) * G_inv_12 * g_sqrt + (N, N, D) * G_inv_13 * g_sqrt - * evaluated at [his, int, his] : (D, N, N) * G_inv_21 * g_sqrt + (N, D, N) * G_inv_22 * g_sqrt + (N, N, D) * G_inv_23 * g_sqrt - * evaluated at [his, his, int] : (D, N, N) * G_inv_31 * g_sqrt + (N, D, N) * G_inv_32 * g_sqrt + (N, N, D) * G_inv_33 * g_sqrt - """ - # x dim check - # x should be R{N^1} - # assert len(x) == self.space.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - # assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - # assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - # assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - # xi1 - mat_f_11 = kron_matvec_3d([self.pts0_D_1, self.pts1_N_2, self.pts1_N_3], x_loc[0]) - mat_f_12 = kron_matvec_3d([self.pts0_N_1, self.pts1_D_2, self.pts1_N_3], x_loc[1]) - mat_f_13 = kron_matvec_3d([self.pts0_N_1, self.pts1_N_2, self.pts1_D_3], x_loc[2]) - - # xi2 - mat_f_21 = kron_matvec_3d([self.pts1_D_1, self.pts0_N_2, self.pts1_N_3], x_loc[0]) - mat_f_22 = kron_matvec_3d([self.pts1_N_1, self.pts0_D_2, self.pts1_N_3], x_loc[1]) - mat_f_23 = kron_matvec_3d([self.pts1_N_1, self.pts0_N_2, self.pts1_D_3], x_loc[2]) - - # xi3 - mat_f_31 = kron_matvec_3d([self.pts1_D_1, self.pts1_N_2, self.pts0_N_3], x_loc[0]) - mat_f_32 = kron_matvec_3d([self.pts1_N_1, self.pts1_D_2, self.pts0_N_3], x_loc[1]) - mat_f_33 = kron_matvec_3d([self.pts1_N_1, self.pts1_N_2, self.pts0_D_3], x_loc[2]) - - mat_f_11_c = mat_f_11 * self.det_df_21 * self.g_inv_21[0, 0] - mat_f_12_c = mat_f_12 * self.det_df_21 * self.g_inv_21[0, 1] - mat_f_13_c = mat_f_13 * self.det_df_21 * self.g_inv_21[0, 2] - mat_f_21_c = mat_f_21 * self.det_df_22 * self.g_inv_22[1, 0] - mat_f_22_c = mat_f_22 * self.det_df_22 * self.g_inv_22[1, 1] - mat_f_23_c = mat_f_23 * self.det_df_22 * self.g_inv_22[1, 2] - mat_f_31_c = mat_f_31 * self.det_df_23 * self.g_inv_23[2, 0] - mat_f_32_c = mat_f_32 * self.det_df_23 * self.g_inv_23[2, 1] - mat_f_33_c = mat_f_33 * self.det_df_23 * self.g_inv_23[2, 2] - - mat_f_1_c = mat_f_11_c + mat_f_12_c + mat_f_13_c - mat_f_2_c = mat_f_21_c + mat_f_22_c + mat_f_23_c - mat_f_3_c = mat_f_31_c + mat_f_32_c + mat_f_33_c - - # ========== Step 2 : R( F(x) ) ==========# - # integration over quadrature points - # xi1 : DOF_1_{i,j,k} = sum_{m} w_{i,m} * mat_f_1_{i,m,j,k} - DOF_1 = self.space.projectors.dofs("21", mat_f_1_c) - - # xi2 : DOF_2_{i,j,k} = sum_{m} w_{j,m} * mat_f_2_{i,j,m,k} - DOF_2 = self.space.projectors.dofs("22", mat_f_2_c) - - # xi3 : DOF_3_{i,j,k} = sum_{m} w_{k,m} * mat_f_3_{i,j,k,m} - DOF_3 = self.space.projectors.dofs("23", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # xi1 : inter(xi1)-histo(xi2)-histo(xi3)-polation. - res_1 = self.space.projectors.PI_mat("21", DOF_1) - - # xi2 : histo(xi1)-inter(xi2)-histo(xi3)-polation. - res_2 = self.space.projectors.PI_mat("22", DOF_2) - - # xi3 : histo(xi1)-histo(xi2)-inter(xi3)-polation. - res_3 = self.space.projectors.PI_mat("23", DOF_3) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def transpose_U1_dot(self, x): - """ - Matrix-vector product U1.T.x - - Parameters - ---------- - x : xp.array - dim R{N^2} - - Returns - ---------- - res : xp.array - dim R{N^1} - - Notes - ----- - U1.x = I_2( R_2 ( F_U1.x)) - - U1.T.x = F_U1.T( R_2.T ( I_2.T.x)) - - See U1_dot for more details. - """ - - # x dim check - # x should be R{N^2} - # assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - # assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - # assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - # assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # step1 : I.T(x) - # xi1 : transpose of inter(xi1)-histo(xi2)-histo(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.N_1.T, self.D_2.T, self.D_3.T], x_loc[0]) - - # xi2 : transpose of histo(xi1)-inter(xi2)-histo(xi3)-polati on. - mat_dofs_2 = kron_solve_3d([self.D_1.T, self.N_2.T, self.D_3.T], x_loc[1]) - - # xi3 : transpose of histo(xi1)-histo(xi2)-inter(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.D_1.T, self.D_2.T, self.N_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - # transpose of integration over quadrature points - # xi1 - mat_f_1 = self.space.projectors.dofs_T("21", mat_dofs_1) - - # xi2 - mat_f_2 = self.space.projectors.dofs_T("22", mat_dofs_2) - - # xi3 - mat_f_3 = self.space.projectors.dofs_T("23", mat_dofs_3) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_11_c = mat_f_1 * self.det_df_21 * self.g_inv_21[0, 0] - mat_f_12_c = mat_f_1 * self.det_df_21 * self.g_inv_21[0, 1] - mat_f_13_c = mat_f_1 * self.det_df_21 * self.g_inv_21[0, 2] - mat_f_21_c = mat_f_2 * self.det_df_22 * self.g_inv_22[1, 0] - mat_f_22_c = mat_f_2 * self.det_df_22 * self.g_inv_22[1, 1] - mat_f_23_c = mat_f_2 * self.det_df_22 * self.g_inv_22[1, 2] - mat_f_31_c = mat_f_3 * self.det_df_23 * self.g_inv_23[2, 0] - mat_f_32_c = mat_f_3 * self.det_df_23 * self.g_inv_23[2, 1] - mat_f_33_c = mat_f_3 * self.det_df_23 * self.g_inv_23[2, 2] - - res_11 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_N_2.T, self.pts1_N_3.T], mat_f_11_c) - res_12 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_D_2.T, self.pts1_N_3.T], mat_f_12_c) - res_13 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_N_2.T, self.pts1_D_3.T], mat_f_13_c) - - res_21 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_N_2.T, self.pts1_N_3.T], mat_f_21_c) - res_22 = kron_matvec_3d([self.pts1_N_1.T, self.pts0_D_2.T, self.pts1_N_3.T], mat_f_22_c) - res_23 = kron_matvec_3d([self.pts1_N_1.T, self.pts0_N_2.T, self.pts1_D_3.T], mat_f_23_c) - - res_31 = kron_matvec_3d([self.pts1_D_1.T, self.pts1_N_2.T, self.pts0_N_3.T], mat_f_31_c) - res_32 = kron_matvec_3d([self.pts1_N_1.T, self.pts1_D_2.T, self.pts0_N_3.T], mat_f_32_c) - res_33 = kron_matvec_3d([self.pts1_N_1.T, self.pts1_N_2.T, self.pts0_D_3.T], mat_f_33_c) - - res_1 = res_11 + res_21 + res_31 - res_2 = res_12 + res_22 + res_32 - res_3 = res_13 + res_23 + res_33 - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def P1_dot(self, x): - """ - Matrix-vector product P1.x - - Parameters - ---------- - x : xp.array - dim R^{N^2} - - Returns - ---------- - res : xp.array - dim R^{N^1} - - Notes - ----- - P1 = pi_1[jmat_eq / g_sqrt * lambda^2] in R{N^1 x N^2} - - jmat_eq = [[0 , -j_eq_z, j_eq_y], [j_eq_z, 0 , -j_eq_x], [-j_eq_y, j_eq_x, 0]] in R^{3 x 3} - - P1.x = I_1( R_1 ( F_P1.x)) - - I_1 ... inverse inter/histopolation matrix (tensor product) - - R_1 ... compute DOFs from function values at point set pts_ijk - - F_P1[ijk, mno] = jmat_eq(pts_ijk) / g_sqrt(pts_ijk) * lambda^2_mno(pts_ijk) - - * spline evaluation (at V_1 point sets) - * [his, int, int] points: {quad_pts[0], greville[1], greville[2]} - * [int, his, int] points: {greville[0], quad_pts[1], greville[2]} - * [int, int, his] points: {greville[0], greville[1], quad_pts[2]} - - * Components of F_P1: - * evaluated at [his, int, int] : (D, N, D) * (-j_eq_z) / g_sqrt + (D, D, N) * j_eq_y / g_sqrt - * evaluated at [int, his, int] : (N, D, D) * j_eq_z / g_sqrt + (D, D, N) * (-j_eq_x) / g_sqrt - * evaluated at [int, int, his] : (N, D, D) * (-j_eq_y) / g_sqrt + (D, N, D) * j_eq_x / g_sqrt, - """ - - # x dim check - # x should be R{N^2} - # assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - # assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - # assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - # assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - # xi1 - mat_f_11 = kron_matvec_3d([self.pts1_N_1, self.pts0_D_2, self.pts0_D_3], x_loc[0]) # 0 - mat_f_12 = kron_matvec_3d([self.pts1_D_1, self.pts0_N_2, self.pts0_D_3], x_loc[1]) - mat_f_13 = kron_matvec_3d([self.pts1_D_1, self.pts0_D_2, self.pts0_N_3], x_loc[2]) - - # xi2 - mat_f_21 = kron_matvec_3d([self.pts0_N_1, self.pts1_D_2, self.pts0_D_3], x_loc[0]) - mat_f_22 = kron_matvec_3d([self.pts0_D_1, self.pts1_N_2, self.pts0_D_3], x_loc[1]) # 0 - mat_f_23 = kron_matvec_3d([self.pts0_D_1, self.pts1_D_2, self.pts0_N_3], x_loc[2]) - - # xi3 - mat_f_31 = kron_matvec_3d([self.pts0_N_1, self.pts0_D_2, self.pts1_D_3], x_loc[0]) - mat_f_32 = kron_matvec_3d([self.pts0_D_1, self.pts0_N_2, self.pts1_D_3], x_loc[1]) - mat_f_33 = kron_matvec_3d([self.pts0_D_1, self.pts0_D_2, self.pts1_N_3], x_loc[2]) # 0 - - mat_f_11_c = mat_f_11 * 0 / self.det_df_11 - mat_f_12_c = mat_f_12 * (-self.j2_eq_11_3) / self.det_df_11 - mat_f_13_c = mat_f_13 * (self.j2_eq_11_2) / self.det_df_11 - mat_f_21_c = mat_f_21 * (self.j2_eq_12_3) / self.det_df_12 - mat_f_22_c = mat_f_22 * 0 / self.det_df_12 - mat_f_23_c = mat_f_23 * (-self.j2_eq_12_1) / self.det_df_12 - mat_f_31_c = mat_f_31 * (-self.j2_eq_13_2) / self.det_df_13 - mat_f_32_c = mat_f_32 * (self.j2_eq_13_1) / self.det_df_13 - mat_f_33_c = mat_f_33 * 0 / self.det_df_13 - - mat_f_1_c = mat_f_11_c + mat_f_12_c + mat_f_13_c - mat_f_2_c = mat_f_21_c + mat_f_22_c + mat_f_23_c - mat_f_3_c = mat_f_31_c + mat_f_32_c + mat_f_33_c - - # ========== Step 2 : R( F(x) ) ==========# - # integration over quadrature points - # xi1 : DOF_1_{i,j,k} = sum_{m} w_{i,m} * mat_f_1_{i,m,j,k} - DOF_1 = self.space.projectors.dofs("11", mat_f_1_c) - - # xi2 : DOF_2_{i,j,k} = sum_{m} w_{j,m} * mat_f_2_{i,j,m,k} - DOF_2 = self.space.projectors.dofs("12", mat_f_2_c) - - # xi3 : DOF_3_{i,j,k} = sum_{m} w_{k,m} * mat_f_3_{i,j,k,m} - DOF_3 = self.space.projectors.dofs("13", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # xi1 : histo(xi1)-inter(xi2)-inter(xi3)-polation. - res_1 = self.space.projectors.PI_mat("11", DOF_1) - - # xi2 : inter(xi1)-histo(xi2)-inter(xi3)-polation. - res_2 = self.space.projectors.PI_mat("12", DOF_2) - - # xi3 : inter(xi1)-inter(xi2)-histo(xi3)-polation. - res_3 = self.space.projectors.PI_mat("13", DOF_3) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def transpose_P1_dot(self, x): - """ - Matrix-vector product P1.T.x - - Parameters - ---------- - x : xp.array - dim R{N^1} - - Returns - ---------- - res : xp.array - dim R{N^2} - - Notes - ----- - P1.x = I_1( R_1 ( F_P1.x)) - - P1.T.x = F_P1.T( R_1.T ( I_1.T.x)) - - See P1_dot for more details. - """ - - # x dim check - # x should be R{N^1} - # assert len(x) == self.space.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - # assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - # assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - # assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # step1 : I.T(x) - # xi1 : transpose of histo(xi1)-inter(xi2)-inter(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.D_1.T, self.N_2.T, self.N_3.T], x_loc[0]) - - # xi2 : transpose of inter(xi1)-histo(xi2)-inter(xi3)-polation. - mat_dofs_2 = kron_solve_3d([self.N_1.T, self.D_2.T, self.N_3.T], x_loc[1]) - - # xi3 : transpose of inter(xi1)-inter(xi2)-histo(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.N_1.T, self.N_2.T, self.D_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - # transpose of integration over quadrature points - # xi1 - mat_f_1 = self.space.projectors.dofs_T("11", mat_dofs_1) - - # xi2 - mat_f_2 = self.space.projectors.dofs_T("12", mat_dofs_2) - - # xi3 - mat_f_3 = self.space.projectors.dofs_T("13", mat_dofs_3) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_11_c = mat_f_1 * 0 / self.det_df_11 - mat_f_12_c = mat_f_1 * (-self.j2_eq_11_3) / self.det_df_11 - mat_f_13_c = mat_f_1 * (self.j2_eq_11_2) / self.det_df_11 - mat_f_21_c = mat_f_2 * (self.j2_eq_12_3) / self.det_df_12 - mat_f_22_c = mat_f_2 * 0 / self.det_df_12 - mat_f_23_c = mat_f_2 * (-self.j2_eq_12_1) / self.det_df_12 - mat_f_31_c = mat_f_3 * (-self.j2_eq_13_2) / self.det_df_13 - mat_f_32_c = mat_f_3 * (self.j2_eq_13_1) / self.det_df_13 - mat_f_33_c = mat_f_3 * 0 / self.det_df_13 - - res_11 = kron_matvec_3d([self.pts1_N_1.T, self.pts0_D_2.T, self.pts0_D_3.T], mat_f_11_c) # 0 - res_12 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_N_2.T, self.pts0_D_3.T], mat_f_12_c) - res_13 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_D_2.T, self.pts0_N_3.T], mat_f_13_c) - - res_21 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_D_2.T, self.pts0_D_3.T], mat_f_21_c) - res_22 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_N_2.T, self.pts0_D_3.T], mat_f_22_c) # 0 - res_23 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_D_2.T, self.pts0_N_3.T], mat_f_23_c) - - res_31 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_D_2.T, self.pts1_D_3.T], mat_f_31_c) - res_32 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_N_2.T, self.pts1_D_3.T], mat_f_32_c) - res_33 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_D_2.T, self.pts1_N_3.T], mat_f_33_c) # 0 - - res_1 = res_11 + res_21 + res_31 - res_2 = res_12 + res_22 + res_32 - res_3 = res_13 + res_23 + res_33 - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def S1_dot(self, x): - """ - Matrix-vector product S1.x - - Parameters - ---------- - x : xp.array - dim R^{N^1} - - Returns - ---------- - res : xp.array - dim R^{N^2} - - Notes - ----- - S1 = pi_2[p_eq * G_inv * lambda^1] in R{N^2 x N^1} - - S1.x = I_2( R_2 ( F_S1.x)) - - I_2 ... inverse inter/histopolation matrix (tensor product) - - R_2 ... compute DOFs from function values at point set pts_ijk - - F_S1[ijk, mno] = p_eq(pts_ijk) * G_inv(pts_ijk) * lambda^1_mno(pts_ijk) - - * spline evaluation (at V_2 point sets) - * [int, his, his] points: {greville[0], quad_pts[1], quad_pts[2]} - * [his, int, his] points: {quad_pts[0], greville[1], quad_pts[2]} - * [his, his, int] points: {quad_pts[0], quad_pts[1], greville[2]} - - * Components of F_S1: - * evaluated at [int, his, his] : (D, N, N) * G_inv_11 * p_eq + (N, D, N) * G_inv_12 * p_eq + (N, N, D) * G_inv_13 * p_eq - * evaluated at [his, int, his] : (D, N, N) * G_inv_21 * p_eq + (N, D, N) * G_inv_22 * p_eq + (N, N, D) * G_inv_23 * p_eq - * evaluated at [his, his, int] : (D, N, N) * G_inv_31 * p_eq + (N, D, N) * G_inv_32 * p_eq + (N, N, D) * G_inv_33 * p_eq - """ - - # x dim check - # x should be R{N^1} - # assert len(x) == self.space.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - # assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - # assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - # assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - # xi1 - mat_f_11 = kron_matvec_3d([self.pts0_D_1, self.pts1_N_2, self.pts1_N_3], x_loc[0]) - mat_f_12 = kron_matvec_3d([self.pts0_N_1, self.pts1_D_2, self.pts1_N_3], x_loc[1]) - mat_f_13 = kron_matvec_3d([self.pts0_N_1, self.pts1_N_2, self.pts1_D_3], x_loc[2]) - - # xi2 - mat_f_21 = kron_matvec_3d([self.pts1_D_1, self.pts0_N_2, self.pts1_N_3], x_loc[0]) - mat_f_22 = kron_matvec_3d([self.pts1_N_1, self.pts0_D_2, self.pts1_N_3], x_loc[1]) - mat_f_23 = kron_matvec_3d([self.pts1_N_1, self.pts0_N_2, self.pts1_D_3], x_loc[2]) - - # xi3 - mat_f_31 = kron_matvec_3d([self.pts1_D_1, self.pts1_N_2, self.pts0_N_3], x_loc[0]) - mat_f_32 = kron_matvec_3d([self.pts1_N_1, self.pts1_D_2, self.pts0_N_3], x_loc[1]) - mat_f_33 = kron_matvec_3d([self.pts1_N_1, self.pts1_N_2, self.pts0_D_3], x_loc[2]) - - mat_f_11_c = mat_f_11 * self.p3_eq_21 * self.g_inv_21[0, 0] - mat_f_12_c = mat_f_12 * self.p3_eq_21 * self.g_inv_21[0, 1] - mat_f_13_c = mat_f_13 * self.p3_eq_21 * self.g_inv_21[0, 2] - mat_f_21_c = mat_f_21 * self.p3_eq_22 * self.g_inv_22[1, 0] - mat_f_22_c = mat_f_22 * self.p3_eq_22 * self.g_inv_22[1, 1] - mat_f_23_c = mat_f_23 * self.p3_eq_22 * self.g_inv_22[1, 2] - mat_f_31_c = mat_f_31 * self.p3_eq_23 * self.g_inv_23[2, 0] - mat_f_32_c = mat_f_32 * self.p3_eq_23 * self.g_inv_23[2, 1] - mat_f_33_c = mat_f_33 * self.p3_eq_23 * self.g_inv_23[2, 2] - - mat_f_1_c = mat_f_11_c + mat_f_12_c + mat_f_13_c - mat_f_2_c = mat_f_21_c + mat_f_22_c + mat_f_23_c - mat_f_3_c = mat_f_31_c + mat_f_32_c + mat_f_33_c - - # ========== Step 2 : R( F(x) ) ==========# - # integration over quadrature points - # xi1 : DOF_1_{i,j,k} = sum_{m} w_{i,m} * mat_f_1_{i,m,j,k} - DOF_1 = self.space.projectors.dofs("21", mat_f_1_c) - - # xi2 : DOF_2_{i,j,k} = sum_{m} w_{j,m} * mat_f_2_{i,j,m,k} - DOF_2 = self.space.projectors.dofs("22", mat_f_2_c) - - # xi3 : DOF_3_{i,j,k} = sum_{m} w_{k,m} * mat_f_3_{i,j,k,m} - DOF_3 = self.space.projectors.dofs("23", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # xi1 : inter(xi1)-histo(xi2)-histo(xi3)-polation. - res_1 = self.space.projectors.PI_mat("21", DOF_1) - - # xi2 : histo(xi1)-inter(xi2)-histo(xi3)-polation. - res_2 = self.space.projectors.PI_mat("22", DOF_2) - - # xi3 : histo(xi1)-histo(xi2)-inter(xi3)-polation. - res_3 = self.space.projectors.PI_mat("23", DOF_3) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def transpose_S1_dot(self, x): - """ - Matrix-vector product S1.T.x - - Parameters - ---------- - x : xp.array - dim R{N^2} - - Returns - ---------- - res : xp.array - dim R{N^1} - - Notes - ----- - S1.x = I_2( R_2 ( F_S1.x)) - - S1.T.x = F_S1.T( R_2.T ( I_2.T.x)) - - See S1_dot for more details. - """ - - # x dim check - # x should be R{N^2} - # assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - # assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - # assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - # assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # step1 : I.T(x) - # xi1 : transpose of inter(xi1)-histo(xi2)-histo(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.N_1.T, self.D_2.T, self.D_3.T], x_loc[0]) - - # xi2 : transpose of histo(xi1)-inter(xi2)-histo(xi3)-polati on. - mat_dofs_2 = kron_solve_3d([self.D_1.T, self.N_2.T, self.D_3.T], x_loc[1]) - - # xi3 : transpose of histo(xi1)-histo(xi2)-inter(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.D_1.T, self.D_2.T, self.N_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - # transpose of integration over quadrature points - # xi1 - mat_f_1 = self.space.projectors.dofs_T("21", mat_dofs_1) - - # xi2 - mat_f_2 = self.space.projectors.dofs_T("22", mat_dofs_2) - - # xi3 - mat_f_3 = self.space.projectors.dofs_T("23", mat_dofs_3) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_11_c = mat_f_1 * self.p3_eq_21 * self.g_inv_21[0, 0] - mat_f_12_c = mat_f_1 * self.p3_eq_21 * self.g_inv_21[0, 1] - mat_f_13_c = mat_f_1 * self.p3_eq_21 * self.g_inv_21[0, 2] - mat_f_21_c = mat_f_2 * self.p3_eq_22 * self.g_inv_22[1, 0] - mat_f_22_c = mat_f_2 * self.p3_eq_22 * self.g_inv_22[1, 1] - mat_f_23_c = mat_f_2 * self.p3_eq_22 * self.g_inv_22[1, 2] - mat_f_31_c = mat_f_3 * self.p3_eq_23 * self.g_inv_23[2, 0] - mat_f_32_c = mat_f_3 * self.p3_eq_23 * self.g_inv_23[2, 1] - mat_f_33_c = mat_f_3 * self.p3_eq_23 * self.g_inv_23[2, 2] - - res_11 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_N_2.T, self.pts1_N_3.T], mat_f_11_c) - res_21 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_D_2.T, self.pts1_N_3.T], mat_f_12_c) - res_31 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_N_2.T, self.pts1_D_3.T], mat_f_13_c) - - res_12 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_N_2.T, self.pts1_N_3.T], mat_f_21_c) - res_22 = kron_matvec_3d([self.pts1_N_1.T, self.pts0_D_2.T, self.pts1_N_3.T], mat_f_22_c) - res_32 = kron_matvec_3d([self.pts1_N_1.T, self.pts0_N_2.T, self.pts1_D_3.T], mat_f_23_c) - - res_13 = kron_matvec_3d([self.pts1_D_1.T, self.pts1_N_2.T, self.pts0_N_3.T], mat_f_31_c) - res_23 = kron_matvec_3d([self.pts1_N_1.T, self.pts1_D_2.T, self.pts0_N_3.T], mat_f_32_c) - res_33 = kron_matvec_3d([self.pts1_N_1.T, self.pts1_N_2.T, self.pts0_D_3.T], mat_f_33_c) - - res_1 = res_11 + res_21 + res_31 - res_2 = res_12 + res_22 + res_32 - res_3 = res_13 + res_23 + res_33 - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # =================================================================== - def S10_dot(self, x): - """ - Matrix-vector product S10.x - - Parameters - ---------- - x : xp.array - dim R^{N^1} - - Returns - ---------- - res : xp.array - dim R^{N^1} - - Notes - ----- - S10 = pi_1[p_eq * lambda^1] in R{N^1 x N^1} - - S10.x = I_1( R_1 ( F_S10.x)) - - I_1 ... inverse inter/histopolation matrix (tensor product) - - R_1 ... compute DOFs from function values at point set pts_ijk - - F_S10[ijk, mno] = p_eq(pts_ijk) * lambda^1_mno(pts_ijk) - - * spline evaluation (at V_1 point sets) - * [his, int, int] points: {quad_pts[0], greville[1], greville[2]} - * [int, his, int] points: {greville[0], quad_pts[1], greville[2]} - * [int, int, his] points: {greville[0], greville[1], quad_pts[2]} - - * Components of F_W1: - * evaluated at [his, int, int] : (D, N, N) * p_eq + (N, D, N) * p_eq + (N, N, D) * p_eq - * evaluated at [int, his, int] : (D, N, N) * p_eq + (N, D, N) * p_eq + (N, N, D) * p_eq - * evaluated at [int, int, his] : (D, N, N) * p_eq + (N, D, N) * p_eq + (N, N, D) * p_eq - """ - - # x dim check - # x should be R{N^1} - # assert len(x) == self.space.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - # assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - # assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - # assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - mat_f_1 = kron_matvec_3d([self.pts1_D_1, self.pts0_N_2, self.pts0_N_3], x_loc[0]) - mat_f_2 = kron_matvec_3d([self.pts0_N_1, self.pts1_D_2, self.pts0_N_3], x_loc[1]) - mat_f_3 = kron_matvec_3d([self.pts0_N_1, self.pts0_N_2, self.pts1_D_3], x_loc[2]) - - mat_f_1_c = mat_f_1 * self.p0_eq_11 - mat_f_2_c = mat_f_2 * self.p0_eq_12 - mat_f_3_c = mat_f_3 * self.p0_eq_13 - - # ========== Step 2 : R( F(x) ) ==========# - # integration over quadrature points - # xi1 : DOF_1_{i,j,k} = sum_{m} w_{i,m} * mat_f_1_{i,m,j,k} - DOF_1 = self.space.projectors.dofs("11", mat_f_1_c) - - # xi2 : DOF_2_{i,j,k} = sum_{m} w_{j,m} * mat_f_2_{i,j,m,k} - DOF_2 = self.space.projectors.dofs("12", mat_f_2_c) - - # xi3 : DOF_3_{i,j,k} = sum_{m} w_{k,m} * mat_f_3_{i,j,k,m} - DOF_3 = self.space.projectors.dofs("13", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # xi1 : histo(xi1)-inter(xi2)-inter(xi3)-polation. - res_1 = self.space.projectors.PI_mat("11", DOF_1) - - # xi2 : inter(xi1)-histo(xi2)-inter(xi3)-polation. - res_2 = self.space.projectors.PI_mat("12", DOF_2) - - # xi3 : inter(xi1)-inter(xi2)-histo(xi3)-polation. - res_3 = self.space.projectors.PI_mat("13", DOF_3) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # =================================================================== - def transpose_S10_dot(self, x): - """ - Matrix-vector product S10.T.x - - Parameters - ---------- - x : xp.array - dim R{N^1} - - Returns - ---------- - res : xp.array - dim R{N^1} - - Notes - ----- - S10.x = I_1( R_1 ( F_S10.x)) - - S10.T.x = F_S10.T( R_1.T ( I_1.T.x)) - - See S10_dot for more details. - """ - # x dim check - # x should be R{N^1} - # assert len(x) == self.space.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - # assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - # assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - # assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # step1 : I.T(x) - # xi1 : transpose of histo(xi1)-inter(xi2)-inter(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.D_1.T, self.N_2.T, self.N_3.T], x_loc[0]) - - # xi2 : transpose of inter(xi1)-histo(xi2)-inter(xi3)-polation. - mat_dofs_2 = kron_solve_3d([self.N_1.T, self.D_2.T, self.N_3.T], x_loc[1]) - - # xi3 : transpose of inter(xi1)-inter(xi2)-histo(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.N_1.T, self.N_2.T, self.D_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - # transpose of integration over quadrature points - # xi1 : mat_f_1_{i,m,j,k} = w_{i,m} * DOF_1_{i,j,k} - mat_f_1 = self.space.projectors.dofs_T("11", mat_dofs_1) - - # xi2 : mat_f_2_{i,j,m,k} = w_{j,m} * DOF_2_{i,j,k} - mat_f_2 = self.space.projectors.dofs_T("12", mat_dofs_2) - - # xi3 : mat_f_2_{i,j,k,m} = w_{k,m} * DOF_3_{i,j,k} - mat_f_3 = self.space.projectors.dofs_T("13", mat_dofs_3) - - mat_f_1_c = mat_f_1 * self.p0_eq_11 - mat_f_2_c = mat_f_2 * self.p0_eq_12 - mat_f_3_c = mat_f_3 * self.p0_eq_13 - - res_1 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_N_2.T, self.pts0_N_3.T], mat_f_1_c) - res_2 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_D_2.T, self.pts0_N_3.T], mat_f_2_c) - res_3 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_N_2.T, self.pts1_D_3.T], mat_f_3_c) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ================================================================= - def K1_dot(self, x): - """ - Matrix-vector product K1.x - - Parameters - ---------- - x : xp.array - dim R^{N^3} - - Returns - ---------- - res : xp.array - dim R^{N^3} - - Notes - ----- - K1 = pi_3[p_eq / g_sqrt * lambda^3] in R{N^3 x N^3} - - K1.x = I_3( R_3 ( F_K1.x)) - - I_3 ... inverse histopolation matrix (tensor product) - - R_3 ... compute DOFs from function values at point set pts_ijk - - F_K1[ijk,mno] = p_eq(pts_ijk) / g_sqrt(pts_ijk) * lambda^3_mno(pts_ijk) - - * spline evaluation (at V_3 point sets) - * [his, his, his] points: {quad_pts[0], quad_pts[1], quad_pts[2]} - - * Components of F_K1: - * evaluated at [his, his, his] : (D, D, D) * p_eq / sqrt g - """ - - # x dim check - # assert len(x) == self.space.Ntot_3form - x_loc = self.space.extract_3(x) - - # assert x_loc.shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseD[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - - mat_f = kron_matvec_3d([self.pts1_D_1, self.pts1_D_2, self.pts1_D_3], x_loc) - - mat_f_c = mat_f * self.p3_eq_3 / self.det_df_3 - - # ========== Step 2 : R( F(x) ) ==========# - # Linear operator : evaluation values at the projection points to the Degree of Freedom of the spline. - DOF = self.space.projectors.dofs("3", mat_f_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # histo(xi1)-histo(xi2)-histo(xi3)-polation. - res = self.space.projectors.PI_mat("3", DOF) - - return res.flatten() - - # ================================================================= - def transpose_K1_dot(self, x): - """ - Matrix-vector product K1.T.x - - Parameters - ---------- - x : xp.array - dim R{N^3} - - Returns - ---------- - res : 3d array - dim R{N^3} - - Notes - ----- - K1.x = I_3( R_3 ( F_K1.x)) - - K1.T.x = F_K1.T( R_3.T ( I_3.T.x)) - - See K1_dot for more details. - """ - - # x dim check - # assert len(x) == self.space.Ntot_3form - x_loc = self.space.extract_3(x) - - # assert x_loc.shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseD[2]) - - # step1 : I.T(x) - mat_dofs = kron_solve_3d([self.D_1.T, self.D_2.T, self.D_3.T], x_loc) - - # step2 : R.T( I.T(x) ) - mat_f = self.space.projectors.dofs_T("3", mat_dofs) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_c = self.p3_eq_3 * mat_f / self.det_df_3 - - res = kron_matvec_3d([self.pts1_D_1.T, self.pts1_D_2.T, self.pts1_D_3.T], mat_f_c) - - return res.flatten() - - # ================================================================= - def K10_dot(self, x): - """ - Matrix-vector product K10.x - - Parameters - ---------- - x : xp.array - dim R^{N^0} - - Returns - ---------- - res : xp.array - dim R^{N^0} - - Notes - ----- - K10 = pi_0[p_eq * lambda^0] in R^{N^0 x N^0} - - K10.x = I_0( R_0 ( F_K10.x)) - - I_0 ... inverse interpolation matrix (tensor product) - - R_0 ... compute DOFs from function values at point set pts_ijk - - F_K10[ijk,mno] = p_eq(pts_ijk) * lambda^0_mno(pts_ijk) - - * spline evaluation (at V_0 point sets) - * [int, int, int] points: {greville[0], greville[1], greville[2]} - - * Components of F_K10: - * evaluated at [int, int, int] : (N, N, N) * p_eq - """ - - # x dim check - # assert len(x) == self.space.Ntot_0form - x_loc = self.space.extract_0(x) - - # assert x_loc.shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseN[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - mat_f = kron_matvec_3d([self.pts0_N_1, self.pts0_N_2, self.pts0_N_3], x_loc) - - mat_f_c = mat_f * self.p0_eq_0 - - # ========== Step 2 : R( F(x) ) ==========# - # Linear operator : evaluation values at the projection points to the Degree of Freedom of the spline. - DOF = self.space.projectors.dofs("0", mat_f_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # histo(xi1)-histo(xi2)-histo(xi3)-polation. - res = self.space.projectors.PI_mat("0", DOF) - - return res.flatten() - - # ================================================================= - def transpose_K10_dot(self, x): - """ - Matrix vecotr product K10.T.x - - Parameters - ---------- - x : xp.array - dim R{N^0} - - Returns - ---------- - res : 3d array - dim R{N^0} - - Notes - ----- - K10.x = I_0( R_0 ( F_K10.x)) - - K10.T.x = F_K10.T( R_0.T ( I_0.T.x)) - - See K10_dot for more details. - """ - - # x dim check - # assert len(x) == self.space.Ntot_0form - x_loc = self.space.extract_0(x) - - # assert x_loc.shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseN[2]) - - # step1 : I.T(x) - mat_dofs = kron_solve_3d([self.N_1.T, self.N_2.T, self.N_3.T], x_loc) - - # step2 : R.T( I.T(x) ) - mat_f = self.space.projectors.dofs_T("0", mat_dofs) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_c = self.p0_eq_0 * mat_f - - res = kron_matvec_3d([self.pts0_N_1.T, self.pts0_N_2.T, self.pts0_N_3.T], mat_f_c) - - return res.flatten() - - # ================================================================= - def T1_dot(self, x): - """ - Matrix-vector product T1.x - - Parameters - ---------- - x : xp.array - dim R^{N^1} - - Returns - ---------- - res : xp.array - dim R^{N^1} - - Notes - ----- - T1 = pi_1[Bmat_eq * G_inv * lambda^1] in R^{N^1 x N^1} - - Bmat_eq = [[0 , -b_eq_z, b_eq_y], [b_eq_z, 0 , -b_eq_x], [-b_eq_y, b_eq_x, 0]] - - T1.x = I_1( R_1 ( F_T1.x)) - - I_1 ... inverse inter/histopolation matrix (tensor product) - - R_1 ... compute DOFs from function values at point set pts_ijk - - F_T1[ijk, mno] = B_eq(pts_ijk) * G_inv(pts_ijk) lambda^1_mno(pts_ijk) - - * spline evaluation (at V_1 point sets) - * [his, int, int] points: {quad_pts[0], greville[1], greville[2]} - * [int, his, int] points: {greville[0], quad_pts[1], greville[2]} - * [int, int, his] points: {greville[0], greville[1], quad_pts[2]} - - * Components of F_T1: - * evaluated at [his, int, int] : (D, N, N) * (G_inv_31 * b_eq_y - G_inv_21 * b_eq_z) + (N, D, N) * (G_inv_32 * b_eq_y - G_inv_22 * b_eq_z) + (N, N, D) * (G_inv_33 * b_eq_y - G_inv_23 * b_eq_z) - * evaluated at [int, his, int] : (D, N, N) * (G_inv_11 * b_eq_z - G_inv_31 * b_eq_x) + (N, D, N) * (G_inv_12 * b_eq_z - G_inv_32 * b_eq_x) + (N, N, D) * (G_inv_13 * b_eq_z - G_inv_33 * b_eq_x) - * evaluated at [int, int, his] : (D, N, N) * (G_inv_21 * b_eq_x - G_inv_11 * b_eq_y) + (N, D, N) * (G_inv_22 * b_eq_x - G_inv_12 * b_eq_y) + (N, N, D) * (G_inv_23 * b_eq_x - G_inv_13 * b_eq_y) - """ - - # x dim check - # x should be R{N^1} - # assert len(x) == self.space.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - # assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - # assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - # assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - # xi1 - mat_f_11 = kron_matvec_3d([self.pts1_D_1, self.pts0_N_2, self.pts0_N_3], x_loc[0]) - mat_f_12 = kron_matvec_3d([self.pts1_N_1, self.pts0_D_2, self.pts0_N_3], x_loc[1]) - mat_f_13 = kron_matvec_3d([self.pts1_N_1, self.pts0_N_2, self.pts0_D_3], x_loc[2]) - - # xi2 - mat_f_21 = kron_matvec_3d([self.pts0_D_1, self.pts1_N_2, self.pts0_N_3], x_loc[0]) - mat_f_22 = kron_matvec_3d([self.pts0_N_1, self.pts1_D_2, self.pts0_N_3], x_loc[1]) - mat_f_23 = kron_matvec_3d([self.pts0_N_1, self.pts1_N_2, self.pts0_D_3], x_loc[2]) - - # xi3 - mat_f_31 = kron_matvec_3d([self.pts0_D_1, self.pts0_N_2, self.pts1_N_3], x_loc[0]) - mat_f_32 = kron_matvec_3d([self.pts0_N_1, self.pts0_D_2, self.pts1_N_3], x_loc[1]) - mat_f_33 = kron_matvec_3d([self.pts0_N_1, self.pts0_N_2, self.pts1_D_3], x_loc[2]) - - mat_f_11_c = mat_f_11 * (self.g_inv_11[2, 0] * self.b2_eq_11_2 - self.g_inv_11[1, 0] * self.b2_eq_11_3) - mat_f_12_c = mat_f_12 * (self.g_inv_11[2, 1] * self.b2_eq_11_2 - self.g_inv_11[1, 1] * self.b2_eq_11_3) - mat_f_13_c = mat_f_13 * (self.g_inv_11[2, 2] * self.b2_eq_11_2 - self.g_inv_11[1, 2] * self.b2_eq_11_3) - mat_f_21_c = mat_f_21 * (self.g_inv_12[0, 0] * self.b2_eq_12_3 - self.g_inv_12[2, 0] * self.b2_eq_12_1) - mat_f_22_c = mat_f_22 * (self.g_inv_12[0, 1] * self.b2_eq_12_3 - self.g_inv_12[2, 1] * self.b2_eq_12_1) - mat_f_23_c = mat_f_23 * (self.g_inv_12[0, 2] * self.b2_eq_12_3 - self.g_inv_12[2, 2] * self.b2_eq_12_1) - mat_f_31_c = mat_f_31 * (self.g_inv_13[1, 0] * self.b2_eq_13_1 - self.g_inv_13[0, 0] * self.b2_eq_13_2) - mat_f_32_c = mat_f_32 * (self.g_inv_13[1, 1] * self.b2_eq_13_1 - self.g_inv_13[0, 1] * self.b2_eq_13_2) - mat_f_33_c = mat_f_33 * (self.g_inv_13[1, 2] * self.b2_eq_13_1 - self.g_inv_13[0, 2] * self.b2_eq_13_2) - - mat_f_1_c = mat_f_11_c + mat_f_12_c + mat_f_13_c - mat_f_2_c = mat_f_21_c + mat_f_22_c + mat_f_23_c - mat_f_3_c = mat_f_31_c + mat_f_32_c + mat_f_33_c - - # ========== Step 2 : R( F(x) ) ==========# - # integration over quadrature points - # xi1 : DOF_1_{i,j,k} = sum_{m} w_{i,m} * mat_f_1_{i,m,j,k} - DOF_1 = self.space.projectors.dofs("11", mat_f_1_c) - - # xi2 : DOF_2_{i,j,k} = sum_{m} w_{j,m} * mat_f_2_{i,j,m,k} - DOF_2 = self.space.projectors.dofs("12", mat_f_2_c) - - # xi3 : DOF_3_{i,j,k} = sum_{m} w_{k,m} * mat_f_3_{i,j,k,m} - DOF_3 = self.space.projectors.dofs("13", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # xi1 : histo(xi1)-inter(xi2)-inter(xi3)-polation. - res_1 = self.space.projectors.PI_mat("11", DOF_1) - - # xi2 : inter(xi1)-histo(xi2)-inter(xi3)-polation. - res_2 = self.space.projectors.PI_mat("12", DOF_2) - - # xi3 : inter(xi1)-inter(xi2)-histo(xi3)-polation. - res_3 = self.space.projectors.PI_mat("13", DOF_3) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ================================================================= - def transpose_T1_dot(self, x): - """ - Matrix-vector product T1.T.x - - Parameters - ---------- - x : xp.array - dim R{N^1} - - Returns - ---------- - res : xp.array - dim R{N^1} - - Notes - ----- - T1.x = I_1( R_1 ( F_T1.x)) - - T1.T.x = F_T1.T( R_1.T ( I_1.T.x)) - - See T1_dot for more details. - """ - - # x dim check - # x should be R{N^1} - # assert len(x) == self.space.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - # assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - # assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - # assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # step1 : I.T(x) - # xi1 : transpose of histo(xi1)-inter(xi2)-inter(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.D_1.T, self.N_2.T, self.N_3.T], x_loc[0]) - - # xi2 : transpose of inter(xi1)-histo(xi2)-inter(xi3)-polation. - mat_dofs_2 = kron_solve_3d([self.N_1.T, self.D_2.T, self.N_3.T], x_loc[1]) - - # xi3 : transpose of inter(xi1)-inter(xi2)-histo(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.N_1.T, self.N_2.T, self.D_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - # transpose of integration over quadrature points - # xi1 - mat_f_1 = self.space.projectors.dofs_T("11", mat_dofs_1) - - # xi2 - mat_f_2 = self.space.projectors.dofs_T("12", mat_dofs_2) - - # xi3 - mat_f_3 = self.space.projectors.dofs_T("13", mat_dofs_3) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_11_c = mat_f_1 * (self.g_inv_11[2, 0] * self.b2_eq_11_2 - self.g_inv_11[1, 0] * self.b2_eq_11_3) - mat_f_12_c = mat_f_1 * (self.g_inv_11[2, 1] * self.b2_eq_11_2 - self.g_inv_11[1, 1] * self.b2_eq_11_3) - mat_f_13_c = mat_f_1 * (self.g_inv_11[2, 2] * self.b2_eq_11_2 - self.g_inv_11[1, 2] * self.b2_eq_11_3) - mat_f_21_c = mat_f_2 * (self.g_inv_12[0, 0] * self.b2_eq_12_3 - self.g_inv_12[2, 0] * self.b2_eq_12_1) - mat_f_22_c = mat_f_2 * (self.g_inv_12[0, 1] * self.b2_eq_12_3 - self.g_inv_12[2, 1] * self.b2_eq_12_1) - mat_f_23_c = mat_f_2 * (self.g_inv_12[0, 2] * self.b2_eq_12_3 - self.g_inv_12[2, 2] * self.b2_eq_12_1) - mat_f_31_c = mat_f_3 * (self.g_inv_13[1, 0] * self.b2_eq_13_1 - self.g_inv_13[0, 0] * self.b2_eq_13_2) - mat_f_32_c = mat_f_3 * (self.g_inv_13[1, 1] * self.b2_eq_13_1 - self.g_inv_13[0, 1] * self.b2_eq_13_2) - mat_f_33_c = mat_f_3 * (self.g_inv_13[1, 2] * self.b2_eq_13_1 - self.g_inv_13[0, 2] * self.b2_eq_13_2) - - res_11 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_N_2.T, self.pts0_N_3.T], mat_f_11_c) - res_12 = kron_matvec_3d([self.pts1_N_1.T, self.pts0_D_2.T, self.pts0_N_3.T], mat_f_12_c) - res_13 = kron_matvec_3d([self.pts1_N_1.T, self.pts0_N_2.T, self.pts0_D_3.T], mat_f_13_c) - - res_21 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_N_2.T, self.pts0_N_3.T], mat_f_21_c) - res_22 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_D_2.T, self.pts0_N_3.T], mat_f_22_c) - res_23 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_N_2.T, self.pts0_D_3.T], mat_f_23_c) - - res_31 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_N_2.T, self.pts1_N_3.T], mat_f_31_c) - res_32 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_D_2.T, self.pts1_N_3.T], mat_f_32_c) - res_33 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_N_2.T, self.pts1_D_3.T], mat_f_33_c) - - res_1 = res_11 + res_21 + res_31 - res_2 = res_12 + res_22 + res_32 - res_3 = res_13 + res_23 + res_33 - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ================================================================= - def X1_dot(self, x): - """ - Matrix-vector product X1.x - - Parameters - ---------- - x : xp.array - dim R^{N^1} - - Returns - ---------- - res : list - 3 xp.arrays of dim R^{N^0} - - Notes - ----- - X1 = pi_0[DF^-T * lambda^1] in R^{N^0 x 3 x N^1} - - X1.x = I_0( R_0 ( F_X1.x)) - - I_0 ... inverse interpolation matrix (tensor product) - - R_0 ... compute DOFs from function values at point set pts_ijk - - F_X1[ijk, mno] = DF^-T(pts.ijk) * lambda^1_mno(pts_ijk) - - * spline evaluation (at V_0 point sets) - * [int, int, int] points: {greville[0], greville[1], greville[2]} - - * Components of F_X1: - * evaluated at [int, int, int] : (D, N, N) * DF^-T_11 + (N, D, N) * DF^-T_12 + (N, N, D) * DF^-T_13 - * evaluated at [int, int, int] : (D, N, N) * DF^-T_21 + (N, D, N) * DF^-T_22 + (N, N, D) * DF^-T_23 - * evaluated at [int, int, int] : (D, N, N) * DF^-T_31 + (N, D, N) * DF^-T_32 + (N, N, D) * DF^-T_33 - """ - - # x dim check - # x should be R{N^1} - assert len(x) == self.space.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - # xi1 - mat_f_1 = kron_matvec_3d([self.pts0_D_1, self.pts0_N_2, self.pts0_N_3], x_loc[0]) - mat_f_2 = kron_matvec_3d([self.pts0_N_1, self.pts0_D_2, self.pts0_N_3], x_loc[1]) - mat_f_3 = kron_matvec_3d([self.pts0_N_1, self.pts0_N_2, self.pts0_D_3], x_loc[2]) - - mat_f_11_c = mat_f_1 * self.df_inv_0[0, 0] - mat_f_12_c = mat_f_2 * self.df_inv_0[1, 0] - mat_f_13_c = mat_f_3 * self.df_inv_0[2, 0] - mat_f_21_c = mat_f_1 * self.df_inv_0[0, 1] - mat_f_22_c = mat_f_2 * self.df_inv_0[1, 1] - mat_f_23_c = mat_f_3 * self.df_inv_0[2, 1] - mat_f_31_c = mat_f_1 * self.df_inv_0[0, 2] - mat_f_32_c = mat_f_2 * self.df_inv_0[1, 2] - mat_f_33_c = mat_f_3 * self.df_inv_0[2, 2] - - mat_f_1_c = mat_f_11_c + mat_f_12_c + mat_f_13_c - mat_f_2_c = mat_f_21_c + mat_f_22_c + mat_f_23_c - mat_f_3_c = mat_f_31_c + mat_f_32_c + mat_f_33_c - - # ========== Step 2 : R( F(x) ) ==========# - DOF_1 = self.space.projectors.dofs("0", mat_f_1_c) - DOF_2 = self.space.projectors.dofs("0", mat_f_2_c) - DOF_3 = self.space.projectors.dofs("0", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # inter(xi1)-inter(xi2)-inter(xi3)-polation. - res_1 = self.space.projectors.PI_mat("0", DOF_1) - - # inter(xi1)-inter(xi2)-inter(xi3)-polation. - res_2 = self.space.projectors.PI_mat("0", DOF_2) - - # inter(xi1)-inter(xi2)-inter(xi3)-polation. - res_3 = self.space.projectors.PI_mat("0", DOF_3) - - return [res_1.flatten(), res_2.flatten(), res_3.flatten()] - - # ================================================================= - def transpose_X1_dot(self, x): - """ - Matrix-vector product X1.T.x - - Parameters - ---------- - x : xp.array - dim R{N^0 x 3} - - Returns - ---------- - res : xp.array - dim R{N^1} - - Notes - ----- - X1.x = I_0( R_0 ( F_X1.x)) - - X1.T.x = F_X1.T( R_0.T ( I_0.T.x)) - - See X1_dot for more details. - """ - - # x dim check - # x should be R{N^0 * 3} - # assert len(x) == self.space.Ntot_0form * 3 - # x_loc_1 = self.space.extract_0(xp.split(x,3)[0]) - # x_loc_2 = self.space.extract_0(xp.split(x,3)[1]) - # x_loc_3 = self.space.extract_0(xp.split(x,3)[2]) - # x_loc = list((x_loc_1, x_loc_2, x_loc_3)) - - x_loc_1 = self.space.extract_0(x[0]) - x_loc_2 = self.space.extract_0(x[1]) - x_loc_3 = self.space.extract_0(x[2]) - x_loc = list((x_loc_1, x_loc_2, x_loc_3)) - - assert x_loc[0].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseN[2]) - assert x_loc[1].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseN[2]) - assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseN[2]) - - # step1 : I.T(x) - # xi1 : transpose of inter(xi1)-inter(xi2)-inter(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.N_1.T, self.N_2.T, self.N_3.T], x_loc[0]) - - # xi2 : transpose of inter(xi1)-inter(xi2)-inter(xi3)-polati on. - mat_dofs_2 = kron_solve_3d([self.N_1.T, self.N_2.T, self.N_3.T], x_loc[1]) - - # xi3 : transpose of inter(xi1)-inter(xi2)-inter(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.N_1.T, self.N_2.T, self.N_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - mat_f_1 = self.space.projectors.dofs_T("0", mat_dofs_1) - mat_f_2 = self.space.projectors.dofs_T("0", mat_dofs_2) - mat_f_3 = self.space.projectors.dofs_T("0", mat_dofs_3) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_11_c = mat_f_1 * self.df_inv_0[0, 0] - mat_f_12_c = mat_f_1 * self.df_inv_0[1, 0] - mat_f_13_c = mat_f_1 * self.df_inv_0[2, 0] - mat_f_21_c = mat_f_2 * self.df_inv_0[0, 1] - mat_f_22_c = mat_f_2 * self.df_inv_0[1, 1] - mat_f_23_c = mat_f_2 * self.df_inv_0[2, 1] - mat_f_31_c = mat_f_3 * self.df_inv_0[0, 2] - mat_f_32_c = mat_f_3 * self.df_inv_0[1, 2] - mat_f_33_c = mat_f_3 * self.df_inv_0[2, 2] - - res_11 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_N_2.T, self.pts0_N_3.T], mat_f_11_c) - res_12 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_D_2.T, self.pts0_N_3.T], mat_f_12_c) - res_13 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_N_2.T, self.pts0_D_3.T], mat_f_13_c) - - res_21 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_N_2.T, self.pts0_N_3.T], mat_f_21_c) - res_22 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_D_2.T, self.pts0_N_3.T], mat_f_22_c) - res_23 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_N_2.T, self.pts0_D_3.T], mat_f_23_c) - - res_31 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_N_2.T, self.pts0_N_3.T], mat_f_31_c) - res_32 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_D_2.T, self.pts0_N_3.T], mat_f_32_c) - res_33 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_N_2.T, self.pts0_D_3.T], mat_f_33_c) - - res_1 = res_11 + res_21 + res_31 - res_2 = res_12 + res_22 + res_32 - res_3 = res_13 + res_23 + res_33 - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - ######################################## - ########## 2-form formulation ########## - ######################################## - # ==================================================================== - def Q2_dot(self, x): - """ - Matrix-vector product Q2.x - - Parameters - ---------- - x : xp.array - dim R^{N^2} - - Returns - ---------- - res : xp.array - dim R^{N^2} - - Notes - ----- - Q2 = pi_2[rho_eq / g_sqrt * lambda^2] in R^{N^2 x N^2} - - Q2.x = I_2( R_2 ( F_Q2.x)) - - I_2 ... inverse inter/histopolation matrix (tensor product) - - R_2 ... compute DOFs from function values at point set pts_ijk - - F_Q2[ijk, mno] = rho_eq(pts_ijk) / g_sqrt(pts_ijk) * lambda^2_mno(pts_ijk) - - * spline evaluation (at V_2 point sets) - * [int, his, his] points: {greville[0], quad_pts[1], quad_pts[2]} - * [his, int, his] points: {quad_pts[0], greville[1], quad_pts[2]} - * [his, his, int] points: {quad_pts[0], quad_pts[1], greville[2]} - - * Components of F_Q2: - * evaluated at [int, his, his] : (N, D, D) * rho_eq / g_sqrt - * evaluated at [his, int, his] : (D, N, D) * rho_eq / g_sqrt - * evaluated at [his, his, int] : (D, D, N) * rho_eq / g_sqrt - """ - - # x dim check - # x should be R{N^2} - # assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - # assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - # assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - # assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - # xi1 - mat_f_1 = kron_matvec_3d([self.pts0_N_1, self.pts1_D_2, self.pts1_D_3], x_loc[0]) - - # xi2 - mat_f_2 = kron_matvec_3d([self.pts1_D_1, self.pts0_N_2, self.pts1_D_3], x_loc[1]) - - # xi3 - mat_f_3 = kron_matvec_3d([self.pts1_D_1, self.pts1_D_2, self.pts0_N_3], x_loc[2]) - - mat_f_1_c = mat_f_1 * self.n3_eq_21 / self.det_df_21 - mat_f_2_c = mat_f_2 * self.n3_eq_22 / self.det_df_22 - mat_f_3_c = mat_f_3 * self.n3_eq_23 / self.det_df_23 - - # ========== Step 2 : R( F(x) ) ==========# - # integration over quadrature points - # xi1 : DOF_1_{i,j,k} = sum_{m} w_{i,m} * mat_f_1_{i,m,j,k} - DOF_1 = self.space.projectors.dofs("21", mat_f_1_c) - - # xi2 : DOF_2_{i,j,k} = sum_{m} w_{j,m} * mat_f_2_{i,j,m,k} - DOF_2 = self.space.projectors.dofs("22", mat_f_2_c) - - # xi3 : DOF_3_{i,j,k} = sum_{m} w_{k,m} * mat_f_3_{i,j,k,m} - DOF_3 = self.space.projectors.dofs("23", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # xi1 : inter(xi1)-histo(xi2)-histo(xi3)-polation. - res_1 = self.space.projectors.PI_mat("21", DOF_1) - - # xi2 : histo(xi1)-inter(xi2)-histo(xi3)-polation. - res_2 = self.space.projectors.PI_mat("22", DOF_2) - - # xi3 : histo(xi1)-histo(xi2)-inter(xi3)-polation. - res_3 = self.space.projectors.PI_mat("23", DOF_3) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def transpose_Q2_dot(self, x): - """ - Matrix-vector product Q2.T.x - - Parameters - ---------- - x : xp.array - dim R{N^2} - - Returns - ---------- - res : xp.array - dim R{N^2} - - Notes - ----- - Q2.x = I_2( R_2 ( F_Q2.x)) - - Q2.T.x = F_Q2.T( R_2.T ( I2.T.x)) - - See Q2_dot for more details. - """ - - # x dim check - # x should be R{N^2} - # assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - # assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - # assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - # assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # step1 : I.T(x) - # xi1 : transpose of inter(xi1)-histo(xi2)-histo(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.N_1.T, self.D_2.T, self.D_3.T], x_loc[0]) - - # xi2 : transpose of histo(xi1)-inter(xi2)-histo(xi3)-polati on. - mat_dofs_2 = kron_solve_3d([self.D_1.T, self.N_2.T, self.D_3.T], x_loc[1]) - - # xi3 : transpose of histo(xi1)-histo(xi2)-inter(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.D_1.T, self.D_2.T, self.N_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - # transpose of integration over quadrature points - # xi1 - mat_f_1 = self.space.projectors.dofs_T("21", mat_dofs_1) - - # xi2 - mat_f_2 = self.space.projectors.dofs_T("22", mat_dofs_2) - - # xi3 - mat_f_3 = self.space.projectors.dofs_T("23", mat_dofs_3) - - mat_f_1_c = mat_f_1 * self.n3_eq_21 / self.det_df_21 - mat_f_2_c = mat_f_2 * self.n3_eq_22 / self.det_df_22 - mat_f_3_c = mat_f_3 * self.n3_eq_23 / self.det_df_23 - - res_1 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_D_2.T, self.pts1_D_3.T], mat_f_1_c) - res_2 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_N_2.T, self.pts1_D_3.T], mat_f_2_c) - res_3 = kron_matvec_3d([self.pts1_D_1.T, self.pts1_D_2.T, self.pts0_N_3.T], mat_f_3_c) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def T2_dot(self, x): - """ - Matrix-vector product T2.x - - Parameters - ---------- - x : xp.array - dim R^{N^2} - - Returns - ---------- - res : xp.array - dim R^{N^1} - - Notes - ----- - T2 = pi_1[Bmat_eq / g_sqrt * lambda^2] in R^{N^1 * N^2} - - Bmat_eq = [[0 , -b_eq_z, b_eq_y], [b_eq_z, 0 , -b_eq_x], [-b_eq_y, b_eq_x, 0]] in R^{3 x 3} - - T2.x = I_1( R_1 ( F_T2.x)) - - I_1 ... inverse inter/histopolation matrix (tensor product) - - R_1 ... compute DOFs from function values at point set pts_ijk - - F_T2[ijk, mno] = B_eq(pts_ijk) / g_sqrt(pts_ijk) * lambda^2_mno(pts_ijk) - - * spline evaluation (at V_1 point sets) - * [his, int, int] points: {quad_pts[0], greville[1], greville[2]} - * [int, his, int] points: {greville[0], quad_pts[1], greville[2]} - * [int, int, his] points: {greville[0], greville[1], quad_pts[2]} - - * Components of F_T2: - * evaluated at [his, int, int] : (D, N, D) * (-b_eq_z) / g_sqrt + (D, D, N) * b_eq_y / g_sqrt - * evaluated at [int, his, int] : (N, D, D) * b_eq_z / g_sqrt + (D, D, N) * (-b_eq_x) / g_sqrt - * evaluated at [int, int, his] : (N, D, D) * (-b_eq_y) / g_sqrt + (D, N, D) * b_eq_x / g_sqrt, - """ - - # x dim check - # x should be R{N^2} - # assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - # assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - # assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - # assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - # xi1 - mat_f_11 = kron_matvec_3d([self.pts1_N_1, self.pts0_D_2, self.pts0_D_3], x_loc[0]) # 0 - mat_f_12 = kron_matvec_3d([self.pts1_D_1, self.pts0_N_2, self.pts0_D_3], x_loc[1]) - mat_f_13 = kron_matvec_3d([self.pts1_D_1, self.pts0_D_2, self.pts0_N_3], x_loc[2]) - - # xi2 - mat_f_21 = kron_matvec_3d([self.pts0_N_1, self.pts1_D_2, self.pts0_D_3], x_loc[0]) - mat_f_22 = kron_matvec_3d([self.pts0_D_1, self.pts1_N_2, self.pts0_D_3], x_loc[1]) # 0 - mat_f_23 = kron_matvec_3d([self.pts0_D_1, self.pts1_D_2, self.pts0_N_3], x_loc[2]) - - # xi3 - mat_f_31 = kron_matvec_3d([self.pts0_N_1, self.pts0_D_2, self.pts1_D_3], x_loc[0]) - mat_f_32 = kron_matvec_3d([self.pts0_D_1, self.pts0_N_2, self.pts1_D_3], x_loc[1]) - mat_f_33 = kron_matvec_3d([self.pts0_D_1, self.pts0_D_2, self.pts1_N_3], x_loc[2]) # 0 - - mat_f_11_c = mat_f_11 * 0 / self.det_df_11 - mat_f_12_c = mat_f_12 * (-self.b2_eq_11_3) / self.det_df_11 - mat_f_13_c = mat_f_13 * (self.b2_eq_11_2) / self.det_df_11 - mat_f_21_c = mat_f_21 * (self.b2_eq_12_3) / self.det_df_12 - mat_f_22_c = mat_f_22 * 0 / self.det_df_12 - mat_f_23_c = mat_f_23 * (-self.b2_eq_12_1) / self.det_df_12 - mat_f_31_c = mat_f_31 * (-self.b2_eq_13_2) / self.det_df_13 - mat_f_32_c = mat_f_32 * (self.b2_eq_13_1) / self.det_df_13 - mat_f_33_c = mat_f_33 * 0 / self.det_df_13 - - mat_f_1_c = mat_f_11_c + mat_f_12_c + mat_f_13_c - mat_f_2_c = mat_f_21_c + mat_f_22_c + mat_f_23_c - mat_f_3_c = mat_f_31_c + mat_f_32_c + mat_f_33_c - - # ========== Step 2 : R( F(x) ) ==========# - # integration over quadrature points - # xi1 : DOF_1_{i,j,k} = sum_{m} w_{i,m} * mat_f_1_{i,m,j,k} - DOF_1 = self.space.projectors.dofs("11", mat_f_1_c) - - # xi2 : DOF_2_{i,j,k} = sum_{m} w_{j,m} * mat_f_2_{i,j,m,k} - DOF_2 = self.space.projectors.dofs("12", mat_f_2_c) - - # xi3 : DOF_3_{i,j,k} = sum_{m} w_{k,m} * mat_f_3_{i,j,k,m} - DOF_3 = self.space.projectors.dofs("13", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # xi1 : histo(xi1)-inter(xi2)-inter(xi3)-polation. - res_1 = self.space.projectors.PI_mat("11", DOF_1) - - # xi2 : inter(xi1)-histo(xi2)-inter(xi3)-polation. - res_2 = self.space.projectors.PI_mat("12", DOF_2) - - # xi3 : inter(xi1)-inter(xi2)-histo(xi3)-polation. - res_3 = self.space.projectors.PI_mat("13", DOF_3) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def transpose_T2_dot(self, x): - """ - Matrix-vector product T2.T.x - - Parameters - ---------- - x : xp.array - dim R{N^1} - - Returns - ---------- - res : xp.array - dim R{N^2} - - Notes - ----- - T2.x = I_1( R_1 ( F_T2.x)) - - T2.T.x = F_T2.T( R_1.T ( I_1.T.x)) - - See T2_dot for more details. - """ - - # x dim check - # x should be R{N^1} - # assert len(x) == self.space.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - # assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - # assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - # assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # step1 : I.T(x) - # xi1 : transpose of histo(xi1)-inter(xi2)-inter(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.D_1.T, self.N_2.T, self.N_3.T], x_loc[0]) - - # xi2 : transpose of inter(xi1)-histo(xi2)-inter(xi3)-polation. - mat_dofs_2 = kron_solve_3d([self.N_1.T, self.D_2.T, self.N_3.T], x_loc[1]) - - # xi3 : transpose of inter(xi1)-inter(xi2)-histo(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.N_1.T, self.N_2.T, self.D_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - # transpose of integration over quadrature points - # xi1 - mat_f_1 = self.space.projectors.dofs_T("11", mat_dofs_1) - - # xi2 - mat_f_2 = self.space.projectors.dofs_T("12", mat_dofs_2) - - # xi3 - mat_f_3 = self.space.projectors.dofs_T("13", mat_dofs_3) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_11_c = mat_f_1 * 0 / self.det_df_11 - mat_f_12_c = mat_f_1 * (-self.b2_eq_11_3) / self.det_df_11 - mat_f_13_c = mat_f_1 * (self.b2_eq_11_2) / self.det_df_11 - mat_f_21_c = mat_f_2 * (self.b2_eq_12_3) / self.det_df_12 - mat_f_22_c = mat_f_2 * 0 / self.det_df_12 - mat_f_23_c = mat_f_2 * (-self.b2_eq_12_1) / self.det_df_12 - mat_f_31_c = mat_f_3 * (-self.b2_eq_13_2) / self.det_df_13 - mat_f_32_c = mat_f_3 * (self.b2_eq_13_1) / self.det_df_13 - mat_f_33_c = mat_f_3 * 0 / self.det_df_13 - - res_11 = kron_matvec_3d([self.pts1_N_1.T, self.pts0_D_2.T, self.pts0_D_3.T], mat_f_11_c) # 0 - res_12 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_N_2.T, self.pts0_D_3.T], mat_f_12_c) - res_13 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_D_2.T, self.pts0_N_3.T], mat_f_13_c) - - res_21 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_D_2.T, self.pts0_D_3.T], mat_f_21_c) - res_22 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_N_2.T, self.pts0_D_3.T], mat_f_22_c) # 0 - res_23 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_D_2.T, self.pts0_N_3.T], mat_f_23_c) - - res_31 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_D_2.T, self.pts1_D_3.T], mat_f_31_c) - res_32 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_N_2.T, self.pts1_D_3.T], mat_f_32_c) - res_33 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_D_2.T, self.pts1_N_3.T], mat_f_33_c) # 0 - - res_1 = res_11 + res_21 + res_31 - res_2 = res_12 + res_22 + res_32 - res_3 = res_13 + res_23 + res_33 - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def P2_dot(self, x): - """ - Matrix-vector product P2.x - - Parameters - ---------- - x : xp.array - dim R^{N^2} - - Returns - ---------- - res : xp.array - dim R^{N^2} - - Notes - ----- - P2 = pi_2[G_inv * jmat_eq * lambda^2] in R^{N^2 x N^2} - - jmat_eq = [[0 , -j_eq_z, j_eq_y], [ j_eq_z, 0 , -j_eq_x], [-j_eq_y, j_eq_x, 0]] - - P2.x = I_2( R_2 ( F_P2.x)) - - I_2 ... inverse inter/histopolation matrix (tensor product) - - R_2 ... compute DOFs from function values at point set pts_ijk - - F_P2[ijk, mno] = G_inv(pts_ijk) * jmat_eq(pts_ijk) lambda^2_mno(pts_ijk) - - * spline evaluation (at V_2 point sets) - * [int, his, his] points: {greville[0], quad_pts[1], quad_pts[2]} - * [his, int, his] points: {quad_pts[0], greville[1], quad_pts[2]} - * [his, his, int] points: {quad_pts[0], quad_pts[1], greville[2]} - - * Components of F_P2: - * evaluated at [int, his, his] : (N, D, D) * (G_inv_12 * j_eq_z - G_inv_13 * j_eq_y) + (D, N, D) * (G_inv_13 * j_eq_x - G_inv_11 * j_eq_z) + (D, D, N) * (G_inv_11 * j_eq_y - G_inv_12 * j_eq_x) - * evaluated at [his, int, his] : (N, D, D) * (G_inv_22 * j_eq_z - G_inv_23 * j_eq_y) + (D, N, D) * (G_inv_23 * j_eq_x - G_inv_21 * j_eq_z) + (D, D, N) * (G_inv_21 * j_eq_y - G_inv_22 * j_eq_x) - * evaluated at [his, his, int] : (N, D, D) * (G_inv_32 * j_eq_z - G_inv_33 * j_eq_y) + (D, N, D) * (G_inv_33 * j_eq_x - G_inv_31 * j_eq_z) + (D, D, N) * (G_inv_31 * j_eq_y - G_inv_32 * j_eq_x) - """ - - # x dim check - # x should be R{N^2} - # assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - # assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - # assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - # assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - # xi1 - mat_f_11 = kron_matvec_3d([self.pts0_N_1, self.pts1_D_2, self.pts1_D_3], x_loc[0]) - mat_f_12 = kron_matvec_3d([self.pts0_D_1, self.pts1_N_2, self.pts1_D_3], x_loc[1]) - mat_f_13 = kron_matvec_3d([self.pts0_D_1, self.pts1_D_2, self.pts1_N_3], x_loc[2]) - - # xi2 - mat_f_21 = kron_matvec_3d([self.pts1_N_1, self.pts0_D_2, self.pts1_D_3], x_loc[0]) - mat_f_22 = kron_matvec_3d([self.pts1_D_1, self.pts0_N_2, self.pts1_D_3], x_loc[1]) - mat_f_23 = kron_matvec_3d([self.pts1_D_1, self.pts0_D_2, self.pts1_N_3], x_loc[2]) - - # xi3 - mat_f_31 = kron_matvec_3d([self.pts1_N_1, self.pts1_D_2, self.pts0_D_3], x_loc[0]) - mat_f_32 = kron_matvec_3d([self.pts1_D_1, self.pts1_N_2, self.pts0_D_3], x_loc[1]) - mat_f_33 = kron_matvec_3d([self.pts1_D_1, self.pts1_D_2, self.pts0_N_3], x_loc[2]) - - mat_f_11_c = mat_f_11 * (self.g_inv_21[0, 1] * self.j2_eq_21_3 - self.g_inv_21[0, 2] * self.j2_eq_21_2) - mat_f_12_c = mat_f_12 * (self.g_inv_21[0, 2] * self.j2_eq_21_1 - self.g_inv_21[0, 0] * self.j2_eq_21_3) - mat_f_13_c = mat_f_13 * (self.g_inv_21[0, 0] * self.j2_eq_21_2 - self.g_inv_21[0, 1] * self.j2_eq_21_1) - mat_f_21_c = mat_f_21 * (self.g_inv_22[1, 1] * self.j2_eq_22_3 - self.g_inv_22[1, 2] * self.j2_eq_22_2) - mat_f_22_c = mat_f_22 * (self.g_inv_22[1, 2] * self.j2_eq_22_1 - self.g_inv_22[1, 0] * self.j2_eq_22_3) - mat_f_23_c = mat_f_23 * (self.g_inv_22[1, 0] * self.j2_eq_22_2 - self.g_inv_22[1, 1] * self.j2_eq_22_1) - mat_f_31_c = mat_f_31 * (self.g_inv_23[2, 1] * self.j2_eq_23_3 - self.g_inv_23[2, 2] * self.j2_eq_23_2) - mat_f_32_c = mat_f_32 * (self.g_inv_23[2, 2] * self.j2_eq_23_1 - self.g_inv_23[2, 0] * self.j2_eq_23_3) - mat_f_33_c = mat_f_33 * (self.g_inv_23[2, 0] * self.j2_eq_23_2 - self.g_inv_23[2, 1] * self.j2_eq_23_1) - - mat_f_1_c = mat_f_11_c + mat_f_12_c + mat_f_13_c - mat_f_2_c = mat_f_21_c + mat_f_22_c + mat_f_23_c - mat_f_3_c = mat_f_31_c + mat_f_32_c + mat_f_33_c - - # ========== Step 2 : R( F(x) ) ==========# - # integration over quadrature points - # xi1 : DOF_1_{i,j,k} = sum_{m} w_{i,m} * mat_f_1_{i,m,j,k} - DOF_1 = self.space.projectors.dofs("21", mat_f_1_c) - - # xi2 : DOF_2_{i,j,k} = sum_{m} w_{j,m} * mat_f_2_{i,j,m,k} - DOF_2 = self.space.projectors.dofs("22", mat_f_2_c) - - # xi3 : DOF_3_{i,j,k} = sum_{m} w_{k,m} * mat_f_3_{i,j,k,m} - DOF_3 = self.space.projectors.dofs("23", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # xi1 : inter(xi1)-histo(xi2)-histo(xi3)-polation. - res_1 = self.space.projectors.PI_mat("21", DOF_1) - - # xi2 : histo(xi1)-inter(xi2)-histo(xi3)-polation. - res_2 = self.space.projectors.PI_mat("22", DOF_2) - - # xi3 : histo(xi1)-histo(xi2)-inter(xi3)-polation. - res_3 = self.space.projectors.PI_mat("23", DOF_3) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def transpose_P2_dot(self, x): - """ - Matrix-vector product P2.T.x - - Parameters - ---------- - x : xp.array - dim R{N^2} - - Returns - ---------- - res : xp.array - dim R{N^2} - - Notes - ----- - P2.x = I_2( R_2 ( F_P2.x)) - - P2.T.x = F_P2.T( R_2.T ( I_2.T.x)) - - See P2_dot for more details. - """ - - # x dim check - # x should be R{N^2} - # assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - # assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - # assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - # assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # step1 : I.T(x) - # xi1 : transpose of inter(xi1)-histo(xi2)-histo(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.N_1.T, self.D_2.T, self.D_3.T], x_loc[0]) - - # xi2 : transpose of histo(xi1)-inter(xi2)-histo(xi3)-polati on. - mat_dofs_2 = kron_solve_3d([self.D_1.T, self.N_2.T, self.D_3.T], x_loc[1]) - - # xi3 : transpose of histo(xi1)-histo(xi2)-inter(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.D_1.T, self.D_2.T, self.N_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - # transpose of integration over quadrature points - # xi1 - mat_f_1 = self.space.projectors.dofs_T("21", mat_dofs_1) - - # xi2 - mat_f_2 = self.space.projectors.dofs_T("22", mat_dofs_2) - - # xi3 - mat_f_3 = self.space.projectors.dofs_T("23", mat_dofs_3) - - mat_f_11_c = mat_f_1 * (self.g_inv_21[0, 1] * self.j2_eq_21_3 - self.g_inv_21[0, 2] * self.j2_eq_21_2) - mat_f_12_c = mat_f_1 * (self.g_inv_21[0, 2] * self.j2_eq_21_1 - self.g_inv_21[0, 0] * self.j2_eq_21_3) - mat_f_13_c = mat_f_1 * (self.g_inv_21[0, 0] * self.j2_eq_21_2 - self.g_inv_21[0, 1] * self.j2_eq_21_1) - mat_f_21_c = mat_f_2 * (self.g_inv_22[1, 1] * self.j2_eq_22_3 - self.g_inv_22[1, 2] * self.j2_eq_22_2) - mat_f_22_c = mat_f_2 * (self.g_inv_22[1, 2] * self.j2_eq_22_1 - self.g_inv_22[1, 0] * self.j2_eq_22_3) - mat_f_23_c = mat_f_2 * (self.g_inv_22[1, 0] * self.j2_eq_22_2 - self.g_inv_22[1, 1] * self.j2_eq_22_1) - mat_f_31_c = mat_f_3 * (self.g_inv_23[2, 1] * self.j2_eq_23_3 - self.g_inv_23[2, 2] * self.j2_eq_23_2) - mat_f_32_c = mat_f_3 * (self.g_inv_23[2, 2] * self.j2_eq_23_1 - self.g_inv_23[2, 0] * self.j2_eq_23_3) - mat_f_33_c = mat_f_3 * (self.g_inv_23[2, 0] * self.j2_eq_23_2 - self.g_inv_23[2, 1] * self.j2_eq_23_1) - - res_11 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_D_2.T, self.pts1_D_3.T], mat_f_11_c) - res_12 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_N_2.T, self.pts1_D_3.T], mat_f_12_c) - res_13 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_D_2.T, self.pts1_N_3.T], mat_f_13_c) - - res_21 = kron_matvec_3d([self.pts1_N_1.T, self.pts0_D_2.T, self.pts1_D_3.T], mat_f_21_c) - res_22 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_N_2.T, self.pts1_D_3.T], mat_f_22_c) - res_23 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_D_2.T, self.pts1_N_3.T], mat_f_23_c) - - res_31 = kron_matvec_3d([self.pts1_N_1.T, self.pts1_D_2.T, self.pts0_D_3.T], mat_f_31_c) - res_32 = kron_matvec_3d([self.pts1_D_1.T, self.pts1_N_2.T, self.pts0_D_3.T], mat_f_32_c) - res_33 = kron_matvec_3d([self.pts1_D_1.T, self.pts1_D_2.T, self.pts0_N_3.T], mat_f_33_c) - - res_1 = res_11 + res_21 + res_31 - res_2 = res_12 + res_22 + res_32 - res_3 = res_13 + res_23 + res_33 - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def S2_dot(self, x): - """ - Matrix-vector product S2.x - - Parameters - ---------- - x : xp.array - dim R^{N^2} - - Returns - ---------- - res : xp.array - dim R^{N^2} - - Notes - ----- - S2 = pi_2[p_eq / g_sqrt * lambda^2] in R^{N^2 x N^2} - - S2.x = I_2( R_2 ( F_S2.x)) - - I_2 ... inverse inter/histopolation matrix (tensor product) - - R_2 ... compute DOFs from function values at point set pts_ijk - - F_S2[ijk, mno] = p_eq(pts_ijk) / g_sqrt(pts_ijk) * lambda^2_mno(pts_ijk) - - * spline evaluation (at V_2 point sets) - * [int, his, his] points: {greville[0], quad_pts[1], quad_pts[2]} - * [his, int, his] points: {quad_pts[0], greville[1], quad_pts[2]} - * [his, his, int] points: {quad_pts[0], quad_pts[1], greville[2]} - - * Components of F_S2: - * evaluated at [int, his, his] : (N, D, D) * p_eq / g_sqrt - * evaluated at [his, int, his] : (D, N, D) * p_eq / g_sqrt - * evaluated at [his, his, int] : (D, D, N) * p_eq / g_sqrt - """ - - # x dim check - # x should be R{N^2} - # assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - # assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - # assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - # assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - # xi1 - mat_f_1 = kron_matvec_3d([self.pts0_N_1, self.pts1_D_2, self.pts1_D_3], x_loc[0]) - - # xi2 - mat_f_2 = kron_matvec_3d([self.pts1_D_1, self.pts0_N_2, self.pts1_D_3], x_loc[1]) - - # xi3 - mat_f_3 = kron_matvec_3d([self.pts1_D_1, self.pts1_D_2, self.pts0_N_3], x_loc[2]) - - mat_f_1_c = mat_f_1 * self.p3_eq_21 / self.det_df_21 - mat_f_2_c = mat_f_2 * self.p3_eq_22 / self.det_df_22 - mat_f_3_c = mat_f_3 * self.p3_eq_23 / self.det_df_23 - - # ========== Step 2 : R( F(x) ) ==========# - # integration over quadrature points - # xi1 : DOF_1_{i,j,k} = sum_{m} w_{i,m} * mat_f_1_{i,m,j,k} - DOF_1 = self.space.projectors.dofs("21", mat_f_1_c) - - # xi2 : DOF_2_{i,j,k} = sum_{m} w_{j,m} * mat_f_2_{i,j,m,k} - DOF_2 = self.space.projectors.dofs("22", mat_f_2_c) - - # xi3 : DOF_3_{i,j,k} = sum_{m} w_{k,m} * mat_f_3_{i,j,k,m} - DOF_3 = self.space.projectors.dofs("23", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # xi1 : inter(xi1)-histo(xi2)-histo(xi3)-polation. - res_1 = self.space.projectors.PI_mat("21", DOF_1) - - # xi2 : histo(xi1)-inter(xi2)-histo(xi3)-polation. - res_2 = self.space.projectors.PI_mat("22", DOF_2) - - # xi3 : histo(xi1)-histo(xi2)-inter(xi3)-polation. - res_3 = self.space.projectors.PI_mat("23", DOF_3) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def transpose_S2_dot(self, x): - """ - Matrix-vecotr product S2.T.x - - Parameters - ---------- - x : xp.array - dim R{N^2} - - Returns - ---------- - res : xp.array - dim R{N^2} - - Notes - ----- - S2.x = I_2( R_2 ( F_S2.x)) - - S2.T.x = F_S2.T( R_2.T ( I_2.T.x)) - - See S2_dot for more details. - """ - - # x dim check - # x should be R{N^2} - # assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - # assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - # assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - # assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # step1 : I.T(x) - # xi1 : transpose of inter(xi1)-histo(xi2)-histo(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.N_1.T, self.D_2.T, self.D_3.T], x_loc[0]) - - # xi2 : transpose of histo(xi1)-inter(xi2)-histo(xi3)-polati on. - mat_dofs_2 = kron_solve_3d([self.D_1.T, self.N_2.T, self.D_3.T], x_loc[1]) - - # xi3 : transpose of histo(xi1)-histo(xi2)-inter(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.D_1.T, self.D_2.T, self.N_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - # transpose of integration over quadrature points - # xi1 - mat_f_1 = self.space.projectors.dofs_T("21", mat_dofs_1) - - # xi2 - mat_f_2 = self.space.projectors.dofs_T("22", mat_dofs_2) - - # xi3 - mat_f_3 = self.space.projectors.dofs_T("23", mat_dofs_3) - - mat_f_1_c = mat_f_1 * self.p3_eq_21 / self.det_df_21 - mat_f_2_c = mat_f_2 * self.p3_eq_22 / self.det_df_22 - mat_f_3_c = mat_f_3 * self.p3_eq_23 / self.det_df_23 - - res_1 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_D_2.T, self.pts1_D_3.T], mat_f_1_c) - res_2 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_N_2.T, self.pts1_D_3.T], mat_f_2_c) - res_3 = kron_matvec_3d([self.pts1_D_1.T, self.pts1_D_2.T, self.pts0_N_3.T], mat_f_3_c) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def K2_dot(self, x): - """ - Matrix-vector product K2.x - - Parameters - ---------- - x : xp.array - dim R^{N^3} - - Returns - ---------- - res : xp.array - dim R^{N^3} - - Notes - ----- - K2 = pi_3[p_eq / g_sqrt * lambda^3] in R{N^3 x N^3} - - K2.x = I_3( R_3 ( F_K2.x)) - - I_3 ... inverse histopolation matrix (tensor product) - - R_3 ... compute DOFs from function values at point set pts_ijk - - F_K2[ijk,mno] = p_eq(pts_ijk) / g_sqrt(pts_ijk) * lambda^3_mno(pts_ijk) - - * spline evaluation (at V_3 point sets) - * [his, his, his] points: {quad_pts[0], quad_pts[1], quad_pts[2]} - - * Components of F_K2: - * evaluated at [his, his, his] : (D, D, D) * p_eq / sqrt g - """ - - # x dim check - # assert len(x) == self.space.Ntot_3form - x_loc = self.space.extract_3(x) - - # assert x_loc.shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseD[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - mat_f = kron_matvec_3d([self.pts1_D_1, self.pts1_D_2, self.pts1_D_3], x_loc) - - # Point-wise multiplication of mat_f and peq - mat_f_c = mat_f * self.p3_eq_3 / self.det_df_3 - - # ========== Step 2 : R( F(x) ) ==========# - # Linear operator : evaluation values at the projection points to the Degree of Freedom of the spline. - DOF = self.space.projectors.dofs("3", mat_f_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # histo(xi1)-histo(xi2)-histo(xi3)-polation. - res = self.space.projectors.PI_mat("3", DOF) - - return res.flatten() - - # ==================================================================== - def transpose_K2_dot(self, x): - """ - Matrix-vector product K2.T.x - - Parameters - ---------- - x : xp.array - dim R{N^3} - - Returns - ---------- - res : 3d array - dim R{N^3} - - Notes - ----- - K2.x = I_3( R_3 ( F_K2.x)) - - K2.T.x = F_K2.T( R_3.T ( I_3.T.x)) - - See K2_dot for more details. - """ - - # x dim check - # assert len(x) == self.space.Ntot_3form - x_loc = self.space.extract_3(x) - - # assert x_loc.shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseD[2]) - - # step1 : I.T(x) - mat_dofs = kron_solve_3d([self.D_1.T, self.D_2.T, self.D_3.T], x_loc) - - # step2 : R.T( I.T(x) ) - mat_f = self.space.projectors.dofs_T("3", mat_dofs) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_c = self.p3_eq_3 * mat_f / self.det_df_3 - - res = kron_matvec_3d([self.pts1_D_1.T, self.pts1_D_2.T, self.pts1_D_3.T], mat_f_c) - - return res.flatten() - - # ==================================================================== - def X2_dot(self, x): - """ - Matrix-vector product X2.x - - Parameters - ---------- - x : xp.array - dim R^{N^2} - - Returns - ---------- - res : list - 3 xp.arrays of dim R^{N^0} - - Notes - ----- - X2 = pi_0[DF / g_sqrt * lambda^2] in R^{N^0 x 3 x N^2} - - X2.x = I_0( R_0 ( F_X2.x)) - - I_0 ... inverse interpolation matrix (tensor product) - - R_0 ... compute DOFs from function values at point set pts_ijk - - F_X2[ijk, mno] = G(pts_ijk) / g_sqrt(pts_ijk) * lambda^2_mno(pts_ijk) - - * spline evaluation (at V_0 point sets) - * [int, int, int] points: {greville[0], greville[1], greville[2]} - - * Components of F_X2: - * evaluated at [int, int, int] : (N, D, D) * df_11 / g_sqrt + (D, N, D) * df_21 / g_sqrt + (D, D, N) * df_31 / g_sqrt - * evaluated at [int, int, int] : (N, D, D) * df_12 / g_sqrt + (D, N, D) * df_22 / g_sqrt + (D, D, N) * df_23 / g_sqrt - * evaluated at [int, int, int] : (N, D, D) * df_13 / g_sqrt + (D, N, D) * df_23 / g_sqrt + (D, D, N) * df_33 / g_sqrt - """ - - # x dim check - # x should be R{N^2} - assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - # xi1 - mat_f_1 = kron_matvec_3d([self.pts0_N_1, self.pts0_D_2, self.pts0_D_3], x_loc[0]) - mat_f_2 = kron_matvec_3d([self.pts0_D_1, self.pts0_N_2, self.pts0_D_3], x_loc[1]) - mat_f_3 = kron_matvec_3d([self.pts0_D_1, self.pts0_D_2, self.pts0_N_3], x_loc[2]) - - mat_f_11_c = mat_f_1 * self.df_0[0, 0] / self.det_df_0 - mat_f_12_c = mat_f_2 * self.df_0[0, 1] / self.det_df_0 - mat_f_13_c = mat_f_3 * self.df_0[0, 2] / self.det_df_0 - mat_f_21_c = mat_f_1 * self.df_0[1, 0] / self.det_df_0 - mat_f_22_c = mat_f_2 * self.df_0[1, 1] / self.det_df_0 - mat_f_23_c = mat_f_3 * self.df_0[1, 2] / self.det_df_0 - mat_f_31_c = mat_f_1 * self.df_0[2, 0] / self.det_df_0 - mat_f_32_c = mat_f_2 * self.df_0[2, 1] / self.det_df_0 - mat_f_33_c = mat_f_3 * self.df_0[2, 2] / self.det_df_0 - - mat_f_1_c = mat_f_11_c + mat_f_12_c + mat_f_13_c - mat_f_2_c = mat_f_21_c + mat_f_22_c + mat_f_23_c - mat_f_3_c = mat_f_31_c + mat_f_32_c + mat_f_33_c - - # ========== Step 2 : R( F(x) ) ==========# - DOF_1 = self.space.projectors.dofs("0", mat_f_1_c) - DOF_2 = self.space.projectors.dofs("0", mat_f_2_c) - DOF_3 = self.space.projectors.dofs("0", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # inter(xi1)-inter(xi2)-inter(xi3)-polation. - res_1 = self.space.projectors.PI_mat("0", DOF_1) - - # inter(xi1)-inter(xi2)-inter(xi3)-polation. - res_2 = self.space.projectors.PI_mat("0", DOF_2) - - # inter(xi1)-inter(xi2)-inter(xi3)-polation. - res_3 = self.space.projectors.PI_mat("0", DOF_3) - - return [res_1.flatten(), res_2.flatten(), res_3.flatten()] - - # ==================================================================== - def transpose_X2_dot(self, x): - """ - Matrix-vector product X2.T.x - - Parameters - ---------- - x : xp.array - dim R{N^0 x 3} - - Returns - ---------- - res : xp.array - dim R{N^2} - - Notes - ----- - X2.x = I_0( R_0 ( F_X2.x)) - - X2.T.x = F_X2.T( R_0.T ( I_0.T.x)) - - See X2_dot for more details. - """ - - # x dim check - # x should be R{N^0 * 3} - # assert len(x) == self.space.Ntot_0form * 3 - # x_loc_1 = self.space.extract_0(xp.split(x,3)[0]) - # x_loc_2 = self.space.extract_0(xp.split(x,3)[1]) - # x_loc_3 = self.space.extract_0(xp.split(x,3)[2]) - # x_loc = list((x_loc_1, x_loc_2, x_loc_3)) - - x_loc_1 = self.space.extract_0(x[0]) - x_loc_2 = self.space.extract_0(x[1]) - x_loc_3 = self.space.extract_0(x[2]) - x_loc = list((x_loc_1, x_loc_2, x_loc_3)) - - assert x_loc[0].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseN[2]) - assert x_loc[1].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseN[2]) - assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseN[2]) - - # step1 : I.T(x) - # xi1 : transpose of inter(xi1)-inter(xi2)-inter(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.N_1.T, self.N_2.T, self.N_3.T], x_loc[0]) - - # xi2 : transpose of inter(xi1)-inter(xi2)-inter(xi3)-polati on. - mat_dofs_2 = kron_solve_3d([self.N_1.T, self.N_2.T, self.N_3.T], x_loc[1]) - - # xi3 : transpose of inter(xi1)-inter(xi2)-inter(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.N_1.T, self.N_2.T, self.N_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - mat_f_1 = self.space.projectors.dofs_T("0", mat_dofs_1) - mat_f_2 = self.space.projectors.dofs_T("0", mat_dofs_2) - mat_f_3 = self.space.projectors.dofs_T("0", mat_dofs_3) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_11_c = mat_f_1 * self.df_0[0, 0] / self.det_df_0 - mat_f_12_c = mat_f_1 * self.df_0[0, 1] / self.det_df_0 - mat_f_13_c = mat_f_1 * self.df_0[0, 2] / self.det_df_0 - mat_f_21_c = mat_f_2 * self.df_0[1, 0] / self.det_df_0 - mat_f_22_c = mat_f_2 * self.df_0[1, 1] / self.det_df_0 - mat_f_23_c = mat_f_2 * self.df_0[1, 2] / self.det_df_0 - mat_f_31_c = mat_f_3 * self.df_0[2, 0] / self.det_df_0 - mat_f_32_c = mat_f_3 * self.df_0[2, 1] / self.det_df_0 - mat_f_33_c = mat_f_3 * self.df_0[2, 2] / self.det_df_0 - - res_11 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_D_2.T, self.pts0_D_3.T], mat_f_11_c) - res_12 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_N_2.T, self.pts0_D_3.T], mat_f_12_c) - res_13 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_D_2.T, self.pts0_N_3.T], mat_f_13_c) - - res_21 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_D_2.T, self.pts0_D_3.T], mat_f_21_c) - res_22 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_N_2.T, self.pts0_D_3.T], mat_f_22_c) - res_23 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_D_2.T, self.pts0_N_3.T], mat_f_23_c) - - res_31 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_D_2.T, self.pts0_D_3.T], mat_f_31_c) - res_32 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_N_2.T, self.pts0_D_3.T], mat_f_32_c) - res_33 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_D_2.T, self.pts0_N_3.T], mat_f_33_c) - - res_1 = res_11 + res_21 + res_31 - res_2 = res_12 + res_22 + res_32 - res_3 = res_13 + res_23 + res_33 - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def Z20_dot(self, x): - """ - Matrix-vector product Z20.x - - Parameters - ---------- - x : xp.array - dim R^{N^2} - - Returns - ---------- - res : xp.array - dim R^{N^1} - - Notes - ----- - Z20 = pi_1[G / g_sqrt * lambda^2] in R{N^1 x N^2} - - Z20.x = I_1( R_1 ( F_Z20.x)) - - I_1 ... inverse inter/histopolation matrix (tensor product) - - R_1 ... compute DOFs from function values at point set pts_ijk - - F_Z20[ijk, mno] = G(pts_ijk) / g_sqrt(pts_ijk) * lambda^2_mno(pts_ijk) - - * spline evaluation (at V_1 point sets) - * [his, int, int] points: {quad_pts[0], greville[1], greville[2]} - * [int, his, int] points: {greville[0], quad_pts[1], greville[2]} - * [int, int, his] points: {greville[0], greville[1], quad_pts[2]} - - * Components of F_Z20: - * evaluated at [his, int, int] : (N, D, D) * G_11 / g_sqrt + (D, N, D) * G_12 / g_sqrt + (D, D, N) * G_13 / g_sqrt - * evaluated at [int, his, int] : (N, D, D) * G_21 / g_sqrt + (D, N, D) * G_22 / g_sqrt + (D, D, N) * G_23 / g_sqrt - * evaluated at [int, int, his] : (N, D, D) * G_31 / g_sqrt + (D, N, D) * G_32 / g_sqrt + (D, D, N) * G_33 / g_sqrt - """ - - # x dim check - # x should be R{N^1} - assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - # xi1 - mat_f_11 = kron_matvec_3d([self.pts1_N_1, self.pts0_D_2, self.pts0_D_3], x_loc[0]) - mat_f_12 = kron_matvec_3d([self.pts1_D_1, self.pts0_N_2, self.pts0_D_3], x_loc[1]) - mat_f_13 = kron_matvec_3d([self.pts1_D_1, self.pts0_D_2, self.pts0_N_3], x_loc[2]) - - # xi2 - mat_f_21 = kron_matvec_3d([self.pts0_N_1, self.pts1_D_2, self.pts0_D_3], x_loc[0]) - mat_f_22 = kron_matvec_3d([self.pts0_D_1, self.pts1_N_2, self.pts0_D_3], x_loc[1]) - mat_f_23 = kron_matvec_3d([self.pts0_D_1, self.pts1_D_2, self.pts0_N_3], x_loc[2]) - - # xi3 - mat_f_31 = kron_matvec_3d([self.pts0_N_1, self.pts0_D_2, self.pts1_D_3], x_loc[0]) - mat_f_32 = kron_matvec_3d([self.pts0_D_1, self.pts0_N_2, self.pts1_D_3], x_loc[1]) - mat_f_33 = kron_matvec_3d([self.pts0_D_1, self.pts0_D_2, self.pts1_N_3], x_loc[2]) - - mat_f_11_c = mat_f_11 * self.g_11[0, 0] / self.det_df_11 - mat_f_12_c = mat_f_12 * self.g_11[0, 1] / self.det_df_11 # 0 - mat_f_13_c = mat_f_13 * self.g_11[0, 2] / self.det_df_11 # 0 - mat_f_21_c = mat_f_21 * self.g_12[1, 0] / self.det_df_12 # 0 - mat_f_22_c = mat_f_22 * self.g_12[1, 1] / self.det_df_12 - mat_f_23_c = mat_f_23 * self.g_12[1, 2] / self.det_df_12 # 0 - mat_f_31_c = mat_f_31 * self.g_13[2, 0] / self.det_df_13 # 0 - mat_f_32_c = mat_f_32 * self.g_13[2, 1] / self.det_df_13 # 0 - mat_f_33_c = mat_f_33 * self.g_13[2, 2] / self.det_df_13 - - mat_f_1_c = mat_f_11_c + mat_f_12_c + mat_f_13_c - mat_f_2_c = mat_f_21_c + mat_f_22_c + mat_f_23_c - mat_f_3_c = mat_f_31_c + mat_f_32_c + mat_f_33_c - - # ========== Step 2 : R( F(x) ) ==========# - # integration over quadrature points - # xi1 : DOF_1_{i,j,k} = sum_{m} w_{i,m} * mat_f_1_{i,m,j,k} - DOF_1 = self.space.projectors.dofs("11", mat_f_1_c) - - # xi2 : DOF_2_{i,j,k} = sum_{m} w_{j,m} * mat_f_2_{i,j,m,k} - DOF_2 = self.space.projectors.dofs("12", mat_f_2_c) - - # xi3 : DOF_3_{i,j,k} = sum_{m} w_{k,m} * mat_f_3_{i,j,k,m} - DOF_3 = self.space.projectors.dofs("13", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # xi1 : histo(xi1)-inter(xi2)-inter(xi3)-polation. - res_1 = self.space.projectors.PI_mat("11", DOF_1) - - # xi2 : inter(xi1)-histo(xi2)-inter(xi3)-polation. - res_2 = self.space.projectors.PI_mat("12", DOF_2) - - # xi3 : inter(xi1)-inter(xi2)-histo(xi3)-polation. - res_3 = self.space.projectors.PI_mat("13", DOF_3) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def transpose_Z20_dot(self, x): - """ - Matrix-vector product Z20.T.x - - Parameters - ---------- - x : xp.array - dim R{N^2} - - Returns - ---------- - res : xp.array - dim R{N^1} - - Notes - ----- - Z20.x = I_1( R_1 ( F_Z20.x)) - - Z20.T.x = F_Z20.T( R_1.T ( I_1.T.x)) - - See Z20_dot for more details. - """ - - # x dim check - # x should be R{N^1} - assert len(x) == self.space.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # step1 : I.T(x) - # xi1 : transpose of histo(xi1)-inter(xi2)-inter(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.D_1.T, self.N_2.T, self.N_3.T], x_loc[0]) - - # xi2 : transpose of inter(xi1)-histo(xi2)-inter(xi3)-polation. - mat_dofs_2 = kron_solve_3d([self.N_1.T, self.D_2.T, self.N_3.T], x_loc[1]) - - # xi3 : transpose of inter(xi1)-inter(xi2)-histo(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.N_1.T, self.N_2.T, self.D_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - # transpose of integration over quadrature points - # xi1 - mat_f_1 = self.space.projectors.dofs_T("11", mat_dofs_1) - - # xi2 - mat_f_2 = self.space.projectors.dofs_T("12", mat_dofs_2) - - # xi3 - mat_f_3 = self.space.projectors.dofs_T("13", mat_dofs_3) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_11_c = mat_f_1 * self.g_11[0, 0] / self.det_df_11 - mat_f_12_c = mat_f_1 * self.g_11[0, 1] / self.det_df_11 - mat_f_13_c = mat_f_1 * self.g_11[0, 2] / self.det_df_11 - mat_f_21_c = mat_f_2 * self.g_12[1, 0] / self.det_df_12 - mat_f_22_c = mat_f_2 * self.g_12[1, 1] / self.det_df_12 - mat_f_23_c = mat_f_2 * self.g_12[1, 2] / self.det_df_12 - mat_f_31_c = mat_f_3 * self.g_13[2, 0] / self.det_df_13 - mat_f_32_c = mat_f_3 * self.g_13[2, 1] / self.det_df_13 - mat_f_33_c = mat_f_3 * self.g_13[2, 2] / self.det_df_13 - - res_11 = kron_matvec_3d([self.pts1_N_1.T, self.pts0_D_2.T, self.pts0_D_3.T], mat_f_11_c) # 0 - res_12 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_N_2.T, self.pts0_D_3.T], mat_f_12_c) - res_13 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_D_2.T, self.pts0_N_3.T], mat_f_13_c) - - res_21 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_D_2.T, self.pts0_D_3.T], mat_f_21_c) - res_22 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_N_2.T, self.pts0_D_3.T], mat_f_22_c) # 0 - res_23 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_D_2.T, self.pts0_N_3.T], mat_f_23_c) - - res_31 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_D_2.T, self.pts1_D_3.T], mat_f_31_c) - res_32 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_N_2.T, self.pts1_D_3.T], mat_f_32_c) - res_33 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_D_2.T, self.pts1_N_3.T], mat_f_33_c) # 0 - - res_1 = res_11 + res_21 + res_31 - res_2 = res_12 + res_22 + res_32 - res_3 = res_13 + res_23 + res_33 - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def Y20_dot(self, x): - """ - Matrix-vector product Y20.x - - Parameters - ---------- - x : xp.array - dim R^{N^0} - - Returns - ---------- - res : xp.array - dim R^{N^3} - - Notes - ----- - Y20 = pi_3[g_sqrt * lambda^0] in R^{N^3 x N^0} - - Y20.x = I_3( R_3 ( F_Y20.x)) - - I_3 ... inverse histopolation matrix (tensor product) - - R_3 ... compute DOFs from function values at point set pts_ijk - - F_Y20[ijk,mno] = g_sqrt(pts_ijk) * lambda^0_mno(pts_ijk) - - * spline evaluation (at V_3 point sets) - * [his, his, his] points: {quad_pts[0], quad_pts[1], quad_pts[2]} - - * Components of F_Y20: - * evaluated at [his, his, his] : (N, N, N) * sqrt g - """ - - # x dim check - # assert len(x) == self.space.Ntot_0form - x_loc = self.space.extract_0(x) - - # assert x_loc.shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseD[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - mat_f = kron_matvec_3d([self.pts1_N_1, self.pts1_N_2, self.pts1_N_3], x_loc) - - # Point-wise multiplication of mat_f and peq - mat_f_c = mat_f * self.det_df_3 - - # ========== Step 2 : R( F(x) ) ==========# - # Linear operator : evaluation values at the projection points to the Degree of Freedom of the spline. - DOF = self.space.projectors.dofs("3", mat_f_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # histo(xi1)-histo(xi2)-histo(xi3)-polation. - res = self.space.projectors.PI_mat("3", DOF) - - return res.flatten() - - # ==================================================================== - def transpose_Y20_dot(self, x): - """ - Matrix-vector product Y20.T.x - - Parameters - ---------- - x : xp.array - dim R{N^3} - - Returns - ---------- - res : xp.array - dim R{N^0} - - Notes - ----- - Y20.x = I_3( R_3 ( F_Y20.x)) - - Y20.T.x = I_3.T( R_3.T ( F_Y20.T.x)) - - See Y20_dot for more details. - """ - - # x dim check - # assert len(x) == self.space.Ntot_3form - x_loc = self.space.extract_3(x) - - # assert x_loc.shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseD[2]) - - # step1 : I.T(x) - mat_dofs = kron_solve_3d([self.D_1.T, self.D_2.T, self.D_3.T], x_loc) - - # step2 : R.T( I.T(x) ) - mat_f = self.space.projectors.dofs_T("3", mat_dofs) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_c = mat_f * self.det_df_3 - - res = kron_matvec_3d([self.pts1_N_1.T, self.pts1_N_2.T, self.pts1_N_3.T], mat_f_c) - - return res.flatten() - - # ==================================================================== - def S20_dot(self, x): - """ - Matrix-vector product S20.x - - Parameters - ---------- - x : xp.array - dim R^{N^2} - - Returns - ---------- - res : xp.array - dim R^{N^1} - - Notes - ----- - S20 = pi_1[p_eq * G / g_sqrt lambda^2] in R^{N^1 x N^2} - - S20.x = I_1( R_1 ( F_S20.x)) - - I_1 ... inverse inter/histopolation matrix (tensor product) - - R_1 ... compute DOFs from function values at point set pts_ijk - - F_S20[ijk, mno] = p_eq(pts_ijk) * G(pts_ijk) / g_sqrt(pts_ijk) * lambda^2_mno(pts_ijk) - - * spline evaluation (at V_1 point sets) - * [his, int, int] points: {quad_pts[0], greville[1], greville[2]} - * [int, his, int] points: {greville[0], quad_pts[1], greville[2]} - * [int, int, his] points: {greville[0], greville[1], quad_pts[2]} - - * Components of F_S20: - * evaluated at [his, int, int] : (N, D, D) * G_11 * p_eq / g_sqrt + (D, N, D) * G_12 * p_eq / g_sqrt + (D, D, N) * G_13 * p_eq / g_sqrt - * evaluated at [int, his, int] : (N, D, D) * G_21 * p_eq / g_sqrt + (D, N, D) * G_22 * p_eq / g_sqrt + (D, D, N) * G_23 * p_eq / g_sqrt - * evaluated at [int, int, his] : (N, D, D) * G_31 * p_eq / g_sqrt + (D, N, D) * G_32 * p_eq / g_sqrt + (D, D, N) * G_33 * p_eq / g_sqrt - """ - - # x dim check - # x should be R{N^2} - assert len(x) == self.space.Ntot_2form_cum[-1] - x_loc = list(self.space.extract_2(x)) - - assert x_loc[0].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]) - assert x_loc[1].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]) - assert x_loc[2].shape == (self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]) - - # ========== Step 1 : F(x) ========== # - # Splline evaulation at the projection points then dot product with the x. - # xi1 - mat_f_11 = kron_matvec_3d([self.pts1_N_1, self.pts0_D_2, self.pts0_D_3], x_loc[0]) - mat_f_12 = kron_matvec_3d([self.pts1_D_1, self.pts0_N_2, self.pts0_D_3], x_loc[1]) - mat_f_13 = kron_matvec_3d([self.pts1_D_1, self.pts0_D_2, self.pts0_N_3], x_loc[2]) - - # xi2 - mat_f_21 = kron_matvec_3d([self.pts0_N_1, self.pts1_D_2, self.pts0_D_3], x_loc[0]) - mat_f_22 = kron_matvec_3d([self.pts0_D_1, self.pts1_N_2, self.pts0_D_3], x_loc[1]) - mat_f_23 = kron_matvec_3d([self.pts0_D_1, self.pts1_D_2, self.pts0_N_3], x_loc[2]) - - # xi3 - mat_f_31 = kron_matvec_3d([self.pts0_N_1, self.pts0_D_2, self.pts1_D_3], x_loc[0]) - mat_f_32 = kron_matvec_3d([self.pts0_D_1, self.pts0_N_2, self.pts1_D_3], x_loc[1]) - mat_f_33 = kron_matvec_3d([self.pts0_D_1, self.pts0_D_2, self.pts1_N_3], x_loc[2]) - - mat_f_11_c = mat_f_11 * self.p0_eq_11 * self.g_11[0, 0] / self.det_df_11 - mat_f_12_c = mat_f_12 * self.p0_eq_11 * self.g_11[0, 1] / self.det_df_11 - mat_f_13_c = mat_f_13 * self.p0_eq_11 * self.g_11[0, 2] / self.det_df_11 - mat_f_21_c = mat_f_21 * self.p0_eq_12 * self.g_12[1, 0] / self.det_df_12 - mat_f_22_c = mat_f_22 * self.p0_eq_12 * self.g_12[1, 1] / self.det_df_12 - mat_f_23_c = mat_f_23 * self.p0_eq_12 * self.g_12[1, 2] / self.det_df_12 - mat_f_31_c = mat_f_31 * self.p0_eq_13 * self.g_13[2, 0] / self.det_df_13 - mat_f_32_c = mat_f_32 * self.p0_eq_13 * self.g_13[2, 1] / self.det_df_13 - mat_f_33_c = mat_f_33 * self.p0_eq_13 * self.g_13[2, 2] / self.det_df_13 - - mat_f_1_c = mat_f_11_c + mat_f_12_c + mat_f_13_c - mat_f_2_c = mat_f_21_c + mat_f_22_c + mat_f_23_c - mat_f_3_c = mat_f_31_c + mat_f_32_c + mat_f_33_c - - # ========== Step 2 : R( F(x) ) ==========# - # integration over quadrature points - # xi1 : DOF_1_{i,j,k} = sum_{m} w_{i,m} * mat_f_1_{i,m,j,k} - DOF_1 = self.space.projectors.dofs("11", mat_f_1_c) - - # xi2 : DOF_2_{i,j,k} = sum_{m} w_{j,m} * mat_f_2_{i,j,m,k} - DOF_2 = self.space.projectors.dofs("12", mat_f_2_c) - - # xi3 : DOF_3_{i,j,k} = sum_{m} w_{k,m} * mat_f_3_{i,j,k,m} - DOF_3 = self.space.projectors.dofs("13", mat_f_3_c) - - # ========== Step 3 : I( R( F(x) ) ) ==========# - # xi1 : histo(xi1)-inter(xi2)-inter(xi3)-polation. - res_1 = self.space.projectors.PI_mat("11", DOF_1) - - # xi2 : inter(xi1)-histo(xi2)-inter(xi3)-polation. - res_2 = self.space.projectors.PI_mat("12", DOF_2) - - # xi3 : inter(xi1)-inter(xi2)-histo(xi3)-polation. - res_3 = self.space.projectors.PI_mat("13", DOF_3) - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) - - # ==================================================================== - def transpose_S20_dot(self, x): - """ - Matrix-vector product S20.T.x - - Parameters - ---------- - x : xp.array - dim R{N^1} - - Returns - ---------- - res : xp.array - dim R{N^2} - - Notes - ----- - S20.x = I_1( R_1 ( F_S20.x)) - - S20.T dot x = F_S20.T( R_1.T ( I_1.T(x))) - - See S20_dot for more details. - """ - - # x dim check - # x should be R{N^1} - assert len(x) == self.space.Ntot_1form_cum[-1] - x_loc = list(self.space.extract_1(x)) - - assert x_loc[0].shape == (self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]) - assert x_loc[1].shape == (self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]) - assert x_loc[2].shape == (self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]) - - # step1 : I.T(x) - # xi1 : transpose of histo(xi1)-inter(xi2)-inter(xi3)-polation. - mat_dofs_1 = kron_solve_3d([self.D_1.T, self.N_2.T, self.N_3.T], x_loc[0]) - - # xi2 : transpose of inter(xi1)-histo(xi2)-inter(xi3)-polation. - mat_dofs_2 = kron_solve_3d([self.N_1.T, self.D_2.T, self.N_3.T], x_loc[1]) - - # xi3 : transpose of inter(xi1)-inter(xi2)-histo(xi3)-polation. - mat_dofs_3 = kron_solve_3d([self.N_1.T, self.N_2.T, self.D_3.T], x_loc[2]) - - # step2 : R.T( I.T(x) ) - # transpose of integration over quadrature points - # xi1 - mat_f_1 = self.space.projectors.dofs_T("11", mat_dofs_1) - - # xi2 - mat_f_2 = self.space.projectors.dofs_T("12", mat_dofs_2) - - # xi3 - mat_f_3 = self.space.projectors.dofs_T("13", mat_dofs_3) - - # step3 : F.T( R.T( I.T(x) ) ) - mat_f_11_c = mat_f_1 * self.p0_eq_11 * self.g_11[0, 0] / self.det_df_11 - mat_f_12_c = mat_f_1 * self.p0_eq_11 * self.g_11[0, 1] / self.det_df_11 - mat_f_13_c = mat_f_1 * self.p0_eq_11 * self.g_11[0, 2] / self.det_df_11 - mat_f_21_c = mat_f_2 * self.p0_eq_12 * self.g_12[1, 0] / self.det_df_12 - mat_f_22_c = mat_f_2 * self.p0_eq_12 * self.g_12[1, 1] / self.det_df_12 - mat_f_23_c = mat_f_2 * self.p0_eq_12 * self.g_12[1, 2] / self.det_df_12 - mat_f_31_c = mat_f_3 * self.p0_eq_13 * self.g_13[2, 0] / self.det_df_13 - mat_f_32_c = mat_f_3 * self.p0_eq_13 * self.g_13[2, 1] / self.det_df_13 - mat_f_33_c = mat_f_3 * self.p0_eq_13 * self.g_13[2, 2] / self.det_df_13 - - res_11 = kron_matvec_3d([self.pts1_N_1.T, self.pts0_D_2.T, self.pts0_D_3.T], mat_f_11_c) # 0 - res_12 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_N_2.T, self.pts0_D_3.T], mat_f_12_c) - res_13 = kron_matvec_3d([self.pts1_D_1.T, self.pts0_D_2.T, self.pts0_N_3.T], mat_f_13_c) - - res_21 = kron_matvec_3d([self.pts0_N_1.T, self.pts1_D_2.T, self.pts0_D_3.T], mat_f_21_c) - res_22 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_N_2.T, self.pts0_D_3.T], mat_f_22_c) # 0 - res_23 = kron_matvec_3d([self.pts0_D_1.T, self.pts1_D_2.T, self.pts0_N_3.T], mat_f_23_c) - - res_31 = kron_matvec_3d([self.pts0_N_1.T, self.pts0_D_2.T, self.pts1_D_3.T], mat_f_31_c) - res_32 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_N_2.T, self.pts1_D_3.T], mat_f_32_c) - res_33 = kron_matvec_3d([self.pts0_D_1.T, self.pts0_D_2.T, self.pts1_N_3.T], mat_f_33_c) # 0 - - res_1 = res_11 + res_21 + res_31 - res_2 = res_12 + res_22 + res_32 - res_3 = res_13 + res_23 + res_33 - - return xp.concatenate((res_1.flatten(), res_2.flatten(), res_3.flatten())) diff --git a/src/struphy/eigenvalue_solvers/legacy/projectors_local/__init__.py b/src/struphy/eigenvalue_solvers/legacy/projectors_local/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/__init__.py b/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/kernels_projectors_local.py b/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/kernels_projectors_local.py deleted file mode 100644 index 8aaa57182..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/kernels_projectors_local.py +++ /dev/null @@ -1,371 +0,0 @@ -# ========================================================================================== -def kernel_pi0_3d( - n: "int[:]", - p: "int[:]", - coeff_i1: "float[:,:]", - coeff_i2: "float[:,:]", - coeff_i3: "float[:,:]", - coeffi_ind1: "int[:]", - coeffi_ind2: "int[:]", - coeffi_ind3: "int[:]", - x_int_ind1: "int[:,:]", - x_int_ind2: "int[:,:]", - x_int_ind3: "int[:,:]", - mat_f: "float[:,:,:]", - lambdas: "float[:,:,:]", -): - n_pts1 = 2 * (p[0] - 1) + 1 - n_pts2 = 2 * (p[1] - 1) + 1 - n_pts3 = 2 * (p[2] - 1) + 1 - - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for il1 in range(n_pts1): - for il2 in range(n_pts2): - for il3 in range(n_pts3): - lambdas[i1, i2, i3] += ( - coeff_i1[coeffi_ind1[i1], il1] - * coeff_i2[coeffi_ind2[i2], il2] - * coeff_i3[coeffi_ind3[i3], il3] - * mat_f[x_int_ind1[i1, il1], x_int_ind2[i2, il2], x_int_ind3[i3, il3]] - ) - - -# ========================================================================================== -def kernel_pi11_3d( - n: "int[:]", - p: "int[:]", - nq: "int[:]", - coeff_h1: "float[:,:]", - coeff_i2: "float[:,:]", - coeff_i3: "float[:,:]", - coeffh_ind1: "int[:]", - coeffi_ind2: "int[:]", - coeffi_ind3: "int[:]", - x_his_ind1: "int[:,:]", - x_int_ind2: "int[:,:]", - x_int_ind3: "int[:,:]", - wts1: "float[:,:]", - mat_f: "float[:,:,:,:]", - lambdas: "float[:,:,:]", -): - n_pts2 = 2 * (p[1] - 1) + 1 - n_pts3 = 2 * (p[2] - 1) + 1 - - n_his1 = 2 * p[0] - - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for il1 in range(n_his1): - for il2 in range(n_pts2): - for il3 in range(n_pts3): - f_int = 0.0 - - for q1 in range(nq[0]): - f_int += ( - wts1[x_his_ind1[i1, il1], q1] - * mat_f[x_his_ind1[i1, il1], q1, x_int_ind2[i2, il2], x_int_ind3[i3, il3]] - ) - - lambdas[i1, i2, i3] += ( - coeff_h1[coeffh_ind1[i1], il1] - * coeff_i2[coeffi_ind2[i2], il2] - * coeff_i3[coeffi_ind3[i3], il3] - * f_int - ) - - -# ========================================================================================== -def kernel_pi12_3d( - n: "int[:]", - p: "int[:]", - nq: "int[:]", - coeff_i1: "float[:,:]", - coeff_h2: "float[:,:]", - coeff_i3: "float[:,:]", - coeffi_ind1: "int[:]", - coeffh_ind2: "int[:]", - coeffi_ind3: "int[:]", - x_int_ind1: "int[:,:]", - x_his_ind2: "int[:,:]", - x_int_ind3: "int[:,:]", - wts2: "float[:,:]", - mat_f: "float[:,:,:,:]", - lambdas: "float[:,:,:]", -): - n_pts1 = 2 * (p[0] - 1) + 1 - n_pts3 = 2 * (p[2] - 1) + 1 - - n_his2 = 2 * p[1] - - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for il1 in range(n_pts1): - for il2 in range(n_his2): - for il3 in range(n_pts3): - f_int = 0.0 - - for q2 in range(nq[1]): - f_int += ( - wts2[x_his_ind2[i2, il2], q2] - * mat_f[x_int_ind1[i1, il1], x_his_ind2[i2, il2], q2, x_int_ind3[i3, il3]] - ) - - lambdas[i1, i2, i3] += ( - coeff_i1[coeffi_ind1[i1], il1] - * coeff_h2[coeffh_ind2[i2], il2] - * coeff_i3[coeffi_ind3[i3], il3] - * f_int - ) - - -# ========================================================================================== -def kernel_pi13_3d( - n: "int[:]", - p: "int[:]", - nq: "int[:]", - coeff_i1: "float[:,:]", - coeff_i2: "float[:,:]", - coeff_h3: "float[:,:]", - coeffi_ind1: "int[:]", - coeffi_ind2: "int[:]", - coeffh_ind3: "int[:]", - x_int_ind1: "int[:,:]", - x_int_ind2: "int[:,:]", - x_his_ind3: "int[:,:]", - wts3: "float[:,:]", - mat_f: "float[:,:,:,:]", - lambdas: "float[:,:,:]", -): - n_pts1 = 2 * (p[0] - 1) + 1 - n_pts2 = 2 * (p[1] - 1) + 1 - - n_his3 = 2 * p[2] - - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for il1 in range(n_pts1): - for il2 in range(n_pts2): - for il3 in range(n_his3): - f_int = 0.0 - - for q3 in range(nq[2]): - f_int += ( - wts3[x_his_ind3[i3, il3], q3] - * mat_f[x_int_ind1[i1, il1], x_int_ind2[i2, il2], x_his_ind3[i3, il3], q3] - ) - - lambdas[i1, i2, i3] += ( - coeff_i1[coeffi_ind1[i1], il1] - * coeff_i2[coeffi_ind2[i2], il2] - * coeff_h3[coeffh_ind3[i3], il3] - * f_int - ) - - -# ========================================================================================== -def kernel_pi21_3d( - n: "int[:]", - p: "int[:]", - nq: "int[:]", - coeff_i1: "float[:,:]", - coeff_h2: "float[:,:]", - coeff_h3: "float[:,:]", - coeffi_ind1: "int[:]", - coeffh_ind2: "int[:]", - coeffh_ind3: "int[:]", - x_int_ind1: "int[:,:]", - x_his_ind2: "int[:,:]", - x_his_ind3: "int[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", - mat_f: "float[:,:,:,:,:]", - lambdas: "float[:,:,:]", -): - n_pts1 = 2 * (p[0] - 1) + 1 - - n_his2 = 2 * p[1] - n_his3 = 2 * p[2] - - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for il1 in range(n_pts1): - for il2 in range(n_his2): - for il3 in range(n_his3): - f_int = 0.0 - - for q2 in range(nq[1]): - for q3 in range(nq[2]): - wvol = wts2[x_his_ind2[i2, il2], q2] * wts3[x_his_ind3[i3, il3], q3] - f_int += ( - wvol - * mat_f[x_int_ind1[i1, il1], x_his_ind2[i2, il2], q2, x_his_ind3[i3, il3], q3] - ) - - lambdas[i1, i2, i3] += ( - coeff_i1[coeffi_ind1[i1], il1] - * coeff_h2[coeffh_ind2[i2], il2] - * coeff_h3[coeffh_ind3[i3], il3] - * f_int - ) - - -# ========================================================================================== -def kernel_pi22_3d( - n: "int[:]", - p: "int[:]", - nq: "int[:]", - coeff_h1: "float[:,:]", - coeff_i2: "float[:,:]", - coeff_h3: "float[:,:]", - coeffh_ind1: "int[:]", - coeffi_ind2: "int[:]", - coeffh_ind3: "int[:]", - x_his_ind1: "int[:,:]", - x_int_ind2: "int[:,:]", - x_his_ind3: "int[:,:]", - wts1: "float[:,:]", - wts3: "float[:,:]", - mat_f: "float[:,:,:,:,:]", - lambdas: "float[:,:,:]", -): - n_pts2 = 2 * (p[1] - 1) + 1 - - n_his1 = 2 * p[0] - n_his3 = 2 * p[2] - - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for il1 in range(n_his1): - for il2 in range(n_pts2): - for il3 in range(n_his3): - f_int = 0.0 - - for q1 in range(nq[0]): - for q3 in range(nq[2]): - wvol = wts1[x_his_ind1[i1, il1], q1] * wts3[x_his_ind3[i3, il3], q3] - f_int += ( - wvol - * mat_f[x_his_ind1[i1, il1], q1, x_int_ind2[i2, il2], x_his_ind3[i3, il3], q3] - ) - - lambdas[i1, i2, i3] += ( - coeff_h1[coeffh_ind1[i1], il1] - * coeff_i2[coeffi_ind2[i2], il2] - * coeff_h3[coeffh_ind3[i3], il3] - * f_int - ) - - -# ========================================================================================== -def kernel_pi23_3d( - n: "int[:]", - p: "int[:]", - nq: "int[:]", - coeff_h1: "float[:,:]", - coeff_h2: "float[:,:]", - coeff_i3: "float[:,:]", - coeffh_ind1: "int[:]", - coeffh_ind2: "int[:]", - coeffi_ind3: "int[:]", - x_his_ind1: "int[:,:]", - x_his_ind2: "int[:,:]", - x_int_ind3: "int[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - mat_f: "float[:,:,:,:,:]", - lambdas: "float[:,:,:]", -): - n_pts3 = 2 * (p[2] - 1) + 1 - - n_his1 = 2 * p[0] - n_his2 = 2 * p[1] - - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for il1 in range(n_his1): - for il2 in range(n_his2): - for il3 in range(n_pts3): - f_int = 0.0 - - for q1 in range(nq[0]): - for q2 in range(nq[1]): - wvol = wts1[x_his_ind1[i1, il1], q1] * wts2[x_his_ind2[i2, il2], q2] - f_int += ( - wvol - * mat_f[x_his_ind1[i1, il1], q1, x_his_ind2[i2, il2], q2, x_int_ind3[i3, il3]] - ) - - lambdas[i1, i2, i3] += ( - coeff_h1[coeffh_ind1[i1], il1] - * coeff_h2[coeffh_ind2[i2], il2] - * coeff_i3[coeffi_ind3[i3], il3] - * f_int - ) - - -# ========================================================================================== -def kernel_pi3_3d( - n: "int[:]", - p: "int[:]", - nq: "int[:]", - coeff_h1: "float[:,:]", - coeff_h2: "float[:,:]", - coeff_h3: "float[:,:]", - coeffh_ind1: "int[:]", - coeffh_ind2: "int[:]", - coeffh_ind3: "int[:]", - x_his_ind1: "int[:,:]", - x_his_ind2: "int[:,:]", - x_his_ind3: "int[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", - mat_f: "float[:,:,:,:,:,:]", - lambdas: "float[:,:,:]", -): - n_his1 = 2 * p[0] - n_his2 = 2 * p[1] - n_his3 = 2 * p[2] - - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for il1 in range(n_his1): - for il2 in range(n_his2): - for il3 in range(n_his3): - f_int = 0.0 - - for q1 in range(nq[0]): - for q2 in range(nq[1]): - for q3 in range(nq[2]): - wvol = ( - wts1[x_his_ind1[i1, il1], q1] - * wts2[x_his_ind2[i2, il2], q2] - * wts3[x_his_ind3[i3, il3], q3] - ) - f_int += ( - wvol - * mat_f[ - x_his_ind1[i1, il1], - q1, - x_his_ind2[i2, il2], - q2, - x_his_ind3[i3, il3], - q3, - ] - ) - - lambdas[i1, i2, i3] += ( - coeff_h1[coeffh_ind1[i1], il1] - * coeff_h2[coeffh_ind2[i2], il2] - * coeff_h3[coeffh_ind3[i3], il3] - * f_int - ) diff --git a/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/kernels_projectors_local_mhd.py b/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/kernels_projectors_local_mhd.py deleted file mode 100644 index fe2855764..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/kernels_projectors_local_mhd.py +++ /dev/null @@ -1,598 +0,0 @@ -# ======================================================== -def kernel_pi0( - n: "int[:]", - n_int: "int[:]", - n_nvbf: "int[:]", - i_glo1: "int[:,:]", - i_glo2: "int[:,:]", - i_glo3: "int[:,:]", - c_loc1: "int[:,:]", - c_loc2: "int[:,:]", - c_loc3: "int[:,:]", - coeff1: "float[:,:]", - coeff2: "float[:,:]", - coeff3: "float[:,:]", - coeff_ind1: "int[:]", - coeff_ind2: "int[:]", - coeff_ind3: "int[:]", - bs1: "float[:,:]", - bs2: "float[:,:]", - bs3: "float[:,:]", - x_int_ind1: "int[:,:]", - x_int_ind2: "int[:,:]", - x_int_ind3: "int[:,:]", - tau: "float[:,:,:,:,:,:]", - mat_eq: "float[:,:,:]", -): - tau[:, :, :, :, :, :] = 0.0 - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : tau) private (i1, i2, i3, j1, j2, j3, coeff, kl1, k1, c1, kl2, k2, c2, kl3, k3, c3, basis) - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for j1 in range(n_int[0]): - for j2 in range(n_int[1]): - for j3 in range(n_int[2]): - coeff = coeff1[coeff_ind1[i1], j1] * coeff2[coeff_ind2[i2], j2] * coeff3[coeff_ind3[i3], j3] - - for kl1 in range(n_nvbf[0]): - k1 = i_glo1[i1, kl1] - c1 = c_loc1[i1, kl1] - - for kl2 in range(n_nvbf[1]): - k2 = i_glo2[i2, kl2] - c2 = c_loc2[i2, kl2] - - for kl3 in range(n_nvbf[2]): - k3 = i_glo3[i3, kl3] - c3 = c_loc3[i3, kl3] - - basis = ( - bs1[x_int_ind1[i1, j1], k1] - * bs2[x_int_ind2[i2, j2], k2] - * bs3[x_int_ind3[i3, j3], k3] - ) - - tau[k1, k2, k3, c1, c2, c3] += ( - coeff - * basis - * mat_eq[x_int_ind1[i1, j1], x_int_ind2[i2, j2], x_int_ind3[i3, j3]] - ) - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ======================================================== -def kernel_pi1_1( - n: "int[:]", - n_quad1: "int", - n_inthis: "int[:]", - n_nvbf: "int[:]", - i_glo1: "int[:,:]", - i_glo2: "int[:,:]", - i_glo3: "int[:,:]", - c_loc1: "int[:,:]", - c_loc2: "int[:,:]", - c_loc3: "int[:,:]", - coeff1: "float[:,:]", - coeff2: "float[:,:]", - coeff3: "float[:,:]", - coeff_ind1: "int[:]", - coeff_ind2: "int[:]", - coeff_ind3: "int[:]", - bs1: "float[:,:,:]", - bs2: "float[:,:]", - bs3: "float[:,:]", - x_his_ind1: "int[:,:]", - x_int_ind2: "int[:,:]", - x_int_ind3: "int[:,:]", - wts1: "float[:,:]", - tau: "float[:,:,:,:,:,:]", - mat_eq: "float[:,:,:,:]", -): - tau[:, :, :, :, :, :] = 0.0 - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : tau) private (i1, i2, i3, j1, j2, j3, coeff, kl1, k1, c1, kl2, k2, c2, kl3, k3, c3, f_int, q1) - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for j1 in range(n_inthis[0]): - for j2 in range(n_inthis[1]): - for j3 in range(n_inthis[2]): - coeff = coeff1[coeff_ind1[i1], j1] * coeff2[coeff_ind2[i2], j2] * coeff3[coeff_ind3[i3], j3] - - for kl1 in range(n_nvbf[0]): - k1 = i_glo1[i1, kl1] - c1 = c_loc1[i1, kl1] - - for kl2 in range(n_nvbf[1]): - k2 = i_glo2[i2, kl2] - c2 = c_loc2[i2, kl2] - - for kl3 in range(n_nvbf[2]): - k3 = i_glo3[i3, kl3] - c3 = c_loc3[i3, kl3] - - f_int = 0.0 - - for q1 in range(n_quad1): - f_int += ( - wts1[x_his_ind1[i1, j1], q1] - * bs1[x_his_ind1[i1, j1], q1, k1] - * bs2[x_int_ind2[i2, j2], k2] - * bs3[x_int_ind3[i3, j3], k3] - * mat_eq[x_his_ind1[i1, j1], q1, x_int_ind2[i2, j2], x_int_ind3[i3, j3]] - ) - - tau[k1, k2, k3, c1, c2, c3] += coeff * f_int - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ======================================================== -def kernel_pi1_2( - n: "int[:]", - n_quad2: "int", - n_inthis: "int[:]", - n_nvbf: "int[:]", - i_glo1: "int[:,:]", - i_glo2: "int[:,:]", - i_glo3: "int[:,:]", - c_loc1: "int[:,:]", - c_loc2: "int[:,:]", - c_loc3: "int[:,:]", - coeff1: "float[:,:]", - coeff2: "float[:,:]", - coeff3: "float[:,:]", - coeff_ind1: "int[:]", - coeff_ind2: "int[:]", - coeff_ind3: "int[:]", - bs1: "float[:,:]", - bs2: "float[:,:,:]", - bs3: "float[:,:]", - x_int_ind1: "int[:,:]", - x_his_ind2: "int[:,:]", - x_int_ind3: "int[:,:]", - wts2: "float[:,:]", - tau: "float[:,:,:,:,:,:]", - mat_eq: "float[:,:,:,:]", -): - tau[:, :, :, :, :, :] = 0.0 - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : tau) private (i1, i2, i3, j1, j2, j3, coeff, kl1, k1, c1, kl2, k2, c2, kl3, k3, c3, f_int, q2) - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for j1 in range(n_inthis[0]): - for j2 in range(n_inthis[1]): - for j3 in range(n_inthis[2]): - coeff = coeff1[coeff_ind1[i1], j1] * coeff2[coeff_ind2[i2], j2] * coeff3[coeff_ind3[i3], j3] - - for kl1 in range(n_nvbf[0]): - k1 = i_glo1[i1, kl1] - c1 = c_loc1[i1, kl1] - - for kl2 in range(n_nvbf[1]): - k2 = i_glo2[i2, kl2] - c2 = c_loc2[i2, kl2] - - for kl3 in range(n_nvbf[2]): - k3 = i_glo3[i3, kl3] - c3 = c_loc3[i3, kl3] - - f_int = 0.0 - - for q2 in range(n_quad2): - f_int += ( - wts2[x_his_ind2[i2, j2], q2] - * bs1[x_int_ind1[i1, j1], k1] - * bs2[x_his_ind2[i2, j2], q2, k2] - * bs3[x_int_ind3[i3, j3], k3] - * mat_eq[x_int_ind1[i1, j1], x_his_ind2[i2, j2], q2, x_int_ind3[i3, j3]] - ) - - tau[k1, k2, k3, c1, c2, c3] += coeff * f_int - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ======================================================== -def kernel_pi1_3( - n: "int[:]", - n_quad3: "int", - n_inthis: "int[:]", - n_nvbf: "int[:]", - i_glo1: "int[:,:]", - i_glo2: "int[:,:]", - i_glo3: "int[:,:]", - c_loc1: "int[:,:]", - c_loc2: "int[:,:]", - c_loc3: "int[:,:]", - coeff1: "float[:,:]", - coeff2: "float[:,:]", - coeff3: "float[:,:]", - coeff_ind1: "int[:]", - coeff_ind2: "int[:]", - coeff_ind3: "int[:]", - bs1: "float[:,:]", - bs2: "float[:,:]", - bs3: "float[:,:,:]", - x_int_ind1: "int[:,:]", - x_int_ind2: "int[:,:]", - x_his_ind3: "int[:,:]", - wts3: "float[:,:]", - tau: "float[:,:,:,:,:,:]", - mat_eq: "float[:,:,:,:]", -): - tau[:, :, :, :, :, :] = 0.0 - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : tau) private (i1, i2, i3, j1, j2, j3, coeff, kl1, k1, c1, kl2, k2, c2, kl3, k3, c3, f_int, q3) - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for j1 in range(n_inthis[0]): - for j2 in range(n_inthis[1]): - for j3 in range(n_inthis[2]): - coeff = coeff1[coeff_ind1[i1], j1] * coeff2[coeff_ind2[i2], j2] * coeff3[coeff_ind3[i3], j3] - - for kl1 in range(n_nvbf[0]): - k1 = i_glo1[i1, kl1] - c1 = c_loc1[i1, kl1] - - for kl2 in range(n_nvbf[1]): - k2 = i_glo2[i2, kl2] - c2 = c_loc2[i2, kl2] - - for kl3 in range(n_nvbf[2]): - k3 = i_glo3[i3, kl3] - c3 = c_loc3[i3, kl3] - - f_int = 0.0 - - for q3 in range(n_quad3): - f_int += ( - wts3[x_his_ind3[i3, j3], q3] - * bs1[x_int_ind1[i1, j1], k1] - * bs2[x_int_ind2[i2, j2], k2] - * bs3[x_his_ind3[i3, j3], q3, k3] - * mat_eq[x_int_ind1[i1, j1], x_int_ind2[i2, j2], x_his_ind3[i3, j3], q3] - ) - - tau[k1, k2, k3, c1, c2, c3] += coeff * f_int - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ======================================================== -def kernel_pi2_1( - n: "int[:]", - n_quad: "int[:]", - n_inthis: "int[:]", - n_nvbf: "int[:]", - i_glo1: "int[:,:]", - i_glo2: "int[:,:]", - i_glo3: "int[:,:]", - c_loc1: "int[:,:]", - c_loc2: "int[:,:]", - c_loc3: "int[:,:]", - coeff1: "float[:,:]", - coeff2: "float[:,:]", - coeff3: "float[:,:]", - coeff_ind1: "int[:]", - coeff_ind2: "int[:]", - coeff_ind3: "int[:]", - bs1: "float[:,:]", - bs2: "float[:,:,:]", - bs3: "float[:,:,:]", - x_int_ind1: "int[:,:]", - x_his_ind2: "int[:,:]", - x_his_ind3: "int[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", - tau: "float[:,:,:,:,:,:]", - mat_eq: "float[:,:,:,:,:]", -): - tau[:, :, :, :, :, :] = 0.0 - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : tau) private (i1, i2, i3, j1, j2, j3, coeff, kl1, k1, c1, kl2, k2, c2, kl3, k3, c3, f_int, q2, q3, wvol) - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for j1 in range(n_inthis[0]): - for j2 in range(n_inthis[1]): - for j3 in range(n_inthis[2]): - coeff = coeff1[coeff_ind1[i1], j1] * coeff2[coeff_ind2[i2], j2] * coeff3[coeff_ind3[i3], j3] - - for kl1 in range(n_nvbf[0]): - k1 = i_glo1[i1, kl1] - c1 = c_loc1[i1, kl1] - - for kl2 in range(n_nvbf[1]): - k2 = i_glo2[i2, kl2] - c2 = c_loc2[i2, kl2] - - for kl3 in range(n_nvbf[2]): - k3 = i_glo3[i3, kl3] - c3 = c_loc3[i3, kl3] - - f_int = 0.0 - - for q2 in range(n_quad[0]): - for q3 in range(n_quad[1]): - wvol = wts2[x_his_ind2[i2, j2], q2] * wts3[x_his_ind3[i3, j3], q3] - f_int += ( - wvol - * bs1[x_int_ind1[i1, j1], k1] - * bs2[x_his_ind2[i2, j2], q2, k2] - * bs3[x_his_ind3[i3, j3], q3, k3] - * mat_eq[ - x_int_ind1[i1, j1], - x_his_ind2[i2, j2], - q2, - x_his_ind3[i3, j3], - q3, - ] - ) - - tau[k1, k2, k3, c1, c2, c3] += coeff * f_int - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ======================================================== -def kernel_pi2_2( - n: "int[:]", - n_quad: "int[:]", - n_inthis: "int[:]", - n_nvbf: "int[:]", - i_glo1: "int[:,:]", - i_glo2: "int[:,:]", - i_glo3: "int[:,:]", - c_loc1: "int[:,:]", - c_loc2: "int[:,:]", - c_loc3: "int[:,:]", - coeff1: "float[:,:]", - coeff2: "float[:,:]", - coeff3: "float[:,:]", - coeff_ind1: "int[:]", - coeff_ind2: "int[:]", - coeff_ind3: "int[:]", - bs1: "float[:,:,:]", - bs2: "float[:,:]", - bs3: "float[:,:,:]", - x_his_ind1: "int[:,:]", - x_int_ind2: "int[:,:]", - x_his_ind3: "int[:,:]", - wts1: "float[:,:]", - wts3: "float[:,:]", - tau: "float[:,:,:,:,:,:]", - mat_eq: "float[:,:,:,:,:]", -): - tau[:, :, :, :, :, :] = 0.0 - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : tau) private (i1, i2, i3, j1, j2, j3, coeff, kl1, k1, c1, kl2, k2, c2, kl3, k3, c3, f_int, q1, q3, wvol) - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for j1 in range(n_inthis[0]): - for j2 in range(n_inthis[1]): - for j3 in range(n_inthis[2]): - coeff = coeff1[coeff_ind1[i1], j1] * coeff2[coeff_ind2[i2], j2] * coeff3[coeff_ind3[i3], j3] - - for kl1 in range(n_nvbf[0]): - k1 = i_glo1[i1, kl1] - c1 = c_loc1[i1, kl1] - - for kl2 in range(n_nvbf[1]): - k2 = i_glo2[i2, kl2] - c2 = c_loc2[i2, kl2] - - for kl3 in range(n_nvbf[2]): - k3 = i_glo3[i3, kl3] - c3 = c_loc3[i3, kl3] - - f_int = 0.0 - - for q1 in range(n_quad[0]): - for q3 in range(n_quad[1]): - wvol = wts1[x_his_ind1[i1, j1], q1] * wts3[x_his_ind3[i3, j3], q3] - f_int += ( - wvol - * bs1[x_his_ind1[i1, j1], q1, k1] - * bs2[x_int_ind2[i2, j2], k2] - * bs3[x_his_ind3[i3, j3], q3, k3] - * mat_eq[ - x_his_ind1[i1, j1], - q1, - x_int_ind2[i2, j2], - x_his_ind3[i3, j3], - q3, - ] - ) - - tau[k1, k2, k3, c1, c2, c3] += coeff * f_int - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ======================================================== -def kernel_pi2_3( - n: "int[:]", - n_quad: "int[:]", - n_inthis: "int[:]", - n_nvbf: "int[:]", - i_glo1: "int[:,:]", - i_glo2: "int[:,:]", - i_glo3: "int[:,:]", - c_loc1: "int[:,:]", - c_loc2: "int[:,:]", - c_loc3: "int[:,:]", - coeff1: "float[:,:]", - coeff2: "float[:,:]", - coeff3: "float[:,:]", - coeff_ind1: "int[:]", - coeff_ind2: "int[:]", - coeff_ind3: "int[:]", - bs1: "float[:,:,:]", - bs2: "float[:,:,:]", - bs3: "float[:,:]", - x_his_ind1: "int[:,:]", - x_his_ind2: "int[:,:]", - x_int_ind3: "int[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - tau: "float[:,:,:,:,:,:]", - mat_eq: "float[:,:,:,:,:]", -): - tau[:, :, :, :, :, :] = 0.0 - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : tau) private (i1, i2, i3, j1, j2, j3, coeff, kl1, k1, c1, kl2, k2, c2, kl3, k3, c3, f_int, q1, q2, wvol) - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for j1 in range(n_inthis[0]): - for j2 in range(n_inthis[1]): - for j3 in range(n_inthis[2]): - coeff = coeff1[coeff_ind1[i1], j1] * coeff2[coeff_ind2[i2], j2] * coeff3[coeff_ind3[i3], j3] - - for kl1 in range(n_nvbf[0]): - k1 = i_glo1[i1, kl1] - c1 = c_loc1[i1, kl1] - - for kl2 in range(n_nvbf[1]): - k2 = i_glo2[i2, kl2] - c2 = c_loc2[i2, kl2] - - for kl3 in range(n_nvbf[2]): - k3 = i_glo3[i3, kl3] - c3 = c_loc3[i3, kl3] - - f_int = 0.0 - - for q1 in range(n_quad[0]): - for q2 in range(n_quad[1]): - wvol = wts1[x_his_ind1[i1, j1], q1] * wts2[x_his_ind2[i2, j2], q2] - f_int += ( - wvol - * bs1[x_his_ind1[i1, j1], q1, k1] - * bs2[x_his_ind2[i2, j2], q2, k2] - * bs3[x_int_ind3[i3, j3], k3] - * mat_eq[ - x_his_ind1[i1, j1], - q1, - x_his_ind2[i2, j2], - q2, - x_int_ind3[i3, j3], - ] - ) - - tau[k1, k2, k3, c1, c2, c3] += coeff * f_int - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ======================================================== -def kernel_pi3( - n: "int[:]", - n_quad: "int[:]", - n_his: "int[:]", - n_nvbf: "int[:]", - i_glo1: "int[:,:]", - i_glo2: "int[:,:]", - i_glo3: "int[:,:]", - c_loc1: "int[:,:]", - c_loc2: "int[:,:]", - c_loc3: "int[:,:]", - coeff1: "float[:,:]", - coeff2: "float[:,:]", - coeff3: "float[:,:]", - coeff_ind1: "int[:]", - coeff_ind2: "int[:]", - coeff_ind3: "int[:]", - bs1: "float[:,:,:]", - bs2: "float[:,:,:]", - bs3: "float[:,:,:]", - x_his_ind1: "int[:,:]", - x_his_ind2: "int[:,:]", - x_his_ind3: "int[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", - tau: "float[:,:,:,:,:,:]", - mat_eq: "float[:,:,:,:,:,:]", -): - tau[:, :, :, :, :, :] = 0.0 - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : tau) private (i1, i2, i3, j1, j2, j3, coeff, kl1, k1, c1, kl2, k2, c2, kl3, k3, c3, f_int, q1, q2, q3, wvol) - for i1 in range(n[0]): - for i2 in range(n[1]): - for i3 in range(n[2]): - for j1 in range(n_his[0]): - for j2 in range(n_his[1]): - for j3 in range(n_his[2]): - coeff = coeff1[coeff_ind1[i1], j1] * coeff2[coeff_ind2[i2], j2] * coeff3[coeff_ind3[i3], j3] - - for kl1 in range(n_nvbf[0]): - k1 = i_glo1[i1, kl1] - c1 = c_loc1[i1, kl1] - - for kl2 in range(n_nvbf[1]): - k2 = i_glo2[i2, kl2] - c2 = c_loc2[i2, kl2] - - for kl3 in range(n_nvbf[2]): - k3 = i_glo3[i3, kl3] - c3 = c_loc3[i3, kl3] - - f_int = 0.0 - - for q1 in range(n_quad[0]): - for q2 in range(n_quad[1]): - for q3 in range(n_quad[2]): - wvol = ( - wts1[x_his_ind1[i1, j1], q1] - * wts2[x_his_ind2[i2, j2], q2] - * wts3[x_his_ind3[i3, j3], q3] - ) - f_int += ( - wvol - * bs1[x_his_ind1[i1, j1], q1, k1] - * bs2[x_his_ind2[i2, j2], q2, k2] - * bs3[x_his_ind3[i3, j3], q3, k3] - * mat_eq[ - x_his_ind1[i1, j1], - q1, - x_his_ind2[i2, j2], - q2, - x_his_ind3[i3, j3], - q3, - ] - ) - - tau[k1, k2, k3, c1, c2, c3] += coeff * f_int - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/mhd_operators_3d_local.py b/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/mhd_operators_3d_local.py deleted file mode 100644 index 6734a11b0..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/mhd_operators_3d_local.py +++ /dev/null @@ -1,4905 +0,0 @@ -# coding: utf-8 -# -# Copyright 2020 Florian Holderied (florian.holderied@ipp.mpg.de) - -""" -Class for local projections for linear ideal mhd in 3d based on quasi-interpolation -""" - -import sys - -import cunumpy as xp -import scipy.sparse as spa -import source_run.kernels_projectors_evaluation as ker_eva - -import struphy.feec.basics.kernels_3d as ker_loc_3d -import struphy.feec.bsplines as bsp -import struphy.feec.projectors.pro_local.kernels_projectors_local_mhd as ker_loc - - -class projectors_local_mhd: - """ - Local commuting projections of various terms in linear ideal MHD. - - Parameters - ---------- - tensor_space : Tensor_spline_space - a 3d tensor product space of B-splines - - n_quad : list of ints - number of quadrature points per integration interval for histopolations - """ - - def __init__(self, tensor_space, n_quad): - self.tensor_space = tensor_space - - self.T = tensor_space.T # knot vector - self.p = tensor_space.p # spline degree - self.bc = tensor_space.bc # boundary conditions - - self.Nel = tensor_space.Nel # number of elements - self.NbaseN = tensor_space.NbaseN # number of basis functions (N) - self.NbaseD = tensor_space.NbaseD # number of basis functions (D) - - self.n_quad = n_quad # number of quadrature point per integration interval - - # Gauss - Legendre quadrature points and weights in (-1, 1) - self.pts_loc = [xp.polynomial.legendre.leggauss(n_quad)[0] for n_quad in self.n_quad] - self.wts_loc = [xp.polynomial.legendre.leggauss(n_quad)[1] for n_quad in self.n_quad] - - # set interpolation and histopolation coefficients - self.coeff_i = [0, 0, 0] - self.coeff_h = [0, 0, 0] - - for a in range(3): - if self.bc[a]: - self.coeff_i[a] = xp.zeros((1, 2 * self.p[a] - 1), dtype=float) - self.coeff_h[a] = xp.zeros((1, 2 * self.p[a]), dtype=float) - - if self.p[a] == 1: - self.coeff_i[a][0, :] = xp.array([1.0]) - self.coeff_h[a][0, :] = xp.array([1.0, 1.0]) - - elif self.p[a] == 2: - self.coeff_i[a][0, :] = 1 / 2 * xp.array([-1.0, 4.0, -1.0]) - self.coeff_h[a][0, :] = 1 / 2 * xp.array([-1.0, 3.0, 3.0, -1.0]) - - elif self.p[a] == 3: - self.coeff_i[a][0, :] = 1 / 6 * xp.array([1.0, -8.0, 20.0, -8.0, 1.0]) - self.coeff_h[a][0, :] = 1 / 6 * xp.array([1.0, -7.0, 12.0, 12.0, -7.0, 1.0]) - - elif self.p[a] == 4: - self.coeff_i[a][0, :] = 2 / 45 * xp.array([-1.0, 16.0, -295 / 4, 140.0, -295 / 4, 16.0, -1.0]) - self.coeff_h[a][0, :] = ( - 2 / 45 * xp.array([-1.0, 15.0, -231 / 4, 265 / 4, 265 / 4, -231 / 4, 15.0, -1.0]) - ) - - else: - print("degree > 4 not implemented!") - - else: - self.coeff_i[a] = xp.zeros((2 * self.p[a] - 1, 2 * self.p[a] - 1), dtype=float) - self.coeff_h[a] = xp.zeros((2 * self.p[a] - 1, 2 * self.p[a]), dtype=float) - - if self.p[a] == 1: - self.coeff_i[a][0, :] = xp.array([1.0]) - self.coeff_h[a][0, :] = xp.array([1.0, 1.0]) - - elif self.p[a] == 2: - self.coeff_i[a][0, :] = 1 / 2 * xp.array([2.0, 0.0, 0.0]) - self.coeff_i[a][1, :] = 1 / 2 * xp.array([-1.0, 4.0, -1.0]) - self.coeff_i[a][2, :] = 1 / 2 * xp.array([0.0, 0.0, 2.0]) - - self.coeff_h[a][0, :] = 1 / 2 * xp.array([3.0, -1.0, 0.0, 0.0]) - self.coeff_h[a][1, :] = 1 / 2 * xp.array([-1.0, 3.0, 3.0, -1.0]) - self.coeff_h[a][2, :] = 1 / 2 * xp.array([0.0, 0.0, -1.0, 3.0]) - - elif self.p[a] == 3: - self.coeff_i[a][0, :] = 1 / 18 * xp.array([18.0, 0.0, 0.0, 0.0, 0.0]) - self.coeff_i[a][1, :] = 1 / 18 * xp.array([-5.0, 40.0, -24.0, 8.0, -1.0]) - self.coeff_i[a][2, :] = 1 / 18 * xp.array([3.0, -24.0, 60.0, -24.0, 3.0]) - self.coeff_i[a][3, :] = 1 / 18 * xp.array([-1.0, 8.0, -24.0, 40.0, -5.0]) - self.coeff_i[a][4, :] = 1 / 18 * xp.array([0.0, 0.0, 0.0, 0.0, 18.0]) - - self.coeff_h[a][0, :] = 1 / 18 * xp.array([23.0, -17.0, 7.0, -1.0, 0.0, 0.0]) - self.coeff_h[a][1, :] = 1 / 18 * xp.array([-8.0, 56.0, -28.0, 4.0, 0.0, 0.0]) - self.coeff_h[a][2, :] = 1 / 18 * xp.array([3.0, -21.0, 36.0, 36.0, -21.0, 3.0]) - self.coeff_h[a][3, :] = 1 / 18 * xp.array([0.0, 0.0, 4.0, -28.0, 56.0, -8.0]) - self.coeff_h[a][4, :] = 1 / 18 * xp.array([0.0, 0.0, -1.0, 7.0, -17.0, 23.0]) - - elif self.p[a] == 4: - self.coeff_i[a][0, :] = 1 / 360 * xp.array([360.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) - self.coeff_i[a][1, :] = 1 / 360 * xp.array([-59.0, 944.0, -1000.0, 720.0, -305.0, 64.0, -4.0]) - self.coeff_i[a][2, :] = 1 / 360 * xp.array([23.0, -368.0, 1580.0, -1360.0, 605.0, -128.0, 8.0]) - self.coeff_i[a][3, :] = 1 / 360 * xp.array([-16.0, 256.0, -1180.0, 2240.0, -1180.0, 256.0, -16.0]) - self.coeff_i[a][4, :] = 1 / 360 * xp.array([8.0, -128.0, 605.0, -1360.0, 1580.0, -368.0, 23.0]) - self.coeff_i[a][5, :] = 1 / 360 * xp.array([-4.0, 64.0, -305.0, 720.0, -1000.0, 944.0, -59.0]) - self.coeff_i[a][6, :] = 1 / 360 * xp.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 360.0]) - - self.coeff_h[a][0, :] = 1 / 360 * xp.array([419.0, -525.0, 475.0, -245.0, 60.0, -4.0, 0.0, 0.0]) - self.coeff_h[a][1, :] = 1 / 360 * xp.array([-82.0, 1230.0, -1350.0, 730.0, -180.0, 12.0, 0.0, 0.0]) - self.coeff_h[a][2, :] = 1 / 360 * xp.array([39.0, -585.0, 2175.0, -1425.0, 360.0, -24.0, 0.0, 0.0]) - self.coeff_h[a][3, :] = ( - 1 / 360 * xp.array([-16.0, 240.0, -924.0, 1060.0, 1060.0, -924.0, 240.0, -16.0]) - ) - self.coeff_h[a][4, :] = 1 / 360 * xp.array([0.0, 0.0, -24.0, 360.0, -1425.0, 2175.0, -585.0, 39.0]) - self.coeff_h[a][5, :] = 1 / 360 * xp.array([0.0, 0.0, 12.0, -180.0, 730.0, -1350.0, 1230.0, -82.0]) - self.coeff_h[a][6, :] = 1 / 360 * xp.array([0.0, 0.0, -4.0, 60.0, -245.0, 475.0, -525.0, 419.0]) - - else: - print("degree > 4 not implemented!") - - # set interpolation points - n_lambda_int = [NbaseN for NbaseN in self.NbaseN] # number of coefficients in space V0 - self.n_int = [2 * p - 1 for p in self.p] # number of interpolation points (1, 3, 5, 7, ...) - - self.n_int_locbf_N = [0, 0, 0] - self.n_int_locbf_D = [0, 0, 0] - - for a in range(3): - if self.p[a] == 1: - self.n_int_locbf_N[a] = 2 # number of non-vanishing N bf in interpolation interval (2, 3, 5, 7) - self.n_int_locbf_D[a] = 1 # number of non-vanishing D bf in interpolation interval (1, 2, 4, 6) - - else: - self.n_int_locbf_N[a] = ( - 2 * self.p[a] - 1 - ) # number of non-vanishing N bf in interpolation interval (2, 3, 5, 7) - self.n_int_locbf_D[a] = ( - 2 * self.p[a] - 2 - ) # number of non-vanishing D bf in interpolation interval (1, 2, 4, 6) - - self.x_int = [ - xp.zeros((n_lambda_int, n_int), dtype=float) for n_lambda_int, n_int in zip(n_lambda_int, self.n_int) - ] - - self.int_global_N = [ - xp.zeros((n_lambda_int, n_int_locbf_N), dtype=int) - for n_lambda_int, n_int_locbf_N in zip(n_lambda_int, self.n_int_locbf_N) - ] - self.int_global_D = [ - xp.zeros((n_lambda_int, n_int_locbf_D), dtype=int) - for n_lambda_int, n_int_locbf_D in zip(n_lambda_int, self.n_int_locbf_D) - ] - - self.int_loccof_N = [ - xp.zeros((n_lambda_int, n_int_locbf_N), dtype=int) - for n_lambda_int, n_int_locbf_N in zip(n_lambda_int, self.n_int_locbf_N) - ] - self.int_loccof_D = [ - xp.zeros((n_lambda_int, n_int_locbf_D), dtype=int) - for n_lambda_int, n_int_locbf_D in zip(n_lambda_int, self.n_int_locbf_D) - ] - - self.x_int_indices = [ - xp.zeros((n_lambda_int, n_int), dtype=int) for n_lambda_int, n_int in zip(n_lambda_int, self.n_int) - ] - self.coeffi_indices = [xp.zeros(n_lambda_int, dtype=int) for n_lambda_int in n_lambda_int] - - self.n_int_nvcof_D = [None, None, None] - self.n_int_nvcof_N = [None, None, None] - - self.int_add_D = [None, None, None] - self.int_add_N = [None, None, None] - - self.int_shift_D = [0, 0, 0] - self.int_shift_N = [0, 0, 0] - - for a in range(3): - if not self.bc[a]: - # maximum number of non-vanishing coefficients - if self.p[a] == 1: - self.n_int_nvcof_D[a] = 2 - self.n_int_nvcof_N[a] = 2 - - else: - self.n_int_nvcof_D[a] = 3 * self.p[a] - 3 - self.n_int_nvcof_N[a] = 3 * self.p[a] - 2 - - # shift in local coefficient indices at right boundary (only for non-periodic boundary conditions) - self.int_add_D[a] = xp.arange(self.n_int[a] - 2) + 1 - self.int_add_N[a] = xp.arange(self.n_int[a] - 1) + 1 - - counter_D = 0 - counter_N = 0 - - # shift local coefficients --> global coefficients (D) - if self.p[a] == 1: - self.int_shift_D[a] = xp.arange(self.NbaseD[a]) - else: - self.int_shift_D[a] = xp.arange(self.NbaseD[a]) - (self.p[a] - 2) - self.int_shift_D[a][: 2 * self.p[a] - 2] = 0 - self.int_shift_D[a][-(2 * self.p[a] - 2) :] = self.int_shift_D[a][-(2 * self.p[a] - 2)] - - # shift local coefficients --> global coefficients (N) - if self.p[a] == 1: - self.int_shift_N[a] = xp.arange(self.NbaseN[a]) - self.int_shift_N[a][-1] = self.int_shift_N[a][-2] - - else: - self.int_shift_N[a] = xp.arange(self.NbaseN[a]) - (self.p[a] - 1) - self.int_shift_N[a][: 2 * self.p[a] - 1] = 0 - self.int_shift_N[a][-(2 * self.p[a] - 1) :] = self.int_shift_N[a][-(2 * self.p[a] - 1)] - - counter_coeffi = xp.copy(self.p[a]) - - for i in range(n_lambda_int[a]): - # left boundary region - if i < self.p[a] - 1: - self.int_global_N[a][i] = xp.arange(self.n_int_locbf_N[a]) - self.int_global_D[a][i] = xp.arange(self.n_int_locbf_D[a]) - - self.x_int_indices[a][i] = xp.arange(self.n_int[a]) - self.coeffi_indices[a][i] = i - for j in range(2 * (self.p[a] - 1) + 1): - xi = self.p[a] - 1 - self.x_int[a][i, j] = ( - self.T[a][xi + 1 + int(j / 2)] + self.T[a][xi + 1 + int((j + 1) / 2)] - ) / 2 - - # right boundary region - elif i > n_lambda_int[a] - self.p[a]: - self.int_global_N[a][i] = ( - xp.arange(self.n_int_locbf_N[a]) + n_lambda_int[a] - self.p[a] - (self.p[a] - 1) - ) - self.int_global_D[a][i] = ( - xp.arange(self.n_int_locbf_D[a]) + n_lambda_int[a] - self.p[a] - (self.p[a] - 1) - ) - - self.x_int_indices[a][i] = xp.arange(self.n_int[a]) + 2 * ( - n_lambda_int[a] - self.p[a] - (self.p[a] - 1) - ) - self.coeffi_indices[a][i] = counter_coeffi - counter_coeffi += 1 - for j in range(2 * (self.p[a] - 1) + 1): - xi = n_lambda_int[a] - self.p[a] - self.x_int[a][i, j] = ( - self.T[a][xi + 1 + int(j / 2)] + self.T[a][xi + 1 + int((j + 1) / 2)] - ) / 2 - - # interior - else: - if self.p[a] == 1: - self.int_global_N[a][i] = xp.arange(self.n_int_locbf_N[a]) + i - self.int_global_D[a][i] = xp.arange(self.n_int_locbf_D[a]) + i - - self.int_global_N[a][-1] = self.int_global_N[a][-2] - self.int_global_D[a][-1] = self.int_global_D[a][-2] - - else: - self.int_global_N[a][i] = xp.arange(self.n_int_locbf_N[a]) + i - (self.p[a] - 1) - self.int_global_D[a][i] = xp.arange(self.n_int_locbf_D[a]) + i - (self.p[a] - 1) - - if self.p[a] == 1: - self.x_int_indices[a][i] = i - else: - self.x_int_indices[a][i] = xp.arange(self.n_int[a]) + 2 * (i - (self.p[a] - 1)) - - self.coeffi_indices[a][i] = self.p[a] - 1 - - for j in range(2 * (self.p[a] - 1) + 1): - self.x_int[a][i, j] = ( - self.T[a][i + 1 + int(j / 2)] + self.T[a][i + 1 + int((j + 1) / 2)] - ) / 2 - - # local coefficient index - if self.p[a] == 1: - self.int_loccof_N[a][i] = xp.array([0, 1]) - self.int_loccof_D[a][-1] = xp.array([1]) - - else: - if i > 0: - for il in range(self.n_int_locbf_D[a]): - k_glob_new = self.int_global_D[a][i, il] - bol = k_glob_new == self.int_global_D[a][i - 1] - - if xp.any(bol): - self.int_loccof_D[a][i, il] = self.int_loccof_D[a][i - 1, xp.where(bol)[0][0]] + 1 - - if (k_glob_new >= n_lambda_int[a] - self.p[a] - (self.p[a] - 2)) and ( - self.int_loccof_D[a][i, il] == 0 - ): - self.int_loccof_D[a][i, il] = self.int_add_D[a][counter_D] - counter_D += 1 - - for il in range(self.n_int_locbf_N[a]): - k_glob_new = self.int_global_N[a][i, il] - bol = k_glob_new == self.int_global_N[a][i - 1] - - if xp.any(bol): - self.int_loccof_N[a][i, il] = self.int_loccof_N[a][i - 1, xp.where(bol)[0][0]] + 1 - - if (k_glob_new >= n_lambda_int[a] - self.p[a] - (self.p[a] - 2)) and ( - self.int_loccof_N[a][i, il] == 0 - ): - self.int_loccof_N[a][i, il] = self.int_add_N[a][counter_N] - counter_N += 1 - - else: - # maximum number of non-vanishing coefficients - if self.p[a] == 1: - self.n_int_nvcof_D[a] = 2 * self.p[a] - 1 - self.n_int_nvcof_N[a] = 2 * self.p[a] - - else: - self.n_int_nvcof_D[a] = 2 * self.p[a] - 2 - self.n_int_nvcof_N[a] = 2 * self.p[a] - 1 - - # shift local coefficients --> global coefficients - if self.p[a] == 1: - self.int_shift_D[a] = xp.arange(self.NbaseN[a]) - (self.p[a] - 1) - self.int_shift_N[a] = xp.arange(self.NbaseN[a]) - (self.p[a]) - else: - self.int_shift_D[a] = xp.arange(self.NbaseN[a]) - (self.p[a] - 2) - self.int_shift_N[a] = xp.arange(self.NbaseN[a]) - (self.p[a] - 1) - - for i in range(n_lambda_int[a]): - # global indices of non-vanishing basis functions and position of coefficients in final matrix - self.int_global_N[a][i] = (xp.arange(self.n_int_locbf_N[a]) + i - (self.p[a] - 1)) % self.NbaseN[a] - self.int_global_D[a][i] = (xp.arange(self.n_int_locbf_D[a]) + i - (self.p[a] - 1)) % self.NbaseD[a] - - self.int_loccof_N[a][i] = xp.arange(self.n_int_locbf_N[a] - 1, -1, -1) - self.int_loccof_D[a][i] = xp.arange(self.n_int_locbf_D[a] - 1, -1, -1) - - if self.p[a] == 1: - self.x_int_indices[a][i] = i - else: - self.x_int_indices[a][i] = (xp.arange(self.n_int[a]) + 2 * (i - (self.p[a] - 1))) % ( - 2 * self.Nel[a] - ) - - self.coeffi_indices[a][i] = 0 - - for j in range(2 * (self.p[a] - 1) + 1): - self.x_int[a][i, j] = ( - (self.T[a][i + 1 + int(j / 2)] + self.T[a][i + 1 + int((j + 1) / 2)]) / 2 - ) % 1.0 - - # identify unique interpolation points to save memory - self.x_int[a] = xp.unique(self.x_int[a].flatten()) - - # set histopolation points, quadrature points and weights - n_lambda_his = [xp.copy(NbaseD) for NbaseD in self.NbaseD] # number of coefficients in space V1 - - self.n_his = [2 * p for p in self.p] # number of histopolation intervals - self.n_his_locbf_N = [2 * p for p in self.p] # number of non-vanishing N bf in histopolation interval - self.n_his_locbf_D = [2 * p - 1 for p in self.p] # number of non-vanishing D bf in histopolation interval - - self.x_his = [ - xp.zeros((n_lambda_his, n_his + 1), dtype=float) for n_lambda_his, n_his in zip(n_lambda_his, self.n_his) - ] - - self.his_global_N = [ - xp.zeros((n_lambda_his, n_his_locbf_N), dtype=int) - for n_lambda_his, n_his_locbf_N in zip(n_lambda_his, self.n_his_locbf_N) - ] - self.his_global_D = [ - xp.zeros((n_lambda_his, n_his_locbf_D), dtype=int) - for n_lambda_his, n_his_locbf_D in zip(n_lambda_his, self.n_his_locbf_D) - ] - - self.his_loccof_N = [ - xp.zeros((n_lambda_his, n_his_locbf_N), dtype=int) - for n_lambda_his, n_his_locbf_N in zip(n_lambda_his, self.n_his_locbf_N) - ] - self.his_loccof_D = [ - xp.zeros((n_lambda_his, n_his_locbf_D), dtype=int) - for n_lambda_his, n_his_locbf_D in zip(n_lambda_his, self.n_his_locbf_D) - ] - - self.x_his_indices = [ - xp.zeros((n_lambda_his, n_his), dtype=int) for n_lambda_his, n_his in zip(n_lambda_his, self.n_his) - ] - self.coeffh_indices = [xp.zeros(n_lambda_his, dtype=int) for n_lambda_his in n_lambda_his] - - self.pts = [0, 0, 0] - self.wts = [0, 0, 0] - - self.n_his_nvcof_D = [None, None, None] - self.n_his_nvcof_N = [None, None, None] - - self.his_add_D = [None, None, None] - self.his_add_N = [None, None, None] - - self.his_shift_D = [0, 0, 0] - self.his_shift_N = [0, 0, 0] - - for a in range(3): - if not self.bc[a]: - # maximum number of non-vanishing coefficients - self.n_his_nvcof_D[a] = 3 * self.p[a] - 2 - self.n_his_nvcof_N[a] = 3 * self.p[a] - 1 - - # shift in local coefficient indices at right boundary (only for non-periodic boundary conditions) - self.his_add_D[a] = xp.arange(self.n_his[a] - 2) + 1 - self.his_add_N[a] = xp.arange(self.n_his[a] - 1) + 1 - - counter_D = 0 - counter_N = 0 - - # shift local coefficients --> global coefficients (D) - self.his_shift_D[a] = xp.arange(self.NbaseD[a]) - (self.p[a] - 1) - self.his_shift_D[a][: 2 * self.p[a] - 1] = 0 - self.his_shift_D[a][-(2 * self.p[a] - 1) :] = self.his_shift_D[a][-(2 * self.p[a] - 1)] - - # shift local coefficients --> global coefficients (N) - self.his_shift_N[a] = xp.arange(self.NbaseN[a]) - self.p[a] - self.his_shift_N[a][: 2 * self.p[a]] = 0 - self.his_shift_N[a][-2 * self.p[a] :] = self.his_shift_N[a][-2 * self.p[a]] - - counter_coeffh = xp.copy(self.p[a]) - - for i in range(n_lambda_his[a]): - # left boundary region - if i < self.p[a] - 1: - self.his_global_N[a][i] = xp.arange(self.n_his_locbf_N[a]) - self.his_global_D[a][i] = xp.arange(self.n_his_locbf_D[a]) - - self.x_his_indices[a][i] = xp.arange(self.n_his[a]) - self.coeffh_indices[a][i] = i - for j in range(2 * self.p[a] + 1): - xi = self.p[a] - 1 - self.x_his[a][i, j] = ( - self.T[a][xi + 1 + int(j / 2)] + self.T[a][xi + 1 + int((j + 1) / 2)] - ) / 2 - - # right boundary region - elif i > n_lambda_his[a] - self.p[a]: - self.his_global_N[a][i] = ( - xp.arange(self.n_his_locbf_N[a]) + n_lambda_his[a] - self.p[a] - (self.p[a] - 1) - ) - self.his_global_D[a][i] = ( - xp.arange(self.n_his_locbf_D[a]) + n_lambda_his[a] - self.p[a] - (self.p[a] - 1) - ) - - self.x_his_indices[a][i] = xp.arange(self.n_his[a]) + 2 * ( - n_lambda_his[a] - self.p[a] - (self.p[a] - 1) - ) - self.coeffh_indices[a][i] = counter_coeffh - counter_coeffh += 1 - for j in range(2 * self.p[a] + 1): - xi = n_lambda_his[a] - self.p[a] - self.x_his[a][i, j] = ( - self.T[a][xi + 1 + int(j / 2)] + self.T[a][xi + 1 + int((j + 1) / 2)] - ) / 2 - - # interior - else: - self.his_global_N[a][i] = xp.arange(self.n_his_locbf_N[a]) + i - (self.p[a] - 1) - self.his_global_D[a][i] = xp.arange(self.n_his_locbf_D[a]) + i - (self.p[a] - 1) - - self.x_his_indices[a][i] = xp.arange(self.n_his[a]) + 2 * (i - (self.p[a] - 1)) - self.coeffh_indices[a][i] = self.p[a] - 1 - for j in range(2 * self.p[a] + 1): - self.x_his[a][i, j] = ( - self.T[a][i + 1 + int(j / 2)] + self.T[a][i + 1 + int((j + 1) / 2)] - ) / 2 - - # local coefficient index - if i > 0: - for il in range(self.n_his_locbf_D[a]): - k_glob_new = self.his_global_D[a][i, il] - bol = k_glob_new == self.his_global_D[a][i - 1] - - if xp.any(bol): - self.his_loccof_D[a][i, il] = self.his_loccof_D[a][i - 1, xp.where(bol)[0][0]] + 1 - - if (k_glob_new >= n_lambda_his[a] - self.p[a] - (self.p[a] - 2)) and ( - self.his_loccof_D[a][i, il] == 0 - ): - self.his_loccof_D[a][i, il] = self.his_add_D[a][counter_D] - counter_D += 1 - - for il in range(self.n_his_locbf_N[a]): - k_glob_new = self.his_global_N[a][i, il] - bol = k_glob_new == self.his_global_N[a][i - 1] - - if xp.any(bol): - self.his_loccof_N[a][i, il] = self.his_loccof_N[a][i - 1, xp.where(bol)[0][0]] + 1 - - if (k_glob_new >= n_lambda_his[a] - self.p[a] - (self.p[a] - 2)) and ( - self.his_loccof_N[a][i, il] == 0 - ): - self.his_loccof_N[a][i, il] = self.his_add_N[a][counter_N] - counter_N += 1 - - # quadrature points and weights - self.pts[a], self.wts[a] = bsp.quadrature_grid( - xp.unique(self.x_his[a].flatten()), - self.pts_loc[a], - self.wts_loc[a], - ) - - else: - # maximum number of non-vanishing coefficients - self.n_his_nvcof_D[a] = 2 * self.p[a] - 1 - self.n_his_nvcof_N[a] = 2 * self.p[a] - - # shift local coefficients --> global coefficients (D) - self.his_shift_D[a] = xp.arange(self.NbaseD[a]) - (self.p[a] - 1) - - # shift local coefficients --> global coefficients (N) - self.his_shift_N[a] = xp.arange(self.NbaseD[a]) - self.p[a] - - for i in range(n_lambda_his[a]): - self.his_global_N[a][i] = (xp.arange(self.n_his_locbf_N[a]) + i - (self.p[a] - 1)) % self.NbaseN[a] - self.his_global_D[a][i] = (xp.arange(self.n_his_locbf_D[a]) + i - (self.p[a] - 1)) % self.NbaseD[a] - self.his_loccof_N[a][i] = xp.arange(self.n_his_locbf_N[a] - 1, -1, -1) - self.his_loccof_D[a][i] = xp.arange(self.n_his_locbf_D[a] - 1, -1, -1) - - self.x_his_indices[a][i] = (xp.arange(self.n_his[a]) + 2 * (i - (self.p[a] - 1))) % ( - 2 * self.Nel[a] - ) - self.coeffh_indices[a][i] = 0 - - for j in range(2 * self.p[a] + 1): - self.x_his[a][i, j] = (self.T[a][i + 1 + int(j / 2)] + self.T[a][i + 1 + int((j + 1) / 2)]) / 2 - - # quadrature points and weights - self.pts[a], self.wts[a] = bsp.quadrature_grid( - xp.append(xp.unique(self.x_his[a].flatten() % 1.0), 1.0), - self.pts_loc[a], - self.wts_loc[a], - ) - - # evaluate N basis functions at interpolation and quadrature points - self.basisN_int = [ - bsp.collocation_matrix(T, p, x_int, bc) for T, p, x_int, bc in zip(self.T, self.p, self.x_int, self.bc) - ] - - self.basisN_his = [ - bsp.collocation_matrix(T, p, pts.flatten(), bc).reshape(pts[:, 0].size, pts[0, :].size, NbaseN) - for T, p, pts, bc, NbaseN in zip(self.T, self.p, self.pts, self.bc, self.NbaseN) - ] - - # evaluate D basis functions at interpolation and quadrature points - self.basisD_int = [ - bsp.collocation_matrix(T[1:-1], p - 1, x_int, bc, normalize=True) - for T, p, x_int, bc in zip(self.T, self.p, self.x_int, self.bc) - ] - - self.basisD_his = [ - bsp.collocation_matrix(T[1:-1], p - 1, pts.flatten(), bc, normalize=True).reshape( - pts[:, 0].size, - pts[0, :].size, - NbaseD, - ) - for T, p, pts, bc, NbaseD in zip(self.T, self.p, self.pts, self.bc, self.NbaseD) - ] - - # ======================================================================== - def projection_Q_0form(self, domain): - """ - Computes the sparse matrix of the expression pi_2(rho3_eq * lambda^0) with the output (coefficients, basis_fun of lambda^2). - - The following blocks need to be computed: - - 1 - component [int, his, his] : (N, N, N)*rho3_eq, None , None - 2 - component [his, int, his] : None , (N, N, N)*rho3_eq, None - 3 - component [his, his, int] : None , None , (N, N, N)*rho3_eq - - An analytical mapping is called from struphy.geometry.mappings_analytical. - - Parameters - ---------- - domain : domain - domain object created with struphy.geometry.domain that defines the geometry - - Returns - ------- - Q : sparse matrix in csc-format - the projection of each basis function in V0 on V2 weighted with rho3_eq - """ - - # non-vanishing coefficients - Q11 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - dtype=float, - ) - Q22 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - dtype=float, - ) - Q33 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - - # size of interpolation/quadrature points of the 3 components - n_unique1 = [self.x_int[0].size, self.pts[1].flatten().size, self.pts[2].flatten().size] - n_unique2 = [self.pts[0].flatten().size, self.x_int[1].size, self.pts[2].flatten().size] - n_unique3 = [self.pts[0].flatten().size, self.pts[1].flatten().size, self.x_int[2].size] - - # ========= assembly of 1 - component (pi2_1 : int, his, his) ============ - mat_eq = xp.empty((n_unique1[0], n_unique1[1], n_unique1[2]), dtype=float) - - ker_eva.kernel_eva( - self.x_int[0], - self.pts[1].flatten(), - self.pts[2].flatten(), - mat_eq, - 11, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_1( - [self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]], - [self.n_quad[1], self.n_quad[2]], - [self.n_int[0], self.n_his[1], self.n_his[2]], - [self.n_int_locbf_N[0], self.n_his_locbf_N[1], self.n_his_locbf_N[2]], - self.int_global_N[0], - self.his_global_N[1], - self.his_global_N[2], - self.int_loccof_N[0], - self.his_loccof_N[1], - self.his_loccof_N[2], - self.coeff_i[0], - self.coeff_h[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffh_indices[2], - self.basisN_int[0], - self.basisN_his[1], - self.basisN_his[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_his_indices[2], - self.wts[1], - self.wts[2], - Q11, - mat_eq.reshape( - n_unique1[0], - self.pts[1][:, 0].size, - self.pts[1][0, :].size, - self.pts[2][:, 0].size, - self.pts[2][0, :].size, - ), - ) - - # ========= assembly of 2 - component (pi2_2 : his, int, his) ============ - mat_eq = xp.empty((n_unique2[0], n_unique2[1], n_unique2[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.x_int[1], - self.pts[2].flatten(), - mat_eq, - 11, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_2( - [self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]], - [self.n_quad[0], self.n_quad[2]], - [self.n_his[0], self.n_int[1], self.n_his[2]], - [self.n_his_locbf_N[0], self.n_int_locbf_N[1], self.n_his_locbf_N[2]], - self.his_global_N[0], - self.int_global_N[1], - self.his_global_N[2], - self.his_loccof_N[0], - self.int_loccof_N[1], - self.his_loccof_N[2], - self.coeff_h[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.basisN_his[0], - self.basisN_int[1], - self.basisN_his[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[0], - self.wts[2], - Q22, - mat_eq.reshape( - self.pts[0][:, 0].size, - self.pts[0][0, :].size, - n_unique2[1], - self.pts[2][:, 0].size, - self.pts[2][0, :].size, - ), - ) - - # ========= assembly of 3 - component (pi2_3 : his, his, int) ============ - mat_eq = xp.empty((n_unique3[0], n_unique3[1], n_unique3[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.pts[1].flatten(), - self.x_int[2], - mat_eq, - 11, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_3( - [self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]], - [self.n_quad[0], self.n_quad[1]], - [self.n_his[0], self.n_his[1], self.n_int[2]], - [self.n_his_locbf_N[0], self.n_his_locbf_N[1], self.n_int_locbf_N[2]], - self.his_global_N[0], - self.his_global_N[1], - self.int_global_N[2], - self.his_loccof_N[0], - self.his_loccof_N[1], - self.int_loccof_N[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.basisN_his[0], - self.basisN_his[1], - self.basisN_int[2], - self.x_his_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[0], - self.wts[1], - Q33, - mat_eq.reshape( - self.pts[0][:, 0].size, - self.pts[0][0, :].size, - self.pts[1][:, 0].size, - self.pts[1][0, :].size, - n_unique3[2], - ), - ) - - # ========= conversion to sparse matrices (1 - component) ================= - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.his_shift_N[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.his_shift_N[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseD[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - Q11 = spa.csc_matrix( - (Q11.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseN[0] * self.NbaseD[1] * self.NbaseD[2]), - ) - Q11.eliminate_zeros() - - # ========= conversion to sparse matrices (2 - component) ================= - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_N[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.his_shift_N[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseN[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - Q22 = spa.csc_matrix( - (Q22.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseD[0] * self.NbaseN[1] * self.NbaseD[2]), - ) - Q22.eliminate_zeros() - - # ========= conversion to sparse matrices (3 - component) ================= - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_N[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.his_shift_N[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseD[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - Q33 = spa.csc_matrix( - (Q33.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseD[0] * self.NbaseD[1] * self.NbaseN[2]), - ) - Q33.eliminate_zeros() - - self.Q = spa.bmat([[Q11.T, None, None], [None, Q22.T, None], [None, None, Q33.T]], format="csc") - - # ======================================================================== - def projection_Q_2form(self, domain): - """ - Computes the sparse matrix of the expression pi_2(rho3_eq * lambda^2) with the output (coefficients, basis_fun of lambda^2). - - The following blocks need to be computed: - - 1 - component [int, his, his] : (N, D, D)*rho3_eq, None , None - 2 - component [his, int, his] : None , (D, N, D)*rho3_eq, None - 3 - component [his, his, int] : None , None , (D, D, N)*rho3_eq - - An analytical mapping is called from struphy.geometry.mappings_analytical. - - Parameters - ---------- - domain : domain - domain object created with struphy.geometry.domain that defines the geometry - - Returns - ------- - Q : sparse matrix in csc-format - the projection of each basis function in V2 on V2 weighted with rho3_eq - """ - - # non-vanishing coefficients - Q11 = xp.empty( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseD[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_D[1], - self.n_his_nvcof_D[2], - ), - dtype=float, - ) - Q22 = xp.empty( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_his_nvcof_D[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_D[2], - ), - dtype=float, - ) - Q33 = xp.empty( - ( - self.NbaseD[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_his_nvcof_D[0], - self.n_his_nvcof_D[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - - # size of interpolation/quadrature points of the 3 components - n_unique1 = [self.x_int[0].size, self.pts[1].flatten().size, self.pts[2].flatten().size] - n_unique2 = [self.pts[0].flatten().size, self.x_int[1].size, self.pts[2].flatten().size] - n_unique3 = [self.pts[0].flatten().size, self.pts[1].flatten().size, self.x_int[2].size] - - # ========= assembly of 1 - component (pi2_1 : int, his, his) ============ - mat_eq = xp.empty((n_unique1[0], n_unique1[1], n_unique1[2]), dtype=float) - - ker_eva.kernel_eva( - self.x_int[0], - self.pts[1].flatten(), - self.pts[2].flatten(), - mat_eq, - 11, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_1( - [self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]], - [self.n_quad[1], self.n_quad[2]], - [self.n_int[0], self.n_his[1], self.n_his[2]], - [self.n_int_locbf_N[0], self.n_his_locbf_D[1], self.n_his_locbf_D[2]], - self.int_global_N[0], - self.his_global_D[1], - self.his_global_D[2], - self.int_loccof_N[0], - self.his_loccof_D[1], - self.his_loccof_D[2], - self.coeff_i[0], - self.coeff_h[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffh_indices[2], - self.basisN_int[0], - self.basisD_his[1], - self.basisD_his[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_his_indices[2], - self.wts[1], - self.wts[2], - Q11, - mat_eq.reshape( - n_unique1[0], - self.pts[1][:, 0].size, - self.pts[1][0, :].size, - self.pts[2][:, 0].size, - self.pts[2][0, :].size, - ), - ) - - # ========= assembly of 2 - component (pi2_2 : his, int, his) ============ - mat_eq = xp.empty((n_unique2[0], n_unique2[1], n_unique2[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.x_int[1], - self.pts[2].flatten(), - mat_eq, - 11, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_2( - [self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]], - [self.n_quad[0], self.n_quad[2]], - [self.n_his[0], self.n_int[1], self.n_his[2]], - [self.n_his_locbf_D[0], self.n_int_locbf_N[1], self.n_his_locbf_D[2]], - self.his_global_D[0], - self.int_global_N[1], - self.his_global_D[2], - self.his_loccof_D[0], - self.int_loccof_N[1], - self.his_loccof_D[2], - self.coeff_h[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.basisD_his[0], - self.basisN_int[1], - self.basisD_his[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[0], - self.wts[2], - Q22, - mat_eq.reshape( - self.pts[0][:, 0].size, - self.pts[0][0, :].size, - n_unique2[1], - self.pts[2][:, 0].size, - self.pts[2][0, :].size, - ), - ) - - # ========= assembly of 3 - component (pi2_3 : his, his, int) ============ - mat_eq = xp.empty((n_unique3[0], n_unique3[1], n_unique3[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.pts[1].flatten(), - self.x_int[2], - mat_eq, - 11, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_3( - [self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]], - [self.n_quad[0], self.n_quad[1]], - [self.n_his[0], self.n_his[1], self.n_int[2]], - [self.n_his_locbf_D[0], self.n_his_locbf_D[1], self.n_int_locbf_N[2]], - self.his_global_D[0], - self.his_global_D[1], - self.int_global_N[2], - self.his_loccof_D[0], - self.his_loccof_D[1], - self.int_loccof_N[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.basisD_his[0], - self.basisD_his[1], - self.basisN_int[2], - self.x_his_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[0], - self.wts[1], - Q33, - mat_eq.reshape( - self.pts[0][:, 0].size, - self.pts[0][0, :].size, - self.pts[1][:, 0].size, - self.pts[1][0, :].size, - n_unique3[2], - ), - ) - - # ========= conversion to sparse matrices (1 - component) ================= - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseD[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_D[1], - self.n_his_nvcof_D[2], - ), - ) - row = self.NbaseD[1] * self.NbaseD[2] * indices[0] + self.NbaseD[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.his_shift_D[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.his_shift_D[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseD[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - Q11 = spa.csc_matrix( - (Q11.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseD[1] * self.NbaseD[2], self.NbaseN[0] * self.NbaseD[1] * self.NbaseD[2]), - ) - Q11.eliminate_zeros() - - # ========= conversion to sparse matrices (2 - component) ================= - indices = xp.indices( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_his_nvcof_D[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_D[2], - ), - ) - row = self.NbaseN[1] * self.NbaseD[2] * indices[0] + self.NbaseD[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_D[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.his_shift_D[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseN[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - Q22 = spa.csc_matrix( - (Q22.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseD[0] * self.NbaseN[1] * self.NbaseD[2], self.NbaseD[0] * self.NbaseN[1] * self.NbaseD[2]), - ) - Q22.eliminate_zeros() - - # ========= conversion to sparse matrices (3 - component) ================= - indices = xp.indices( - ( - self.NbaseD[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_his_nvcof_D[0], - self.n_his_nvcof_D[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseD[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_D[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.his_shift_D[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseD[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - Q33 = spa.csc_matrix( - (Q33.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseD[0] * self.NbaseD[1] * self.NbaseN[2], self.NbaseD[0] * self.NbaseD[1] * self.NbaseN[2]), - ) - Q33.eliminate_zeros() - - self.Q = spa.bmat([[Q11.T, None, None], [None, Q22.T, None], [None, None, Q33.T]], format="csc") - - # ======================================================================== - def projection_W_0form(self, domain): - """ - Computes the sparse matrix of the expression pi_0(rho0_eq * lambda^0) with the output (coefficients, basis_fun of lambda^2). - - The following blocks need to be computed: - - 1 - component [int, int, int] : (N, N, N)*rho0_eq, None , None - 2 - component [int, int, int] : None , (N, N, N)*rho0_eq, None - 3 - component [int, int, int] : None , None , (N, N, N)*rho0_eq - - An analytical mapping is called from struphy.geometry.mappings_analytical. - - Parameters - ---------- - domain : domain - domain object created with struphy.geometry.domain that defines the geometry - - Returns - ------- - W : sparse matrix in csc-format - the projection of each basis function in V0 on V0 weighted with rho0_eq - """ - - # non-vanishing coefficients - W1 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - # W2 = xp.empty((self.NbaseN[0], self.NbaseN[1], self.NbaseN[2], self.n_int_nvcof_N[0], self.n_int_nvcof_N[1], self.n_int_nvcof_N[2]), dtype=float) - # W3 = xp.empty((self.NbaseN[0], self.NbaseN[1], self.NbaseN[2], self.n_int_nvcof_N[0], self.n_int_nvcof_N[1], self.n_int_nvcof_N[2]), dtype=float) - - # size of interpolation/quadrature points of the 3 components - n_unique = [self.x_int[0].size, self.x_int[1].size, self.x_int[2].size] - - # assembly - mat_eq = xp.empty((n_unique[0], n_unique[1], n_unique[2]), dtype=float) - - ker_eva.kernel_eva( - self.x_int[0], - self.x_int[1], - self.x_int[2], - mat_eq, - 12, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi0( - self.NbaseN, - self.n_int, - self.n_int_locbf_N, - self.int_global_N[0], - self.int_global_N[1], - self.int_global_N[2], - self.int_loccof_N[0], - self.int_loccof_N[1], - self.int_loccof_N[2], - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeffi_indices[0], - self.coeffi_indices[1], - self.coeffi_indices[2], - self.basisN_int[0], - self.basisN_int[1], - self.basisN_int[2], - self.x_int_indices[0], - self.x_int_indices[1], - self.x_int_indices[2], - W1, - mat_eq, - ) - - # ker_loc.kernel_pi0(self.NbaseN, self.n_int, self.n_int_locbf_N, self.int_global_N[0], self.int_global_N[1], self.int_global_N[2], self.int_loccof_N[0], self.int_loccof_N[1], self.int_loccof_N[2], self.coeff_i[0], self.coeff_i[1], self.coeff_i[2], self.coeffi_indices[0], self.coeffi_indices[1], self.coeffi_indices[2], self.basisN_int[0], self.basisN_int[1], self.basisN_int[2], self.x_int_indices[0], self.x_int_indices[1], self.x_int_indices[2], W2, mat_eq) - - # ker_loc.kernel_pi0(self.NbaseN, self.n_int, self.n_int_locbf_N, self.int_global_N[0], self.int_global_N[1], self.int_global_N[2], self.int_loccof_N[0], self.int_loccof_N[1], self.int_loccof_N[2], self.coeff_i[0], self.coeff_i[1], self.coeff_i[2], self.coeffi_indices[0], self.coeffi_indices[1], self.coeffi_indices[2], self.basisN_int[0], self.basisN_int[1], self.basisN_int[2], self.x_int_indices[0], self.x_int_indices[1], self.x_int_indices[2], W3, mat_eq) - - """ - if self.bc[0] == False: - # apply Dirichlet boundary conditions for u1 at eta1 = 0 - if bc_u1[0][0] == 'dirichlet': - W1[0] = 0. - - # apply Dirichlet boundary conditions for u1 at eta1 = 1 - if bc_u1[0][1] == 'dirichlet': - W1[-1] = 0. - """ - - # conversion to sparse matrix - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - ) - - # row indices - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - # column indices - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseN[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - # create sparse matrices - W1 = spa.csc_matrix( - (W1.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2]), - ) - W1.eliminate_zeros() - - # W2 = spa.csc_matrix((W2.flatten(), (row.flatten(), col.flatten())), shape=(self.NbaseN[0]*self.NbaseN[1]*self.NbaseN[2], self.NbaseN[0]*self.NbaseN[1]*self.NbaseN[2])) - # W2.eliminate_zeros() - - # W3 = spa.csc_matrix((W3.flatten(), (row.flatten(), col.flatten())), shape=(self.NbaseN[0]*self.NbaseN[1]*self.NbaseN[2], self.NbaseN[0]*self.NbaseN[1]*self.NbaseN[2])) - # W3.eliminate_zeros() - - self.W = spa.bmat([[W1.T, None, None], [None, W1.T, None], [None, None, W1.T]], format="csc") - - # ========================================================================= - def projection_T_0form(self, domain): - """ - Computes the matrix of the expression pi_1(b2_eq * lambda^0) with the output (coefficients, basis_fun of lambda^0). - - The following blocks need to be computed: - - 1 - component [his, int, int] : None , -(N, N, N)*B3, (N, N, N)*B2 - 2 - component [int, his, int] : (N, N, N)*B3, None , -(N, N, N)*B1 - 3 - component [int, int, his] : -(N, N, N)*B2, (N, N, N)*B1, None - - An analytical mapping is called from struphy.geometry.mappings_analytical. - - Parameters - ---------- - domain : domain - domain object created with struphy.geometry.domain that defines the geometry - - Returns - ------- - T : sparse matrix in csc-format - the projection of each basis function in V2 on V1 weighted with b2_eq - """ - - # non-vanishing coefficients - T12 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - T13 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - - T21 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - T23 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - - T31 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - dtype=float, - ) - T32 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - dtype=float, - ) - - # unique interpolation points - n_unique1 = [self.pts[0].flatten().size, self.x_int[1].size, self.x_int[2].size] - n_unique2 = [self.x_int[0].size, self.pts[1].flatten().size, self.x_int[2].size] - n_unique3 = [self.x_int[0].size, self.x_int[1].size, self.pts[2].flatten().size] - - # ================= assembly of 1 - component (pi1_1 : his, int, int) ============ - mat_eq = xp.empty((n_unique1[0], n_unique1[1], n_unique1[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.x_int[1], - self.x_int[2], - mat_eq, - 23, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_1( - [self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]], - self.n_quad[0], - [self.n_his[0], self.n_int[1], self.n_int[2]], - [self.n_his_locbf_N[0], self.n_int_locbf_N[1], self.n_int_locbf_N[2]], - self.his_global_N[0], - self.int_global_N[1], - self.int_global_N[2], - self.his_loccof_N[0], - self.int_loccof_N[1], - self.int_loccof_N[2], - self.coeff_h[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffi_indices[2], - self.basisN_his[0], - self.basisN_int[1], - self.basisN_int[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_int_indices[2], - self.wts[0], - T12, - mat_eq.reshape(self.pts[0][:, 0].size, self.pts[0][0, :].size, n_unique1[1], n_unique1[2]), - ) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.x_int[1], - self.x_int[2], - mat_eq, - 22, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_1( - [self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]], - self.n_quad[0], - [self.n_his[0], self.n_int[1], self.n_int[2]], - [self.n_his_locbf_N[0], self.n_int_locbf_N[1], self.n_int_locbf_N[2]], - self.his_global_N[0], - self.int_global_N[1], - self.int_global_N[2], - self.his_loccof_N[0], - self.int_loccof_N[1], - self.int_loccof_N[2], - self.coeff_h[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffi_indices[2], - self.basisN_his[0], - self.basisN_int[1], - self.basisN_int[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_int_indices[2], - self.wts[0], - T13, - mat_eq.reshape(self.pts[0][:, 0].size, self.pts[0][0, :].size, n_unique1[1], n_unique1[2]), - ) - - # ================= assembly of 2 - component (PI_1_2 : int, his, int) ============ - mat_eq = xp.empty((n_unique2[0], n_unique2[1], n_unique2[2]), dtype=float) - - ker_eva.kernel_eva( - self.x_int[0], - self.pts[1].flatten(), - self.x_int[2], - mat_eq, - 23, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_2( - [self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]], - self.n_quad[1], - [self.n_int[0], self.n_his[1], self.n_int[2]], - [self.n_int_locbf_N[0], self.n_his_locbf_N[1], self.n_int_locbf_N[2]], - self.int_global_N[0], - self.his_global_N[1], - self.int_global_N[2], - self.int_loccof_N[0], - self.his_loccof_N[1], - self.int_loccof_N[2], - self.coeff_i[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.basisN_int[0], - self.basisN_his[1], - self.basisN_int[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[1], - T21, - mat_eq.reshape(n_unique2[0], self.pts[1][:, 0].size, self.pts[1][0, :].size, n_unique2[2]), - ) - - """ - if self.bc[0] == False: - # apply Dirichlet boundary conditions for u1 at eta1 = 0 - if bc_u1[0][0] == 'dirichlet': - T21[0] = 0. - - # apply Dirichlet boundary conditions for u1 at eta1 = 1 - if bc_u1[0][1] == 'dirichlet': - T21[-1] = 0. - """ - - ker_eva.kernel_eva( - self.x_int[0], - self.pts[1].flatten(), - self.x_int[2], - mat_eq, - 21, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_2( - [self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]], - self.n_quad[1], - [self.n_int[0], self.n_his[1], self.n_int[2]], - [self.n_int_locbf_N[0], self.n_his_locbf_N[1], self.n_int_locbf_N[2]], - self.int_global_N[0], - self.his_global_N[1], - self.int_global_N[2], - self.int_loccof_N[0], - self.his_loccof_N[1], - self.int_loccof_N[2], - self.coeff_i[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.basisN_int[0], - self.basisN_his[1], - self.basisN_int[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[1], - T23, - mat_eq.reshape(n_unique2[0], self.pts[1][:, 0].size, self.pts[1][0, :].size, n_unique2[2]), - ) - - # ================= assembly of 3 - component (PI_1_3 : int, int, his) ============ - mat_eq = xp.empty((n_unique3[0], n_unique3[1], n_unique3[2]), dtype=float) - - ker_eva.kernel_eva( - self.x_int[0], - self.x_int[1], - self.pts[2].flatten(), - mat_eq, - 22, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_3( - [self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]], - self.n_quad[2], - [self.n_int[0], self.n_int[1], self.n_his[2]], - [self.n_int_locbf_N[0], self.n_int_locbf_N[1], self.n_his_locbf_N[2]], - self.int_global_N[0], - self.int_global_N[1], - self.his_global_N[2], - self.int_loccof_N[0], - self.int_loccof_N[1], - self.his_loccof_N[2], - self.coeff_i[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.basisN_int[0], - self.basisN_int[1], - self.basisN_his[2], - self.x_int_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[2], - T31, - mat_eq.reshape(n_unique3[0], n_unique3[1], self.pts[2][:, 0].size, self.pts[2][0, :].size), - ) - - """ - if self.bc[0] == False: - # apply Dirichlet boundary conditions for u1 at eta1 = 0 - if bc_u1[0][0] == 'dirichlet': - T31[0] = 0. - - # apply Dirichlet boundary conditions for u1 at eta1 = 1 - if bc_u1[0][1] == 'dirichlet': - T31[-1] = 0. - """ - - ker_eva.kernel_eva( - self.x_int[0], - self.x_int[1], - self.pts[2].flatten(), - mat_eq, - 21, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_3( - [self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]], - self.n_quad[2], - [self.n_int[0], self.n_int[1], self.n_his[2]], - [self.n_int_locbf_N[0], self.n_int_locbf_N[1], self.n_his_locbf_N[2]], - self.int_global_N[0], - self.int_global_N[1], - self.his_global_N[2], - self.int_loccof_N[0], - self.int_loccof_N[1], - self.his_loccof_N[2], - self.coeff_i[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.basisN_int[0], - self.basisN_int[1], - self.basisN_his[2], - self.x_int_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[2], - T32, - mat_eq.reshape(n_unique3[0], n_unique3[1], self.pts[2][:, 0].size, self.pts[2][0, :].size), - ) - - # conversion to sparse matrices (1 - component) - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_N[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseN[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - T12 = spa.csc_matrix( - (T12.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseD[0] * self.NbaseN[1] * self.NbaseN[2]), - ) - T12.eliminate_zeros() - - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_N[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseN[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - T13 = spa.csc_matrix( - (T13.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseD[0] * self.NbaseN[1] * self.NbaseN[2]), - ) - T13.eliminate_zeros() - - # conversion to sparse matrices (2 - component) - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.his_shift_N[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseD[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - T21 = spa.csc_matrix( - (T21.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseN[0] * self.NbaseD[1] * self.NbaseN[2]), - ) - T21.eliminate_zeros() - - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.his_shift_N[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseD[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - T23 = spa.csc_matrix( - (T23.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseN[0] * self.NbaseD[1] * self.NbaseN[2]), - ) - T23.eliminate_zeros() - - # conversion to sparse matrices (3 - component) - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.his_shift_N[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseN[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - T31 = spa.csc_matrix( - (T31.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseN[0] * self.NbaseN[1] * self.NbaseD[2]), - ) - T31.eliminate_zeros() - - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.his_shift_N[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseN[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - T32 = spa.csc_matrix( - (T32.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseN[0] * self.NbaseN[1] * self.NbaseD[2]), - ) - T32.eliminate_zeros() - - self.TAU = spa.bmat([[None, -T12.T, T13.T], [T21.T, None, -T23.T], [-T31.T, T32.T, None]], format="csc") - - # ========================================================================= - def projection_T_1form(self, domain): - """ - Computes the matrix of the expression pi_1(b2_eq * lambda^1) with the output (coefficients, basis_fun of lambda^1). - - The following blocks need to be computed: - - 1 - component [his, int, int] : None , -(N, D, N)*B3, (N, N, D)*B2 - 2 - component [int, his, int] : (D, N, N)*B3, None , -(N, N, D)*B1 - 3 - component [int, int, his] : -(D, N, N)*B2, (N, D, N)*B1, None - - An analytical mapping is called from struphy.geometry.mappings_analytical. - - Parameters - ---------- - domain : domain - domain object created with struphy.geometry.domain that defines the geometry - - Returns - ------- - T : sparse matrix in csc-format - the projection of each basis function in V2 on V1 weighted with b2_eq - """ - - # non-vanishing coefficients - T12 = xp.empty( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_D[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - T13 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_int_nvcof_D[2], - ), - dtype=float, - ) - - T21 = xp.empty( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_D[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - T23 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_D[2], - ), - dtype=float, - ) - - T31 = xp.empty( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_D[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - dtype=float, - ) - T32 = xp.empty( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_int_nvcof_D[1], - self.n_his_nvcof_N[2], - ), - dtype=float, - ) - - # unique interpolation points - n_unique1 = [self.pts[0].flatten().size, self.x_int[1].size, self.x_int[2].size] - n_unique2 = [self.x_int[0].size, self.pts[1].flatten().size, self.x_int[2].size] - n_unique3 = [self.x_int[0].size, self.x_int[1].size, self.pts[2].flatten().size] - - # ================= assembly of 1 - component (pi1_1 : his, int, int) ============ - mat_eq = xp.empty((n_unique1[0], n_unique1[1], n_unique1[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.x_int[1], - self.x_int[2], - mat_eq, - 23, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_1( - [self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]], - self.n_quad[0], - [self.n_his[0], self.n_int[1], self.n_int[2]], - [self.n_his_locbf_N[0], self.n_int_locbf_D[1], self.n_int_locbf_N[2]], - self.his_global_N[0], - self.int_global_D[1], - self.int_global_N[2], - self.his_loccof_N[0], - self.int_loccof_D[1], - self.int_loccof_N[2], - self.coeff_h[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffi_indices[2], - self.basisN_his[0], - self.basisD_int[1], - self.basisN_int[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_int_indices[2], - self.wts[0], - T12, - mat_eq.reshape(self.pts[0][:, 0].size, self.pts[0][0, :].size, n_unique1[1], n_unique1[2]), - ) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.x_int[1], - self.x_int[2], - mat_eq, - 22, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_1( - [self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]], - self.n_quad[0], - [self.n_his[0], self.n_int[1], self.n_int[2]], - [self.n_his_locbf_N[0], self.n_int_locbf_N[1], self.n_int_locbf_D[2]], - self.his_global_N[0], - self.int_global_N[1], - self.int_global_D[2], - self.his_loccof_N[0], - self.int_loccof_N[1], - self.int_loccof_D[2], - self.coeff_h[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffi_indices[2], - self.basisN_his[0], - self.basisN_int[1], - self.basisD_int[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_int_indices[2], - self.wts[0], - T13, - mat_eq.reshape(self.pts[0][:, 0].size, self.pts[0][0, :].size, n_unique1[1], n_unique1[2]), - ) - - # ================= assembly of 2 - component (PI_1_2 : int, his, int) ============ - mat_eq = xp.empty((n_unique2[0], n_unique2[1], n_unique2[2]), dtype=float) - - ker_eva.kernel_eva( - self.x_int[0], - self.pts[1].flatten(), - self.x_int[2], - mat_eq, - 23, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_2( - [self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]], - self.n_quad[1], - [self.n_int[0], self.n_his[1], self.n_int[2]], - [self.n_int_locbf_D[0], self.n_his_locbf_N[1], self.n_int_locbf_N[2]], - self.int_global_D[0], - self.his_global_N[1], - self.int_global_N[2], - self.int_loccof_D[0], - self.his_loccof_N[1], - self.int_loccof_N[2], - self.coeff_i[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.basisD_int[0], - self.basisN_his[1], - self.basisN_int[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[1], - T21, - mat_eq.reshape(n_unique2[0], self.pts[1][:, 0].size, self.pts[1][0, :].size, n_unique2[2]), - ) - - ker_eva.kernel_eva( - self.x_int[0], - self.pts[1].flatten(), - self.x_int[2], - mat_eq, - 21, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_2( - [self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]], - self.n_quad[1], - [self.n_int[0], self.n_his[1], self.n_int[2]], - [self.n_int_locbf_N[0], self.n_his_locbf_N[1], self.n_int_locbf_D[2]], - self.int_global_N[0], - self.his_global_N[1], - self.int_global_D[2], - self.int_loccof_N[0], - self.his_loccof_N[1], - self.int_loccof_D[2], - self.coeff_i[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.basisN_int[0], - self.basisN_his[1], - self.basisD_int[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[1], - T23, - mat_eq.reshape(n_unique2[0], self.pts[1][:, 0].size, self.pts[1][0, :].size, n_unique2[2]), - ) - - # ================= assembly of 3 - component (PI_1_3 : int, int, his) ============ - mat_eq = xp.empty((n_unique3[0], n_unique3[1], n_unique3[2]), dtype=float) - - ker_eva.kernel_eva( - self.x_int[0], - self.x_int[1], - self.pts[2].flatten(), - mat_eq, - 22, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_3( - [self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]], - self.n_quad[2], - [self.n_int[0], self.n_int[1], self.n_his[2]], - [self.n_int_locbf_D[0], self.n_int_locbf_N[1], self.n_his_locbf_N[2]], - self.int_global_D[0], - self.int_global_N[1], - self.his_global_N[2], - self.int_loccof_D[0], - self.int_loccof_N[1], - self.his_loccof_N[2], - self.coeff_i[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.basisD_int[0], - self.basisN_int[1], - self.basisN_his[2], - self.x_int_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[2], - T31, - mat_eq.reshape(n_unique3[0], n_unique3[1], self.pts[2][:, 0].size, self.pts[2][0, :].size), - ) - - ker_eva.kernel_eva( - self.x_int[0], - self.x_int[1], - self.pts[2].flatten(), - mat_eq, - 21, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_3( - [self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]], - self.n_quad[2], - [self.n_int[0], self.n_int[1], self.n_his[2]], - [self.n_int_locbf_N[0], self.n_int_locbf_D[1], self.n_his_locbf_N[2]], - self.int_global_N[0], - self.int_global_D[1], - self.his_global_N[2], - self.int_loccof_N[0], - self.int_loccof_D[1], - self.his_loccof_N[2], - self.coeff_i[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.basisN_int[0], - self.basisD_int[1], - self.basisN_his[2], - self.x_int_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[2], - T32, - mat_eq.reshape(n_unique3[0], n_unique3[1], self.pts[2][:, 0].size, self.pts[2][0, :].size), - ) - - # conversion to sparse matrices (1 - component) - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_D[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseD[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_N[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.int_shift_D[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseN[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - T12 = spa.csc_matrix( - (T12.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseD[1] * self.NbaseN[2], self.NbaseD[0] * self.NbaseN[1] * self.NbaseN[2]), - ) - T12.eliminate_zeros() - - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_int_nvcof_D[2], - ), - ) - row = self.NbaseN[1] * self.NbaseD[2] * indices[0] + self.NbaseD[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_N[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.int_shift_D[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseN[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - T13 = spa.csc_matrix( - (T13.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseD[2], self.NbaseD[0] * self.NbaseN[1] * self.NbaseN[2]), - ) - T13.eliminate_zeros() - - # conversion to sparse matrices (2 - component) - indices = xp.indices( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_D[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_D[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.his_shift_N[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseD[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - T21 = spa.csc_matrix( - (T21.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseD[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseN[0] * self.NbaseD[1] * self.NbaseN[2]), - ) - T21.eliminate_zeros() - - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_D[2], - ), - ) - row = self.NbaseN[1] * self.NbaseD[2] * indices[0] + self.NbaseD[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.his_shift_N[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.int_shift_D[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseD[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - T23 = spa.csc_matrix( - (T23.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseD[2], self.NbaseN[0] * self.NbaseD[1] * self.NbaseN[2]), - ) - T23.eliminate_zeros() - - # conversion to sparse matrices (3 - component) - indices = xp.indices( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_D[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_D[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.his_shift_N[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseN[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - T31 = spa.csc_matrix( - (T31.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseD[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseN[0] * self.NbaseN[1] * self.NbaseD[2]), - ) - T31.eliminate_zeros() - - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_int_nvcof_D[1], - self.n_his_nvcof_N[2], - ), - ) - row = self.NbaseD[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.int_shift_D[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.his_shift_N[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseN[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - T32 = spa.csc_matrix( - (T32.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseD[1] * self.NbaseN[2], self.NbaseN[0] * self.NbaseN[1] * self.NbaseD[2]), - ) - T32.eliminate_zeros() - - self.TAU = spa.bmat([[None, -T12.T, T13.T], [T21.T, None, -T23.T], [-T31.T, T32.T, None]], format="csc") - - # ========================================================================= - def projection_T_2form(self, domain): - """ - Computes the matrix of the expression pi_1(b2_eq * lambda^2) with the output (coefficients, basis_fun of lambda^2). - - The following blocks need to be computed: - - 1 - component [his, int, int] : None , -(D, N, D)*B3, (D, D, N)*B2 - 2 - component [int, his, int] : (N, D, D)*B3, None , -(D, D, N)*B1 - 3 - component [int, int, his] : -(N, D, D)*B2, (D, N, D)*B1, None - - An analytical mapping is called from struphy.geometry.mappings_analytical. - - Parameters - ---------- - domain : domain - domain object created with struphy.geometry.domain that defines the geometry - - Returns - ------- - T : sparse matrix in csc-format - the projection of each basis function in V2 on V1 weighted with b2_eq - """ - - # non-vanishing coefficients - T12 = xp.empty( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_his_nvcof_D[0], - self.n_int_nvcof_N[1], - self.n_int_nvcof_D[2], - ), - dtype=float, - ) - T13 = xp.empty( - ( - self.NbaseD[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_his_nvcof_D[0], - self.n_int_nvcof_D[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - - T21 = xp.empty( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseD[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_D[1], - self.n_int_nvcof_D[2], - ), - dtype=float, - ) - T23 = xp.empty( - ( - self.NbaseD[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_int_nvcof_D[0], - self.n_his_nvcof_D[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - - T31 = xp.empty( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseD[2], - self.n_int_nvcof_N[0], - self.n_int_nvcof_D[1], - self.n_his_nvcof_D[2], - ), - dtype=float, - ) - T32 = xp.empty( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_int_nvcof_D[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_D[2], - ), - dtype=float, - ) - - # unique interpolation points - n_unique1 = [self.pts[0].flatten().size, self.x_int[1].size, self.x_int[2].size] - n_unique2 = [self.x_int[0].size, self.pts[1].flatten().size, self.x_int[2].size] - n_unique3 = [self.x_int[0].size, self.x_int[1].size, self.pts[2].flatten().size] - - # ================= assembly of 1 - component (pi1_1 : his, int, int) ============ - mat_eq = xp.empty((n_unique1[0], n_unique1[1], n_unique1[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.x_int[1], - self.x_int[2], - mat_eq, - 23, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_1( - [self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]], - self.n_quad[0], - [self.n_his[0], self.n_int[1], self.n_int[2]], - [self.n_his_locbf_D[0], self.n_int_locbf_N[1], self.n_int_locbf_D[2]], - self.his_global_D[0], - self.int_global_N[1], - self.int_global_D[2], - self.his_loccof_D[0], - self.int_loccof_N[1], - self.int_loccof_D[2], - self.coeff_h[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffi_indices[2], - self.basisD_his[0], - self.basisN_int[1], - self.basisD_int[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_int_indices[2], - self.wts[0], - T12, - mat_eq.reshape(self.pts[0][:, 0].size, self.pts[0][0, :].size, n_unique1[1], n_unique1[2]), - ) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.x_int[1], - self.x_int[2], - mat_eq, - 22, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_1( - [self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]], - self.n_quad[0], - [self.n_his[0], self.n_int[1], self.n_int[2]], - [self.n_his_locbf_D[0], self.n_int_locbf_D[1], self.n_int_locbf_N[2]], - self.his_global_D[0], - self.int_global_D[1], - self.int_global_N[2], - self.his_loccof_D[0], - self.int_loccof_D[1], - self.int_loccof_N[2], - self.coeff_h[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffi_indices[2], - self.basisD_his[0], - self.basisD_int[1], - self.basisN_int[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_int_indices[2], - self.wts[0], - T13, - mat_eq.reshape(self.pts[0][:, 0].size, self.pts[0][0, :].size, n_unique1[1], n_unique1[2]), - ) - - # ================= assembly of 2 - component (PI_1_2 : int, his, int) ============ - mat_eq = xp.empty((n_unique2[0], n_unique2[1], n_unique2[2]), dtype=float) - - ker_eva.kernel_eva( - self.x_int[0], - self.pts[1].flatten(), - self.x_int[2], - mat_eq, - 23, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_2( - [self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]], - self.n_quad[1], - [self.n_int[0], self.n_his[1], self.n_int[2]], - [self.n_int_locbf_N[0], self.n_his_locbf_D[1], self.n_int_locbf_D[2]], - self.int_global_N[0], - self.his_global_D[1], - self.int_global_D[2], - self.int_loccof_N[0], - self.his_loccof_D[1], - self.int_loccof_D[2], - self.coeff_i[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.basisN_int[0], - self.basisD_his[1], - self.basisD_int[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[1], - T21, - mat_eq.reshape(n_unique2[0], self.pts[1][:, 0].size, self.pts[1][0, :].size, n_unique2[2]), - ) - - ker_eva.kernel_eva( - self.x_int[0], - self.pts[1].flatten(), - self.x_int[2], - mat_eq, - 21, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_2( - [self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]], - self.n_quad[1], - [self.n_int[0], self.n_his[1], self.n_int[2]], - [self.n_int_locbf_D[0], self.n_his_locbf_D[1], self.n_int_locbf_N[2]], - self.int_global_D[0], - self.his_global_D[1], - self.int_global_N[2], - self.int_loccof_D[0], - self.his_loccof_D[1], - self.int_loccof_N[2], - self.coeff_i[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.basisD_int[0], - self.basisD_his[1], - self.basisN_int[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[1], - T23, - mat_eq.reshape(n_unique2[0], self.pts[1][:, 0].size, self.pts[1][0, :].size, n_unique2[2]), - ) - - # ================= assembly of 3 - component (PI_1_3 : int, int, his) ============ - mat_eq = xp.empty((n_unique3[0], n_unique3[1], n_unique3[2]), dtype=float) - - ker_eva.kernel_eva( - self.x_int[0], - self.x_int[1], - self.pts[2].flatten(), - mat_eq, - 22, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_3( - [self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]], - self.n_quad[2], - [self.n_int[0], self.n_int[1], self.n_his[2]], - [self.n_int_locbf_N[0], self.n_int_locbf_D[1], self.n_his_locbf_D[2]], - self.int_global_N[0], - self.int_global_D[1], - self.his_global_D[2], - self.int_loccof_N[0], - self.int_loccof_D[1], - self.his_loccof_D[2], - self.coeff_i[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.basisN_int[0], - self.basisD_int[1], - self.basisD_his[2], - self.x_int_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[2], - T31, - mat_eq.reshape(n_unique3[0], n_unique3[1], self.pts[2][:, 0].size, self.pts[2][0, :].size), - ) - - ker_eva.kernel_eva( - self.x_int[0], - self.x_int[1], - self.pts[2].flatten(), - mat_eq, - 21, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi1_3( - [self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]], - self.n_quad[2], - [self.n_int[0], self.n_int[1], self.n_his[2]], - [self.n_int_locbf_D[0], self.n_int_locbf_N[1], self.n_his_locbf_D[2]], - self.int_global_D[0], - self.int_global_N[1], - self.his_global_D[2], - self.int_loccof_D[0], - self.int_loccof_N[1], - self.his_loccof_D[2], - self.coeff_i[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.basisD_int[0], - self.basisN_int[1], - self.basisD_his[2], - self.x_int_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[2], - T32, - mat_eq.reshape(n_unique3[0], n_unique3[1], self.pts[2][:, 0].size, self.pts[2][0, :].size), - ) - - # ============== conversion to sparse matrices (1 - component) ============== - indices = xp.indices( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_his_nvcof_D[0], - self.n_int_nvcof_N[1], - self.n_int_nvcof_D[2], - ), - ) - row = self.NbaseN[1] * self.NbaseD[2] * indices[0] + self.NbaseD[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_D[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.int_shift_D[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseN[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - T12 = spa.csc_matrix( - (T12.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseD[0] * self.NbaseN[1] * self.NbaseD[2], self.NbaseD[0] * self.NbaseN[1] * self.NbaseN[2]), - ) - T12.eliminate_zeros() - - indices = xp.indices( - ( - self.NbaseD[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_his_nvcof_D[0], - self.n_int_nvcof_D[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseD[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_D[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.int_shift_D[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseN[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - T13 = spa.csc_matrix( - (T13.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseD[0] * self.NbaseD[1] * self.NbaseN[2], self.NbaseD[0] * self.NbaseN[1] * self.NbaseN[2]), - ) - T13.eliminate_zeros() - - # ============== conversion to sparse matrices (2 - component) ============== - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseD[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_D[1], - self.n_int_nvcof_D[2], - ), - ) - row = self.NbaseD[1] * self.NbaseD[2] * indices[0] + self.NbaseD[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.his_shift_D[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.int_shift_D[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseD[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - T21 = spa.csc_matrix( - (T21.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseD[1] * self.NbaseD[2], self.NbaseN[0] * self.NbaseD[1] * self.NbaseN[2]), - ) - T21.eliminate_zeros() - - indices = xp.indices( - ( - self.NbaseD[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_int_nvcof_D[0], - self.n_his_nvcof_D[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseD[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_D[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.his_shift_D[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseD[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - T23 = spa.csc_matrix( - (T23.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseD[0] * self.NbaseD[1] * self.NbaseN[2], self.NbaseN[0] * self.NbaseD[1] * self.NbaseN[2]), - ) - T23.eliminate_zeros() - - # ============== conversion to sparse matrices (3 - component) ============== - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseD[2], - self.n_int_nvcof_N[0], - self.n_int_nvcof_D[1], - self.n_his_nvcof_D[2], - ), - ) - row = self.NbaseD[1] * self.NbaseD[2] * indices[0] + self.NbaseD[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.int_shift_D[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.his_shift_D[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseN[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - T31 = spa.csc_matrix( - (T31.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseD[1] * self.NbaseD[2], self.NbaseN[0] * self.NbaseN[1] * self.NbaseD[2]), - ) - T31.eliminate_zeros() - - indices = xp.indices( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_int_nvcof_D[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_D[2], - ), - ) - row = self.NbaseN[1] * self.NbaseD[2] * indices[0] + self.NbaseD[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_D[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.his_shift_D[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseN[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - T32 = spa.csc_matrix( - (T32.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseD[0] * self.NbaseN[1] * self.NbaseD[2], self.NbaseN[0] * self.NbaseN[1] * self.NbaseD[2]), - ) - T32.eliminate_zeros() - - self.TAU = spa.bmat([[None, -T12.T, T13.T], [T21.T, None, -T23.T], [-T31.T, T32.T, None]], format="csc") - - # ======================================================================== - def projection_S_0form(self, domain): - """ - Computes the sparse matrix of the expression pi_2(p3_eq * lambda^0) with the output (coefficients, basis_fun of lambda^0). - - The following blocks need to be computed: - - 1 - component [int, his, his] : (N, N, N)*p3_eq, None , None - 2 - component [his, int, his] : None , (N, N, N)*p3_eq, None - 3 - component [his, his, int] : None , None , (N, N, N)*p3_eq - - An analytical mapping is called from struphy.geometry.mappings_analytical. - - Parameters - ---------- - domain : domain - domain object created with struphy.geometry.domain that defines the geometry - - Returns - ------- - S : sparse matrix in csc-format - the projection of each basis function in V0 on V2 weighted with p3_eq - """ - - # non-vanishing coefficients - S11 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - dtype=float, - ) - S22 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - dtype=float, - ) - S33 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - - # size of interpolation/quadrature points of the 3 components - n_unique1 = [self.x_int[0].size, self.pts[1].flatten().size, self.pts[2].flatten().size] - n_unique2 = [self.pts[0].flatten().size, self.x_int[1].size, self.pts[2].flatten().size] - n_unique3 = [self.pts[0].flatten().size, self.pts[1].flatten().size, self.x_int[2].size] - - # ========= assembly of 1 - component (pi2_1 : int, his, his) ============ - mat_eq = xp.empty((n_unique1[0], n_unique1[1], n_unique1[2]), dtype=float) - - ker_eva.kernel_eva( - self.x_int[0], - self.pts[1].flatten(), - self.pts[2].flatten(), - mat_eq, - 31, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_1( - [self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]], - [self.n_quad[1], self.n_quad[2]], - [self.n_int[0], self.n_his[1], self.n_his[2]], - [self.n_int_locbf_N[0], self.n_his_locbf_N[1], self.n_his_locbf_N[2]], - self.int_global_N[0], - self.his_global_N[1], - self.his_global_N[2], - self.int_loccof_N[0], - self.his_loccof_N[1], - self.his_loccof_N[2], - self.coeff_i[0], - self.coeff_h[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffh_indices[2], - self.basisN_int[0], - self.basisN_his[1], - self.basisN_his[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_his_indices[2], - self.wts[1], - self.wts[2], - S11, - mat_eq.reshape( - n_unique1[0], - self.pts[1][:, 0].size, - self.pts[1][0, :].size, - self.pts[2][:, 0].size, - self.pts[2][0, :].size, - ), - ) - - # ========= assembly of 2 - component (pi2_2 : his, int, his) ============ - mat_eq = xp.empty((n_unique2[0], n_unique2[1], n_unique2[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.x_int[1], - self.pts[2].flatten(), - mat_eq, - 31, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_2( - [self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]], - [self.n_quad[0], self.n_quad[2]], - [self.n_his[0], self.n_int[1], self.n_his[2]], - [self.n_his_locbf_N[0], self.n_int_locbf_N[1], self.n_his_locbf_N[2]], - self.his_global_N[0], - self.int_global_N[1], - self.his_global_N[2], - self.his_loccof_N[0], - self.int_loccof_N[1], - self.his_loccof_N[2], - self.coeff_h[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.basisN_his[0], - self.basisN_int[1], - self.basisN_his[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[0], - self.wts[2], - S22, - mat_eq.reshape( - self.pts[0][:, 0].size, - self.pts[0][0, :].size, - n_unique2[1], - self.pts[2][:, 0].size, - self.pts[2][0, :].size, - ), - ) - - # ========= assembly of 3 - component (pi2_3 : his, his, int) ============ - mat_eq = xp.empty((n_unique3[0], n_unique3[1], n_unique3[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.pts[1].flatten(), - self.x_int[2], - mat_eq, - 31, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_3( - [self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]], - [self.n_quad[0], self.n_quad[1]], - [self.n_his[0], self.n_his[1], self.n_int[2]], - [self.n_his_locbf_N[0], self.n_his_locbf_N[1], self.n_int_locbf_N[2]], - self.his_global_N[0], - self.his_global_N[1], - self.int_global_N[2], - self.his_loccof_N[0], - self.his_loccof_N[1], - self.int_loccof_N[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.basisN_his[0], - self.basisN_his[1], - self.basisN_int[2], - self.x_his_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[0], - self.wts[1], - S33, - mat_eq.reshape( - self.pts[0][:, 0].size, - self.pts[0][0, :].size, - self.pts[1][:, 0].size, - self.pts[1][0, :].size, - n_unique3[2], - ), - ) - - # ========= conversion to sparse matrices (1 - component) ================= - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.his_shift_N[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.his_shift_N[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseD[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - S11 = spa.csc_matrix( - (S11.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseN[0] * self.NbaseD[1] * self.NbaseD[2]), - ) - S11.eliminate_zeros() - - # ========= conversion to sparse matrices (2 - component) ================= - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_N[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.his_shift_N[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseN[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - S22 = spa.csc_matrix( - (S22.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseD[0] * self.NbaseN[1] * self.NbaseD[2]), - ) - S22.eliminate_zeros() - - # ========= conversion to sparse matrices (3 - component) ================= - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_N[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.his_shift_N[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseD[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - S33 = spa.csc_matrix( - (S33.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseD[0] * self.NbaseD[1] * self.NbaseN[2]), - ) - S33.eliminate_zeros() - - self.S = spa.bmat([[S11.T, None, None], [None, S22.T, None], [None, None, S33.T]], format="csc") - - # ======================================================================== - def projection_S_2form(self, domain): - """ - Computes the sparse matrix of the expression pi_2(p3_eq * lambda^2) with the output (coefficients, basis_fun of lambda^2). - - The following blocks need to be computed: - - 1 - component [int, his, his] : (N, D, D)*p3_eq, None , None - 2 - component [his, int, his] : None , (D, N, D)*p3_eq, None - 3 - component [his, his, int] : None , None , (D, D, N)*p3_eq - - An analytical mapping is called from struphy.geometry.mappings_analytical. - - Parameters - ---------- - domain : domain - domain object created with struphy.geometry.domain that defines the geometry - - Returns - ------- - S : sparse matrix in csc-format - the projection of each basis function in V2 on V2 weighted with rho3_eq - """ - - # non-vanishing coefficients - S11 = xp.empty( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseD[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_D[1], - self.n_his_nvcof_D[2], - ), - dtype=float, - ) - S22 = xp.empty( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_his_nvcof_D[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_D[2], - ), - dtype=float, - ) - S33 = xp.empty( - ( - self.NbaseD[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_his_nvcof_D[0], - self.n_his_nvcof_D[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - - # size of interpolation/quadrature points of the 3 components - n_unique1 = [self.x_int[0].size, self.pts[1].flatten().size, self.pts[2].flatten().size] - n_unique2 = [self.pts[0].flatten().size, self.x_int[1].size, self.pts[2].flatten().size] - n_unique3 = [self.pts[0].flatten().size, self.pts[1].flatten().size, self.x_int[2].size] - - # ========= assembly of 1 - component (pi2_1 : int, his, his) ============ - mat_eq = xp.empty((n_unique1[0], n_unique1[1], n_unique1[2]), dtype=float) - - ker_eva.kernel_eva( - self.x_int[0], - self.pts[1].flatten(), - self.pts[2].flatten(), - mat_eq, - 31, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_1( - [self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]], - [self.n_quad[1], self.n_quad[2]], - [self.n_int[0], self.n_his[1], self.n_his[2]], - [self.n_int_locbf_N[0], self.n_his_locbf_D[1], self.n_his_locbf_D[2]], - self.int_global_N[0], - self.his_global_D[1], - self.his_global_D[2], - self.int_loccof_N[0], - self.his_loccof_D[1], - self.his_loccof_D[2], - self.coeff_i[0], - self.coeff_h[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffh_indices[2], - self.basisN_int[0], - self.basisD_his[1], - self.basisD_his[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_his_indices[2], - self.wts[1], - self.wts[2], - S11, - mat_eq.reshape( - n_unique1[0], - self.pts[1][:, 0].size, - self.pts[1][0, :].size, - self.pts[2][:, 0].size, - self.pts[2][0, :].size, - ), - ) - - # ========= assembly of 2 - component (pi2_2 : his, int, his) ============ - mat_eq = xp.empty((n_unique2[0], n_unique2[1], n_unique2[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.x_int[1], - self.pts[2].flatten(), - mat_eq, - 31, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_2( - [self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]], - [self.n_quad[0], self.n_quad[2]], - [self.n_his[0], self.n_int[1], self.n_his[2]], - [self.n_his_locbf_D[0], self.n_int_locbf_N[1], self.n_his_locbf_D[2]], - self.his_global_D[0], - self.int_global_N[1], - self.his_global_D[2], - self.his_loccof_D[0], - self.int_loccof_N[1], - self.his_loccof_D[2], - self.coeff_h[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.basisD_his[0], - self.basisN_int[1], - self.basisD_his[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[0], - self.wts[2], - S22, - mat_eq.reshape( - self.pts[0][:, 0].size, - self.pts[0][0, :].size, - n_unique2[1], - self.pts[2][:, 0].size, - self.pts[2][0, :].size, - ), - ) - - # ========= assembly of 3 - component (pi2_3 : his, his, int) ============ - mat_eq = xp.empty((n_unique3[0], n_unique3[1], n_unique3[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.pts[1].flatten(), - self.x_int[2], - mat_eq, - 31, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_3( - [self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]], - [self.n_quad[0], self.n_quad[1]], - [self.n_his[0], self.n_his[1], self.n_int[2]], - [self.n_his_locbf_D[0], self.n_his_locbf_D[1], self.n_int_locbf_N[2]], - self.his_global_D[0], - self.his_global_D[1], - self.int_global_N[2], - self.his_loccof_D[0], - self.his_loccof_D[1], - self.int_loccof_N[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.basisD_his[0], - self.basisD_his[1], - self.basisN_int[2], - self.x_his_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[0], - self.wts[1], - S33, - mat_eq.reshape( - self.pts[0][:, 0].size, - self.pts[0][0, :].size, - self.pts[1][:, 0].size, - self.pts[1][0, :].size, - n_unique3[2], - ), - ) - - # ========= conversion to sparse matrices (1 - component) ================= - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseD[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_D[1], - self.n_his_nvcof_D[2], - ), - ) - row = self.NbaseD[1] * self.NbaseD[2] * indices[0] + self.NbaseD[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.his_shift_D[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.his_shift_D[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseD[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - S11 = spa.csc_matrix( - (S11.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseD[1] * self.NbaseD[2], self.NbaseN[0] * self.NbaseD[1] * self.NbaseD[2]), - ) - S11.eliminate_zeros() - - # ========= conversion to sparse matrices (2 - component) ================= - indices = xp.indices( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_his_nvcof_D[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_D[2], - ), - ) - row = self.NbaseN[1] * self.NbaseD[2] * indices[0] + self.NbaseD[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_D[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.his_shift_D[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseN[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - S22 = spa.csc_matrix( - (S22.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseD[0] * self.NbaseN[1] * self.NbaseD[2], self.NbaseD[0] * self.NbaseN[1] * self.NbaseD[2]), - ) - S22.eliminate_zeros() - - # ========= conversion to sparse matrices (3 - component) ================= - indices = xp.indices( - ( - self.NbaseD[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_his_nvcof_D[0], - self.n_his_nvcof_D[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseD[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_D[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.his_shift_D[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseD[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - S33 = spa.csc_matrix( - (S33.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseD[0] * self.NbaseD[1] * self.NbaseN[2], self.NbaseD[0] * self.NbaseD[1] * self.NbaseN[2]), - ) - S33.eliminate_zeros() - - self.S = spa.bmat([[S11.T, None, None], [None, S22.T, None], [None, None, S33.T]], format="csc") - - # ======================================================================== - def projection_K_3form(self, domain): - """ - Computes the sparse matrix of the expression pi_3(p0_eq * lambda^3) with the output (coefficients, basis_fun of lambda^2). - - The following block needs to be computed: - - [his, his, his] : (D, D, D)*p0_eq - - An analytical mapping is called from struphy.geometry.mappings_analytical. - - Parameters - ---------- - domain : domain - domain object created with struphy.geometry.domain that defines the geometry - - Returns - ------- - K : sparse matrix in csc-format - the projection of each basis function in V3 on V3 weighted with p0_eq - """ - - # non-vanishing coefficients - K = xp.zeros( - ( - self.NbaseD[0], - self.NbaseD[1], - self.NbaseD[2], - self.n_his_nvcof_D[0], - self.n_his_nvcof_D[1], - self.n_his_nvcof_D[2], - ), - dtype=float, - ) - - # evaluation of equilibrium pressure at interpolation points - n_unique = [self.pts[0].flatten().size, self.pts[1].flatten().size, self.pts[2].flatten().size] - - mat_eq = xp.zeros((n_unique[0], n_unique[1], n_unique[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.pts[1].flatten(), - self.pts[2].flatten(), - mat_eq, - 41, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - # assembly of K - ker_loc.kernel_pi3( - self.NbaseD, - self.n_quad, - self.n_his, - self.n_his_locbf_D, - self.his_global_D[0], - self.his_global_D[1], - self.his_global_D[2], - self.his_loccof_D[0], - self.his_loccof_D[1], - self.his_loccof_D[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_h[2], - self.coeffh_indices[0], - self.coeffh_indices[1], - self.coeffh_indices[2], - self.basisD_his[0], - self.basisD_his[1], - self.basisD_his[2], - self.x_his_indices[0], - self.x_his_indices[1], - self.x_his_indices[2], - self.wts[0], - self.wts[1], - self.wts[2], - K, - mat_eq.reshape( - self.pts[0][:, 0].size, - self.pts[0][0, :].size, - self.pts[1][:, 0].size, - self.pts[1][0, :].size, - self.pts[2][:, 0].size, - self.pts[2][0, :].size, - ), - ) - - # conversion to sparse matrix - indices = xp.indices( - ( - self.NbaseD[0], - self.NbaseD[1], - self.NbaseD[2], - self.n_his_nvcof_D[0], - self.n_his_nvcof_D[1], - self.n_his_nvcof_D[2], - ), - ) - - # row indices - row = self.NbaseD[1] * self.NbaseD[2] * indices[0] + self.NbaseD[2] * indices[1] + indices[2] - - # column indices - col1 = (indices[3] + self.his_shift_D[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.his_shift_D[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.his_shift_D[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseD[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - # create sparse matrix - K = spa.csc_matrix( - (K.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseD[0] * self.NbaseD[1] * self.NbaseD[2], self.NbaseD[0] * self.NbaseD[1] * self.NbaseD[2]), - ) - K.eliminate_zeros() - - self.K = K.T - - # ======================================================================== - def projection_N_0form(self, domain): - """ - Computes the sparse matrix of the expression pi_2(g_sqrt * lambda^0) with the output (coefficients, basis_fun of lambda^0). - - The following blocks need to be computed: - - 1 - component [int, his, his] : (N, N, N)*g_sqrt, None , None - 2 - component [his, int, his] : None , (N, N, N)*g_sqrt, None - 3 - component [his, his, int] : None , None , (N, N, N)*g_sqrt - - An analytical mapping is called from struphy.geometry.mappings_analytical. - - Parameters - ---------- - domain : domain - domain object created with struphy.geometry.domain that defines the geometry - - Returns - ------- - N : sparse matrix in csc-format - the projection of each basis function in V0 on V2 weighted with g_sqrt - """ - - # non-vanishing coefficients - N11 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - dtype=float, - ) - N22 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - dtype=float, - ) - N33 = xp.empty( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - - # size of interpolation/quadrature points of the 3 components - n_unique1 = [self.x_int[0].size, self.pts[1].flatten().size, self.pts[2].flatten().size] - n_unique2 = [self.pts[0].flatten().size, self.x_int[1].size, self.pts[2].flatten().size] - n_unique3 = [self.pts[0].flatten().size, self.pts[1].flatten().size, self.x_int[2].size] - - # ========= assembly of 1 - component (pi2_1 : int, his, his) ============ - mat_eq = xp.empty((n_unique1[0], n_unique1[1], n_unique1[2]), dtype=float) - - ker_eva.kernel_eva( - self.x_int[0], - self.pts[1].flatten(), - self.pts[2].flatten(), - mat_eq, - 51, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_1( - [self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]], - [self.n_quad[1], self.n_quad[2]], - [self.n_int[0], self.n_his[1], self.n_his[2]], - [self.n_int_locbf_N[0], self.n_his_locbf_N[1], self.n_his_locbf_N[2]], - self.int_global_N[0], - self.his_global_N[1], - self.his_global_N[2], - self.int_loccof_N[0], - self.his_loccof_N[1], - self.his_loccof_N[2], - self.coeff_i[0], - self.coeff_h[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffh_indices[2], - self.basisN_int[0], - self.basisN_his[1], - self.basisN_his[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_his_indices[2], - self.wts[1], - self.wts[2], - N11, - mat_eq.reshape( - n_unique1[0], - self.pts[1][:, 0].size, - self.pts[1][0, :].size, - self.pts[2][:, 0].size, - self.pts[2][0, :].size, - ), - ) - - # ========= assembly of 2 - component (pi2_2 : his, int, his) ============ - mat_eq = xp.empty((n_unique2[0], n_unique2[1], n_unique2[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.x_int[1], - self.pts[2].flatten(), - mat_eq, - 51, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_2( - [self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]], - [self.n_quad[0], self.n_quad[2]], - [self.n_his[0], self.n_int[1], self.n_his[2]], - [self.n_his_locbf_N[0], self.n_int_locbf_N[1], self.n_his_locbf_N[2]], - self.his_global_N[0], - self.int_global_N[1], - self.his_global_N[2], - self.his_loccof_N[0], - self.int_loccof_N[1], - self.his_loccof_N[2], - self.coeff_h[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.basisN_his[0], - self.basisN_int[1], - self.basisN_his[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[0], - self.wts[2], - N22, - mat_eq.reshape( - self.pts[0][:, 0].size, - self.pts[0][0, :].size, - n_unique2[1], - self.pts[2][:, 0].size, - self.pts[2][0, :].size, - ), - ) - - # ========= assembly of 3 - component (pi2_3 : his, his, int) ============ - mat_eq = xp.empty((n_unique3[0], n_unique3[1], n_unique3[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.pts[1].flatten(), - self.x_int[2], - mat_eq, - 51, - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - ker_loc.kernel_pi2_3( - [self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]], - [self.n_quad[0], self.n_quad[1]], - [self.n_his[0], self.n_his[1], self.n_int[2]], - [self.n_his_locbf_N[0], self.n_his_locbf_N[1], self.n_int_locbf_N[2]], - self.his_global_N[0], - self.his_global_N[1], - self.int_global_N[2], - self.his_loccof_N[0], - self.his_loccof_N[1], - self.int_loccof_N[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.basisN_his[0], - self.basisN_his[1], - self.basisN_int[2], - self.x_his_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[0], - self.wts[1], - N33, - mat_eq.reshape( - self.pts[0][:, 0].size, - self.pts[0][0, :].size, - self.pts[1][:, 0].size, - self.pts[1][0, :].size, - n_unique3[2], - ), - ) - - # ========= conversion to sparse matrices (1 - component) ================= - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.his_shift_N[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.his_shift_N[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseD[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - N11 = spa.csc_matrix( - (N11.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseN[0] * self.NbaseD[1] * self.NbaseD[2]), - ) - N11.eliminate_zeros() - - # ========= conversion to sparse matrices (2 - component) ================= - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_N[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.his_shift_N[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseN[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - N22 = spa.csc_matrix( - (N22.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseD[0] * self.NbaseN[1] * self.NbaseD[2]), - ) - N22.eliminate_zeros() - - # ========= conversion to sparse matrices (3 - component) ================= - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.n_his_nvcof_N[0], - self.n_his_nvcof_N[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseN[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_N[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.his_shift_N[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseD[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - N33 = spa.csc_matrix( - (N33.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2], self.NbaseD[0] * self.NbaseD[1] * self.NbaseN[2]), - ) - N33.eliminate_zeros() - - self.N = spa.bmat([[N11.T, None, None], [None, N22.T, None], [None, None, N33.T]], format="csc") - - # ======================================================================== - def projection_N_2form(self, domain): - """ - Computes the sparse matrix of the expression pi_2(g_sqrt * lambda^2) with the output (coefficients, basis_fun of lambda^2). - - The following blocks need to be computed: - - 1 - component [int, his, his] : (N, D, D)*g_sqrt, None , None - 2 - component [his, int, his] : None , (D, N, D)*g_sqrt, None - 3 - component [his, his, int] : None , None , (D, D, N)*g_sqrt - - An analytical mapping is called from struphy.geometry.mappings_analytical. - - Parameters - ---------- - domain : domain - domain object created with struphy.geometry.domain that defines the geometry - - Returns - ------- - N : sparse matrix in csc-format - the projection of each basis function in V2 on V2 weighted with rho3_eq - """ - - # non-vanishing coefficients - N11 = xp.empty( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseD[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_D[1], - self.n_his_nvcof_D[2], - ), - dtype=float, - ) - N22 = xp.empty( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_his_nvcof_D[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_D[2], - ), - dtype=float, - ) - N33 = xp.empty( - ( - self.NbaseD[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_his_nvcof_D[0], - self.n_his_nvcof_D[1], - self.n_int_nvcof_N[2], - ), - dtype=float, - ) - - # size of interpolation/quadrature points of the 3 components - n_unique1 = [self.x_int[0].size, self.pts[1].flatten().size, self.pts[2].flatten().size] - n_unique2 = [self.pts[0].flatten().size, self.x_int[1].size, self.pts[2].flatten().size] - n_unique3 = [self.pts[0].flatten().size, self.pts[1].flatten().size, self.x_int[2].size] - - # ========= assembly of 1 - component (pi2_1 : int, his, his) ============ - mat_eq = xp.empty((n_unique1[0], n_unique1[1], n_unique1[2]), dtype=float) - - ker_eva.kernel_eva( - self.x_int[0], - self.pts[1].flatten(), - self.pts[2].flatten(), - mat_eq, - 51, - kind_map=kind_map, - params_map=params_map, - ) - - ker_loc.kernel_pi2_1( - [self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]], - [self.n_quad[1], self.n_quad[2]], - [self.n_int[0], self.n_his[1], self.n_his[2]], - [self.n_int_locbf_N[0], self.n_his_locbf_D[1], self.n_his_locbf_D[2]], - self.int_global_N[0], - self.his_global_D[1], - self.his_global_D[2], - self.int_loccof_N[0], - self.his_loccof_D[1], - self.his_loccof_D[2], - self.coeff_i[0], - self.coeff_h[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffh_indices[2], - self.basisN_int[0], - self.basisD_his[1], - self.basisD_his[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_his_indices[2], - self.wts[1], - self.wts[2], - N11, - mat_eq.reshape( - n_unique1[0], - self.pts[1][:, 0].size, - self.pts[1][0, :].size, - self.pts[2][:, 0].size, - self.pts[2][0, :].size, - ), - ) - - # ========= assembly of 2 - component (pi2_2 : his, int, his) ============ - mat_eq = xp.empty((n_unique2[0], n_unique2[1], n_unique2[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.x_int[1], - self.pts[2].flatten(), - mat_eq, - 51, - kind_map=kind_map, - params_map=params_map, - ) - - ker_loc.kernel_pi2_2( - [self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]], - [self.n_quad[0], self.n_quad[2]], - [self.n_his[0], self.n_int[1], self.n_his[2]], - [self.n_his_locbf_D[0], self.n_int_locbf_N[1], self.n_his_locbf_D[2]], - self.his_global_D[0], - self.int_global_N[1], - self.his_global_D[2], - self.his_loccof_D[0], - self.int_loccof_N[1], - self.his_loccof_D[2], - self.coeff_h[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.basisD_his[0], - self.basisN_int[1], - self.basisD_his[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[0], - self.wts[2], - N22, - mat_eq.reshape( - self.pts[0][:, 0].size, - self.pts[0][0, :].size, - n_unique2[1], - self.pts[2][:, 0].size, - self.pts[2][0, :].size, - ), - ) - - # ========= assembly of 3 - component (pi2_3 : his, his, int) ============ - mat_eq = xp.empty((n_unique3[0], n_unique3[1], n_unique3[2]), dtype=float) - - ker_eva.kernel_eva( - self.pts[0].flatten(), - self.pts[1].flatten(), - self.x_int[2], - mat_eq, - 51, - kind_map=kind_map, - params_map=params_map, - ) - - ker_loc.kernel_pi2_3( - [self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]], - [self.n_quad[0], self.n_quad[1]], - [self.n_his[0], self.n_his[1], self.n_int[2]], - [self.n_his_locbf_D[0], self.n_his_locbf_D[1], self.n_int_locbf_N[2]], - self.his_global_D[0], - self.his_global_D[1], - self.int_global_N[2], - self.his_loccof_D[0], - self.his_loccof_D[1], - self.int_loccof_N[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.basisD_his[0], - self.basisD_his[1], - self.basisN_int[2], - self.x_his_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[0], - self.wts[1], - N33, - mat_eq.reshape( - self.pts[0][:, 0].size, - self.pts[0][0, :].size, - self.pts[1][:, 0].size, - self.pts[1][0, :].size, - n_unique3[2], - ), - ) - - # ========= conversion to sparse matrices (1 - component) ================= - indices = xp.indices( - ( - self.NbaseN[0], - self.NbaseD[1], - self.NbaseD[2], - self.n_int_nvcof_N[0], - self.n_his_nvcof_D[1], - self.n_his_nvcof_D[2], - ), - ) - row = self.NbaseD[1] * self.NbaseD[2] * indices[0] + self.NbaseD[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.int_shift_N[0][:, None, None, None, None, None]) % self.NbaseN[0] - col2 = (indices[4] + self.his_shift_D[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.his_shift_D[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseD[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - N11 = spa.csc_matrix( - (N11.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseN[0] * self.NbaseD[1] * self.NbaseD[2], self.NbaseN[0] * self.NbaseD[1] * self.NbaseD[2]), - ) - N11.eliminate_zeros() - - # ========= conversion to sparse matrices (2 - component) ================= - indices = xp.indices( - ( - self.NbaseD[0], - self.NbaseN[1], - self.NbaseD[2], - self.n_his_nvcof_D[0], - self.n_int_nvcof_N[1], - self.n_his_nvcof_D[2], - ), - ) - row = self.NbaseN[1] * self.NbaseD[2] * indices[0] + self.NbaseD[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_D[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.int_shift_N[1][None, :, None, None, None, None]) % self.NbaseN[1] - col3 = (indices[5] + self.his_shift_D[2][None, None, :, None, None, None]) % self.NbaseD[2] - - col = self.NbaseN[1] * self.NbaseD[2] * col1 + self.NbaseD[2] * col2 + col3 - - N22 = spa.csc_matrix( - (N22.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseD[0] * self.NbaseN[1] * self.NbaseD[2], self.NbaseD[0] * self.NbaseN[1] * self.NbaseD[2]), - ) - N22.eliminate_zeros() - - # ========= conversion to sparse matrices (3 - component) ================= - indices = xp.indices( - ( - self.NbaseD[0], - self.NbaseD[1], - self.NbaseN[2], - self.n_his_nvcof_D[0], - self.n_his_nvcof_D[1], - self.n_int_nvcof_N[2], - ), - ) - row = self.NbaseD[1] * self.NbaseN[2] * indices[0] + self.NbaseN[2] * indices[1] + indices[2] - - col1 = (indices[3] + self.his_shift_D[0][:, None, None, None, None, None]) % self.NbaseD[0] - col2 = (indices[4] + self.his_shift_D[1][None, :, None, None, None, None]) % self.NbaseD[1] - col3 = (indices[5] + self.int_shift_N[2][None, None, :, None, None, None]) % self.NbaseN[2] - - col = self.NbaseD[1] * self.NbaseN[2] * col1 + self.NbaseN[2] * col2 + col3 - - N33 = spa.csc_matrix( - (N33.flatten(), (row.flatten(), col.flatten())), - shape=(self.NbaseD[0] * self.NbaseD[1] * self.NbaseN[2], self.NbaseD[0] * self.NbaseD[1] * self.NbaseN[2]), - ) - N33.eliminate_zeros() - - self.N = spa.bmat([[N11.T, None, None], [None, N22.T, None], [None, None, N33.T]], format="csc") - - # ===================================== - def setOperators(self, gamma, dt, drop_tol_S6, fill_fac_S6): - A = (1 / 2 * (self.W.T.dot(self.tensor_space.Mv) + self.tensor_space.Mv.dot(self.W))).tocsr() - self.A = spa.linalg.LinearOperator(A.shape, matvec=lambda x: A.dot(x), rmatvec=lambda x: A.T.dot(x)) - - L = (-self.tensor_space.DIV.dot(self.S) - (gamma - 1) * self.K.dot(self.tensor_space.DIV.dot(self.N))).tocsr() - self.L = spa.linalg.LinearOperator(L.shape, matvec=lambda x: L.dot(x), rmatvec=lambda x: L.T.dot(x)) - - S6 = (A - dt**2 / 4 * self.N.T.dot(self.tensor_space.DIV.T.dot(self.tensor_space.M3.dot(L)))).tocsr() - self.S6 = spa.linalg.LinearOperator(S6.shape, matvec=lambda x: S6.dot(x), rmatvec=lambda x: S6.T.dot(x)) - - S6_ILU = spa.linalg.spilu(S6.tocsc(), drop_tol=drop_tol_S6, fill_factor=fill_fac_S6) - self.S6_PRE = spa.linalg.LinearOperator(self.S6.shape, lambda x: S6_ILU.solve(x)) - - # ===================================== - def RHS6(self, u, p, b, dt): - out = ( - self.A(u) - + dt**2 / 4 * self.N.T.dot(self.tensor_space.DIV.T.dot(self.tensor_space.M3.dot(self.L(u)))) - + dt * self.N.T.dot(self.tensor_space.DIV.T.dot(self.tensor_space.M3.dot(p))) - ) - - return out - - -# =========================================================== -class term_curl_beq: - """ - Computes the inner product of the term [nabla x (G * Beq)] x B2 = [nabla x (DF^T * B_eq_phys)] x B2 with each basis function in V2. - - Parameters - ---------- - tensor_space : Tensor_spline_space - tensor product B-spline space - - kind_map : int - type of mapping - - params_map : list of doubles - parameters for the mapping - """ - - def __init__( - self, - tensor_space, - mapping, - kind_map=None, - params_map=None, - tensor_space_F=None, - cx=None, - cy=None, - cz=None, - ): - self.p = tensor_space.p # spline degrees - self.Nel = tensor_space.Nel # number of elements - self.NbaseN = tensor_space.NbaseN # total number of basis functions (N) - self.NbaseD = tensor_space.NbaseD # total number of basis functions (D) - - self.n_quad = tensor_space.n_quad # number of quadrature points per element - self.wts = tensor_space.wts # quadrature weights in format (element, local point) - self.pts = tensor_space.pts # quadrature points in format (element, local point) - self.n_pts = tensor_space.n_pts # total number of quadrature points - - # basis functions evaluated at quadrature points in format (element, local basis function, derivative, local point) - self.basisN = tensor_space.basisN - self.basisD = tensor_space.basisD - - # mapping - self.mapping = mapping - - if mapping == 0: - self.kind_map = kind_map - self.params_map = params_map - - elif mapping == 1: - self.T_F = tensor_space_F.T - self.p_F = tensor_space_F.p - self.NbaseN_F = tensor_space_F.NbaseN - - self.cx = cx - self.cy = cy - self.cz = cz - - # ============= evaluation of background magnetic field at quadrature points ========= - self.mat_curl_beq_1 = xp.empty( - (self.Nel[0], self.Nel[1], self.Nel[2], self.n_quad[0], self.n_quad[1], self.n_quad[2]), - dtype=float, - ) - self.mat_curl_beq_2 = xp.empty( - (self.Nel[0], self.Nel[1], self.Nel[2], self.n_quad[0], self.n_quad[1], self.n_quad[2]), - dtype=float, - ) - self.mat_curl_beq_3 = xp.empty( - (self.Nel[0], self.Nel[1], self.Nel[2], self.n_quad[0], self.n_quad[1], self.n_quad[2]), - dtype=float, - ) - - if mapping == 0: - ker_eva.kernel_eva_quad( - self.Nel, - self.n_quad, - self.pts[0], - self.pts[1], - self.pts[2], - self.mat_curl_beq_1, - 61, - kind_map, - params_map, - ) - ker_eva.kernel_eva_quad( - self.Nel, - self.n_quad, - self.pts[0], - self.pts[1], - self.pts[2], - self.mat_curl_beq_2, - 62, - kind_map, - params_map, - ) - ker_eva.kernel_eva_quad( - self.Nel, - self.n_quad, - self.pts[0], - self.pts[1], - self.pts[2], - self.mat_curl_beq_3, - 63, - kind_map, - params_map, - ) - elif mapping == 1: - ker_eva.kernel_eva_quad( - self.Nel, - self.n_quad, - self.pts[0], - self.pts[1], - self.pts[2], - self.mat_curl_beq_1, - 61, - self.T_F[0], - self.T_F[1], - self.T_F[2], - self.p_F, - self.NbaseN_F, - cx, - cy, - cz, - ) - ker_eva.kernel_eva_quad( - self.Nel, - self.n_quad, - self.pts[0], - self.pts[1], - self.pts[2], - self.mat_curl_beq_2, - 62, - self.T_F[0], - self.T_F[1], - self.T_F[2], - self.p_F, - self.NbaseN_F, - cx, - cy, - cz, - ) - ker_eva.kernel_eva_quad( - self.Nel, - self.n_quad, - self.pts[0], - self.pts[1], - self.pts[2], - self.mat_curl_beq_3, - 63, - self.T_F[0], - self.T_F[1], - self.T_F[2], - self.p_F, - self.NbaseN_F, - cx, - cy, - cz, - ) - - # ====================== perturbed magnetic field at quadrature points ========== - self.B1 = xp.empty( - (self.Nel[0], self.Nel[1], self.Nel[2], self.n_quad[0], self.n_quad[1], self.n_quad[2]), - dtype=float, - ) - self.B2 = xp.empty( - (self.Nel[0], self.Nel[1], self.Nel[2], self.n_quad[0], self.n_quad[1], self.n_quad[2]), - dtype=float, - ) - self.B3 = xp.empty( - (self.Nel[0], self.Nel[1], self.Nel[2], self.n_quad[0], self.n_quad[1], self.n_quad[2]), - dtype=float, - ) - - # ========================== inner products ===================================== - self.F1 = xp.empty((self.NbaseN[0], self.NbaseN[1], self.NbaseN[2]), dtype=float) - self.F2 = xp.empty((self.NbaseN[0], self.NbaseN[1], self.NbaseN[2]), dtype=float) - self.F3 = xp.empty((self.NbaseN[0], self.NbaseN[1], self.NbaseN[2]), dtype=float) - - # ============================================================ - def inner_curl_beq(self, b1, b2, b3): - """ - Computes the inner product of the term [nabla x (G * Beq)] x B2 = [nabla x (DF^T * B_eq_phys)] x B2 with each basis function in V2. - """ - - # evaluation of perturbed magnetic field at quadrature points - ker_loc_3d.kernel_evaluate_2form( - self.Nel, - self.p, - [0, 1, 1], - self.n_quad, - b1, - [self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]], - self.basisN[0], - self.basisD[1], - self.basisD[2], - self.B1, - ) - ker_loc_3d.kernel_evaluate_2form( - self.Nel, - self.p, - [1, 0, 1], - self.n_quad, - b2, - [self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]], - self.basisD[0], - self.basisN[1], - self.basisD[2], - self.B2, - ) - ker_loc_3d.kernel_evaluate_2form( - self.Nel, - self.p, - [1, 1, 0], - self.n_quad, - b3, - [self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]], - self.basisD[0], - self.basisD[1], - self.basisN[2], - self.B3, - ) - - # assembly of F (1 - component) - ker_loc_3d.kernel_inner_2( - self.Nel[0], - self.Nel[1], - self.Nel[2], - self.p[0], - self.p[1], - self.p[2], - self.n_quad[0], - self.n_quad[1], - self.n_quad[2], - 0, - 0, - 0, - self.wts[0], - self.wts[1], - self.wts[2], - self.basisN[0], - self.basisN[1], - self.basisN[2], - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.F1, - self.mat_curl_beq_2 * self.B3 - self.mat_curl_beq_3 * self.B2, - ) - # ker_loc_3d.kernel_inner_2(self.Nel[0], self.Nel[1], self.Nel[2], self.p[0], self.p[1], self.p[2], self.n_quad[0], self.n_quad[1], self.n_quad[2], 0, 0, 0, self.wts[0], self.wts[1], self.wts[2], self.basisN[0], self.basisN[1], self.basisN[2], self.NbaseN[0], self.NbaseN[1], self.NbaseN[2], self.F1, self.mat_curl_beq_1) - - # assembly of F (2 - component) - ker_loc_3d.kernel_inner_2( - self.Nel[0], - self.Nel[1], - self.Nel[2], - self.p[0], - self.p[1], - self.p[2], - self.n_quad[0], - self.n_quad[1], - self.n_quad[2], - 0, - 0, - 0, - self.wts[0], - self.wts[1], - self.wts[2], - self.basisN[0], - self.basisN[1], - self.basisN[2], - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.F2, - self.mat_curl_beq_3 * self.B1 - self.mat_curl_beq_1 * self.B3, - ) - # ker_loc_3d.kernel_inner_2(self.Nel[0], self.Nel[1], self.Nel[2], self.p[0], self.p[1], self.p[2], self.n_quad[0], self.n_quad[1], self.n_quad[2], 0, 0, 0, self.wts[0], self.wts[1], self.wts[2], self.basisN[0], self.basisN[1], self.basisN[2], self.NbaseN[0], self.NbaseN[1], self.NbaseN[2], self.F2, self.mat_curl_beq_2) - - # assembly of F (3 - component) - ker_loc_3d.kernel_inner_2( - self.Nel[0], - self.Nel[1], - self.Nel[2], - self.p[0], - self.p[1], - self.p[2], - self.n_quad[0], - self.n_quad[1], - self.n_quad[2], - 0, - 0, - 0, - self.wts[0], - self.wts[1], - self.wts[2], - self.basisN[0], - self.basisN[1], - self.basisN[2], - self.NbaseN[0], - self.NbaseN[1], - self.NbaseN[2], - self.F3, - self.mat_curl_beq_1 * self.B2 - self.mat_curl_beq_2 * self.B1, - ) - # ker_loc_3d.kernel_inner_2(self.Nel[0], self.Nel[1], self.Nel[2], self.p[0], self.p[1], self.p[2], self.n_quad[0], self.n_quad[1], self.n_quad[2], 0, 0, 0, self.wts[0], self.wts[1], self.wts[2], self.basisN[0], self.basisN[1], self.basisN[2], self.NbaseN[0], self.NbaseN[1], self.NbaseN[2], self.F3, self.mat_curl_beq_3) - - # convert to 1d array and return - return xp.concatenate((self.F1.flatten(), self.F2.flatten(), self.F3.flatten())) - - -# ================ mass matrix in V1 =========================== -def mass_curl(tensor_space, kind_map, params_map): - """ - - Parameters - ---------- - tensor_space : Tensor_spline_space - tensor product B-spline space for finite element spaces - - kind_map : int - type of mapping in case of analytical mapping - - params_map : list of doubles - parameters for the mapping in case of analytical mapping - """ - - p = tensor_space.p # spline degrees - Nel = tensor_space.Nel # number of elements - bc = tensor_space.bc # boundary conditions (periodic vs. clamped) - NbaseN = tensor_space.NbaseN # total number of basis functions (N) - NbaseD = tensor_space.NbaseD # total number of basis functions (D) - - n_quad = tensor_space.n_quad # number of quadrature points per element - pts = tensor_space.pts # global quadrature points - wts = tensor_space.wts # global quadrature weights - - basisN = tensor_space.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space.basisD # evaluated basis functions at quadrature points (D) - - # number of basis functions - # blocks 12 13 21 23 31 32 - Nbi1 = [NbaseN[0], NbaseN[0], NbaseN[0], NbaseN[0], NbaseN[0], NbaseN[0]] - Nbi2 = [NbaseN[1], NbaseN[1], NbaseN[1], NbaseN[1], NbaseN[1], NbaseN[1]] - Nbi3 = [NbaseN[2], NbaseN[2], NbaseN[2], NbaseN[2], NbaseN[2], NbaseN[2]] - - Nbj1 = [NbaseD[0], NbaseD[0], NbaseN[0], NbaseD[0], NbaseN[0], NbaseD[0]] - Nbj2 = [NbaseN[1], NbaseD[1], NbaseD[1], NbaseD[1], NbaseD[1], NbaseN[1]] - Nbj3 = [NbaseD[2], NbaseN[2], NbaseD[2], NbaseN[2], NbaseD[2], NbaseD[2]] - - # ============= evaluation of background magnetic field at quadrature points ========= - mat_curl_beq_1 = xp.empty((Nel[0], Nel[1], Nel[2], n_quad[0], n_quad[1], n_quad[2]), dtype=float) - mat_curl_beq_2 = xp.empty((Nel[0], Nel[1], Nel[2], n_quad[0], n_quad[1], n_quad[2]), dtype=float) - mat_curl_beq_3 = xp.empty((Nel[0], Nel[1], Nel[2], n_quad[0], n_quad[1], n_quad[2]), dtype=float) - - ker_eva.kernel_eva_quad(Nel, n_quad, pts[0], pts[1], pts[2], mat_curl_beq_1, 61, kind_map, params_map) - ker_eva.kernel_eva_quad(Nel, n_quad, pts[0], pts[1], pts[2], mat_curl_beq_2, 62, kind_map, params_map) - ker_eva.kernel_eva_quad(Nel, n_quad, pts[0], pts[1], pts[2], mat_curl_beq_3, 63, kind_map, params_map) - # ===================================================================================== - - # blocks of global mass matrix - M = [ - xp.zeros((Nbi1, Nbi2, Nbi3, 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1), dtype=float) - for Nbi1, Nbi2, Nbi3 in zip(Nbi1, Nbi2, Nbi3) - ] - - # assembly of block 12 - ker_loc_3d.kernel_mass( - Nel[0], - Nel[1], - Nel[2], - p[0], - p[1], - p[2], - n_quad[0], - n_quad[1], - n_quad[2], - 0, - 0, - 0, - 1, - 0, - 1, - wts[0], - wts[1], - wts[2], - basisN[0], - basisN[1], - basisN[2], - basisD[0], - basisN[1], - basisD[2], - NbaseN[0], - NbaseN[1], - NbaseN[2], - M[0], - mat_curl_beq_3, - ) - - # assembly of block 13 - ker_loc_3d.kernel_mass( - Nel[0], - Nel[1], - Nel[2], - p[0], - p[1], - p[2], - n_quad[0], - n_quad[1], - n_quad[2], - 0, - 0, - 0, - 1, - 1, - 0, - wts[0], - wts[1], - wts[2], - basisN[0], - basisN[1], - basisN[2], - basisD[0], - basisD[1], - basisN[2], - NbaseN[0], - NbaseN[1], - NbaseN[2], - M[1], - mat_curl_beq_2, - ) - - # assembly of block 21 - ker_loc_3d.kernel_mass( - Nel[0], - Nel[1], - Nel[2], - p[0], - p[1], - p[2], - n_quad[0], - n_quad[1], - n_quad[2], - 0, - 0, - 0, - 0, - 1, - 1, - wts[0], - wts[1], - wts[2], - basisN[0], - basisN[1], - basisN[2], - basisN[0], - basisD[1], - basisD[2], - NbaseN[0], - NbaseN[1], - NbaseN[2], - M[2], - mat_curl_beq_3, - ) - - # assembly of block 23 - ker_loc_3d.kernel_mass( - Nel[0], - Nel[1], - Nel[2], - p[0], - p[1], - p[2], - n_quad[0], - n_quad[1], - n_quad[2], - 0, - 0, - 0, - 1, - 1, - 0, - wts[0], - wts[1], - wts[2], - basisN[0], - basisN[1], - basisN[2], - basisD[0], - basisD[1], - basisN[2], - NbaseN[0], - NbaseN[1], - NbaseN[2], - M[3], - mat_curl_beq_1, - ) - - # assembly of block 31 - ker_loc_3d.kernel_mass( - Nel[0], - Nel[1], - Nel[2], - p[0], - p[1], - p[2], - n_quad[0], - n_quad[1], - n_quad[2], - 0, - 0, - 0, - 0, - 1, - 1, - wts[0], - wts[1], - wts[2], - basisN[0], - basisN[1], - basisN[2], - basisN[0], - basisD[1], - basisD[2], - NbaseN[0], - NbaseN[1], - NbaseN[2], - M[4], - mat_curl_beq_2, - ) - - # assembly of block 32 - ker_loc_3d.kernel_mass( - Nel[0], - Nel[1], - Nel[2], - p[0], - p[1], - p[2], - n_quad[0], - n_quad[1], - n_quad[2], - 0, - 0, - 0, - 1, - 0, - 1, - wts[0], - wts[1], - wts[2], - basisN[0], - basisN[1], - basisN[2], - basisD[0], - basisN[1], - basisD[2], - NbaseN[0], - NbaseN[1], - NbaseN[2], - M[5], - mat_curl_beq_1, - ) - - # global indices - counter = 0 - - for i in range(6): - indices = xp.indices((Nbi1[counter], Nbi2[counter], Nbi3[counter], 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1)) - - shift1 = xp.arange(Nbi1[counter]) - p[0] - shift2 = xp.arange(Nbi2[counter]) - p[1] - shift3 = xp.arange(Nbi3[counter]) - p[2] - - row = (Nbi2[counter] * Nbi3[counter] * indices[0] + Nbi3[counter] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift1[:, None, None, None, None, None]) % Nbj1[counter] - col2 = (indices[4] + shift2[None, :, None, None, None, None]) % Nbj2[counter] - col3 = (indices[5] + shift3[None, None, :, None, None, None]) % Nbj3[counter] - - col = Nbj2[counter] * Nbj3[counter] * col1 + Nbj3[counter] * col2 + col3 - - M[counter] = spa.csc_matrix( - (M[counter].flatten(), (row, col.flatten())), - shape=(Nbi1[counter] * Nbi2[counter] * Nbi3[counter], Nbj1[counter] * Nbj2[counter] * Nbj3[counter]), - ) - M[counter].eliminate_zeros() - - counter += 1 - - M = spa.bmat([[None, -M[0], M[1]], [M[2], None, -M[3]], [-M[4], M[5], None]], format="csc") - - return M diff --git a/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/projectors_local.py b/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/projectors_local.py deleted file mode 100644 index 9ede3f608..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/projectors_local/pro_local/projectors_local.py +++ /dev/null @@ -1,1648 +0,0 @@ -# coding: utf-8 -# -# Copyright 2021 Florian Holderied (florian.holderied@ipp.mpg.de) - -""" -Classes for local projectors in 1D and 3D based on quasi-spline interpolation and histopolation. -""" - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.feec.bsplines as bsp -import struphy.feec.projectors.pro_local.kernels_projectors_local as ker_loc - - -# ======================= 1d ==================================== -class projectors_local_1d: - """ - Local commuting projectors pi_0 and pi_1 in 1d. - - Parameters - ---------- - spline_space : Spline_space_1d - a 1d space of B-splines - - n_quad : int - number of quadrature points per integration interval for histopolations - """ - - def __init__(self, spline_space, n_quad): - self.kind = "local" - - self.space = spline_space # 1D spline space - self.T = spline_space.T # knot vector - self.p = spline_space.p # spline degree - self.bc = spline_space.bc # boundary conditions - - self.NbaseN = spline_space.NbaseN # number of basis functions (N) - self.NbaseD = spline_space.NbaseD # number of basis functions (D) - - self.n_quad = n_quad # number of quadrature point per integration interval - - # Gauss - Legendre quadrature points and weights in (-1, 1) - self.pts_loc = xp.polynomial.legendre.leggauss(self.n_quad)[0] - self.wts_loc = xp.polynomial.legendre.leggauss(self.n_quad)[1] - - # set interpolation and histopolation coefficients - if self.bc: - self.coeff_i = xp.zeros((1, 2 * self.p - 1), dtype=float) - self.coeff_h = xp.zeros((1, 2 * self.p), dtype=float) - - if self.p == 1: - self.coeff_i[0, :] = xp.array([1.0]) - self.coeff_h[0, :] = xp.array([1.0, 1.0]) - - elif self.p == 2: - self.coeff_i[0, :] = 1 / 2 * xp.array([-1.0, 4.0, -1.0]) - self.coeff_h[0, :] = 1 / 2 * xp.array([-1.0, 3.0, 3.0, -1.0]) - - elif self.p == 3: - self.coeff_i[0, :] = 1 / 6 * xp.array([1.0, -8.0, 20.0, -8.0, 1.0]) - self.coeff_h[0, :] = 1 / 6 * xp.array([1.0, -7.0, 12.0, 12.0, -7.0, 1.0]) - - elif self.p == 4: - self.coeff_i[0, :] = 2 / 45 * xp.array([-1.0, 16.0, -295 / 4, 140.0, -295 / 4, 16.0, -1.0]) - self.coeff_h[0, :] = 2 / 45 * xp.array([-1.0, 15.0, -231 / 4, 265 / 4, 265 / 4, -231 / 4, 15.0, -1.0]) - - else: - print("degree > 4 not implemented!") - - else: - self.coeff_i = xp.zeros((2 * self.p - 1, 2 * self.p - 1), dtype=float) - self.coeff_h = xp.zeros((2 * self.p - 1, 2 * self.p), dtype=float) - - if self.p == 1: - self.coeff_i[0, :] = xp.array([1.0]) - self.coeff_h[0, :] = xp.array([1.0, 1.0]) - - elif self.p == 2: - self.coeff_i[0, :] = 1 / 2 * xp.array([2.0, 0.0, 0.0]) - self.coeff_i[1, :] = 1 / 2 * xp.array([-1.0, 4.0, -1.0]) - self.coeff_i[2, :] = 1 / 2 * xp.array([0.0, 0.0, 2.0]) - - self.coeff_h[0, :] = 1 / 2 * xp.array([3.0, -1.0, 0.0, 0.0]) - self.coeff_h[1, :] = 1 / 2 * xp.array([-1.0, 3.0, 3.0, -1.0]) - self.coeff_h[2, :] = 1 / 2 * xp.array([0.0, 0.0, -1.0, 3.0]) - - elif self.p == 3: - self.coeff_i[0, :] = 1 / 18 * xp.array([18.0, 0.0, 0.0, 0.0, 0.0]) - self.coeff_i[1, :] = 1 / 18 * xp.array([-5.0, 40.0, -24.0, 8.0, -1.0]) - self.coeff_i[2, :] = 1 / 18 * xp.array([3.0, -24.0, 60.0, -24.0, 3.0]) - self.coeff_i[3, :] = 1 / 18 * xp.array([-1.0, 8.0, -24.0, 40.0, -5.0]) - self.coeff_i[4, :] = 1 / 18 * xp.array([0.0, 0.0, 0.0, 0.0, 18.0]) - - self.coeff_h[0, :] = 1 / 18 * xp.array([23.0, -17.0, 7.0, -1.0, 0.0, 0.0]) - self.coeff_h[1, :] = 1 / 18 * xp.array([-8.0, 56.0, -28.0, 4.0, 0.0, 0.0]) - self.coeff_h[2, :] = 1 / 18 * xp.array([3.0, -21.0, 36.0, 36.0, -21.0, 3.0]) - self.coeff_h[3, :] = 1 / 18 * xp.array([0.0, 0.0, 4.0, -28.0, 56.0, -8.0]) - self.coeff_h[4, :] = 1 / 18 * xp.array([0.0, 0.0, -1.0, 7.0, -17.0, 23.0]) - - elif self.p == 4: - self.coeff_i[0, :] = 1 / 360 * xp.array([360.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) - self.coeff_i[1, :] = 1 / 360 * xp.array([-59.0, 944.0, -1000.0, 720.0, -305.0, 64.0, -4.0]) - self.coeff_i[2, :] = 1 / 360 * xp.array([23.0, -368.0, 1580.0, -1360.0, 605.0, -128.0, 8.0]) - self.coeff_i[3, :] = 1 / 360 * xp.array([-16.0, 256.0, -1180.0, 2240.0, -1180.0, 256.0, -16.0]) - self.coeff_i[4, :] = 1 / 360 * xp.array([8.0, -128.0, 605.0, -1360.0, 1580.0, -368.0, 23.0]) - self.coeff_i[5, :] = 1 / 360 * xp.array([-4.0, 64.0, -305.0, 720.0, -1000.0, 944.0, -59.0]) - self.coeff_i[6, :] = 1 / 360 * xp.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 360.0]) - - self.coeff_h[0, :] = 1 / 360 * xp.array([419.0, -525.0, 475.0, -245.0, 60.0, -4.0, 0.0, 0.0]) - self.coeff_h[1, :] = 1 / 360 * xp.array([-82.0, 1230.0, -1350.0, 730.0, -180.0, 12.0, 0.0, 0.0]) - self.coeff_h[2, :] = 1 / 360 * xp.array([39.0, -585.0, 2175.0, -1425.0, 360.0, -24.0, 0.0, 0.0]) - self.coeff_h[3, :] = 1 / 360 * xp.array([-16.0, 240.0, -924.0, 1060.0, 1060.0, -924.0, 240.0, -16.0]) - self.coeff_h[4, :] = 1 / 360 * xp.array([0.0, 0.0, -24.0, 360.0, -1425.0, 2175.0, -585.0, 39.0]) - self.coeff_h[5, :] = 1 / 360 * xp.array([0.0, 0.0, 12.0, -180.0, 730.0, -1350.0, 1230.0, -82.0]) - self.coeff_h[6, :] = 1 / 360 * xp.array([0.0, 0.0, -4.0, 60.0, -245.0, 475.0, -525.0, 419.0]) - - else: - print("degree > 4 not implemented!") - - # set interpolation points - n_lambda_int = xp.copy(self.NbaseN) # number of coefficients in space V0 - self.n_int = 2 * self.p - 1 # number of local interpolation points (1, 3, 5, 7, ...) - - if self.p == 1: - self.n_int_locbf_N = 2 # number of non-vanishing N bf in interpolation interval (2, 3, 5, 7, ...) - self.n_int_locbf_D = 1 # number of non-vanishing D bf in interpolation interval (1, 2, 4, 6, ...) - - else: - self.n_int_locbf_N = ( - 2 * self.p - 1 - ) # number of non-vanishing N bf in interpolation interval (2, 3, 5, 7, ...) - self.n_int_locbf_D = ( - 2 * self.p - 2 - ) # number of non-vanishing D bf in interpolation interval (1, 2, 4, 6, ...) - - self.x_int = xp.zeros((n_lambda_int, self.n_int), dtype=float) # interpolation points for each coeff. - - self.int_global_N = xp.zeros( - (n_lambda_int, self.n_int_locbf_N), - dtype=int, - ) # global indices of non-vanishing N bf - self.int_global_D = xp.zeros( - (n_lambda_int, self.n_int_locbf_D), - dtype=int, - ) # global indices of non-vanishing D bf - - self.int_loccof_N = xp.zeros((n_lambda_int, self.n_int_locbf_N), dtype=int) # index of non-vanishing coeff. (N) - self.int_loccof_D = xp.zeros((n_lambda_int, self.n_int_locbf_D), dtype=int) # index of non-vanishing coeff. (D) - - self.x_int_indices = xp.zeros((n_lambda_int, self.n_int), dtype=int) - - self.coeffi_indices = xp.zeros(n_lambda_int, dtype=int) - - if not self.bc: - # maximum number of non-vanishing coefficients - if self.p == 1: - self.n_int_nvcof_D = 2 - self.n_int_nvcof_N = 2 - else: - self.n_int_nvcof_D = 3 * self.p - 3 - self.n_int_nvcof_N = 3 * self.p - 2 - - # shift in local coefficient indices at right boundary (only for non-periodic boundary conditions) - self.int_add_D = xp.arange(self.n_int - 2) + 1 - self.int_add_N = xp.arange(self.n_int - 1) + 1 - - counter_D = 0 - counter_N = 0 - - # shift local coefficients --> global coefficients (D) - if self.p == 1: - self.int_shift_D = xp.arange(self.NbaseD) - else: - self.int_shift_D = xp.arange(self.NbaseD) - (self.p - 2) - self.int_shift_D[: 2 * self.p - 2] = 0 - self.int_shift_D[-(2 * self.p - 2) :] = self.int_shift_D[-(2 * self.p - 2)] - - # shift local coefficients --> global coefficients (N) - if self.p == 1: - self.int_shift_N = xp.arange(self.NbaseN) - self.int_shift_N[-1] = self.int_shift_N[-2] - - else: - self.int_shift_N = xp.arange(self.NbaseN) - (self.p - 1) - self.int_shift_N[: 2 * self.p - 1] = 0 - self.int_shift_N[-(2 * self.p - 1) :] = self.int_shift_N[-(2 * self.p - 1)] - - counter_coeffi = xp.copy(self.p) - - for i in range(n_lambda_int): - # left boundary region - if i < self.p - 1: - self.int_global_N[i] = xp.arange(self.n_int_locbf_N) - self.int_global_D[i] = xp.arange(self.n_int_locbf_D) - - self.x_int_indices[i] = xp.arange(self.n_int) - self.coeffi_indices[i] = i - for j in range(2 * (self.p - 1) + 1): - xi = self.p - 1 - self.x_int[i, j] = (self.T[xi + 1 + int(j / 2)] + self.T[xi + 1 + int((j + 1) / 2)]) / 2 - - # right boundary region - elif i > n_lambda_int - self.p: - self.int_global_N[i] = xp.arange(self.n_int_locbf_N) + n_lambda_int - self.p - (self.p - 1) - self.int_global_D[i] = xp.arange(self.n_int_locbf_D) + n_lambda_int - self.p - (self.p - 1) - - self.x_int_indices[i] = xp.arange(self.n_int) + 2 * (n_lambda_int - self.p - (self.p - 1)) - self.coeffi_indices[i] = counter_coeffi - counter_coeffi += 1 - for j in range(2 * (self.p - 1) + 1): - xi = n_lambda_int - self.p - self.x_int[i, j] = (self.T[xi + 1 + int(j / 2)] + self.T[xi + 1 + int((j + 1) / 2)]) / 2 - - # interior - else: - if self.p == 1: - self.int_global_N[i] = xp.arange(self.n_int_locbf_N) + i - self.int_global_D[i] = xp.arange(self.n_int_locbf_D) + i - - self.int_global_N[-1] = self.int_global_N[-2] - self.int_global_D[-1] = self.int_global_D[-2] - - else: - self.int_global_N[i] = xp.arange(self.n_int_locbf_N) + i - (self.p - 1) - self.int_global_D[i] = xp.arange(self.n_int_locbf_D) + i - (self.p - 1) - - if self.p == 1: - self.x_int_indices[i] = i - else: - self.x_int_indices[i] = xp.arange(self.n_int) + 2 * (i - (self.p - 1)) - - self.coeffi_indices[i] = self.p - 1 - for j in range(2 * (self.p - 1) + 1): - self.x_int[i, j] = (self.T[i + 1 + int(j / 2)] + self.T[i + 1 + int((j + 1) / 2)]) / 2 - - # local coefficient index - if self.p == 1: - self.int_loccof_N[i] = xp.array([0, 1]) - self.int_loccof_D[-1] = xp.array([1]) - - else: - if i > 0: - for il in range(self.n_int_locbf_D): - k_glob_new = self.int_global_D[i, il] - bol = k_glob_new == self.int_global_D[i - 1] - - if xp.any(bol): - self.int_loccof_D[i, il] = self.int_loccof_D[i - 1, xp.where(bol)[0][0]] + 1 - - if (k_glob_new >= n_lambda_int - self.p - (self.p - 2)) and (self.int_loccof_D[i, il] == 0): - self.int_loccof_D[i, il] = self.int_add_D[counter_D] - counter_D += 1 - - for il in range(self.n_int_locbf_N): - k_glob_new = self.int_global_N[i, il] - bol = k_glob_new == self.int_global_N[i - 1] - - if xp.any(bol): - self.int_loccof_N[i, il] = self.int_loccof_N[i - 1, xp.where(bol)[0][0]] + 1 - - if (k_glob_new >= n_lambda_int - self.p - (self.p - 2)) and (self.int_loccof_N[i, il] == 0): - self.int_loccof_N[i, il] = self.int_add_N[counter_N] - counter_N += 1 - - else: - # maximum number of non-vanishing coefficients - if self.p == 1: - self.n_int_nvcof_D = 2 * self.p - 1 - self.n_int_nvcof_N = 2 * self.p - - else: - self.n_int_nvcof_D = 2 * self.p - 2 - self.n_int_nvcof_N = 2 * self.p - 1 - - # shift local coefficients --> global coefficients - if self.p == 1: - self.int_shift_D = xp.arange(self.NbaseN) - (self.p - 1) - self.int_shift_N = xp.arange(self.NbaseN) - (self.p) - else: - self.int_shift_D = xp.arange(self.NbaseN) - (self.p - 2) - self.int_shift_N = xp.arange(self.NbaseN) - (self.p - 1) - - for i in range(n_lambda_int): - # global indices of non-vanishing basis functions and position of coefficients in final matrix - self.int_global_D[i] = (xp.arange(self.n_int_locbf_D) + i - (self.p - 1)) % self.NbaseD - self.int_loccof_D[i] = xp.arange(self.n_int_locbf_D - 1, -1, -1) - - self.int_global_N[i] = (xp.arange(self.n_int_locbf_N) + i - (self.p - 1)) % self.NbaseN - self.int_loccof_N[i] = xp.arange(self.n_int_locbf_N - 1, -1, -1) - - if self.p == 1: - self.x_int_indices[i] = i - else: - self.x_int_indices[i] = xp.arange(self.n_int) + 2 * (i - (self.p - 1)) - - self.coeffi_indices[i] = 0 - - for j in range(2 * (self.p - 1) + 1): - self.x_int[i, j] = ((self.T[i + 1 + int(j / 2)] + self.T[i + 1 + int((j + 1) / 2)]) / 2) % 1.0 - - # set histopolation points, quadrature points and weights - n_lambda_his = xp.copy(self.NbaseD) # number of coefficients in space V1 - - self.n_his = 2 * self.p # number of histopolation intervals (2, 4, 6, 8, ...) - self.n_his_locbf_N = 2 * self.p # number of non-vanishing N bf in histopolation interval (2, 4, 6, 8, ...) - self.n_his_locbf_D = 2 * self.p - 1 # number of non-vanishing D bf in histopolation interval (2, 4, 6, 8, ...) - - self.x_his = xp.zeros((n_lambda_his, self.n_his + 1), dtype=float) # histopolation boundaries - - self.his_global_N = xp.zeros((n_lambda_his, self.n_his_locbf_N), dtype=int) - self.his_global_D = xp.zeros((n_lambda_his, self.n_his_locbf_D), dtype=int) - - self.his_loccof_N = xp.zeros((n_lambda_his, self.n_his_locbf_N), dtype=int) - self.his_loccof_D = xp.zeros((n_lambda_his, self.n_his_locbf_D), dtype=int) - - self.x_his_indices = xp.zeros((n_lambda_his, self.n_his), dtype=int) - - self.coeffh_indices = xp.zeros(n_lambda_his, dtype=int) - - if not self.bc: - # maximum number of non-vanishing coefficients - self.n_his_nvcof_D = 3 * self.p - 2 - self.n_his_nvcof_N = 3 * self.p - 1 - - # shift in local coefficient indices at right boundary (only for non-periodic boundary conditions) - self.his_add_D = xp.arange(self.n_his - 2) + 1 - self.his_add_N = xp.arange(self.n_his - 1) + 1 - - counter_D = 0 - counter_N = 0 - - # shift local coefficients --> global coefficients (D) - self.his_shift_D = xp.arange(self.NbaseD) - (self.p - 1) - self.his_shift_D[: 2 * self.p - 1] = 0 - self.his_shift_D[-(2 * self.p - 1) :] = self.his_shift_D[-(2 * self.p - 1)] - - # shift local coefficients --> global coefficients (N) - self.his_shift_N = xp.arange(self.NbaseN) - self.p - self.his_shift_N[: 2 * self.p] = 0 - self.his_shift_N[-2 * self.p :] = self.his_shift_N[-2 * self.p] - - counter_coeffh = xp.copy(self.p) - - for i in range(n_lambda_his): - # left boundary region - if i < self.p - 1: - self.his_global_N[i] = xp.arange(self.n_his_locbf_N) - self.his_global_D[i] = xp.arange(self.n_his_locbf_D) - - self.x_his_indices[i] = xp.arange(self.n_his) - self.coeffh_indices[i] = i - for j in range(2 * self.p + 1): - xi = self.p - 1 - self.x_his[i, j] = (self.T[xi + 1 + int(j / 2)] + self.T[xi + 1 + int((j + 1) / 2)]) / 2 - - # right boundary region - elif i > n_lambda_his - self.p: - self.his_global_N[i] = xp.arange(self.n_his_locbf_N) + n_lambda_his - self.p - (self.p - 1) - self.his_global_D[i] = xp.arange(self.n_his_locbf_D) + n_lambda_his - self.p - (self.p - 1) - - self.x_his_indices[i] = xp.arange(self.n_his) + 2 * (n_lambda_his - self.p - (self.p - 1)) - self.coeffh_indices[i] = counter_coeffh - counter_coeffh += 1 - for j in range(2 * self.p + 1): - xi = n_lambda_his - self.p - self.x_his[i, j] = (self.T[xi + 1 + int(j / 2)] + self.T[xi + 1 + int((j + 1) / 2)]) / 2 - - # interior - else: - self.his_global_N[i] = xp.arange(self.n_his_locbf_N) + i - (self.p - 1) - self.his_global_D[i] = xp.arange(self.n_his_locbf_D) + i - (self.p - 1) - - self.x_his_indices[i] = xp.arange(self.n_his) + 2 * (i - (self.p - 1)) - self.coeffh_indices[i] = self.p - 1 - for j in range(2 * self.p + 1): - self.x_his[i, j] = (self.T[i + 1 + int(j / 2)] + self.T[i + 1 + int((j + 1) / 2)]) / 2 - - # local coefficient index - if i > 0: - for il in range(self.n_his_locbf_D): - k_glob_new = self.his_global_D[i, il] - bol = k_glob_new == self.his_global_D[i - 1] - - if xp.any(bol): - self.his_loccof_D[i, il] = self.his_loccof_D[i - 1, xp.where(bol)[0][0]] + 1 - - if (k_glob_new >= n_lambda_his - self.p - (self.p - 2)) and (self.his_loccof_D[i, il] == 0): - self.his_loccof_D[i, il] = self.his_add_D[counter_D] - counter_D += 1 - - for il in range(self.n_his_locbf_N): - k_glob_new = self.his_global_N[i, il] - bol = k_glob_new == self.his_global_N[i - 1] - - if xp.any(bol): - self.his_loccof_N[i, il] = self.his_loccof_N[i - 1, xp.where(bol)[0][0]] + 1 - - if (k_glob_new >= n_lambda_his - self.p - (self.p - 2)) and (self.his_loccof_N[i, il] == 0): - self.his_loccof_N[i, il] = self.his_add_N[counter_N] - counter_N += 1 - - # quadrature points and weights - self.pts, self.wts = bsp.quadrature_grid(xp.unique(self.x_his.flatten()), self.pts_loc, self.wts_loc) - - else: - # maximum number of non-vanishing coefficients - self.n_his_nvcof_D = 2 * self.p - 1 - self.n_his_nvcof_N = 2 * self.p - - # shift local coefficients --> global coefficients - self.his_shift_D = xp.arange(self.NbaseD) - (self.p - 1) - self.his_shift_N = xp.arange(self.NbaseD) - self.p - - for i in range(n_lambda_his): - self.his_global_N[i] = (xp.arange(self.n_his_locbf_N) + i - (self.p - 1)) % self.NbaseN - self.his_global_D[i] = (xp.arange(self.n_his_locbf_D) + i - (self.p - 1)) % self.NbaseD - self.his_loccof_N[i] = xp.arange(self.n_his_locbf_N - 1, -1, -1) - self.his_loccof_D[i] = xp.arange(self.n_his_locbf_D - 1, -1, -1) - - self.x_his_indices[i] = xp.arange(self.n_his) + 2 * (i - (self.p - 1)) - self.coeffh_indices[i] = 0 - for j in range(2 * self.p + 1): - self.x_his[i, j] = (self.T[i + 1 + int(j / 2)] + self.T[i + 1 + int((j + 1) / 2)]) / 2 - - # quadrature points and weights - self.pts, self.wts = bsp.quadrature_grid( - xp.append(xp.unique(self.x_his.flatten() % 1.0), 1.0), - self.pts_loc, - self.wts_loc, - ) - - # quasi interpolation - def pi_0(self, fun): - lambdas = xp.zeros(self.NbaseN, dtype=float) - - # evaluate function at interpolation points - mat_f = fun(xp.unique(self.x_int.flatten())) - - for i in range(self.NbaseN): - for j in range(self.n_int): - lambdas[i] += self.coeff_i[self.coeffi_indices[i], j] * mat_f[self.x_int_indices[i, j]] - - return lambdas - - # quasi histopolation - def pi_1(self, fun): - lambdas = xp.zeros(self.NbaseD, dtype=float) - - # evaluate function at quadrature points - mat_f = fun(self.pts) - - for i in range(self.NbaseD): - for j in range(self.n_his): - f_int = 0.0 - - for q in range(self.n_quad): - f_int += self.wts[self.x_his_indices[i, j], q] * mat_f[self.x_his_indices[i, j], q] - - lambdas[i] += self.coeff_h[self.coeffh_indices[i], j] * f_int - - return lambdas - - # projection matrices of products of basis functions: pi0_i(A_j*B_k) and pi1_i(A_j*B_k) - def projection_matrices_1d(self, bc_kind=["free", "free"]): - PI0_NN = xp.empty((self.NbaseN, self.NbaseN, self.NbaseN), dtype=float) - PI0_DN = xp.empty((self.NbaseN, self.NbaseD, self.NbaseN), dtype=float) - PI0_DD = xp.empty((self.NbaseN, self.NbaseD, self.NbaseD), dtype=float) - - PI1_NN = xp.empty((self.NbaseD, self.NbaseN, self.NbaseN), dtype=float) - PI1_DN = xp.empty((self.NbaseD, self.NbaseD, self.NbaseN), dtype=float) - PI1_DD = xp.empty((self.NbaseD, self.NbaseD, self.NbaseD), dtype=float) - - # ========= PI0__NN and PI1_NN ============= - ci = xp.zeros(self.NbaseN, dtype=float) - cj = xp.zeros(self.NbaseN, dtype=float) - - for i in range(self.NbaseN): - for j in range(self.NbaseN): - ci[:] = 0.0 - cj[:] = 0.0 - - ci[i] = 1.0 - cj[j] = 1.0 - - fun = lambda eta: self.space.evaluate_N(eta, ci) * self.space.evaluate_N(eta, cj) - - PI0_NN[:, i, j] = self.pi_0(fun) - PI1_NN[:, i, j] = self.pi_1(fun) - - # ========= PI0__DN and PI1_DN ============= - ci = xp.zeros(self.NbaseD, dtype=float) - cj = xp.zeros(self.NbaseN, dtype=float) - - for i in range(self.NbaseD): - for j in range(self.NbaseN): - ci[:] = 0.0 - cj[:] = 0.0 - - ci[i] = 1.0 - cj[j] = 1.0 - - fun = lambda eta: self.space.evaluate_D(eta, ci) * self.space.evaluate_N(eta, cj) - - PI0_DN[:, i, j] = self.pi_0(fun) - PI1_DN[:, i, j] = self.pi_1(fun) - - # ========= PI0__DD and PI1_DD ============= - ci = xp.zeros(self.NbaseD, dtype=float) - cj = xp.zeros(self.NbaseD, dtype=float) - - for i in range(self.NbaseD): - for j in range(self.NbaseD): - ci[:] = 0.0 - cj[:] = 0.0 - - ci[i] = 1.0 - cj[j] = 1.0 - - fun = lambda eta: self.space.evaluate_D(eta, ci) * self.space.evaluate_D(eta, cj) - - PI0_DD[:, i, j] = self.pi_0(fun) - PI1_DD[:, i, j] = self.pi_1(fun) - - PI0_ND = xp.transpose(PI0_DN, (0, 2, 1)) - PI1_ND = xp.transpose(PI1_DN, (0, 2, 1)) - - # remove contributions from first and last N-splines - if bc_kind[0] == "dirichlet": - PI0_NN[:, :, 0] = 0.0 - PI0_NN[:, 0, :] = 0.0 - PI0_DN[:, :, 0] = 0.0 - PI0_ND[:, 0, :] = 0.0 - - PI1_NN[:, :, 0] = 0.0 - PI1_NN[:, 0, :] = 0.0 - PI1_DN[:, :, 0] = 0.0 - PI1_ND[:, 0, :] = 0.0 - - if bc_kind[1] == "dirichlet": - PI0_NN[:, :, -1] = 0.0 - PI0_NN[:, -1, :] = 0.0 - PI0_DN[:, :, -1] = 0.0 - PI0_ND[:, -1, :] = 0.0 - - PI1_NN[:, :, -1] = 0.0 - PI1_NN[:, -1, :] = 0.0 - PI1_DN[:, :, -1] = 0.0 - PI1_ND[:, -1, :] = 0.0 - - PI0_NN_indices = xp.nonzero(PI0_NN) - PI0_DN_indices = xp.nonzero(PI0_DN) - PI0_ND_indices = xp.nonzero(PI0_ND) - PI0_DD_indices = xp.nonzero(PI0_DD) - - PI1_NN_indices = xp.nonzero(PI1_NN) - PI1_DN_indices = xp.nonzero(PI1_DN) - PI1_ND_indices = xp.nonzero(PI1_ND) - PI1_DD_indices = xp.nonzero(PI1_DD) - - PI0_NN_indices = xp.vstack((PI0_NN_indices[0], PI0_NN_indices[1], PI0_NN_indices[2])) - PI0_DN_indices = xp.vstack((PI0_DN_indices[0], PI0_DN_indices[1], PI0_DN_indices[2])) - PI0_ND_indices = xp.vstack((PI0_ND_indices[0], PI0_ND_indices[1], PI0_ND_indices[2])) - PI0_DD_indices = xp.vstack((PI0_DD_indices[0], PI0_DD_indices[1], PI0_DD_indices[2])) - - PI1_NN_indices = xp.vstack((PI1_NN_indices[0], PI1_NN_indices[1], PI1_NN_indices[2])) - PI1_DN_indices = xp.vstack((PI1_DN_indices[0], PI1_DN_indices[1], PI1_DN_indices[2])) - PI1_ND_indices = xp.vstack((PI1_ND_indices[0], PI1_ND_indices[1], PI1_ND_indices[2])) - PI1_DD_indices = xp.vstack((PI1_DD_indices[0], PI1_DD_indices[1], PI1_DD_indices[2])) - - return ( - PI0_NN, - PI0_DN, - PI0_ND, - PI0_DD, - PI1_NN, - PI1_DN, - PI1_ND, - PI1_DD, - PI0_NN_indices, - PI0_DN_indices, - PI0_ND_indices, - PI0_DD_indices, - PI1_NN_indices, - PI1_DN_indices, - PI1_ND_indices, - PI1_DD_indices, - ) - - -# ======================= 3d ==================================== -class projectors_local_3d: - """ - Local commuting projectors pi_0, pi_1, pi_2 and pi_3 in 3d. - - Parameters - ---------- - tensor_space : Tensor_spline_space - a 3d tensor product space of B-splines - - n_quad : list of ints - number of quadrature points per integration interval for histopolations - """ - - def __init__(self, tensor_space, n_quad): - self.kind = "local" # kind of projector - - self.tensor_space = tensor_space # 3D tensor-product B-splines space - - self.T = tensor_space.T # knot vector - self.p = tensor_space.p # spline degree - self.bc = tensor_space.spl_kind # boundary conditions - self.el_b = tensor_space.el_b # element boundaries - - self.Nel = tensor_space.Nel # number of elements - self.NbaseN = tensor_space.NbaseN # number of basis functions (N) - self.NbaseD = tensor_space.NbaseD # number of basis functions (D) - - self.n_quad = n_quad # number of quadrature point per integration interval - - self.polar = False # local projectors for polar splines are not implemented yet - - # Gauss - Legendre quadrature points and weights in (-1, 1) - self.pts_loc = [xp.polynomial.legendre.leggauss(n_quad)[0] for n_quad in self.n_quad] - self.wts_loc = [xp.polynomial.legendre.leggauss(n_quad)[1] for n_quad in self.n_quad] - - # set interpolation and histopolation coefficients - self.coeff_i = [0, 0, 0] - self.coeff_h = [0, 0, 0] - - for a in range(3): - if self.bc[a]: - self.coeff_i[a] = xp.zeros((1, 2 * self.p[a] - 1), dtype=float) - self.coeff_h[a] = xp.zeros((1, 2 * self.p[a]), dtype=float) - - if self.p[a] == 1: - self.coeff_i[a][0, :] = xp.array([1.0]) - self.coeff_h[a][0, :] = xp.array([1.0, 1.0]) - - elif self.p[a] == 2: - self.coeff_i[a][0, :] = 1 / 2 * xp.array([-1.0, 4.0, -1.0]) - self.coeff_h[a][0, :] = 1 / 2 * xp.array([-1.0, 3.0, 3.0, -1.0]) - - elif self.p[a] == 3: - self.coeff_i[a][0, :] = 1 / 6 * xp.array([1.0, -8.0, 20.0, -8.0, 1.0]) - self.coeff_h[a][0, :] = 1 / 6 * xp.array([1.0, -7.0, 12.0, 12.0, -7.0, 1.0]) - - elif self.p[a] == 4: - self.coeff_i[a][0, :] = 2 / 45 * xp.array([-1.0, 16.0, -295 / 4, 140.0, -295 / 4, 16.0, -1.0]) - self.coeff_h[a][0, :] = ( - 2 / 45 * xp.array([-1.0, 15.0, -231 / 4, 265 / 4, 265 / 4, -231 / 4, 15.0, -1.0]) - ) - - else: - print("degree > 4 not implemented!") - - else: - self.coeff_i[a] = xp.zeros((2 * self.p[a] - 1, 2 * self.p[a] - 1), dtype=float) - self.coeff_h[a] = xp.zeros((2 * self.p[a] - 1, 2 * self.p[a]), dtype=float) - - if self.p[a] == 1: - self.coeff_i[a][0, :] = xp.array([1.0]) - self.coeff_h[a][0, :] = xp.array([1.0, 1.0]) - - elif self.p[a] == 2: - self.coeff_i[a][0, :] = 1 / 2 * xp.array([2.0, 0.0, 0.0]) - self.coeff_i[a][1, :] = 1 / 2 * xp.array([-1.0, 4.0, -1.0]) - self.coeff_i[a][2, :] = 1 / 2 * xp.array([0.0, 0.0, 2.0]) - - self.coeff_h[a][0, :] = 1 / 2 * xp.array([3.0, -1.0, 0.0, 0.0]) - self.coeff_h[a][1, :] = 1 / 2 * xp.array([-1.0, 3.0, 3.0, -1.0]) - self.coeff_h[a][2, :] = 1 / 2 * xp.array([0.0, 0.0, -1.0, 3.0]) - - elif self.p[a] == 3: - self.coeff_i[a][0, :] = 1 / 18 * xp.array([18.0, 0.0, 0.0, 0.0, 0.0]) - self.coeff_i[a][1, :] = 1 / 18 * xp.array([-5.0, 40.0, -24.0, 8.0, -1.0]) - self.coeff_i[a][2, :] = 1 / 18 * xp.array([3.0, -24.0, 60.0, -24.0, 3.0]) - self.coeff_i[a][3, :] = 1 / 18 * xp.array([-1.0, 8.0, -24.0, 40.0, -5.0]) - self.coeff_i[a][4, :] = 1 / 18 * xp.array([0.0, 0.0, 0.0, 0.0, 18.0]) - - self.coeff_h[a][0, :] = 1 / 18 * xp.array([23.0, -17.0, 7.0, -1.0, 0.0, 0.0]) - self.coeff_h[a][1, :] = 1 / 18 * xp.array([-8.0, 56.0, -28.0, 4.0, 0.0, 0.0]) - self.coeff_h[a][2, :] = 1 / 18 * xp.array([3.0, -21.0, 36.0, 36.0, -21.0, 3.0]) - self.coeff_h[a][3, :] = 1 / 18 * xp.array([0.0, 0.0, 4.0, -28.0, 56.0, -8.0]) - self.coeff_h[a][4, :] = 1 / 18 * xp.array([0.0, 0.0, -1.0, 7.0, -17.0, 23.0]) - - elif self.p[a] == 4: - self.coeff_i[a][0, :] = 1 / 360 * xp.array([360.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) - self.coeff_i[a][1, :] = 1 / 360 * xp.array([-59.0, 944.0, -1000.0, 720.0, -305.0, 64.0, -4.0]) - self.coeff_i[a][2, :] = 1 / 360 * xp.array([23.0, -368.0, 1580.0, -1360.0, 605.0, -128.0, 8.0]) - self.coeff_i[a][3, :] = 1 / 360 * xp.array([-16.0, 256.0, -1180.0, 2240.0, -1180.0, 256.0, -16.0]) - self.coeff_i[a][4, :] = 1 / 360 * xp.array([8.0, -128.0, 605.0, -1360.0, 1580.0, -368.0, 23.0]) - self.coeff_i[a][5, :] = 1 / 360 * xp.array([-4.0, 64.0, -305.0, 720.0, -1000.0, 944.0, -59.0]) - self.coeff_i[a][6, :] = 1 / 360 * xp.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 360.0]) - - self.coeff_h[a][0, :] = 1 / 360 * xp.array([419.0, -525.0, 475.0, -245.0, 60.0, -4.0, 0.0, 0.0]) - self.coeff_h[a][1, :] = 1 / 360 * xp.array([-82.0, 1230.0, -1350.0, 730.0, -180.0, 12.0, 0.0, 0.0]) - self.coeff_h[a][2, :] = 1 / 360 * xp.array([39.0, -585.0, 2175.0, -1425.0, 360.0, -24.0, 0.0, 0.0]) - self.coeff_h[a][3, :] = ( - 1 / 360 * xp.array([-16.0, 240.0, -924.0, 1060.0, 1060.0, -924.0, 240.0, -16.0]) - ) - self.coeff_h[a][4, :] = 1 / 360 * xp.array([0.0, 0.0, -24.0, 360.0, -1425.0, 2175.0, -585.0, 39.0]) - self.coeff_h[a][5, :] = 1 / 360 * xp.array([0.0, 0.0, 12.0, -180.0, 730.0, -1350.0, 1230.0, -82.0]) - self.coeff_h[a][6, :] = 1 / 360 * xp.array([0.0, 0.0, -4.0, 60.0, -245.0, 475.0, -525.0, 419.0]) - - else: - print("degree > 4 not implemented!") - - # set interpolation points - n_lambda_int = [NbaseN for NbaseN in self.NbaseN] # number of coefficients in space V0 - self.n_int = [2 * p - 1 for p in self.p] # number of interpolation points (1, 3, 5, 7, ...) - - self.n_int_locbf_N = [0, 0, 0] - self.n_int_locbf_D = [0, 0, 0] - - for a in range(3): - if self.p[a] == 1: - self.n_int_locbf_N[a] = 2 # number of non-vanishing N bf in interpolation interval (2, 3, 5, 7) - self.n_int_locbf_D[a] = 1 # number of non-vanishing D bf in interpolation interval (1, 2, 4, 6) - - else: - self.n_int_locbf_N[a] = ( - 2 * self.p[a] - 1 - ) # number of non-vanishing N bf in interpolation interval (2, 3, 5, 7) - self.n_int_locbf_D[a] = ( - 2 * self.p[a] - 2 - ) # number of non-vanishing D bf in interpolation interval (1, 2, 4, 6) - - self.x_int = [ - xp.zeros((n_lambda_int, n_int), dtype=float) for n_lambda_int, n_int in zip(n_lambda_int, self.n_int) - ] - - self.int_global_N = [ - xp.zeros((n_lambda_int, n_int_locbf_N), dtype=int) - for n_lambda_int, n_int_locbf_N in zip(n_lambda_int, self.n_int_locbf_N) - ] - self.int_global_D = [ - xp.zeros((n_lambda_int, n_int_locbf_D), dtype=int) - for n_lambda_int, n_int_locbf_D in zip(n_lambda_int, self.n_int_locbf_D) - ] - - self.int_loccof_N = [ - xp.zeros((n_lambda_int, n_int_locbf_N), dtype=int) - for n_lambda_int, n_int_locbf_N in zip(n_lambda_int, self.n_int_locbf_N) - ] - self.int_loccof_D = [ - xp.zeros((n_lambda_int, n_int_locbf_D), dtype=int) - for n_lambda_int, n_int_locbf_D in zip(n_lambda_int, self.n_int_locbf_D) - ] - - self.x_int_indices = [ - xp.zeros((n_lambda_int, n_int), dtype=int) for n_lambda_int, n_int in zip(n_lambda_int, self.n_int) - ] - self.coeffi_indices = [xp.zeros(n_lambda_int, dtype=int) for n_lambda_int in n_lambda_int] - - self.n_int_nvcof_D = [None, None, None] - self.n_int_nvcof_N = [None, None, None] - - self.int_add_D = [None, None, None] - self.int_add_N = [None, None, None] - - self.int_shift_D = [0, 0, 0] - self.int_shift_N = [0, 0, 0] - - for a in range(3): - if not self.bc[a]: - # maximum number of non-vanishing coefficients - if self.p[a] == 1: - self.n_int_nvcof_D[a] = 2 - self.n_int_nvcof_N[a] = 2 - - else: - self.n_int_nvcof_D[a] = 3 * self.p[a] - 3 - self.n_int_nvcof_N[a] = 3 * self.p[a] - 2 - - # shift in local coefficient indices at right boundary (only for non-periodic boundary conditions) - self.int_add_D[a] = xp.arange(self.n_int[a] - 2) + 1 - self.int_add_N[a] = xp.arange(self.n_int[a] - 1) + 1 - - counter_D = 0 - counter_N = 0 - - # shift local coefficients --> global coefficients (D) - if self.p[a] == 1: - self.int_shift_D[a] = xp.arange(self.NbaseD[a]) - else: - self.int_shift_D[a] = xp.arange(self.NbaseD[a]) - (self.p[a] - 2) - self.int_shift_D[a][: 2 * self.p[a] - 2] = 0 - self.int_shift_D[a][-(2 * self.p[a] - 2) :] = self.int_shift_D[a][-(2 * self.p[a] - 2)] - - # shift local coefficients --> global coefficients (N) - if self.p[a] == 1: - self.int_shift_N[a] = xp.arange(self.NbaseN[a]) - self.int_shift_N[a][-1] = self.int_shift_N[a][-2] - - else: - self.int_shift_N[a] = xp.arange(self.NbaseN[a]) - (self.p[a] - 1) - self.int_shift_N[a][: 2 * self.p[a] - 1] = 0 - self.int_shift_N[a][-(2 * self.p[a] - 1) :] = self.int_shift_N[a][-(2 * self.p[a] - 1)] - - counter_coeffi = xp.copy(self.p[a]) - - for i in range(n_lambda_int[a]): - # left boundary region - if i < self.p[a] - 1: - self.int_global_N[a][i] = xp.arange(self.n_int_locbf_N[a]) - self.int_global_D[a][i] = xp.arange(self.n_int_locbf_D[a]) - - self.x_int_indices[a][i] = xp.arange(self.n_int[a]) - self.coeffi_indices[a][i] = i - for j in range(2 * (self.p[a] - 1) + 1): - xi = self.p[a] - 1 - self.x_int[a][i, j] = ( - self.T[a][xi + 1 + int(j / 2)] + self.T[a][xi + 1 + int((j + 1) / 2)] - ) / 2 - - # right boundary region - elif i > n_lambda_int[a] - self.p[a]: - self.int_global_N[a][i] = ( - xp.arange(self.n_int_locbf_N[a]) + n_lambda_int[a] - self.p[a] - (self.p[a] - 1) - ) - self.int_global_D[a][i] = ( - xp.arange(self.n_int_locbf_D[a]) + n_lambda_int[a] - self.p[a] - (self.p[a] - 1) - ) - - self.x_int_indices[a][i] = xp.arange(self.n_int[a]) + 2 * ( - n_lambda_int[a] - self.p[a] - (self.p[a] - 1) - ) - self.coeffi_indices[a][i] = counter_coeffi - counter_coeffi += 1 - for j in range(2 * (self.p[a] - 1) + 1): - xi = n_lambda_int[a] - self.p[a] - self.x_int[a][i, j] = ( - self.T[a][xi + 1 + int(j / 2)] + self.T[a][xi + 1 + int((j + 1) / 2)] - ) / 2 - - # interior - else: - if self.p[a] == 1: - self.int_global_N[a][i] = xp.arange(self.n_int_locbf_N[a]) + i - self.int_global_D[a][i] = xp.arange(self.n_int_locbf_D[a]) + i - - self.int_global_N[a][-1] = self.int_global_N[a][-2] - self.int_global_D[a][-1] = self.int_global_D[a][-2] - - else: - self.int_global_N[a][i] = xp.arange(self.n_int_locbf_N[a]) + i - (self.p[a] - 1) - self.int_global_D[a][i] = xp.arange(self.n_int_locbf_D[a]) + i - (self.p[a] - 1) - - if self.p[a] == 1: - self.x_int_indices[a][i] = i - else: - self.x_int_indices[a][i] = xp.arange(self.n_int[a]) + 2 * (i - (self.p[a] - 1)) - - self.coeffi_indices[a][i] = self.p[a] - 1 - - for j in range(2 * (self.p[a] - 1) + 1): - self.x_int[a][i, j] = ( - self.T[a][i + 1 + int(j / 2)] + self.T[a][i + 1 + int((j + 1) / 2)] - ) / 2 - - # local coefficient index - if self.p[a] == 1: - self.int_loccof_N[a][i] = xp.array([0, 1]) - self.int_loccof_D[a][-1] = xp.array([1]) - - else: - if i > 0: - for il in range(self.n_int_locbf_D[a]): - k_glob_new = self.int_global_D[a][i, il] - bol = k_glob_new == self.int_global_D[a][i - 1] - - if xp.any(bol): - self.int_loccof_D[a][i, il] = self.int_loccof_D[a][i - 1, xp.where(bol)[0][0]] + 1 - - if (k_glob_new >= n_lambda_int[a] - self.p[a] - (self.p[a] - 2)) and ( - self.int_loccof_D[a][i, il] == 0 - ): - self.int_loccof_D[a][i, il] = self.int_add_D[a][counter_D] - counter_D += 1 - - for il in range(self.n_int_locbf_N[a]): - k_glob_new = self.int_global_N[a][i, il] - bol = k_glob_new == self.int_global_N[a][i - 1] - - if xp.any(bol): - self.int_loccof_N[a][i, il] = self.int_loccof_N[a][i - 1, xp.where(bol)[0][0]] + 1 - - if (k_glob_new >= n_lambda_int[a] - self.p[a] - (self.p[a] - 2)) and ( - self.int_loccof_N[a][i, il] == 0 - ): - self.int_loccof_N[a][i, il] = self.int_add_N[a][counter_N] - counter_N += 1 - - else: - # maximum number of non-vanishing coefficients - if self.p[a] == 1: - self.n_int_nvcof_D[a] = 2 * self.p[a] - 1 - self.n_int_nvcof_N[a] = 2 * self.p[a] - - else: - self.n_int_nvcof_D[a] = 2 * self.p[a] - 2 - self.n_int_nvcof_N[a] = 2 * self.p[a] - 1 - - # shift local coefficients --> global coefficients - if self.p[a] == 1: - self.int_shift_D[a] = xp.arange(self.NbaseN[a]) - (self.p[a] - 1) - self.int_shift_N[a] = xp.arange(self.NbaseN[a]) - (self.p[a]) - else: - self.int_shift_D[a] = xp.arange(self.NbaseN[a]) - (self.p[a] - 2) - self.int_shift_N[a] = xp.arange(self.NbaseN[a]) - (self.p[a] - 1) - - for i in range(n_lambda_int[a]): - # global indices of non-vanishing basis functions and position of coefficients in final matrix - self.int_global_N[a][i] = (xp.arange(self.n_int_locbf_N[a]) + i - (self.p[a] - 1)) % self.NbaseN[a] - self.int_global_D[a][i] = (xp.arange(self.n_int_locbf_D[a]) + i - (self.p[a] - 1)) % self.NbaseD[a] - - self.int_loccof_N[a][i] = xp.arange(self.n_int_locbf_N[a] - 1, -1, -1) - self.int_loccof_D[a][i] = xp.arange(self.n_int_locbf_D[a] - 1, -1, -1) - - if self.p[a] == 1: - self.x_int_indices[a][i] = i - else: - self.x_int_indices[a][i] = (xp.arange(self.n_int[a]) + 2 * (i - (self.p[a] - 1))) % ( - 2 * self.Nel[a] - ) - - self.coeffi_indices[a][i] = 0 - - for j in range(2 * (self.p[a] - 1) + 1): - self.x_int[a][i, j] = ( - (self.T[a][i + 1 + int(j / 2)] + self.T[a][i + 1 + int((j + 1) / 2)]) / 2 - ) % 1.0 - - # set histopolation points, quadrature points and weights - n_lambda_his = [xp.copy(NbaseD) for NbaseD in self.NbaseD] # number of coefficients in space V1 - - self.n_his = [2 * p for p in self.p] # number of histopolation intervals - self.n_his_locbf_N = [2 * p for p in self.p] # number of non-vanishing N bf in histopolation interval - self.n_his_locbf_D = [2 * p - 1 for p in self.p] # number of non-vanishing D bf in histopolation interval - - self.x_his = [ - xp.zeros((n_lambda_his, n_his + 1), dtype=float) for n_lambda_his, n_his in zip(n_lambda_his, self.n_his) - ] - - self.his_global_N = [ - xp.zeros((n_lambda_his, n_his_locbf_N), dtype=int) - for n_lambda_his, n_his_locbf_N in zip(n_lambda_his, self.n_his_locbf_N) - ] - self.his_global_D = [ - xp.zeros((n_lambda_his, n_his_locbf_D), dtype=int) - for n_lambda_his, n_his_locbf_D in zip(n_lambda_his, self.n_his_locbf_D) - ] - - self.his_loccof_N = [ - xp.zeros((n_lambda_his, n_his_locbf_N), dtype=int) - for n_lambda_his, n_his_locbf_N in zip(n_lambda_his, self.n_his_locbf_N) - ] - self.his_loccof_D = [ - xp.zeros((n_lambda_his, n_his_locbf_D), dtype=int) - for n_lambda_his, n_his_locbf_D in zip(n_lambda_his, self.n_his_locbf_D) - ] - - self.x_his_indices = [ - xp.zeros((n_lambda_his, n_his), dtype=int) for n_lambda_his, n_his in zip(n_lambda_his, self.n_his) - ] - self.coeffh_indices = [xp.zeros(n_lambda_his, dtype=int) for n_lambda_his in n_lambda_his] - - self.pts = [0, 0, 0] - self.wts = [0, 0, 0] - - self.n_his_nvcof_D = [None, None, None] - self.n_his_nvcof_N = [None, None, None] - - self.his_add_D = [None, None, None] - self.his_add_N = [None, None, None] - - self.his_shift_D = [0, 0, 0] - self.his_shift_N = [0, 0, 0] - - for a in range(3): - if not self.bc[a]: - # maximum number of non-vanishing coefficients - self.n_his_nvcof_D[a] = 3 * self.p[a] - 2 - self.n_his_nvcof_N[a] = 3 * self.p[a] - 1 - - # shift in local coefficient indices at right boundary (only for non-periodic boundary conditions) - self.his_add_D[a] = xp.arange(self.n_his[a] - 2) + 1 - self.his_add_N[a] = xp.arange(self.n_his[a] - 1) + 1 - - counter_D = 0 - counter_N = 0 - - # shift local coefficients --> global coefficients (D) - self.his_shift_D[a] = xp.arange(self.NbaseD[a]) - (self.p[a] - 1) - self.his_shift_D[a][: 2 * self.p[a] - 1] = 0 - self.his_shift_D[a][-(2 * self.p[a] - 1) :] = self.his_shift_D[a][-(2 * self.p[a] - 1)] - - # shift local coefficients --> global coefficients (N) - self.his_shift_N[a] = xp.arange(self.NbaseN[a]) - self.p[a] - self.his_shift_N[a][: 2 * self.p[a]] = 0 - self.his_shift_N[a][-2 * self.p[a] :] = self.his_shift_N[a][-2 * self.p[a]] - - counter_coeffh = xp.copy(self.p[a]) - - for i in range(n_lambda_his[a]): - # left boundary region - if i < self.p[a] - 1: - self.his_global_N[a][i] = xp.arange(self.n_his_locbf_N[a]) - self.his_global_D[a][i] = xp.arange(self.n_his_locbf_D[a]) - - self.x_his_indices[a][i] = xp.arange(self.n_his[a]) - self.coeffh_indices[a][i] = i - for j in range(2 * self.p[a] + 1): - xi = self.p[a] - 1 - self.x_his[a][i, j] = ( - self.T[a][xi + 1 + int(j / 2)] + self.T[a][xi + 1 + int((j + 1) / 2)] - ) / 2 - - # right boundary region - elif i > n_lambda_his[a] - self.p[a]: - self.his_global_N[a][i] = ( - xp.arange(self.n_his_locbf_N[a]) + n_lambda_his[a] - self.p[a] - (self.p[a] - 1) - ) - self.his_global_D[a][i] = ( - xp.arange(self.n_his_locbf_D[a]) + n_lambda_his[a] - self.p[a] - (self.p[a] - 1) - ) - - self.x_his_indices[a][i] = xp.arange(self.n_his[a]) + 2 * ( - n_lambda_his[a] - self.p[a] - (self.p[a] - 1) - ) - self.coeffh_indices[a][i] = counter_coeffh - counter_coeffh += 1 - for j in range(2 * self.p[a] + 1): - xi = n_lambda_his[a] - self.p[a] - self.x_his[a][i, j] = ( - self.T[a][xi + 1 + int(j / 2)] + self.T[a][xi + 1 + int((j + 1) / 2)] - ) / 2 - - # interior - else: - self.his_global_N[a][i] = xp.arange(self.n_his_locbf_N[a]) + i - (self.p[a] - 1) - self.his_global_D[a][i] = xp.arange(self.n_his_locbf_D[a]) + i - (self.p[a] - 1) - - self.x_his_indices[a][i] = xp.arange(self.n_his[a]) + 2 * (i - (self.p[a] - 1)) - self.coeffh_indices[a][i] = self.p[a] - 1 - for j in range(2 * self.p[a] + 1): - self.x_his[a][i, j] = ( - self.T[a][i + 1 + int(j / 2)] + self.T[a][i + 1 + int((j + 1) / 2)] - ) / 2 - - # local coefficient index - if i > 0: - for il in range(self.n_his_locbf_D[a]): - k_glob_new = self.his_global_D[a][i, il] - bol = k_glob_new == self.his_global_D[a][i - 1] - - if xp.any(bol): - self.his_loccof_D[a][i, il] = self.his_loccof_D[a][i - 1, xp.where(bol)[0][0]] + 1 - - if (k_glob_new >= n_lambda_his[a] - self.p[a] - (self.p[a] - 2)) and ( - self.his_loccof_D[a][i, il] == 0 - ): - self.his_loccof_D[a][i, il] = self.his_add_D[a][counter_D] - counter_D += 1 - - for il in range(self.n_his_locbf_N[a]): - k_glob_new = self.his_global_N[a][i, il] - bol = k_glob_new == self.his_global_N[a][i - 1] - - if xp.any(bol): - self.his_loccof_N[a][i, il] = self.his_loccof_N[a][i - 1, xp.where(bol)[0][0]] + 1 - - if (k_glob_new >= n_lambda_his[a] - self.p[a] - (self.p[a] - 2)) and ( - self.his_loccof_N[a][i, il] == 0 - ): - self.his_loccof_N[a][i, il] = self.his_add_N[a][counter_N] - counter_N += 1 - - # quadrature points and weights - self.pts[a], self.wts[a] = bsp.quadrature_grid( - xp.unique(self.x_his[a].flatten()), - self.pts_loc[a], - self.wts_loc[a], - ) - - else: - # maximum number of non-vanishing coefficients - self.n_his_nvcof_D[a] = 2 * self.p[a] - 1 - self.n_his_nvcof_N[a] = 2 * self.p[a] - - # shift local coefficients --> global coefficients (D) - self.his_shift_D[a] = xp.arange(self.NbaseD[a]) - (self.p[a] - 1) - - # shift local coefficients --> global coefficients (N) - self.his_shift_N[a] = xp.arange(self.NbaseD[a]) - self.p[a] - - for i in range(n_lambda_his[a]): - self.his_global_N[a][i] = (xp.arange(self.n_his_locbf_N[a]) + i - (self.p[a] - 1)) % self.NbaseN[a] - self.his_global_D[a][i] = (xp.arange(self.n_his_locbf_D[a]) + i - (self.p[a] - 1)) % self.NbaseD[a] - self.his_loccof_N[a][i] = xp.arange(self.n_his_locbf_N[a] - 1, -1, -1) - self.his_loccof_D[a][i] = xp.arange(self.n_his_locbf_D[a] - 1, -1, -1) - - self.x_his_indices[a][i] = (xp.arange(self.n_his[a]) + 2 * (i - (self.p[a] - 1))) % ( - 2 * self.Nel[a] - ) - self.coeffh_indices[a][i] = 0 - - for j in range(2 * self.p[a] + 1): - self.x_his[a][i, j] = (self.T[a][i + 1 + int(j / 2)] + self.T[a][i + 1 + int((j + 1) / 2)]) / 2 - - # quadrature points and weights - self.pts[a], self.wts[a] = bsp.quadrature_grid( - xp.append(xp.unique(self.x_his[a].flatten() % 1.0), 1.0), - self.pts_loc[a], - self.wts_loc[a], - ) - - # projector on space V0 (interpolation) - def pi_0(self, fun, include_bc=True, eval_kind="meshgrid"): - """ - Local projector on the discrete space V0. - - Parameters - ---------- - fun : callable - the function (0-form) to be projected. - - include_bc : boolean - whether the boundary coefficients in the first logical direction are included - - eval_kind : string - kind of evaluation of function at interpolation/quadrature points ('meshgrid', 'tensor_product', 'point_wise') - - Returns - ------- - lambdas : array_like - the coefficients in V0 corresponding to the projected function - """ - - # interpolation points - x_int1 = xp.unique(self.x_int[0].flatten()) - x_int2 = xp.unique(self.x_int[1].flatten()) - x_int3 = xp.unique(self.x_int[2].flatten()) - - # evaluation of function at interpolation points - mat_f = xp.empty((x_int1.size, x_int2.size, x_int3.size), dtype=float) - - # external function call if a callable is passed - if callable(fun): - # create a meshgrid and evaluate function on point set - if eval_kind == "meshgrid": - pts1, pts2, pts3 = xp.meshgrid(x_int1, x_int2, x_int3, indexing="ij") - mat_f[:, :, :] = fun(pts1, pts2, pts3) - - # tensor-product evaluation is done by input function - elif eval_kind == "tensor_product": - mat_f[:, :, :] = fun(x_int1, x_int2, x_int3) - - # point-wise evaluation - else: - for i1 in range(x_int1.size): - for i2 in range(x_int2.size): - for i3 in range(x_int3.size): - mat_f[i1, i2, i3] = fun(x_int1[i1], x_int2[i2], x_int3[i3]) - - # internal function call - else: - print("no internal 3D function implemented!") - - # coefficients - lambdas = xp.zeros((self.NbaseN[0], self.NbaseN[1], self.NbaseN[2]), dtype=float) - - ker_loc.kernel_pi0_3d( - self.NbaseN, - self.p, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeffi_indices[0], - self.coeffi_indices[1], - self.coeffi_indices[2], - self.x_int_indices[0], - self.x_int_indices[1], - self.x_int_indices[2], - mat_f, - lambdas, - ) - - return lambdas.flatten() - - # projector on space V1 ([histo, inter, inter], [inter, histo, inter], [inter, inter, histo]) - def pi_1(self, fun, include_bc=True, eval_kind="meshgrid"): - """ - Local projector on the discrete space V1. - - Parameters - ---------- - fun : list of callables - the function (1-form) to be projected - - include_bc : boolean - whether the boundary coefficients in the first logical direction are included - - eval_kind : string - kind of evaluation of function at interpolation/quadrature points ('meshgrid', 'tensor_product', 'point_wise') - - Returns - ------- - lambdas : list of array_like - the coefficients in V1 corresponding to the projected function - """ - - # interpolation points - x_int1 = xp.unique(self.x_int[0].flatten()) - x_int2 = xp.unique(self.x_int[1].flatten()) - x_int3 = xp.unique(self.x_int[2].flatten()) - - # ======== 1-component ======== - - # evaluation of function at interpolation/quadrature points - mat_f = xp.empty((self.pts[0].flatten().size, x_int2.size, x_int3.size), dtype=float) - - # external function call if a callable is passed - if callable(fun[0]): - # create a meshgrid and evaluate function on point set - if eval_kind == "meshgrid": - pts1, pts2, pts3 = xp.meshgrid(self.pts[0].flatten(), x_int2, x_int3, indexing="ij") - mat_f[:, :, :] = fun[0](pts1, pts2, pts3) - - # tensor-product evaluation is done by input function - elif eval_kind == "tensor_product": - mat_f[:, :, :] = fun[0](self.pts[0].flatten(), x_int2, x_int3) - - # point-wise evaluation - else: - for i1 in range(self.pts[0].size): - for i2 in range(x_int2.size): - for i3 in range(x_int3.size): - mat_f[i1, i2, i3] = fun[0](self.pts[0].flatten()[i1], x_int2[i2], x_int3[i3]) - - # internal function call - else: - print("no internal 3D function implemented!") - - # compute coefficients - lambdas1 = xp.zeros((self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]), dtype=float) - - ker_loc.kernel_pi11_3d( - [self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]], - self.p, - self.n_quad, - self.coeff_h[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffi_indices[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_int_indices[2], - self.wts[0], - mat_f.reshape(self.pts[0].shape[0], self.pts[0].shape[1], x_int2.size, x_int3.size), - lambdas1, - ) - - # ======== 2-component ======== - - # evaluation of function at interpolation/quadrature points - mat_f = xp.empty((x_int1.size, self.pts[1].flatten().size, x_int3.size), dtype=float) - - # external function call if a callable is passed - if callable(fun[1]): - # create a meshgrid and evaluate function on point set - if eval_kind == "meshgrid": - pts1, pts2, pts3 = xp.meshgrid(x_int1, self.pts[1].flatten(), x_int3, indexing="ij") - mat_f[:, :, :] = fun[1](pts1, pts2, pts3) - - # tensor-product evaluation is done by input function - elif eval_kind == "tensor_product": - mat_f[:, :, :] = fun[1](x_int1, self.pts[1].flatten(), x_int3) - - # point-wise evaluation - else: - for i1 in range(x_int1.size): - for i2 in range(self.pts[1].size): - for i3 in range(x_int3.size): - mat_f[i1, i2, i3] = fun[1](x_int1[i1], self.pts[1].flatten()[i2], x_int3[i3]) - - # internal function call - else: - print("no internal 3D function implemented!") - - # compute coefficients - lambdas2 = xp.zeros((self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]), dtype=float) - - ker_loc.kernel_pi12_3d( - [self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]], - self.p, - self.n_quad, - self.coeff_i[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[1], - mat_f.reshape(x_int1.size, self.pts[1].shape[0], self.pts[1].shape[1], x_int3.size), - lambdas2, - ) - - # ======== 3-component ======== - - # evaluation of function at interpolation/quadrature points - mat_f = xp.empty((x_int1.size, x_int1.size, self.pts[2].flatten().size), dtype=float) - - # external function call if a callable is passed - if callable(fun[2]): - # create a meshgrid and evaluate function on point set - if eval_kind == "meshgrid": - pts1, pts2, pts3 = xp.meshgrid(x_int1, x_int2, self.pts[2].flatten(), indexing="ij") - mat_f[:, :, :] = fun[2](pts1, pts2, pts3) - - # tensor-product evaluation is done by input function - elif eval_kind == "tensor_product": - mat_f[:, :, :] = fun[2](x_int1, x_int2, self.pts[2].flatten()) - - # point-wise evaluation - else: - for i1 in range(x_int1.size): - for i2 in range(xint2.size): - for i3 in range(self.pts[2].size): - mat_f[i1, i2, i3] = fun[2](x_int1[i1], x_int2[i2], self.pts[2].flatten()[i3]) - - # internal function call - else: - print("no internal 3D function implemented!") - - # compute coefficients - lambdas3 = xp.zeros((self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]), dtype=float) - - ker_loc.kernel_pi13_3d( - [self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]], - self.p, - self.n_quad, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.x_int_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[2], - mat_f.reshape(x_int1.size, x_int2.size, self.pts[2][:, 0].shape[0], self.pts[2].shape[1]), - lambdas3, - ) - - return xp.concatenate((lambdas1.flatten(), lambdas2.flatten(), lambdas3.flatten())) - - # projector on space V1 ([inter, histo, histo], [histo, inter, histo], [histo, histo, inter]) - def pi_2(self, fun, include_bc=True, eval_kind="meshgrid"): - """ - Local projector on the discrete space V2. - - Parameters - ---------- - fun : list of callables - the function (2-form) to be projected - - include_bc : boolean - whether the boundary coefficients in the first logical direction are included - - eval_kind : string - kind of evaluation of function at interpolation/quadrature points ('meshgrid', 'tensor_product', 'point_wise') - - Returns - ------- - lambdas : list of array_like - the coefficients in V2 corresponding to the projected function - """ - - # interpolation points - x_int1 = xp.unique(self.x_int[0].flatten()) - x_int2 = xp.unique(self.x_int[1].flatten()) - x_int3 = xp.unique(self.x_int[2].flatten()) - - # ======== 1-component ======== - - # evaluation of function at interpolation/quadrature points - mat_f = xp.empty((x_int1.size, self.pts[1].flatten().size, self.pts[2].flatten().size), dtype=float) - - # external function call if a callable is passed - if callable(fun[0]): - # create a meshgrid and evaluate function on point set - if eval_kind == "meshgrid": - pts1, pts2, pts3 = xp.meshgrid(x_int1, self.pts[1].flatten(), self.pts[2].flatten(), indexing="ij") - mat_f[:, :, :] = fun[0](pts1, pts2, pts3) - - # tensor-product evaluation is done by input function - elif eval_kind == "tensor_product": - mat_f[:, :, :] = fun[0](x_int1, self.pts[1].flatten(), self.pts[2].flatten()) - - # point-wise evaluation - else: - for i1 in range(x_int1.size): - for i2 in range(self.pts[1].size): - for i3 in range(self.pts[2].size): - mat_f[i1, i2, i3] = fun[0](x_int1[i1], self.pts[1].flatten()[i2], self.pts[2].flatten()[i3]) - - # internal function call - else: - print("no internal 3D function implemented!") - - # compute coefficients - lambdas1 = xp.zeros((self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]), dtype=float) - - ker_loc.kernel_pi21_3d( - [self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]], - self.p, - self.n_quad, - self.coeff_i[0], - self.coeff_h[1], - self.coeff_h[2], - self.coeffi_indices[0], - self.coeffh_indices[1], - self.coeffh_indices[2], - self.x_int_indices[0], - self.x_his_indices[1], - self.x_his_indices[2], - self.wts[1], - self.wts[2], - mat_f.reshape( - x_int1.size, - self.pts[1].shape[0], - self.pts[1].shape[1], - self.pts[2].shape[0], - self.pts[2].shape[1], - ), - lambdas1, - ) - - # ======== 2-component ======== - - # evaluation of function at interpolation/quadrature points - mat_f = xp.empty((self.pts[0].flatten().size, x_int2.size, self.pts[2].flatten().size), dtype=float) - - # external function call if a callable is passed - if callable(fun[1]): - # create a meshgrid and evaluate function on point set - if eval_kind == "meshgrid": - pts1, pts2, pts3 = xp.meshgrid(self.pts[0].flatten(), x_int2, self.pts[2].flatten(), indexing="ij") - mat_f[:, :, :] = fun[1](pts1, pts2, pts3) - - # tensor-product evaluation is done by input function - elif eval_kind == "tensor_product": - mat_f[:, :, :] = fun[1](self.pts[0].flatten(), x_int2, self.pts[2].flatten()) - - # point-wise evaluation - else: - for i1 in range(self.pts[0].size): - for i2 in range(x_int2.size): - for i3 in range(self.pts[2].size): - mat_f[i1, i2, i3] = fun[1](self.pts[0].flatten()[i1], x_int2[i2], self.pts[2].flatten()[i3]) - - # internal function call - else: - print("no internal 3D function implemented!") - - # compute coefficients - lambdas2 = xp.zeros((self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]), dtype=float) - - ker_loc.kernel_pi22_3d( - [self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]], - self.p, - self.n_quad, - self.coeff_h[0], - self.coeff_i[1], - self.coeff_h[2], - self.coeffh_indices[0], - self.coeffi_indices[1], - self.coeffh_indices[2], - self.x_his_indices[0], - self.x_int_indices[1], - self.x_his_indices[2], - self.wts[0], - self.wts[2], - mat_f.reshape( - self.pts[0].shape[0], - self.pts[0].shape[1], - x_int2.size, - self.pts[2].shape[0], - self.pts[2].shape[1], - ), - lambdas2, - ) - - # ======== 3-component ======== - - # evaluation of function at interpolation/quadrature points - mat_f = xp.empty((self.pts[0].flatten().size, self.pts[1].flatten().size, x_int3.size), dtype=float) - - # external function call if a callable is passed - if callable(fun[2]): - # create a meshgrid and evaluate function on point set - if eval_kind == "meshgrid": - pts1, pts2, pts3 = xp.meshgrid(self.pts[0].flatten(), self.pts[1].flatten(), x_int3, indexing="ij") - mat_f[:, :, :] = fun[2](pts1, pts2, pts3) - - # tensor-product evaluation is done by input function - elif eval_kind == "tensor_product": - mat_f[:, :, :] = fun[2](self.pts[0].flatten(), self.pts[1].flatten(), x_int3) - - # point-wise evaluation - else: - for i1 in range(self.pts[0].size): - for i2 in range(self.pts[1].size): - for i3 in range(x_int3.size): - mat_f[i1, i2, i3] = fun[2](self.pts[0].flatten()[i1], self.pts[1].flatten()[i2], x_int3[i3]) - - # internal function call - else: - print("no internal 3D function implemented!") - - # compute coefficients - lambdas3 = xp.zeros((self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]), dtype=float) - - ker_loc.kernel_pi23_3d( - [self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]], - self.p, - self.n_quad, - self.coeff_h[0], - self.coeff_h[1], - self.coeff_i[2], - self.coeffh_indices[0], - self.coeffh_indices[1], - self.coeffi_indices[2], - self.x_his_indices[0], - self.x_his_indices[1], - self.x_int_indices[2], - self.wts[0], - self.wts[1], - mat_f.reshape( - self.pts[0].shape[0], - self.pts[0].shape[1], - self.pts[1].shape[0], - self.pts[1].shape[1], - x_int3.size, - ), - lambdas3, - ) - - return xp.concatenate((lambdas1.flatten(), lambdas2.flatten(), lambdas3.flatten())) - - # projector on space V3 (histopolation) - def pi_3(self, fun, include_bc=True, eval_kind="meshgrid"): - """ - Local projector on the discrete space V3. - - Parameters - ---------- - fun : callable - the function (3-form) to be projected - - include_bc : boolean - whether the boundary coefficients in the first logical direction are included - - eval_kind : string - kind of evaluation of function at interpolation/quadrature points ('meshgrid', 'tensor_product', 'point_wise') - - Returns - ------- - lambdas : array_like - the coefficients in V3 corresponding to the projected function - """ - - # evaluation of function at quadrature points - mat_f = xp.empty( - (self.pts[0].flatten().size, self.pts[1].flatten().size, self.pts[2].flatten().size), - dtype=float, - ) - - # external function call if a callable is passed - if callable(fun): - # create a meshgrid and evaluate function on point set - if eval_kind == "meshgrid": - pts1, pts2, pts3 = xp.meshgrid( - self.pts[0].flatten(), - self.pts[1].flatten(), - self.pts[2].flatten(), - indexing="ij", - ) - mat_f[:, :, :] = fun(pts1, pts2, pts3) - - # tensor-product evaluation is done by input function - elif eval_kind == "tensor_product": - mat_f[:, :, :] = fun(self.pts[0].flatten(), self.pts[1].flatten(), self.pts[2].flatten()) - - # point-wise evaluation - else: - for i1 in range(self.pts[0].size): - for i2 in range(self.pts[1].size): - for i3 in range(self.pts[2].size): - mat_f[i1, i2, i3] = fun( - self.pts[0].flatten()[i1], - self.pts[1].flatten()[i2], - self.pts[2].flatten()[i3], - ) - - # internal function call - else: - print("no internal 3D function implemented!") - - # compute coefficients - lambdas = xp.zeros((self.NbaseD[0], self.NbaseD[1], self.NbaseD[2]), dtype=float) - - ker_loc.kernel_pi3_3d( - self.NbaseD, - self.p, - self.n_quad, - self.coeff_h[0], - self.coeff_h[1], - self.coeff_h[2], - self.coeffh_indices[0], - self.coeffh_indices[1], - self.coeffh_indices[2], - self.x_his_indices[0], - self.x_his_indices[1], - self.x_his_indices[2], - self.wts[0], - self.wts[1], - self.wts[2], - mat_f.reshape( - self.pts[0].shape[0], - self.pts[0].shape[1], - self.pts[1].shape[0], - self.pts[1].shape[1], - self.pts[2].shape[0], - self.pts[2].shape[1], - ), - lambdas, - ) - - return lambdas.flatten() diff --git a/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/__init__.py b/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/shape_L2_projector_kernel.py b/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/shape_L2_projector_kernel.py deleted file mode 100644 index 0e711dbcf..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/shape_L2_projector_kernel.py +++ /dev/null @@ -1,2315 +0,0 @@ -import struphy.bsplines.bsplines_kernels as bsp -import struphy.geometry.mappings_kernels as mapping_fast -import struphy.linear_algebra.linalg_kernels as linalg - - -# ============================================================================================== -def kernel_1_form( - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - right1: "float[:,:,:]", - right2: "float[:,:,:]", - right3: "float[:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", - Np: "int", - quad: "int[:]", - p: "int[:]", - Nel: "int[:]", - p_shape: "int[:]", - p_size: "float[:]", - particle: "float[:,:]", - lambdas_11: "float[:,:,:]", - lambdas_12: "float[:,:,:]", - lambdas_13: "float[:,:,:]", - lambdas_21: "float[:,:,:]", - lambdas_22: "float[:,:,:]", - lambdas_23: "float[:,:,:]", - lambdas_31: "float[:,:,:]", - lambdas_32: "float[:,:,:]", - lambdas_33: "float[:,:,:]", - kernel_11: "float[:,:,:,:,:,:]", - kernel_12: "float[:,:,:,:,:,:]", - kernel_13: "float[:,:,:,:,:,:]", - kernel_22: "float[:,:,:,:,:,:]", - kernel_23: "float[:,:,:,:,:,:]", - kernel_33: "float[:,:,:,:,:,:]", - NbaseN: "int[:]", - NbaseD: "int[:]", - related: "int[:]", - Np_loc: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, floor, zeros - - cell_left = zeros(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - cell_number = zeros(3, dtype=int) - compact = zeros(3, dtype=float) - - width = zeros(3, dtype=int) - - width2 = zeros(3, dtype=int) - width2[0] = 2 * related[0] + 1 - width2[1] = 2 * related[1] + 1 - width2[2] = 2 * related[2] + 1 - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = zeros((3, 3), dtype=float) - dfinv = zeros((3, 3), dtype=float) - # ==================================== - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : kernel_11, kernel_12, kernel_13, kernel_22, kernel_23, kernel_33, right1, right2, right3) private (mid1, mid2, mid3, ip, w, vol, width2, lambdas_11, lambdas_22, lambdas_33, lambdas_12, lambdas_13, lambdas_21, lambdas_23, lambdas_31, lambdas_32, cell_left, point_left, point_right, cell_number, compact, width, mat_11, mat_12, mat_13, mat_21, mat_22, mat_23, mat_31, mat_32, mat_33, i1, i2, i3, il1, il2, il3, index1, index2, index3, value_x, value_y, value_z, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, dfinv, lambda_index1, lambda_index2, lambda_index3, global_i1, global_i2, global_i3, global_il1, global_il2, global_il3, jl1, jl2, jl3, eta1, eta2, eta3, final_index1, final_index2, final_index3, q1, q2, q3, basisvalue) - for ip in range(Np_loc): - w = particle[6, ip] / Np - - lambdas_11[:, :, :] = 0.0 - lambdas_12[:, :, :] = 0.0 - lambdas_13[:, :, :] = 0.0 - - lambdas_21[:, :, :] = 0.0 - lambdas_22[:, :, :] = 0.0 - lambdas_23[:, :, :] = 0.0 - - lambdas_31[:, :, :] = 0.0 - lambdas_32[:, :, :] = 0.0 - lambdas_33[:, :, :] = 0.0 - - # ================================== - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - point_left[0] = particle[0, ip] - 0.5 * compact[0] - point_right[0] = particle[0, ip] + 0.5 * compact[0] - point_left[1] = particle[1, ip] - 0.5 * compact[1] - point_right[1] = particle[1, ip] + 0.5 * compact[1] - point_left[2] = particle[2, ip] - 0.5 * compact[2] - point_right[2] = particle[2, ip] + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number[0] = int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1 - cell_number[1] = int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1 - cell_number[2] = int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1 - - vol = 1.0 / (p_size[0] * p_size[1] * p_size[2]) - - # evaluation of function at interpolation/quadrature points - mat_11 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_21 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_31 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - - mat_12 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_22 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_32 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - - mat_13 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_23 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_33 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - for jl1 in range(quad[0]): - eta1 = 1.0 / Nel[0] * index1 + pts1[0, jl1] - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - for jl2 in range(quad[1]): - eta2 = 1.0 / Nel[1] * index2 + pts2[0, jl2] - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - for jl3 in range(quad[2]): - eta3 = 1.0 / Nel[2] * index3 + pts3[0, jl3] - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # ========= mapping evaluation ============= - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate inverse of Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - mat_11[i1, i2, i3, jl1, jl2, jl3] = dfinv[0, 0] * value_x * value_y * value_z * vol - mat_21[i1, i2, i3, jl1, jl2, jl3] = dfinv[0, 1] * value_x * value_y * value_z * vol - mat_31[i1, i2, i3, jl1, jl2, jl3] = dfinv[0, 2] * value_x * value_y * value_z * vol - - mat_12[i1, i2, i3, jl1, jl2, jl3] = dfinv[1, 0] * value_x * value_y * value_z * vol - mat_22[i1, i2, i3, jl1, jl2, jl3] = dfinv[1, 1] * value_x * value_y * value_z * vol - mat_32[i1, i2, i3, jl1, jl2, jl3] = dfinv[1, 2] * value_x * value_y * value_z * vol - - mat_13[i1, i2, i3, jl1, jl2, jl3] = dfinv[2, 0] * value_x * value_y * value_z * vol - mat_23[i1, i2, i3, jl1, jl2, jl3] = dfinv[2, 1] * value_x * value_y * value_z * vol - mat_33[i1, i2, i3, jl1, jl2, jl3] = dfinv[2, 2] * value_x * value_y * value_z * vol - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - - for lambda_index1 in range(p[0]): - final_index1 = iddx[index1 % Nel[0], lambda_index1] - for lambda_index2 in range(p[1] + 1): - final_index2 = idny[index2 % Nel[1], lambda_index2] - for lambda_index3 in range(p[2] + 1): - final_index3 = idnz[index3 % Nel[2], lambda_index3] - mid1 = 0.0 - mid2 = 0.0 - mid3 = 0.0 - for q1 in range(quad[0]): - for q2 in range(quad[1]): - for q3 in range(quad[2]): - basisvalue = ( - bd1[index1 % Nel[0], lambda_index1, 0, q1] - * bn2[index2 % Nel[1], lambda_index2, 0, q2] - * bn3[index3 % Nel[2], lambda_index3, 0, q3] - * wts1[index1 % Nel[0], q1] - * wts2[index2 % Nel[1], q2] - * wts3[index3 % Nel[2], q3] - ) - mid1 += mat_11[i1, i2, i3, q1, q2, q3] * basisvalue - mid2 += mat_21[i1, i2, i3, q1, q2, q3] * basisvalue - mid3 += mat_31[i1, i2, i3, q1, q2, q3] * basisvalue - lambdas_11[final_index1, final_index2, final_index3] += mid1 - lambdas_21[final_index1, final_index2, final_index3] += mid2 - lambdas_31[final_index1, final_index2, final_index3] += mid3 - right1[final_index1, final_index2, final_index3] += w * ( - particle[3, ip] * mid1 + particle[4, ip] * mid2 + particle[5, ip] * mid3 - ) - - for lambda_index1 in range(p[0] + 1): - final_index1 = idnx[index1 % Nel[0], lambda_index1] - for lambda_index2 in range(p[1]): - final_index2 = iddy[index2 % Nel[1], lambda_index2] - for lambda_index3 in range(p[2] + 1): - final_index3 = idnz[index3 % Nel[2], lambda_index3] - mid1 = 0.0 - mid2 = 0.0 - mid3 = 0.0 - for q1 in range(quad[0]): - for q2 in range(quad[1]): - for q3 in range(quad[2]): - basisvalue = ( - bn1[index1 % Nel[0], lambda_index1, 0, q1] - * bd2[index2 % Nel[1], lambda_index2, 0, q2] - * bn3[index3 % Nel[2], lambda_index3, 0, q3] - * wts1[index1 % Nel[0], q1] - * wts2[index2 % Nel[1], q2] - * wts3[index3 % Nel[2], q3] - ) - mid1 += mat_12[i1, i2, i3, q1, q2, q3] * basisvalue - mid2 += mat_22[i1, i2, i3, q1, q2, q3] * basisvalue - mid3 += mat_32[i1, i2, i3, q1, q2, q3] * basisvalue - lambdas_12[final_index1, final_index2, final_index3] += mid1 - lambdas_22[final_index1, final_index2, final_index3] += mid2 - lambdas_32[final_index1, final_index2, final_index3] += mid3 - right2[final_index1, final_index2, final_index3] += w * ( - particle[3, ip] * mid1 + particle[4, ip] * mid2 + particle[5, ip] * mid3 - ) - - for lambda_index1 in range(p[0] + 1): - final_index1 = idnx[index1 % Nel[0], lambda_index1] - for lambda_index2 in range(p[1] + 1): - final_index2 = idny[index2 % Nel[1], lambda_index2] - for lambda_index3 in range(p[2]): - final_index3 = iddz[index3 % Nel[2], lambda_index3] - mid1 = 0.0 - mid2 = 0.0 - mid3 = 0.0 - for q1 in range(quad[0]): - for q2 in range(quad[1]): - for q3 in range(quad[2]): - basisvalue = ( - bn1[index1 % Nel[0], lambda_index1, 0, q1] - * bn2[index2 % Nel[1], lambda_index2, 0, q2] - * bd3[index3 % Nel[2], lambda_index3, 0, q3] - * wts1[index1 % Nel[0], q1] - * wts2[index2 % Nel[1], q2] - * wts3[index3 % Nel[2], q3] - ) - mid1 += mat_13[i1, i2, i3, q1, q2, q3] * basisvalue - mid2 += mat_23[i1, i2, i3, q1, q2, q3] * basisvalue - mid3 += mat_33[i1, i2, i3, q1, q2, q3] * basisvalue - lambdas_13[final_index1, final_index2, final_index3] += mid1 - lambdas_23[final_index1, final_index2, final_index3] += mid2 - lambdas_33[final_index1, final_index2, final_index3] += mid3 - right3[final_index1, final_index2, final_index3] += w * ( - particle[3, ip] * mid1 + particle[4, ip] * mid2 + particle[5, ip] * mid3 - ) - - for il1 in range(3): - width[il1] = p[il1] + cell_number[il1] - - if width[0] > NbaseD[0]: - width[0] = NbaseD[0] - if width[1] > NbaseN[1]: - width[1] = NbaseN[1] - if width[2] > NbaseN[2]: - width[2] = NbaseN[2] - for i1 in range(width[0]): - global_i1 = (cell_left[0] + i1) % NbaseD[0] - for i2 in range(width[1]): - global_i2 = (cell_left[1] + i2) % NbaseN[1] - for i3 in range(width[2]): - global_i3 = (cell_left[2] + i3) % NbaseN[2] - # ===== 11 compoponent ========== - for il1 in range(3): - width2[il1] = 2 * related[il1] + 1 - if width2[0] > NbaseD[0]: - width2[0] = NbaseD[0] - if width2[1] > NbaseN[1]: - width2[1] = NbaseN[1] - if width2[2] > NbaseN[2]: - width2[2] = NbaseN[2] - for il1 in range(width2[0]): - global_il1 = (global_i1 + il1 - int(floor(width2[0] / 2.0))) % NbaseD[0] - for il2 in range(width2[1]): - global_il2 = (global_i2 + il2 - int(floor(width2[1] / 2.0))) % NbaseN[1] - for il3 in range(width2[2]): - global_il3 = (global_i3 + il3 - int(floor(width2[2] / 2.0))) % NbaseN[2] - kernel_11[global_i1, global_i2, global_i3, il1, il2, il3] += w * ( - lambdas_11[global_i1, global_i2, global_i3] - * lambdas_11[global_il1, global_il2, global_il3] - + lambdas_21[global_i1, global_i2, global_i3] - * lambdas_21[global_il1, global_il2, global_il3] - + lambdas_31[global_i1, global_i2, global_i3] - * lambdas_31[global_il1, global_il2, global_il3] - ) - # ===== 12 compoponent ========== - for il1 in range(3): - width2[il1] = 2 * related[il1] + 1 - if width2[0] > NbaseN[0]: - width2[0] = NbaseN[0] - if width2[1] > NbaseD[1]: - width2[1] = NbaseD[1] - if width2[2] > NbaseN[2]: - width2[2] = NbaseN[2] - for il1 in range(width2[0]): - global_il1 = (global_i1 + il1 - int(floor(width2[0] / 2.0))) % NbaseN[0] - for il2 in range(width2[1]): - global_il2 = (global_i2 + il2 - int(floor(width2[1] / 2.0))) % NbaseD[1] - for il3 in range(width2[2]): - global_il3 = (global_i3 + il3 - int(floor(width2[2] / 2.0))) % NbaseN[2] - kernel_12[global_i1, global_i2, global_i3, il1, il2, il3] += w * ( - lambdas_11[global_i1, global_i2, global_i3] - * lambdas_12[global_il1, global_il2, global_il3] - + lambdas_21[global_i1, global_i2, global_i3] - * lambdas_22[global_il1, global_il2, global_il3] - + lambdas_31[global_i1, global_i2, global_i3] - * lambdas_32[global_il1, global_il2, global_il3] - ) - - # ===== 13 compoponent ========== - for il1 in range(3): - width2[il1] = 2 * related[il1] + 1 - if width2[0] > NbaseN[0]: - width2[0] = NbaseN[0] - if width2[1] > NbaseN[1]: - width2[1] = NbaseN[1] - if width2[2] > NbaseD[2]: - width2[2] = NbaseD[2] - for il1 in range(width2[0]): - global_il1 = (global_i1 + il1 - int(floor(width2[0] / 2.0))) % NbaseN[0] - for il2 in range(width2[1]): - global_il2 = (global_i2 + il2 - int(floor(width2[1] / 2.0))) % NbaseN[1] - for il3 in range(width2[2]): - global_il3 = (global_i3 + il3 - int(floor(width2[2] / 2.0))) % NbaseD[2] - kernel_13[global_i1, global_i2, global_i3, il1, il2, il3] += w * ( - lambdas_11[global_i1, global_i2, global_i3] - * lambdas_13[global_il1, global_il2, global_il3] - + lambdas_21[global_i1, global_i2, global_i3] - * lambdas_23[global_il1, global_il2, global_il3] - + lambdas_31[global_i1, global_i2, global_i3] - * lambdas_33[global_il1, global_il2, global_il3] - ) - - for il1 in range(3): - width[il1] = p[il1] + cell_number[il1] - if width[0] > NbaseN[0]: - width[0] = NbaseN[0] - if width[1] > NbaseD[1]: - width[1] = NbaseD[1] - if width[2] > NbaseN[2]: - width[2] = NbaseN[2] - for i1 in range(width[0]): - global_i1 = (cell_left[0] + i1) % NbaseN[0] - for i2 in range(width[1]): - global_i2 = (cell_left[1] + i2) % NbaseD[1] - for i3 in range(width[2]): - global_i3 = (cell_left[2] + i3) % NbaseN[2] - # ===== 22 compoponent ========== - for il1 in range(3): - width2[il1] = 2 * related[il1] + 1 - if width2[0] > NbaseN[0]: - width2[0] = NbaseN[0] - if width2[1] > NbaseD[1]: - width2[1] = NbaseD[1] - if width2[2] > NbaseN[2]: - width2[2] = NbaseN[2] - for il1 in range(width2[0]): - global_il1 = (global_i1 + il1 - int(floor(width2[0] / 2.0))) % NbaseN[0] - for il2 in range(width2[1]): - global_il2 = (global_i2 + il2 - int(floor(width2[1] / 2.0))) % NbaseD[1] - for il3 in range(width2[2]): - global_il3 = (global_i3 + il3 - int(floor(width2[2] / 2.0))) % NbaseN[2] - kernel_22[global_i1, global_i2, global_i3, il1, il2, il3] += w * ( - lambdas_12[global_i1, global_i2, global_i3] - * lambdas_12[global_il1, global_il2, global_il3] - + lambdas_22[global_i1, global_i2, global_i3] - * lambdas_22[global_il1, global_il2, global_il3] - + lambdas_32[global_i1, global_i2, global_i3] - * lambdas_32[global_il1, global_il2, global_il3] - ) - # ===== 23 compoponent ========== - for il1 in range(3): - width2[il1] = 2 * related[il1] + 1 - if width2[0] > NbaseN[0]: - width2[0] = NbaseN[0] - if width2[1] > NbaseN[1]: - width2[1] = NbaseN[1] - if width2[2] > NbaseD[2]: - width2[2] = NbaseD[2] - for il1 in range(width2[0]): - global_il1 = (global_i1 + il1 - int(floor(width2[0] / 2.0))) % NbaseN[0] - for il2 in range(width2[1]): - global_il2 = (global_i2 + il2 - int(floor(width2[1] / 2.0))) % NbaseN[1] - for il3 in range(width2[2]): - global_il3 = (global_i3 + il3 - int(floor(width2[2] / 2.0))) % NbaseD[2] - kernel_23[global_i1, global_i2, global_i3, il1, il2, il3] += w * ( - lambdas_12[global_i1, global_i2, global_i3] - * lambdas_13[global_il1, global_il2, global_il3] - + lambdas_22[global_i1, global_i2, global_i3] - * lambdas_23[global_il1, global_il2, global_il3] - + lambdas_32[global_i1, global_i2, global_i3] - * lambdas_33[global_il1, global_il2, global_il3] - ) - - for il1 in range(3): - width[il1] = p[il1] + cell_number[il1] - if width[0] > NbaseN[0]: - width[0] = NbaseN[0] - if width[1] > NbaseN[1]: - width[1] = NbaseN[1] - if width[2] > NbaseD[2]: - width[2] = NbaseD[2] - - for i1 in range(width[0]): - global_i1 = (cell_left[0] + i1) % NbaseN[0] - for i2 in range(width[1]): - global_i2 = (cell_left[1] + i2) % NbaseN[1] - for i3 in range(width[2]): - global_i3 = (cell_left[2] + i3) % NbaseD[2] - # ===== 33 compoponent ========== - for il1 in range(3): - width2[il1] = 2 * related[il1] + 1 - if width2[0] > NbaseN[0]: - width2[0] = NbaseN[0] - if width2[1] > NbaseN[1]: - width2[1] = NbaseN[1] - if width2[2] > NbaseD[2]: - width2[2] = NbaseD[2] - for il1 in range(width2[0]): - global_il1 = (global_i1 + il1 - int(floor(width2[0] / 2.0))) % NbaseN[0] - for il2 in range(width2[1]): - global_il2 = (global_i2 + il2 - int(floor(width2[1] / 2.0))) % NbaseN[1] - for il3 in range(width2[2]): - global_il3 = (global_i3 + il3 - int(floor(width2[2] / 2.0))) % NbaseD[2] - kernel_33[global_i1, global_i2, global_i3, il1, il2, il3] += w * ( - lambdas_13[global_i1, global_i2, global_i3] - * lambdas_13[global_il1, global_il2, global_il3] - + lambdas_23[global_i1, global_i2, global_i3] - * lambdas_23[global_il1, global_il2, global_il3] - + lambdas_33[global_i1, global_i2, global_i3] - * lambdas_33[global_il1, global_il2, global_il3] - ) - - del mat_11 - del mat_12 - del mat_13 - del mat_21 - del mat_22 - del mat_23 - del mat_31 - del mat_32 - del mat_33 - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ============================================================================================== -def bvpushltwo( - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - dt: "float", - bb1: "float[:,:,:]", - bb2: "float[:,:,:]", - bb3: "float[:,:,:]", - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", - Np: "int", - quad: "int[:]", - p: "int[:]", - Nel: "int[:]", - p_shape: "int[:]", - p_size: "float[:]", - particle: "float[:,:]", - lambdas_11: "float[:,:,:]", - lambdas_12: "float[:,:,:]", - lambdas_13: "float[:,:,:]", - lambdas_21: "float[:,:,:]", - lambdas_22: "float[:,:,:]", - lambdas_23: "float[:,:,:]", - lambdas_31: "float[:,:,:]", - lambdas_32: "float[:,:,:]", - lambdas_33: "float[:,:,:]", - NbaseN: "int[:]", - NbaseD: "int[:]", - related: "int[:]", - Np_loc: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, floor, zeros - - cell_left = zeros(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - cell_number = zeros(3, dtype=int) - compact = zeros(3, dtype=float) - - vel = zeros(3, dtype=float) - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = zeros((3, 3), dtype=float) - dfinv = zeros((3, 3), dtype=float) - - # ==================================== - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (vel, mid1, mid2, mid3, ip, vol, lambdas_11, lambdas_12, lambdas_13, lambdas_21, lambdas_22, lambdas_23, lambdas_31, lambdas_32, lambdas_33, cell_left, point_left, point_right, cell_number, compact, mat_11, mat_12, mat_13, mat_21, mat_22, mat_23, mat_31, mat_32, mat_33, i1, i2, i3, index1, index2, index3, value_x, value_y, value_z, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, dfinv, jl1, jl2, jl3, eta1, eta2, eta3, final_index1, final_index2, final_index3, lambda_index1, lambda_index2, lambda_index3, q1, q2, q3, basisvalue) - for ip in range(Np_loc): - vel[:] = 0.0 - - lambdas_11[:, :, :] = 0.0 - lambdas_12[:, :, :] = 0.0 - lambdas_13[:, :, :] = 0.0 - - lambdas_21[:, :, :] = 0.0 - lambdas_22[:, :, :] = 0.0 - lambdas_23[:, :, :] = 0.0 - - lambdas_31[:, :, :] = 0.0 - lambdas_32[:, :, :] = 0.0 - lambdas_33[:, :, :] = 0.0 - - # ================================== - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - point_left[0] = particle[0, ip] - 0.5 * compact[0] - point_right[0] = particle[0, ip] + 0.5 * compact[0] - point_left[1] = particle[1, ip] - 0.5 * compact[1] - point_right[1] = particle[1, ip] + 0.5 * compact[1] - point_left[2] = particle[2, ip] - 0.5 * compact[2] - point_right[2] = particle[2, ip] + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number[0] = int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1 - cell_number[1] = int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1 - cell_number[2] = int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1 - - vol = 1.0 / (p_size[0] * p_size[1] * p_size[2]) - - # evaluation of function at interpolation/quadrature points - mat_11 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_21 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_31 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - - mat_12 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_22 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_32 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - - mat_13 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_23 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_33 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): # num_cell = 1, p = 1; num_cell = 2, p >= 2 - index3 = cell_left[2] + i3 - for jl1 in range(quad[0]): - eta1 = 1.0 / Nel[0] * index1 + pts1[0, jl1] - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - for jl2 in range(quad[1]): - eta2 = 1.0 / Nel[1] * index2 + pts2[0, jl2] - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - for jl3 in range(quad[2]): - eta3 = 1.0 / Nel[2] * index3 + pts3[0, jl3] - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # ========= mapping evaluation ============= - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate inverse of Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - mat_11[i1, i2, i3, jl1, jl2, jl3] = dfinv[0, 0] * value_x * value_y * value_z * vol - mat_21[i1, i2, i3, jl1, jl2, jl3] = dfinv[0, 1] * value_x * value_y * value_z * vol - mat_31[i1, i2, i3, jl1, jl2, jl3] = dfinv[0, 2] * value_x * value_y * value_z * vol - - mat_12[i1, i2, i3, jl1, jl2, jl3] = dfinv[1, 0] * value_x * value_y * value_z * vol - mat_22[i1, i2, i3, jl1, jl2, jl3] = dfinv[1, 1] * value_x * value_y * value_z * vol - mat_32[i1, i2, i3, jl1, jl2, jl3] = dfinv[1, 2] * value_x * value_y * value_z * vol - - mat_13[i1, i2, i3, jl1, jl2, jl3] = dfinv[2, 0] * value_x * value_y * value_z * vol - mat_23[i1, i2, i3, jl1, jl2, jl3] = dfinv[2, 1] * value_x * value_y * value_z * vol - mat_33[i1, i2, i3, jl1, jl2, jl3] = dfinv[2, 2] * value_x * value_y * value_z * vol - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - - for lambda_index1 in range(p[0]): - final_index1 = iddx[index1 % Nel[0], lambda_index1] - for lambda_index2 in range(p[1] + 1): - final_index2 = idny[index2 % Nel[1], lambda_index2] - for lambda_index3 in range(p[2] + 1): - final_index3 = idnz[index3 % Nel[2], lambda_index3] - mid1 = 0.0 - mid2 = 0.0 - mid3 = 0.0 - for q1 in range(quad[0]): - for q2 in range(quad[1]): - for q3 in range(quad[2]): - basisvalue = ( - bd1[index1 % Nel[0], lambda_index1, 0, q1] - * bn2[index2 % Nel[1], lambda_index2, 0, q2] - * bn3[index3 % Nel[2], lambda_index3, 0, q3] - * wts1[index1 % Nel[0], q1] - * wts2[index2 % Nel[1], q2] - * wts3[index3 % Nel[2], q3] - ) - mid1 += mat_11[i1, i2, i3, q1, q2, q3] * basisvalue - mid2 += mat_21[i1, i2, i3, q1, q2, q3] * basisvalue - mid3 += mat_31[i1, i2, i3, q1, q2, q3] * basisvalue - vel[0] += mid1 * bb1[final_index1, final_index2, final_index3] - vel[1] += mid2 * bb1[final_index1, final_index2, final_index3] - vel[2] += mid3 * bb1[final_index1, final_index2, final_index3] - - for lambda_index1 in range(p[0] + 1): - final_index1 = idnx[index1 % Nel[0], lambda_index1] - for lambda_index2 in range(p[1]): - final_index2 = iddy[index2 % Nel[1], lambda_index2] - for lambda_index3 in range(p[2] + 1): - final_index3 = idnz[index3 % Nel[2], lambda_index3] - mid1 = 0.0 - mid2 = 0.0 - mid3 = 0.0 - for q1 in range(quad[0]): - for q2 in range(quad[1]): - for q3 in range(quad[2]): - basisvalue = ( - bn1[index1 % Nel[0], lambda_index1, 0, q1] - * bd2[index2 % Nel[1], lambda_index2, 0, q2] - * bn3[index3 % Nel[2], lambda_index3, 0, q3] - * wts1[index1 % Nel[0], q1] - * wts2[index2 % Nel[1], q2] - * wts3[index3 % Nel[2], q3] - ) - mid1 += mat_12[i1, i2, i3, q1, q2, q3] * basisvalue - mid2 += mat_22[i1, i2, i3, q1, q2, q3] * basisvalue - mid3 += mat_32[i1, i2, i3, q1, q2, q3] * basisvalue - vel[0] += mid1 * bb2[final_index1, final_index2, final_index3] - vel[1] += mid2 * bb2[final_index1, final_index2, final_index3] - vel[2] += mid3 * bb2[final_index1, final_index2, final_index3] - - for lambda_index1 in range(p[0] + 1): - final_index1 = idnx[index1 % Nel[0], lambda_index1] - for lambda_index2 in range(p[1] + 1): - final_index2 = idny[index2 % Nel[1], lambda_index2] - for lambda_index3 in range(p[2]): - final_index3 = iddz[index3 % Nel[2], lambda_index3] - mid1 = 0.0 - mid2 = 0.0 - mid3 = 0.0 - for q1 in range(quad[0]): - for q2 in range(quad[1]): - for q3 in range(quad[2]): - basisvalue = ( - bn1[index1 % Nel[0], lambda_index1, 0, q1] - * bn2[index2 % Nel[1], lambda_index2, 0, q2] - * bd3[index3 % Nel[2], lambda_index3, 0, q3] - * wts1[index1 % Nel[0], q1] - * wts2[index2 % Nel[1], q2] - * wts3[index3 % Nel[2], q3] - ) - mid1 += mat_13[i1, i2, i3, q1, q2, q3] * basisvalue - mid2 += mat_23[i1, i2, i3, q1, q2, q3] * basisvalue - mid3 += mat_33[i1, i2, i3, q1, q2, q3] * basisvalue - vel[0] += mid1 * bb3[final_index1, final_index2, final_index3] - vel[1] += mid2 * bb3[final_index1, final_index2, final_index3] - vel[2] += mid3 * bb3[final_index1, final_index2, final_index3] - - particle[3, ip] += dt * vel[0] - particle[4, ip] += dt * vel[1] - particle[5, ip] += dt * vel[2] - - del mat_11 - del mat_12 - del mat_13 - del mat_21 - del mat_22 - del mat_23 - del mat_31 - del mat_32 - del mat_33 - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ============================================================================================== -def kernel_1_heavy( - bn1: "float[:,:,:,:]", - bn2: "float[:,:,:,:]", - bn3: "float[:,:,:,:]", - bd1: "float[:,:,:,:]", - bd2: "float[:,:,:,:]", - bd3: "float[:,:,:,:]", - idnx: "int[:,:]", - idny: "int[:,:]", - idnz: "int[:,:]", - iddx: "int[:,:]", - iddy: "int[:,:]", - iddz: "int[:,:]", - pts1: "float[:,:]", - pts2: "float[:,:]", - pts3: "float[:,:]", - wts1: "float[:,:]", - wts2: "float[:,:]", - wts3: "float[:,:]", - out1: "float[:,:,:]", - out2: "float[:,:,:]", - out3: "float[:,:,:]", - in1: "float[:,:,:]", - in2: "float[:,:,:]", - in3: "float[:,:,:]", - Np: "int", - quad: "int[:]", - p: "int[:]", - Nel: "int[:]", - p_shape: "int[:]", - p_size: "float[:]", - particle: "float[:,:]", - lambdas_11: "float[:,:,:]", - lambdas_12: "float[:,:,:]", - lambdas_13: "float[:,:,:]", - lambdas_21: "float[:,:,:]", - lambdas_22: "float[:,:,:]", - lambdas_23: "float[:,:,:]", - lambdas_31: "float[:,:,:]", - lambdas_32: "float[:,:,:]", - lambdas_33: "float[:,:,:]", - NbaseN: "int[:]", - NbaseD: "int[:]", - Np_loc: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, floor, zeros - - cell_left = zeros(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - cell_number = zeros(3, dtype=int) - compact = zeros(3, dtype=float) - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = zeros((3, 3), dtype=float) - dfinv = zeros((3, 3), dtype=float) - - # ==================================== - - out1[:, :, :] = 0.0 - out2[:, :, :] = 0.0 - out3[:, :, :] = 0.0 - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : out1, out2, out3) private (value1, value2, value3, mid1, mid2, mid3, ip, w, vol, lambdas_11, lambdas_12, lambdas_13, lambdas_21, lambdas_22, lambdas_23, lambdas_31, lambdas_32, lambdas_33, cell_left, point_left, point_right, cell_number, compact, mat_11, mat_12, mat_13, mat_21, mat_22, mat_23, mat_31, mat_32, mat_33, i1, i2, i3, il1, il2, il3, index1, index2, index3, value_x, value_y, value_z, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, dfinv, lambda_index1, lambda_index2, lambda_index3, eta1, eta2, eta3, final_index1, final_index2, final_index3, jl1, jl2, jl3, q1, q2, q3, basisvalue) - for ip in range(Np_loc): - w = particle[6, ip] / Np - - lambdas_11[:, :, :] = 0.0 - lambdas_22[:, :, :] = 0.0 - lambdas_33[:, :, :] = 0.0 - - lambdas_12[:, :, :] = 0.0 - lambdas_13[:, :, :] = 0.0 - - lambdas_21[:, :, :] = 0.0 - lambdas_23[:, :, :] = 0.0 - - lambdas_31[:, :, :] = 0.0 - lambdas_32[:, :, :] = 0.0 - - value1 = 0.0 - value2 = 0.0 - value3 = 0.0 - - # ================================== - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - point_left[0] = particle[0, ip] - 0.5 * compact[0] - point_right[0] = particle[0, ip] + 0.5 * compact[0] - point_left[1] = particle[1, ip] - 0.5 * compact[1] - point_right[1] = particle[1, ip] + 0.5 * compact[1] - point_left[2] = particle[2, ip] - 0.5 * compact[2] - point_right[2] = particle[2, ip] + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number[0] = int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1 - cell_number[1] = int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1 - cell_number[2] = int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1 - - vol = 1.0 / (p_size[0] * p_size[1] * p_size[2]) - - # evaluation of function at interpolation/quadrature points - mat_11 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_21 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_31 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - - mat_12 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_22 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_32 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - - mat_13 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_23 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - mat_33 = zeros((cell_number[0], cell_number[1], cell_number[2], quad[0], quad[1], quad[2]), dtype=float) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - for jl1 in range(quad[0]): - eta1 = 1.0 / Nel[0] * index1 + pts1[0, jl1] - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - for jl2 in range(quad[1]): - eta2 = 1.0 / Nel[1] * index2 + pts2[0, jl2] - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - for jl3 in range(quad[2]): - eta3 = 1.0 / Nel[2] * index3 + pts3[0, jl3] - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # ========= mapping evaluation ============= - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate inverse of Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - mat_11[i1, i2, i3, jl1, jl2, jl3] = dfinv[0, 0] * value_x * value_y * value_z * vol - mat_21[i1, i2, i3, jl1, jl2, jl3] = dfinv[0, 1] * value_x * value_y * value_z * vol - mat_31[i1, i2, i3, jl1, jl2, jl3] = dfinv[0, 2] * value_x * value_y * value_z * vol - - mat_12[i1, i2, i3, jl1, jl2, jl3] = dfinv[1, 0] * value_x * value_y * value_z * vol - mat_22[i1, i2, i3, jl1, jl2, jl3] = dfinv[1, 1] * value_x * value_y * value_z * vol - mat_32[i1, i2, i3, jl1, jl2, jl3] = dfinv[1, 2] * value_x * value_y * value_z * vol - - mat_13[i1, i2, i3, jl1, jl2, jl3] = dfinv[2, 0] * value_x * value_y * value_z * vol - mat_23[i1, i2, i3, jl1, jl2, jl3] = dfinv[2, 1] * value_x * value_y * value_z * vol - mat_33[i1, i2, i3, jl1, jl2, jl3] = dfinv[2, 2] * value_x * value_y * value_z * vol - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - - for lambda_index1 in range(p[0]): - final_index1 = iddx[index1 % Nel[0], lambda_index1] - for lambda_index2 in range(p[1] + 1): - final_index2 = idny[index2 % Nel[1], lambda_index2] - for lambda_index3 in range(p[2] + 1): - final_index3 = idnz[index3 % Nel[2], lambda_index3] - mid1 = 0.0 - mid2 = 0.0 - mid3 = 0.0 - for q1 in range(quad[0]): - for q2 in range(quad[1]): - for q3 in range(quad[2]): - basisvalue = ( - bd1[index1 % Nel[0], lambda_index1, 0, q1] - * bn2[index2 % Nel[1], lambda_index2, 0, q2] - * bn3[index3 % Nel[2], lambda_index3, 0, q3] - * wts1[index1 % Nel[0], q1] - * wts2[index2 % Nel[1], q2] - * wts3[index3 % Nel[2], q3] - ) - mid1 += mat_11[i1, i2, i3, q1, q2, q3] * basisvalue - mid2 += mat_21[i1, i2, i3, q1, q2, q3] * basisvalue - mid3 += mat_31[i1, i2, i3, q1, q2, q3] * basisvalue - lambdas_11[final_index1, final_index2, final_index3] += mid1 - lambdas_21[final_index1, final_index2, final_index3] += mid2 - lambdas_31[final_index1, final_index2, final_index3] += mid3 - value1 += mid1 * in1[final_index1, final_index2, final_index3] - value2 += mid2 * in1[final_index1, final_index2, final_index3] - value3 += mid3 * in1[final_index1, final_index2, final_index3] - - for lambda_index1 in range(p[0] + 1): - final_index1 = idnx[index1 % Nel[0], lambda_index1] - for lambda_index2 in range(p[1]): - final_index2 = iddy[index2 % Nel[1], lambda_index2] - for lambda_index3 in range(p[2] + 1): - final_index3 = idnz[index3 % Nel[2], lambda_index3] - mid1 = 0.0 - mid2 = 0.0 - mid3 = 0.0 - for q1 in range(quad[0]): - for q2 in range(quad[1]): - for q3 in range(quad[2]): - basisvalue = ( - bn1[index1 % Nel[0], lambda_index1, 0, q1] - * bd2[index2 % Nel[1], lambda_index2, 0, q2] - * bn3[index3 % Nel[2], lambda_index3, 0, q3] - * wts1[index1 % Nel[0], q1] - * wts2[index2 % Nel[1], q2] - * wts3[index3 % Nel[2], q3] - ) - mid1 += mat_12[i1, i2, i3, q1, q2, q3] * basisvalue - mid2 += mat_22[i1, i2, i3, q1, q2, q3] * basisvalue - mid3 += mat_32[i1, i2, i3, q1, q2, q3] * basisvalue - - lambdas_12[final_index1, final_index2, final_index3] += mid1 - lambdas_22[final_index1, final_index2, final_index3] += mid2 - lambdas_32[final_index1, final_index2, final_index3] += mid3 - value1 += mid1 * in2[final_index1, final_index2, final_index3] - value2 += mid2 * in2[final_index1, final_index2, final_index3] - value3 += mid3 * in2[final_index1, final_index2, final_index3] - - for lambda_index1 in range(p[0] + 1): - final_index1 = idnx[index1 % Nel[0], lambda_index1] - for lambda_index2 in range(p[1] + 1): - final_index2 = idny[index2 % Nel[1], lambda_index2] - for lambda_index3 in range(p[2]): - final_index3 = iddz[index3 % Nel[2], lambda_index3] - mid1 = 0.0 - mid2 = 0.0 - mid3 = 0.0 - for q1 in range(quad[0]): - for q2 in range(quad[1]): - for q3 in range(quad[2]): - basisvalue = ( - bn1[index1 % Nel[0], lambda_index1, 0, q1] - * bn2[index2 % Nel[1], lambda_index2, 0, q2] - * bd3[index3 % Nel[2], lambda_index3, 0, q3] - * wts1[index1 % Nel[0], q1] - * wts2[index2 % Nel[1], q2] - * wts3[index3 % Nel[2], q3] - ) - mid1 += mat_13[i1, i2, i3, q1, q2, q3] * basisvalue - mid2 += mat_23[i1, i2, i3, q1, q2, q3] * basisvalue - mid3 += mat_33[i1, i2, i3, q1, q2, q3] * basisvalue - - lambdas_13[final_index1, final_index2, final_index3] += mid1 - lambdas_23[final_index1, final_index2, final_index3] += mid2 - lambdas_33[final_index1, final_index2, final_index3] += mid3 - value1 += mid1 * in3[final_index1, final_index2, final_index3] - value2 += mid2 * in3[final_index1, final_index2, final_index3] - value3 += mid3 * in3[final_index1, final_index2, final_index3] - - for il1 in range(NbaseN[0]): - for il2 in range(NbaseN[1]): - for il3 in range(NbaseN[2]): - out1[il1, il2, il3] += ( - w * value1 * (lambdas_11[il1, il2, il3] + lambdas_21[il1, il2, il3] + lambdas_31[il1, il2, il3]) - ) - out2[il1, il2, il3] += ( - w * value2 * (lambdas_12[il1, il2, il3] + lambdas_22[il1, il2, il3] + lambdas_32[il1, il2, il3]) - ) - out3[il1, il2, il3] += ( - w * value3 * (lambdas_13[il1, il2, il3] + lambdas_23[il1, il2, il3] + lambdas_33[il1, il2, il3]) - ) - - del mat_11 - del mat_12 - del mat_13 - del mat_21 - del mat_22 - del mat_23 - del mat_31 - del mat_32 - del mat_33 - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ============================================================================================== -def vv_1_form( - wts1: "float[:]", - wts2: "float[:]", - wts3: "float[:]", - pts1: "float[:]", - pts2: "float[:]", - pts3: "float[:]", - ddt: "float", - right1: "float[:,:,:]", - right2: "float[:,:,:]", - right3: "float[:,:,:]", - Np: "int", - quad: "int[:]", - p: "int[:]", - Nel: "int[:]", - p_shape: "int[:]", - p_size: "float[:]", - particle: "float[:,:]", - mid_particle: "float[:,:]", - lambdas_11: "float[:,:,:]", - lambdas_12: "float[:,:,:]", - lambdas_13: "float[:,:,:]", - lambdas_21: "float[:,:,:]", - lambdas_22: "float[:,:,:]", - lambdas_23: "float[:,:,:]", - lambdas_31: "float[:,:,:]", - lambdas_32: "float[:,:,:]", - lambdas_33: "float[:,:,:]", - num_cell: "int[:]", - coeff_i_x: "float[:]", - coeff_i_y: "float[:]", - coeff_i_z: "float[:]", - coeff_h_x: "float[:]", - coeff_h_y: "float[:]", - coeff_h_z: "float[:]", - NbaseN: "int[:]", - NbaseD: "int[:]", - related: "int[:]", - Np_loc: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, floor, zeros - - cell_left = zeros(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - cell_number = zeros(3, dtype=int) - compact = zeros(3, dtype=float) - - width = zeros(3, dtype=int) - width[0] = p[0] + cell_number[0] - 1 # the number of coefficients obtained from this smoothed delta function - width[1] = p[1] + cell_number[1] - 1 # the number of coefficients obtained from this smoothed delta function - width[2] = p[2] + cell_number[2] - 1 # the number of coefficients obtained from this smoothed delta function - - width2 = zeros(3, dtype=int) - width2[0] = 2 * related[0] + 1 - width2[1] = 2 * related[1] + 1 - width2[2] = 2 * related[2] + 1 - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = zeros((3, 3), dtype=float) - dft = zeros((3, 3), dtype=float) - - grids_shapex = zeros(p_shape[0] + 2, dtype=float) - grids_shapey = zeros(p_shape[1] + 2, dtype=float) - grids_shapez = zeros(p_shape[2] + 2, dtype=float) - - right1[:, :, :] = 0.0 - right2[:, :, :] = 0.0 - right3[:, :, :] = 0.0 - # ==================================== - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : right1, right2, right3) private (i, grids_shapex, grids_shapey, grids_shapez, mid1, mid2, mid3, ip, w, det_df, vol, lambdas_11, lambdas_22, lambdas_33, lambdas_12, lambdas_13, lambdas_21, lambdas_23, lambdas_31, lambdas_32, cell_left, point_left, point_right, cell_number, compact, mat_11, mat_12, mat_13, mat_21, mat_22, mat_23, mat_31, mat_32, mat_33, i1, i2, i3, il1, il2, il3, jl1, index1, index2, index3, value_x, value_y, value_z, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, dft, lambda_index1, lambda_index2, lambda_index3, eta1, eta2, eta3, final_index1, final_index2, final_index3, f_int) - for ip in range(Np_loc): - w = particle[6, ip] / Np - - lambdas_11[:, :, :] = 0.0 - lambdas_12[:, :, :] = 0.0 - lambdas_13[:, :, :] = 0.0 - - lambdas_21[:, :, :] = 0.0 - lambdas_22[:, :, :] = 0.0 - lambdas_23[:, :, :] = 0.0 - - lambdas_31[:, :, :] = 0.0 - lambdas_32[:, :, :] = 0.0 - lambdas_33[:, :, :] = 0.0 - - # ================================== - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - point_left[0] = particle[0, ip] - 0.5 * compact[0] - point_right[0] = particle[0, ip] + 0.5 * compact[0] - point_left[1] = particle[1, ip] - 0.5 * compact[1] - point_right[1] = particle[1, ip] + 0.5 * compact[1] - point_left[2] = particle[2, ip] - 0.5 * compact[2] - point_right[2] = particle[2, ip] + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number[0] = int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1 - cell_number[1] = int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1 - cell_number[2] = int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1 - - for i in range(p_shape[0] + 1): - grids_shapex[i] = point_left[0] + i * p_size[0] - grids_shapex[p_shape[0] + 1] = point_right[0] - - for i in range(p_shape[1] + 1): - grids_shapey[i] = point_left[1] + i * p_size[1] - grids_shapey[p_shape[1] + 1] = point_right[1] - - for i in range(p_shape[2] + 1): - grids_shapez[i] = point_left[2] + i * p_size[2] - grids_shapez[p_shape[2] + 1] = point_right[2] - - vol = 1.0 / (p_size[0] * p_size[1] * p_size[2]) - - # evaluation of function at interpolation/quadrature points - mat_11 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_21 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_31 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - - mat_12 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_22 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_32 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - - mat_13 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_23 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_33 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): # num_cell = 1, p = 1; num_cell = 2, p >= 2 - index3 = cell_left[2] + i3 - for il1 in range(2): - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1 / Nel[1] / num_cell[1] * il2 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1 / Nel[2] / num_cell[2] * il3 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[0]): - eta1 = 1.0 / Nel[0] * index1 + 1 / Nel[0] / 2.0 * il1 + pts1[jl1] - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - # ========= mapping evaluation ============= - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_11[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_21[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_31[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 2] * value_x * value_y * value_z / det_df * vol - ) - - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(2): - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / num_cell[2] * il3 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / 2.0 * il2 + pts2[jl1] - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - # ========= mapping evaluation ============= - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_12[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_22[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_32[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 2] * value_x * value_y * value_z / det_df * vol - ) - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / num_cell[1] * il2 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(2): - for jl1 in range(quad[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / 2.0 * il3 + pts3[jl1] - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - # ========= mapping evaluation ============= - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_13[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_23[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_33[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 2] * value_x * value_y * value_z / det_df * vol - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseD[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(2): - for il2 in range(num_cell[1]): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_11[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_21[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_31[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - right1[final_index1, final_index2, final_index3] += w * ( - (particle[3, ip] + ddt * mid_particle[0, ip]) * mid1 - + (particle[4, ip] + ddt * mid_particle[1, ip]) * mid2 - + (particle[5, ip] + ddt * mid_particle[2, ip]) * mid3 - ) - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseD[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(num_cell[0]): - for il2 in range(2): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_12[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_22[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_32[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - right2[final_index1, final_index2, final_index3] += w * ( - (particle[3, ip] + ddt * mid_particle[0, ip]) * mid1 - + (particle[4, ip] + ddt * mid_particle[1, ip]) * mid2 - + (particle[5, ip] + ddt * mid_particle[2, ip]) * mid3 - ) - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseD[2] - for il1 in range(num_cell[0]): - for il2 in range(num_cell[1]): - for il3 in range(2): - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_13[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_23[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_33[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - right3[final_index1, final_index2, final_index3] += w * ( - (particle[3, ip] + ddt * mid_particle[0, ip]) * mid1 - + (particle[4, ip] + ddt * mid_particle[1, ip]) * mid2 - + (particle[5, ip] + ddt * mid_particle[2, ip]) * mid3 - ) - - del mat_11 - del mat_12 - del mat_13 - del mat_21 - del mat_22 - del mat_23 - del mat_31 - del mat_32 - del mat_33 - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ============================================================================================== -def vv_push( - out: "float[:,:]", - dt: "float", - bb1: "float[:,:,:]", - bb2: "float[:,:,:]", - bb3: "float[:,:,:]", - pts1: "float[:]", - pts2: "float[:]", - pts3: "float[:]", - wts1: "float[:]", - wts2: "float[:]", - wts3: "float[:]", - Np: "int", - quad: "int[:]", - p: "int[:]", - Nel: "int[:]", - p_shape: "int[:]", - p_size: "float[:]", - particle: "float[:,:]", - lambdas_11: "float[:,:,:]", - lambdas_12: "float[:,:,:]", - lambdas_13: "float[:,:,:]", - lambdas_21: "float[:,:,:]", - lambdas_22: "float[:,:,:]", - lambdas_23: "float[:,:,:]", - lambdas_31: "float[:,:,:]", - lambdas_32: "float[:,:,:]", - lambdas_33: "float[:,:,:]", - num_cell: "int[:]", - coeff_i_x: "float[:]", - coeff_i_y: "float[:]", - coeff_i_z: "float[:]", - coeff_h_x: "float[:]", - coeff_h_y: "float[:]", - coeff_h_z: "float[:]", - NbaseN: "int[:]", - NbaseD: "int[:]", - related: "int[:]", - Np_loc: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, floor, zeros - - cell_left = zeros(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - cell_number = zeros(3, dtype=int) - compact = zeros(3, dtype=float) - - vel = zeros(3, dtype=float) - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = zeros((3, 3), dtype=float) - dft = zeros((3, 3), dtype=float) - - grids_shapex = zeros(p_shape[0] + 2, dtype=float) - grids_shapey = zeros(p_shape[1] + 2, dtype=float) - grids_shapez = zeros(p_shape[2] + 2, dtype=float) - # ==================================== - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (i, grids_shapex, grids_shapey, grids_shapez, vel, mid1, mid2, mid3, ip, w, det_df, vol, lambdas_11, lambdas_12, lambdas_13, lambdas_21, lambdas_22, lambdas_23, lambdas_31, lambdas_32, lambdas_33, cell_left, point_left, point_right, cell_number, compact, mat_11, mat_12, mat_13, mat_21, mat_22, mat_23, mat_31, mat_32, mat_33, i1, i2, i3, il1, il2, il3, jl1, index1, index2, index3, value_x, value_y, value_z, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, dft, eta1, eta2, eta3, final_index1, final_index2, final_index3, lambda_index1, lambda_index2, lambda_index3, f_int) - for ip in range(Np_loc): - vel[:] = 0.0 - - w = particle[6, ip] / Np - - lambdas_11[:, :, :] = 0.0 - lambdas_12[:, :, :] = 0.0 - lambdas_13[:, :, :] = 0.0 - - lambdas_21[:, :, :] = 0.0 - lambdas_22[:, :, :] = 0.0 - lambdas_23[:, :, :] = 0.0 - - lambdas_31[:, :, :] = 0.0 - lambdas_32[:, :, :] = 0.0 - lambdas_33[:, :, :] = 0.0 - - # ================================== - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - point_left[0] = particle[0, ip] - 0.5 * compact[0] - point_right[0] = particle[0, ip] + 0.5 * compact[0] - point_left[1] = particle[1, ip] - 0.5 * compact[1] - point_right[1] = particle[1, ip] + 0.5 * compact[1] - point_left[2] = particle[2, ip] - 0.5 * compact[2] - point_right[2] = particle[2, ip] + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number[0] = int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1 - cell_number[1] = int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1 - cell_number[2] = int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1 - - for i in range(p_shape[0] + 1): - grids_shapex[i] = point_left[0] + i * p_size[0] - grids_shapex[p_shape[0] + 1] = point_right[0] - - for i in range(p_shape[1] + 1): - grids_shapey[i] = point_left[1] + i * p_size[1] - grids_shapey[p_shape[1] + 1] = point_right[1] - - for i in range(p_shape[2] + 1): - grids_shapez[i] = point_left[2] + i * p_size[2] - grids_shapez[p_shape[2] + 1] = point_right[2] - - vol = 1.0 / (p_size[0] * p_size[1] * p_size[2]) - - # evaluation of function at interpolation/quadrature points - mat_11 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_21 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_31 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - - mat_12 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_22 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_32 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - - mat_13 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_23 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_33 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): # num_cell = 1, p = 1; num_cell = 2, p >= 2 - index3 = cell_left[2] + i3 - for il1 in range(2): - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1 / Nel[1] / num_cell[1] * il2 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1 / Nel[2] / num_cell[2] * il3 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[0]): - eta1 = 1.0 / Nel[0] * index1 + 1 / Nel[0] / 2.0 * il1 + pts1[jl1] - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - # ========= mapping evaluation ============= - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_11[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_21[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_31[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 2] * value_x * value_y * value_z / det_df * vol - ) - - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(2): - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / num_cell[2] * il3 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / 2.0 * il2 + pts2[jl1] - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - # ========= mapping evaluation ============= - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_12[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_22[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_32[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 2] * value_x * value_y * value_z / det_df * vol - ) - - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / num_cell[1] * il2 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(2): - for jl1 in range(quad[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / 2.0 * il3 + pts3[jl1] - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - # ========= mapping evaluation ============= - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_13[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_23[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_33[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 2] * value_x * value_y * value_z / det_df * vol - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseD[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(2): - for il2 in range(num_cell[1]): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_11[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[0] += mid1 * bb1[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_21[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[1] += mid2 * bb1[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_31[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[2] += mid3 * bb1[final_index1, final_index2, final_index3] - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseD[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(num_cell[0]): - for il2 in range(2): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_12[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[0] += mid1 * bb2[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_22[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[1] += mid2 * bb2[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_32[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[2] += mid3 * bb2[final_index1, final_index2, final_index3] - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseD[2] - for il1 in range(num_cell[0]): - for il2 in range(num_cell[1]): - for il3 in range(2): - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_13[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[0] += mid1 * bb3[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_23[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[1] += mid2 * bb3[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_33[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[2] += mid3 * bb3[final_index1, final_index2, final_index3] - - out[0, ip] = vel[0] - out[1, ip] = vel[1] - out[2, ip] = vel[2] - - del mat_11 - del mat_12 - del mat_13 - del mat_21 - del mat_22 - del mat_23 - del mat_31 - del mat_32 - del mat_33 - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/shape_function_projectors_L2.py b/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/shape_function_projectors_L2.py deleted file mode 100644 index 137df7f09..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/shape_function_projectors_L2.py +++ /dev/null @@ -1,979 +0,0 @@ -# coding: utf-8 -# - -""" -Classes for local projectors in 1D and 3D based on quasi-spline interpolation and histopolation. -""" - -import cunumpy as xp -import scipy.sparse as spa -from psydac.ddm.mpi import mpi as MPI - -import struphy.feec.bsplines as bsp -import struphy.feec.projectors.shape_pro_local.shape_L2_projector_kernel as ker_loc - - -# ======================= 3d ==================================== -class projectors_L2_3d: - """ - L2 projectors pi_0, pi_1, pi_2 and pi_3 in 3d. - - Parameters - ---------- - tensor_space : tensor_spline_space - a 3d tensor product space of B-splines - - n_quad : list of ints - number of quadrature points per integration interval for histopolations - """ - - def __init__(self, tensor_space, p_shape, p_size, NbaseN, NbaseD, mpi_comm): - self.kind = "l2" # kind of projector - - self.tensor_space = tensor_space # 3D tensor-product B-splines space - self.mpi_rank = mpi_comm.Get_rank() - self.T = tensor_space.T # knot vector - self.p = tensor_space.p # spline degree - self.bc = tensor_space.spl_kind # boundary conditions - self.el_b = tensor_space.el_b # element boundaries - - self.Nel = tensor_space.Nel # number of elements - self.NbaseN = tensor_space.NbaseN # number of basis functions (N) - self.NbaseD = tensor_space.NbaseD # number of basis functions (D) - - self.n_quad = tensor_space.n_quad # number of quadrature point per integration interval - self.pts = tensor_space.pts - self.wts = tensor_space.wts - self.basisN = tensor_space.basisN - self.basisD = tensor_space.basisD - self.indN = tensor_space.indN - self.indD = tensor_space.indD - self.polar = False # local projectors for polar splines are not implemented yet - - self.lambdas_0 = xp.zeros((NbaseN[0], NbaseN[1], NbaseN[2]), dtype=float) - self.potential_lambdas_0 = xp.zeros((NbaseN[0], NbaseN[1], NbaseN[2]), dtype=float) - - self.lambdas_1_11 = xp.zeros((NbaseD[0], NbaseN[1], NbaseN[2]), dtype=float) - self.lambdas_1_12 = xp.zeros((NbaseN[0], NbaseD[1], NbaseN[2]), dtype=float) - self.lambdas_1_13 = xp.zeros((NbaseN[0], NbaseN[1], NbaseD[2]), dtype=float) - - self.lambdas_1_21 = xp.zeros((NbaseD[0], NbaseN[1], NbaseN[2]), dtype=float) - self.lambdas_1_22 = xp.zeros((NbaseN[0], NbaseD[1], NbaseN[2]), dtype=float) - self.lambdas_1_23 = xp.zeros((NbaseN[0], NbaseN[1], NbaseD[2]), dtype=float) - - self.lambdas_1_31 = xp.zeros((NbaseD[0], NbaseN[1], NbaseN[2]), dtype=float) - self.lambdas_1_32 = xp.zeros((NbaseN[0], NbaseD[1], NbaseN[2]), dtype=float) - self.lambdas_1_33 = xp.zeros((NbaseN[0], NbaseN[1], NbaseD[2]), dtype=float) - - self.lambdas_2_11 = xp.zeros((NbaseN[0], NbaseD[1], NbaseD[2]), dtype=float) - self.lambdas_2_12 = xp.zeros((NbaseD[0], NbaseN[1], NbaseD[2]), dtype=float) - self.lambdas_2_13 = xp.zeros((NbaseD[0], NbaseD[1], NbaseN[2]), dtype=float) - - self.lambdas_2_21 = xp.zeros((NbaseN[0], NbaseD[1], NbaseD[2]), dtype=float) - self.lambdas_2_22 = xp.zeros((NbaseD[0], NbaseN[1], NbaseD[2]), dtype=float) - self.lambdas_2_23 = xp.zeros((NbaseD[0], NbaseD[1], NbaseN[2]), dtype=float) - - self.lambdas_2_31 = xp.zeros((NbaseN[0], NbaseD[1], NbaseD[2]), dtype=float) - self.lambdas_2_32 = xp.zeros((NbaseD[0], NbaseN[1], NbaseD[2]), dtype=float) - self.lambdas_2_33 = xp.zeros((NbaseD[0], NbaseD[1], NbaseN[2]), dtype=float) - - self.lambdas_3 = xp.zeros((NbaseD[0], NbaseD[1], NbaseD[2]), dtype=float) - - self.p_size = p_size - self.p_shape = p_shape - - self.related = xp.zeros(3, dtype=int) - for a in range(3): - # self.related[a] = int(xp.floor(NbaseN[a]/2.0)) - self.related[a] = int( - xp.floor((3 * int((self.p_size[a] * (self.p_shape[a] + 1)) * self.Nel[a] + 1) + 3 * self.p[a]) / 2.0), - ) - if (2 * self.related[a] + 1) > NbaseN[a]: - self.related[a] = int(xp.floor(NbaseN[a] / 2.0)) - - self.kernel_0_loc = xp.zeros( - ( - NbaseN[0], - NbaseN[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.kernel_1_11_loc = xp.zeros( - ( - NbaseD[0], - NbaseN[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - self.kernel_1_12_loc = xp.zeros( - ( - NbaseD[0], - NbaseN[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - self.kernel_1_13_loc = xp.zeros( - ( - NbaseD[0], - NbaseN[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.kernel_1_22_loc = xp.zeros( - ( - NbaseN[0], - NbaseD[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - self.kernel_1_23_loc = xp.zeros( - ( - NbaseN[0], - NbaseD[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.kernel_1_33_loc = xp.zeros( - ( - NbaseN[0], - NbaseN[1], - NbaseD[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.right_loc_1 = xp.zeros((NbaseD[0], NbaseN[1], NbaseN[2]), dtype=float) - self.right_loc_2 = xp.zeros((NbaseN[0], NbaseD[1], NbaseN[2]), dtype=float) - self.right_loc_3 = xp.zeros((NbaseN[0], NbaseN[1], NbaseD[2]), dtype=float) - - if self.mpi_rank == 0: - self.kernel_0 = xp.zeros( - ( - NbaseN[0], - NbaseN[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.kernel_1_11 = xp.zeros( - ( - NbaseD[0], - NbaseN[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - self.kernel_1_12 = xp.zeros( - ( - NbaseN[0], - NbaseD[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - self.kernel_1_13 = xp.zeros( - ( - NbaseN[0], - NbaseN[1], - NbaseD[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.kernel_1_22 = xp.zeros( - ( - NbaseN[0], - NbaseD[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - self.kernel_1_23 = xp.zeros( - ( - NbaseN[0], - NbaseN[1], - NbaseD[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.kernel_1_33 = xp.zeros( - ( - NbaseN[0], - NbaseN[1], - NbaseD[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.right_1 = xp.zeros((NbaseD[0], NbaseN[1], NbaseN[2]), dtype=float) - self.right_2 = xp.zeros((NbaseN[0], NbaseD[1], NbaseN[2]), dtype=float) - self.right_3 = xp.zeros((NbaseN[0], NbaseN[1], NbaseD[2]), dtype=float) - - else: - self.kernel_0 = None - - self.kernel_1_11 = None - self.kernel_1_12 = None - self.kernel_1_13 = None - - self.kernel_1_22 = None - self.kernel_1_23 = None - - self.kernel_1_33 = None - - self.right_1 = None - self.right_2 = None - self.right_3 = None - - def accumulate_0_form(self, mpi_comm): - # blocks of global mass matrix - - mpi_comm.Reduce(self.kernel_0_loc, self.kernel_0, op=MPI.SUM, root=0) - - # ================ matrix in V0 =========================== - def assemble_0_form(self, tensor_space_FEM, mpi_comm): - """ - Assembles the 3D mass matrix [[NNN NNN]] * |det(DF)| of the given tensor product B-spline spaces of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from hylife.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - """ - # assembly of global mass matrix - Ni = tensor_space_FEM.Nbase_0form - Nj = tensor_space_FEM.Nbase_0form - - # conversion to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Ni[2] * col1 + Ni[2] * col2 + col3 - - M = spa.csr_matrix( - (self.kernel_0.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - - M.eliminate_zeros() - - return M - - # ================ matrix in V1 =========================== - def accumulate_1_form(self, mpi_comm): - # blocks of global mass matrix - mpi_comm.Reduce(self.kernel_1_11_loc, self.kernel_1_11, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.kernel_1_12_loc, self.kernel_1_12, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.kernel_1_13_loc, self.kernel_1_13, op=MPI.SUM, root=0) - - mpi_comm.Reduce(self.kernel_1_22_loc, self.kernel_1_22, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.kernel_1_23_loc, self.kernel_1_23, op=MPI.SUM, root=0) - - mpi_comm.Reduce(self.kernel_1_33_loc, self.kernel_1_33, op=MPI.SUM, root=0) - - mpi_comm.Reduce(self.right_loc_1, self.right_1, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.right_loc_2, self.right_2, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.right_loc_3, self.right_3, op=MPI.SUM, root=0) - - def assemble_1_form(self, tensor_space_FEM): - """ - Assembles the 3D mass matrix [[DNN DNN, DNN NDN, DNN NND], [NDN DNN, NDN NDN, NDN NND], [NND DNN, NND NDN, NND NND]] * G^(-1) * |det(DF)| of the given tensor product B-spline spaces of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from hylife.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - """ - # === 11 component ===== - a = 0 - b = 0 - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - # convert to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M11 = spa.csr_matrix( - (self.kernel_1_11.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M11.eliminate_zeros() - - # === 12 component ===== - a = 0 - b = 1 - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - # convert to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M12 = spa.csr_matrix( - (self.kernel_1_12.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M12.eliminate_zeros() - - # === 13 component ===== - a = 0 - b = 2 - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - # convert to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M13 = spa.csr_matrix( - (self.kernel_1_13.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M13.eliminate_zeros() - - # === 22 component ===== - a = 1 - b = 1 - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - # convert to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M22 = spa.csr_matrix( - (self.kernel_1_22.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M22.eliminate_zeros() - - # === 23 component ===== - a = 1 - b = 2 - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - # convert to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M23 = spa.csr_matrix( - (self.kernel_1_23.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M23.eliminate_zeros() - - # === 33 component ===== - a = 2 - b = 2 - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - # convert to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M33 = spa.csr_matrix( - (self.kernel_1_33.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M33.eliminate_zeros() - - # final block matrix - M = spa.bmat([[M11, M12, M13], [M12.T, M22, M23], [M13.T, M23.T, M33]], format="csr") - # print('insider_check', self.kernel_1_33) - return (M, xp.concatenate((self.right_1.flatten(), self.right_2.flatten(), self.right_3.flatten()))) - - def heavy_test(self, test1, test2, test3, acc, particles_loc, Np, domain): - ker_loc.kernel_1_heavy( - self.basisN[0], - self.basisN[1], - self.basisN[2], - self.basisD[0], - self.basisD[1], - self.basisD[2], - self.indN[0], - self.indN[1], - self.indN[2], - self.indD[0], - self.indD[1], - self.indD[2], - self.pts[0], - self.pts[1], - self.pts[2], - self.wts[0], - self.wts[1], - self.wts[2], - test1, - test2, - test3, - acc.oneform_temp1, - acc.oneform_temp2, - acc.oneform_temp3, - Np, - self.n_quad, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - self.lambdas_1_11, - self.lambdas_1_12, - self.lambdas_1_13, - self.lambdas_1_21, - self.lambdas_1_22, - self.lambdas_1_23, - self.lambdas_1_31, - self.lambdas_1_32, - self.lambdas_1_33, - self.NbaseN, - self.NbaseD, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - # ker_loc.kernel_1_heavy(self.pts[0][0], self.pts[1][0], self.pts[2][0], self.wts[0][0], self.wts[1][0], self.wts[2][0], test1, test2, test3, acc.oneform_temp1, acc.oneform_temp2, acc.oneform_temp3, Np, self.n_quad, self.p, self.Nel, self.p_shape, self.p_size, particles_loc, self.lambdas_1_11, self.lambdas_1_12, self.lambdas_1_13, self.lambdas_1_21, self.lambdas_1_22, self.lambdas_1_23, self.lambdas_1_31, self.lambdas_1_32, self.lambdas_1_33, self.num_cell, self.coeff_i[0], self.coeff_i[1], self.coeff_i[2], self.coeff_h[0], self.coeff_h[1], self.coeff_h[2], self.NbaseN, self.NbaseD, particles_loc.shape[1], domain.kind_map, domain.params, domain.T[0], domain.T[1], domain.T[2], domain.p, domain.Nel, domain.NbaseN, domain.cx, domain.cy, domain.cz) - - def potential_pi_0(self, particles_loc, Np, domain, mpi_comm): - """ - Local projector on the discrete space V0. - - Parameters - ---------- - - Returns - ------- - kernel_0 matrix - """ - if self.bc[0] and self.bc[1] and self.bc[2]: - ker_loc.potential_kernel_0_form( - Np, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - self.lambdas_0, - self.kernel_0_loc, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.NbaseN, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - else: - print("non-periodic case not implemented!!!") - - mpi_comm.Reduce(self.lambdas_0, self.potential_lambdas_0, op=MPI.SUM, root=0) - # print('check_lambdas', self.lambdas_0) - - def S_pi_0(self, particles_loc, Np, domain): - """ - Local projector on the discrete space V0. - - Parameters - ---------- - - Returns - ------- - kernel_0 matrix - """ - self.kernel_0[:, :, :, :, :, :] = 0.0 - if self.bc[0] and self.bc[1] and self.bc[2]: - ker_loc.kernel_0_form( - Np, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - self.lambdas_0, - self.kernel_0_loc, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.NbaseN, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - else: - print("non-periodic case not implemented!!!") - - # print('check_lambdas', self.lambdas_0) - - def S_pi_1(self, particles_loc, Np, domain): - """ - Local projector on the discrete space V1. - - Parameters - ---------- - pts : quadrature point in the first half cell - wts : quadrature weight in the first half cell - quad: shape of pts or wts - - Returns - ------- - lambdas : array_like - the coefficients in V0 corresponding to the projected function - """ - self.kernel_1_11_loc[:, :, :, :, :, :] = 0.0 - self.kernel_1_12_loc[:, :, :, :, :, :] = 0.0 - self.kernel_1_13_loc[:, :, :, :, :, :] = 0.0 - - self.kernel_1_22_loc[:, :, :, :, :, :] = 0.0 - self.kernel_1_23_loc[:, :, :, :, :, :] = 0.0 - - self.kernel_1_33_loc[:, :, :, :, :, :] = 0.0 - - self.right_loc_1[:, :, :] = 0.0 - self.right_loc_2[:, :, :] = 0.0 - self.right_loc_3[:, :, :] = 0.0 - - if self.bc[0] and self.bc[1] and self.bc[2]: - ker_loc.kernel_1_form( - self.indN[0], - self.indN[1], - self.indN[2], - self.indD[0], - self.indD[1], - self.indD[2], - self.right_loc_1, - self.right_loc_2, - self.right_loc_3, - self.basisN[0], - self.basisN[1], - self.basisN[2], - self.basisD[0], - self.basisD[1], - self.basisD[2], - self.pts[0], - self.pts[1], - self.pts[2], - self.wts[0], - self.wts[1], - self.wts[2], - Np, - self.n_quad, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - self.lambdas_1_11, - self.lambdas_1_12, - self.lambdas_1_13, - self.lambdas_1_21, - self.lambdas_1_22, - self.lambdas_1_23, - self.lambdas_1_31, - self.lambdas_1_32, - self.lambdas_1_33, - self.kernel_1_11_loc, - self.kernel_1_12_loc, - self.kernel_1_13_loc, - self.kernel_1_22_loc, - self.kernel_1_23_loc, - self.kernel_1_33_loc, - self.NbaseN, - self.NbaseD, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - else: - print("non-periodic case not implemented!!!") - - def vv_S1(self, particles_loc, Np, domain, index_label, accvv, dt, mpi_comm): - if self.bc[0] and self.bc[1] and self.bc[2]: - if index_label == 1: - ker_loc.vv_1_form( - self.wts[0][0], - self.wts[1][0], - self.wts[2][0], - self.pts[0][0], - self.pts[1][0], - self.pts[2][0], - 0.0, - self.right_loc_1, - self.right_loc_2, - self.right_loc_3, - Np, - self.n_quad, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - accvv.mid_particles, - self.lambdas_1_11, - self.lambdas_1_12, - self.lambdas_1_13, - self.lambdas_1_21, - self.lambdas_1_22, - self.lambdas_1_23, - self.lambdas_1_31, - self.lambdas_1_32, - self.lambdas_1_33, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_h[2], - self.NbaseN, - self.NbaseD, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif index_label == 2: - ker_loc.vv_1_form( - self.wts[0][0], - self.wts[1][0], - self.wts[2][0], - self.pts[0][0], - self.pts[1][0], - self.pts[2][0], - 0.5 * dt, - self.right_loc_1, - self.right_loc_2, - self.right_loc_3, - Np, - self.n_quad, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - accvv.stage1_out_loc, - self.lambdas_1_11, - self.lambdas_1_12, - self.lambdas_1_13, - self.lambdas_1_21, - self.lambdas_1_22, - self.lambdas_1_23, - self.lambdas_1_31, - self.lambdas_1_32, - self.lambdas_1_33, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_h[2], - self.NbaseN, - self.NbaseD, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif index_label == 3: - ker_loc.vv_1_form( - self.wts[0][0], - self.wts[1][0], - self.wts[2][0], - self.pts[0][0], - self.pts[1][0], - self.pts[2][0], - 0.5 * dt, - self.right_loc_1, - self.right_loc_2, - self.right_loc_3, - Np, - self.n_quad, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - accvv.stage2_out_loc, - self.lambdas_1_11, - self.lambdas_1_12, - self.lambdas_1_13, - self.lambdas_1_21, - self.lambdas_1_22, - self.lambdas_1_23, - self.lambdas_1_31, - self.lambdas_1_32, - self.lambdas_1_33, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_h[2], - self.NbaseN, - self.NbaseD, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif index_label == 4: - ker_loc.vv_1_form( - self.wts[0][0], - self.wts[1][0], - self.wts[2][0], - self.pts[0][0], - self.pts[1][0], - self.pts[2][0], - dt, - self.right_loc_1, - self.right_loc_2, - self.right_loc_3, - Np, - self.n_quad, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - accvv.stage3_out_loc, - self.lambdas_1_11, - self.lambdas_1_12, - self.lambdas_1_13, - self.lambdas_1_21, - self.lambdas_1_22, - self.lambdas_1_23, - self.lambdas_1_31, - self.lambdas_1_32, - self.lambdas_1_33, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_h[2], - self.NbaseN, - self.NbaseD, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - mpi_comm.Reduce(self.right_loc_1, accvv.vec1, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.right_loc_2, accvv.vec2, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.right_loc_3, accvv.vec3, op=MPI.SUM, root=0) diff --git a/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/shape_function_projectors_local.py b/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/shape_function_projectors_local.py deleted file mode 100644 index 2ebb497a3..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/shape_function_projectors_local.py +++ /dev/null @@ -1,1148 +0,0 @@ -# coding: utf-8 -# - -""" -Classes for local projectors in 1D and 3D based on quasi-spline interpolation and histopolation. -""" - -import cunumpy as xp -import scipy.sparse as spa -from psydac.ddm.mpi import mpi as MPI - -import struphy.feec.bsplines as bsp -import struphy.feec.projectors.shape_pro_local.shape_local_projector_kernel as ker_loc - - -# ======================= 3d ==================================== -class projectors_local_3d: - """ - Local commuting projectors pi_0, pi_1, pi_2 and pi_3 in 3d with smoothed delta functions - only the periodic case is implemented. - Parameters - ---------- - tensor_space : tensor_spline_space - a 3d tensor product space of B-splines - - n_quad : list of ints - number of quadrature points per integration interval for histopolations - - p_shape: list of ints B-spline degrees of shape functions in three directions - p_size : list of doubles cell size of smoothed delta function in three directions - NbaseN : list of ints number of N splines in three directions - NbaseD : list of ints number of D splines in three directions - mpi_commm: mpi encironment - """ - - def __init__(self, tensor_space, n_quad, p_shape, p_size, NbaseN, NbaseD, mpi_comm): - self.kind = "local" # kind of projector - - self.tensor_space = tensor_space # 3D tensor-product B-splines space - self.mpi_rank = mpi_comm.Get_rank() - self.T = tensor_space.T # knot vector - self.p = tensor_space.p # spline degree - self.bc = tensor_space.spl_kind # boundary conditions - self.el_b = tensor_space.el_b # element boundaries - - self.Nel = tensor_space.Nel # number of elements - self.NbaseN = tensor_space.NbaseN # number of basis functions (N) - self.NbaseD = tensor_space.NbaseD # number of basis functions (D) - - self.n_quad = n_quad # number of quadrature point per integration interval - - self.polar = False # local projectors for polar splines are not implemented yet - - self.lambdas_0 = xp.zeros((NbaseN[0], NbaseN[1], NbaseN[2]), dtype=float) - self.potential_lambdas_0 = xp.zeros((NbaseN[0], NbaseN[1], NbaseN[2]), dtype=float) - - self.lambdas_1_11 = xp.zeros((NbaseD[0], NbaseN[1], NbaseN[2]), dtype=float) - self.lambdas_1_12 = xp.zeros((NbaseN[0], NbaseD[1], NbaseN[2]), dtype=float) - self.lambdas_1_13 = xp.zeros((NbaseN[0], NbaseN[1], NbaseD[2]), dtype=float) - - self.lambdas_1_21 = xp.zeros((NbaseD[0], NbaseN[1], NbaseN[2]), dtype=float) - self.lambdas_1_22 = xp.zeros((NbaseN[0], NbaseD[1], NbaseN[2]), dtype=float) - self.lambdas_1_23 = xp.zeros((NbaseN[0], NbaseN[1], NbaseD[2]), dtype=float) - - self.lambdas_1_31 = xp.zeros((NbaseD[0], NbaseN[1], NbaseN[2]), dtype=float) - self.lambdas_1_32 = xp.zeros((NbaseN[0], NbaseD[1], NbaseN[2]), dtype=float) - self.lambdas_1_33 = xp.zeros((NbaseN[0], NbaseN[1], NbaseD[2]), dtype=float) - - self.lambdas_2_11 = xp.zeros((NbaseN[0], NbaseD[1], NbaseD[2]), dtype=float) - self.lambdas_2_12 = xp.zeros((NbaseD[0], NbaseN[1], NbaseD[2]), dtype=float) - self.lambdas_2_13 = xp.zeros((NbaseD[0], NbaseD[1], NbaseN[2]), dtype=float) - - self.lambdas_2_21 = xp.zeros((NbaseN[0], NbaseD[1], NbaseD[2]), dtype=float) - self.lambdas_2_22 = xp.zeros((NbaseD[0], NbaseN[1], NbaseD[2]), dtype=float) - self.lambdas_2_23 = xp.zeros((NbaseD[0], NbaseD[1], NbaseN[2]), dtype=float) - - self.lambdas_2_31 = xp.zeros((NbaseN[0], NbaseD[1], NbaseD[2]), dtype=float) - self.lambdas_2_32 = xp.zeros((NbaseD[0], NbaseN[1], NbaseD[2]), dtype=float) - self.lambdas_2_33 = xp.zeros((NbaseD[0], NbaseD[1], NbaseN[2]), dtype=float) - - self.lambdas_3 = xp.zeros((NbaseD[0], NbaseD[1], NbaseD[2]), dtype=float) - - self.p_size = p_size - self.p_shape = p_shape - - self.related = xp.zeros(3, dtype=int) - for a in range(3): - # self.related[a] = int(xp.floor(NbaseN[a]/2.0)) - self.related[a] = int( - xp.floor((3 * int((self.p_size[a] * (self.p_shape[a] + 1)) * self.Nel[a] + 1) + 3 * self.p[a]) / 2.0), - ) - if (2 * self.related[a] + 1) > NbaseN[a]: - self.related[a] = int(xp.floor(NbaseN[a] / 2.0)) - - self.kernel_0_loc = xp.zeros( - ( - NbaseN[0], - NbaseN[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.kernel_1_11_loc = xp.zeros( - ( - NbaseD[0], - NbaseN[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - self.kernel_1_12_loc = xp.zeros( - ( - NbaseD[0], - NbaseN[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - self.kernel_1_13_loc = xp.zeros( - ( - NbaseD[0], - NbaseN[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.kernel_1_22_loc = xp.zeros( - ( - NbaseN[0], - NbaseD[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - self.kernel_1_23_loc = xp.zeros( - ( - NbaseN[0], - NbaseD[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.kernel_1_33_loc = xp.zeros( - ( - NbaseN[0], - NbaseN[1], - NbaseD[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.right_loc_1 = xp.zeros((NbaseD[0], NbaseN[1], NbaseN[2]), dtype=float) - self.right_loc_2 = xp.zeros((NbaseN[0], NbaseD[1], NbaseN[2]), dtype=float) - self.right_loc_3 = xp.zeros((NbaseN[0], NbaseN[1], NbaseD[2]), dtype=float) - - if self.mpi_rank == 0: - self.kernel_0 = xp.zeros( - ( - NbaseN[0], - NbaseN[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.kernel_1_11 = xp.zeros( - ( - NbaseD[0], - NbaseN[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - self.kernel_1_12 = xp.zeros( - ( - NbaseN[0], - NbaseD[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - self.kernel_1_13 = xp.zeros( - ( - NbaseN[0], - NbaseN[1], - NbaseD[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.kernel_1_22 = xp.zeros( - ( - NbaseN[0], - NbaseD[1], - NbaseN[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - self.kernel_1_23 = xp.zeros( - ( - NbaseN[0], - NbaseN[1], - NbaseD[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.kernel_1_33 = xp.zeros( - ( - NbaseN[0], - NbaseN[1], - NbaseD[2], - 2 * self.related[0] + 1, - 2 * self.related[1] + 1, - 2 * self.related[2] + 1, - ), - dtype=float, - ) - - self.right_1 = xp.zeros((NbaseD[0], NbaseN[1], NbaseN[2]), dtype=float) - self.right_2 = xp.zeros((NbaseN[0], NbaseD[1], NbaseN[2]), dtype=float) - self.right_3 = xp.zeros((NbaseN[0], NbaseN[1], NbaseD[2]), dtype=float) - - else: - self.kernel_0 = None - - self.kernel_1_11 = None - self.kernel_1_12 = None - self.kernel_1_13 = None - - self.kernel_1_22 = None - self.kernel_1_23 = None - - self.kernel_1_33 = None - - self.right_1 = None - self.right_2 = None - self.right_3 = None - - self.num_cell = xp.empty(3, dtype=int) - for i in range(3): - if self.p[i] == 1: - self.num_cell[i] = 1 - else: - self.num_cell[i] = 2 - - # Gauss - Legendre quadrature points and weights in (-1, 1) - self.pts_loc = [xp.polynomial.legendre.leggauss(n_quad)[0] for n_quad in self.n_quad] - self.wts_loc = [xp.polynomial.legendre.leggauss(n_quad)[1] for n_quad in self.n_quad] - - self.pts = [0, 0, 0] - self.wts = [0, 0, 0] - for a in range(3): - self.pts[a], self.wts[a] = bsp.quadrature_grid( - [0, 1.0 / 2.0 / self.Nel[a]], - self.pts_loc[a], - self.wts_loc[a], - ) - # print('check_pts', self.pts[0].shape, self.pts[1].shape, self.pts[2].shape) - # print('check_pts', self.wts) - # set interpolation and histopolation coefficients - self.coeff_i = [0, 0, 0] - self.coeff_h = [0, 0, 0] - for a in range(3): - if self.bc[a]: - self.coeff_i[a] = xp.zeros(2 * self.p[a], dtype=float) - self.coeff_h[a] = xp.zeros(2 * self.p[a], dtype=float) - - if self.p[a] == 1: - self.coeff_i[a][:] = xp.array([1.0, 0.0]) - self.coeff_h[a][:] = xp.array([1.0, 1.0]) - - elif self.p[a] == 2: - self.coeff_i[a][:] = 1 / 2 * xp.array([-1.0, 4.0, -1.0, 0.0]) - self.coeff_h[a][:] = 1 / 2 * xp.array([-1.0, 3.0, 3.0, -1.0]) - - elif self.p[a] == 3: - self.coeff_i[a][:] = 1 / 6 * xp.array([1.0, -8.0, 20.0, -8.0, 1.0, 0.0]) - self.coeff_h[a][:] = 1 / 6 * xp.array([1.0, -7.0, 12.0, 12.0, -7.0, 1.0]) - - elif self.p[a] == 4: - self.coeff_i[a][:] = 2 / 45 * xp.array([-1.0, 16.0, -295 / 4, 140.0, -295 / 4, 16.0, -1.0, 0.0]) - self.coeff_h[a][:] = ( - 2 / 45 * xp.array([-1.0, 15.0, -231 / 4, 265 / 4, 265 / 4, -231 / 4, 15.0, -1.0]) - ) - - else: - print("degree > 4 not implemented!") - - else: - self.coeff_i[a] = xp.zeros((2 * self.p[a] - 1, 2 * self.p[a] - 1), dtype=float) - self.coeff_h[a] = xp.zeros((2 * self.p[a] - 1, 2 * self.p[a]), dtype=float) - - if self.p[a] == 1: - self.coeff_i[a][0, :] = xp.array([1.0]) - self.coeff_h[a][0, :] = xp.array([1.0, 1.0]) - - elif self.p[a] == 2: - self.coeff_i[a][0, :] = 1 / 2 * xp.array([2.0, 0.0, 0.0]) - self.coeff_i[a][1, :] = 1 / 2 * xp.array([-1.0, 4.0, -1.0]) - self.coeff_i[a][2, :] = 1 / 2 * xp.array([0.0, 0.0, 2.0]) - - self.coeff_h[a][0, :] = 1 / 2 * xp.array([3.0, -1.0, 0.0, 0.0]) - self.coeff_h[a][1, :] = 1 / 2 * xp.array([-1.0, 3.0, 3.0, -1.0]) - self.coeff_h[a][2, :] = 1 / 2 * xp.array([0.0, 0.0, -1.0, 3.0]) - - elif self.p[a] == 3: - self.coeff_i[a][0, :] = 1 / 18 * xp.array([18.0, 0.0, 0.0, 0.0, 0.0]) - self.coeff_i[a][1, :] = 1 / 18 * xp.array([-5.0, 40.0, -24.0, 8.0, -1.0]) - self.coeff_i[a][2, :] = 1 / 18 * xp.array([3.0, -24.0, 60.0, -24.0, 3.0]) - self.coeff_i[a][3, :] = 1 / 18 * xp.array([-1.0, 8.0, -24.0, 40.0, -5.0]) - self.coeff_i[a][4, :] = 1 / 18 * xp.array([0.0, 0.0, 0.0, 0.0, 18.0]) - - self.coeff_h[a][0, :] = 1 / 18 * xp.array([23.0, -17.0, 7.0, -1.0, 0.0, 0.0]) - self.coeff_h[a][1, :] = 1 / 18 * xp.array([-8.0, 56.0, -28.0, 4.0, 0.0, 0.0]) - self.coeff_h[a][2, :] = 1 / 18 * xp.array([3.0, -21.0, 36.0, 36.0, -21.0, 3.0]) - self.coeff_h[a][3, :] = 1 / 18 * xp.array([0.0, 0.0, 4.0, -28.0, 56.0, -8.0]) - self.coeff_h[a][4, :] = 1 / 18 * xp.array([0.0, 0.0, -1.0, 7.0, -17.0, 23.0]) - - elif self.p[a] == 4: - self.coeff_i[a][0, :] = 1 / 360 * xp.array([360.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) - self.coeff_i[a][1, :] = 1 / 360 * xp.array([-59.0, 944.0, -1000.0, 720.0, -305.0, 64.0, -4.0]) - self.coeff_i[a][2, :] = 1 / 360 * xp.array([23.0, -368.0, 1580.0, -1360.0, 605.0, -128.0, 8.0]) - self.coeff_i[a][3, :] = 1 / 360 * xp.array([-16.0, 256.0, -1180.0, 2240.0, -1180.0, 256.0, -16.0]) - self.coeff_i[a][4, :] = 1 / 360 * xp.array([8.0, -128.0, 605.0, -1360.0, 1580.0, -368.0, 23.0]) - self.coeff_i[a][5, :] = 1 / 360 * xp.array([-4.0, 64.0, -305.0, 720.0, -1000.0, 944.0, -59.0]) - self.coeff_i[a][6, :] = 1 / 360 * xp.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 360.0]) - - self.coeff_h[a][0, :] = 1 / 360 * xp.array([419.0, -525.0, 475.0, -245.0, 60.0, -4.0, 0.0, 0.0]) - self.coeff_h[a][1, :] = 1 / 360 * xp.array([-82.0, 1230.0, -1350.0, 730.0, -180.0, 12.0, 0.0, 0.0]) - self.coeff_h[a][2, :] = 1 / 360 * xp.array([39.0, -585.0, 2175.0, -1425.0, 360.0, -24.0, 0.0, 0.0]) - self.coeff_h[a][3, :] = ( - 1 / 360 * xp.array([-16.0, 240.0, -924.0, 1060.0, 1060.0, -924.0, 240.0, -16.0]) - ) - self.coeff_h[a][4, :] = 1 / 360 * xp.array([0.0, 0.0, -24.0, 360.0, -1425.0, 2175.0, -585.0, 39.0]) - self.coeff_h[a][5, :] = 1 / 360 * xp.array([0.0, 0.0, 12.0, -180.0, 730.0, -1350.0, 1230.0, -82.0]) - self.coeff_h[a][6, :] = 1 / 360 * xp.array([0.0, 0.0, -4.0, 60.0, -245.0, 475.0, -525.0, 419.0]) - - else: - print("degree > 4 not implemented!") - - def accumulate_0_form(self, mpi_comm): - # blocks of global mass matrix - - mpi_comm.Reduce(self.kernel_0_loc, self.kernel_0, op=MPI.SUM, root=0) - - # ================ matrix in V0 =========================== - def assemble_0_form(self, tensor_space_FEM, mpi_comm): - """ - Assembles the 3D mass matrix [[NNN NNN]] * |det(DF)| of the given tensor product B-spline spaces of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from hylife.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - """ - # assembly of global mass matrix - Ni = tensor_space_FEM.Nbase_0form - Nj = tensor_space_FEM.Nbase_0form - - # conversion to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Ni[2] * col1 + Ni[2] * col2 + col3 - - M = spa.csr_matrix( - (self.kernel_0.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - - M.eliminate_zeros() - - return M - - # ================ matrix in V1 =========================== - def accumulate_1_form(self, mpi_comm): - # blocks of global mass matrix - mpi_comm.Reduce(self.kernel_1_11_loc, self.kernel_1_11, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.kernel_1_12_loc, self.kernel_1_12, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.kernel_1_13_loc, self.kernel_1_13, op=MPI.SUM, root=0) - - mpi_comm.Reduce(self.kernel_1_22_loc, self.kernel_1_22, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.kernel_1_23_loc, self.kernel_1_23, op=MPI.SUM, root=0) - - mpi_comm.Reduce(self.kernel_1_33_loc, self.kernel_1_33, op=MPI.SUM, root=0) - - mpi_comm.Reduce(self.right_loc_1, self.right_1, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.right_loc_2, self.right_2, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.right_loc_3, self.right_3, op=MPI.SUM, root=0) - - def assemble_1_form(self, tensor_space_FEM): - """ - Assembles the 3D mass matrix [[DNN DNN, DNN NDN, DNN NND], [NDN DNN, NDN NDN, NDN NND], [NND DNN, NND NDN, NND NND]] * G^(-1) * |det(DF)| of the given tensor product B-spline spaces of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from hylife.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - """ - # === 11 component ===== - a = 0 - b = 0 - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - # convert to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M11 = spa.csr_matrix( - (self.kernel_1_11.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M11.eliminate_zeros() - - # === 12 component ===== - a = 0 - b = 1 - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - # convert to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M12 = spa.csr_matrix( - (self.kernel_1_12.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M12.eliminate_zeros() - - # === 13 component ===== - a = 0 - b = 2 - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - # convert to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M13 = spa.csr_matrix( - (self.kernel_1_13.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M13.eliminate_zeros() - - # === 22 component ===== - a = 1 - b = 1 - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - # convert to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M22 = spa.csr_matrix( - (self.kernel_1_22.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M22.eliminate_zeros() - - # === 23 component ===== - a = 1 - b = 2 - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - # convert to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M23 = spa.csr_matrix( - (self.kernel_1_23.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M23.eliminate_zeros() - - # === 33 component ===== - a = 2 - b = 2 - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - # convert to sparse matrix - indices = xp.indices( - (Ni[0], Ni[1], Ni[2], 2 * self.related[0] + 1, 2 * self.related[1] + 1, 2 * self.related[2] + 1), - ) - - shift = [xp.arange(Ni) - offset for Ni, offset in zip(Ni, self.related)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M33 = spa.csr_matrix( - (self.kernel_1_33.flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M33.eliminate_zeros() - - # final block matrix - M = spa.bmat([[M11, M12, M13], [M12.T, M22, M23], [M13.T, M23.T, M33]], format="csr") - # print('insider_check', self.kernel_1_33) - return (M, xp.concatenate((self.right_1.flatten(), self.right_2.flatten(), self.right_3.flatten()))) - - def heavy_test(self, test1, test2, test3, acc, particles_loc, Np, domain): - ker_loc.kernel_1_heavy( - self.pts[0][0], - self.pts[1][0], - self.pts[2][0], - self.wts[0][0], - self.wts[1][0], - self.wts[2][0], - test1, - test2, - test3, - acc.oneform_temp1, - acc.oneform_temp2, - acc.oneform_temp3, - Np, - self.n_quad, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - self.lambdas_1_11, - self.lambdas_1_12, - self.lambdas_1_13, - self.lambdas_1_21, - self.lambdas_1_22, - self.lambdas_1_23, - self.lambdas_1_31, - self.lambdas_1_32, - self.lambdas_1_33, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_h[2], - self.NbaseN, - self.NbaseD, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - def potential_pi_0(self, particles_loc, Np, domain, mpi_comm): - """ - Local projector on the discrete space V0. - - Parameters - ---------- - - Returns - ------- - kernel_0 matrix - """ - if self.bc[0] and self.bc[1] and self.bc[2]: - ker_loc.potential_kernel_0_form( - Np, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - self.lambdas_0, - self.kernel_0_loc, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.NbaseN, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - else: - print("non-periodic case not implemented!!!") - - mpi_comm.Reduce(self.lambdas_0, self.potential_lambdas_0, op=MPI.SUM, root=0) - # print('check_lambdas', self.lambdas_0) - - def S_pi_0(self, particles_loc, Np, domain): - """ - Local projector on the discrete space V0. - - Parameters - ---------- - - Returns - ------- - kernel_0 matrix - """ - self.kernel_0[:, :, :, :, :, :] = 0.0 - if self.bc[0] and self.bc[1] and self.bc[2]: - ker_loc.kernel_0_form( - Np, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - self.lambdas_0, - self.kernel_0_loc, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.NbaseN, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - else: - print("non-periodic case not implemented!!!") - - # print('check_lambdas', self.lambdas_0) - - def S_pi_1(self, particles_loc, Np, domain): - """ - Local projector on the discrete space V1. - - Parameters - ---------- - pts : quadrature point in the first half cell - wts : quadrature weight in the first half cell - quad: shape of pts or wts - - Returns - ------- - lambdas : array_like - the coefficients in V0 corresponding to the projected function - """ - self.kernel_1_11_loc[:, :, :, :, :, :] = 0.0 - self.kernel_1_12_loc[:, :, :, :, :, :] = 0.0 - self.kernel_1_13_loc[:, :, :, :, :, :] = 0.0 - - self.kernel_1_22_loc[:, :, :, :, :, :] = 0.0 - self.kernel_1_23_loc[:, :, :, :, :, :] = 0.0 - - self.kernel_1_33_loc[:, :, :, :, :, :] = 0.0 - - self.right_loc_1[:, :, :] = 0.0 - self.right_loc_2[:, :, :] = 0.0 - self.right_loc_3[:, :, :] = 0.0 - - if self.bc[0] and self.bc[1] and self.bc[2]: - ker_loc.kernel_1_form( - self.right_loc_1, - self.right_loc_2, - self.right_loc_3, - self.pts[0][0], - self.pts[1][0], - self.pts[2][0], - self.wts[0][0], - self.wts[1][0], - self.wts[2][0], - Np, - self.n_quad, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - self.lambdas_1_11, - self.lambdas_1_12, - self.lambdas_1_13, - self.lambdas_1_21, - self.lambdas_1_22, - self.lambdas_1_23, - self.lambdas_1_31, - self.lambdas_1_32, - self.lambdas_1_33, - self.kernel_1_11_loc, - self.kernel_1_12_loc, - self.kernel_1_13_loc, - self.kernel_1_22_loc, - self.kernel_1_23_loc, - self.kernel_1_33_loc, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_h[2], - self.NbaseN, - self.NbaseD, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - else: - print("non-periodic case not implemented!!!") - - def S_pi_01(self, particles_loc, Np, domain): - """ - Local projector on the discrete space V1. - - Parameters - ---------- - pts : quadrature point in the first half cell - wts : quadrature weight in the first half cell - quad: shape of pts or wts - - Returns - ------- - lambdas : array_like - the coefficients in V0 corresponding to the projected function - """ - self.kernel_1_11_loc[:, :, :, :, :, :] = 0.0 - self.kernel_1_12_loc[:, :, :, :, :, :] = 0.0 - self.kernel_1_13_loc[:, :, :, :, :, :] = 0.0 - - self.kernel_1_22_loc[:, :, :, :, :, :] = 0.0 - self.kernel_1_23_loc[:, :, :, :, :, :] = 0.0 - - self.kernel_1_33_loc[:, :, :, :, :, :] = 0.0 - - self.right_loc_1[:, :, :] = 0.0 - self.right_loc_2[:, :, :] = 0.0 - self.right_loc_3[:, :, :] = 0.0 - - if self.bc[0] and self.bc[1] and self.bc[2]: - ker_loc.kernel_01_form( - self.right_loc_1, - self.right_loc_2, - self.right_loc_3, - Np, - self.n_quad, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - self.lambdas_1_11, - self.lambdas_1_12, - self.lambdas_1_13, - self.lambdas_1_21, - self.lambdas_1_22, - self.lambdas_1_23, - self.lambdas_1_31, - self.lambdas_1_32, - self.lambdas_1_33, - self.kernel_1_11_loc, - self.kernel_1_12_loc, - self.kernel_1_13_loc, - self.kernel_1_22_loc, - self.kernel_1_23_loc, - self.kernel_1_33_loc, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.NbaseN, - self.NbaseD, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - else: - print("non-periodic case not implemented!!!") - - def vv_S1(self, particles_loc, Np, domain, index_label, accvv, dt, mpi_comm): - if self.bc[0] and self.bc[1] and self.bc[2]: - if index_label == 1: - ker_loc.vv_1_form( - self.wts[0][0], - self.wts[1][0], - self.wts[2][0], - self.pts[0][0], - self.pts[1][0], - self.pts[2][0], - 0.0, - self.right_loc_1, - self.right_loc_2, - self.right_loc_3, - Np, - self.n_quad, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - accvv.mid_particles, - self.lambdas_1_11, - self.lambdas_1_12, - self.lambdas_1_13, - self.lambdas_1_21, - self.lambdas_1_22, - self.lambdas_1_23, - self.lambdas_1_31, - self.lambdas_1_32, - self.lambdas_1_33, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_h[2], - self.NbaseN, - self.NbaseD, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif index_label == 2: - ker_loc.vv_1_form( - self.wts[0][0], - self.wts[1][0], - self.wts[2][0], - self.pts[0][0], - self.pts[1][0], - self.pts[2][0], - 0.5 * dt, - self.right_loc_1, - self.right_loc_2, - self.right_loc_3, - Np, - self.n_quad, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - accvv.stage1_out_loc, - self.lambdas_1_11, - self.lambdas_1_12, - self.lambdas_1_13, - self.lambdas_1_21, - self.lambdas_1_22, - self.lambdas_1_23, - self.lambdas_1_31, - self.lambdas_1_32, - self.lambdas_1_33, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_h[2], - self.NbaseN, - self.NbaseD, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif index_label == 3: - ker_loc.vv_1_form( - self.wts[0][0], - self.wts[1][0], - self.wts[2][0], - self.pts[0][0], - self.pts[1][0], - self.pts[2][0], - 0.5 * dt, - self.right_loc_1, - self.right_loc_2, - self.right_loc_3, - Np, - self.n_quad, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - accvv.stage2_out_loc, - self.lambdas_1_11, - self.lambdas_1_12, - self.lambdas_1_13, - self.lambdas_1_21, - self.lambdas_1_22, - self.lambdas_1_23, - self.lambdas_1_31, - self.lambdas_1_32, - self.lambdas_1_33, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_h[2], - self.NbaseN, - self.NbaseD, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - elif index_label == 4: - ker_loc.vv_1_form( - self.wts[0][0], - self.wts[1][0], - self.wts[2][0], - self.pts[0][0], - self.pts[1][0], - self.pts[2][0], - dt, - self.right_loc_1, - self.right_loc_2, - self.right_loc_3, - Np, - self.n_quad, - self.p, - self.Nel, - self.p_shape, - self.p_size, - particles_loc, - accvv.stage3_out_loc, - self.lambdas_1_11, - self.lambdas_1_12, - self.lambdas_1_13, - self.lambdas_1_21, - self.lambdas_1_22, - self.lambdas_1_23, - self.lambdas_1_31, - self.lambdas_1_32, - self.lambdas_1_33, - self.num_cell, - self.coeff_i[0], - self.coeff_i[1], - self.coeff_i[2], - self.coeff_h[0], - self.coeff_h[1], - self.coeff_h[2], - self.NbaseN, - self.NbaseD, - self.related, - particles_loc.shape[1], - domain.kind_map, - domain.params, - domain.T[0], - domain.T[1], - domain.T[2], - domain.p, - domain.Nel, - domain.NbaseN, - domain.cx, - domain.cy, - domain.cz, - ) - - mpi_comm.Reduce(self.right_loc_1, accvv.vec1, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.right_loc_2, accvv.vec2, op=MPI.SUM, root=0) - mpi_comm.Reduce(self.right_loc_3, accvv.vec3, op=MPI.SUM, root=0) diff --git a/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/shape_local_projector_kernel.py b/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/shape_local_projector_kernel.py deleted file mode 100644 index 6db315daa..000000000 --- a/src/struphy/eigenvalue_solvers/legacy/projectors_local/shape_pro_local/shape_local_projector_kernel.py +++ /dev/null @@ -1,3327 +0,0 @@ -import struphy.feec.bsplines_kernels as bsp -import struphy.geometry.mappings_3d_fast as mapping_fast -import struphy.linear_algebra.linalg_kernels as linalg - - -# ============================================================================================== -def kernel_0_form( - Np: "int", - p: "int[:]", - Nel: "int[:]", - p_shape: "int[:]", - p_size: "float[:]", - particle: "float[:,:]", - lambdas: "float[:,:,:]", - kernel_0: "float[:,:,:,:,:,:]", - num_cell: "int[:]", - coeff_x: "float[:]", - coeff_y: "float[:]", - coeff_z: "float[:]", - NbaseN: "int[:]", - related: "int[:]", - Np_loc: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, floor, zeros - - cell_left = zeros(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - cell_number = zeros(3, dtype=int) - compact = zeros(3, dtype=float) - width = zeros(3, dtype=int) - width2 = zeros(3, dtype=int) - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = empty((3, 3), dtype=float) - - lambdas[:, :, :] = 0.0 - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : kernel_0, lambdas) private (ip, w, width2, cell_left, point_left, point_right, cell_number, compact, width, mat_f, i1, i2, i3, il1, il2, il3, index1, index2, index3, value_x, value_y, value_z, final_1, final_2, final_3, lambda_index1, lambda_index2, lambda_index3, global_i1, global_i2, global_i3, global_il1, global_il2, global_il3, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, det_df, eta1, eta2, eta3) - for ip in range(Np_loc): - # lambdas[:,:,:] = 0.0 - w = particle[6, ip] / Np - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - point_left[0] = particle[0, ip] - 0.5 * compact[0] - point_right[0] = particle[0, ip] + 0.5 * compact[0] - point_left[1] = particle[1, ip] - 0.5 * compact[1] - point_right[1] = particle[1, ip] + 0.5 * compact[1] - point_left[2] = particle[2, ip] - 0.5 * compact[2] - point_right[2] = particle[2, ip] + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number[0] = int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1 - cell_number[1] = int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1 - cell_number[2] = int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1 - - for il1 in range(3): - if (p[il1] + cell_number[il1] - 1) > NbaseN[il1]: - width[il1] = NbaseN[il1] - else: - width[il1] = p[il1] + cell_number[il1] - 1 - - mat_f = empty( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], num_cell[2]), - dtype=float, - ) - mat_f[:, :, :, :, :, :] = 0.0 - - # evaluation of function at interpolation points - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): # num_cell = 1, p = 1; num_cell = 2, p >= 2 - index3 = cell_left[2] + i3 - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1 / Nel[1] / num_cell[1] * il2 - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1 / Nel[2] / num_cell[2] * il3 - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - # ========= mapping evaluation ============= - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - det_df = abs(linalg.det(df)) - mat_f[i1, i2, i3, il1, il2, il3] = ( - value_x * value_y * value_z / (p_size[0] * p_size[1] * p_size[2]) / det_df - ) # here should devided by det_df = abs(linalg.det(df)) - - # coefficients - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - for lambda_index1 in range(p[0]): - final_1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(num_cell[0]): - for il2 in range(num_cell[1]): - for il3 in range(num_cell[2]): - lambdas[final_1, final_2, final_3] += ( - coeff_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * mat_f[i1, i2, i3, il1, il2, il3] - ) - - for i1 in range(width[0]): - global_i1 = (cell_left[0] + i1) % NbaseN[0] - for i2 in range(width[1]): - global_i2 = (cell_left[1] + i2) % NbaseN[1] - for i3 in range(width[2]): - global_i3 = (cell_left[2] + i3) % NbaseN[2] - for il1 in range(3): - width2[il1] = 2 * related[il1] + 1 - if width2[0] > NbaseN[0]: - width2[0] = NbaseN[0] - if width2[1] > NbaseN[1]: - width2[1] = NbaseN[1] - if width2[2] > NbaseN[2]: - width2[2] = NbaseN[2] - for il1 in range(width2[0]): - global_il1 = (global_i1 + il1 - int(floor(width2[0] / 2.0))) % NbaseN[0] - for il2 in range(width2[1]): - global_il2 = (global_i2 + il2 - int(floor(width2[1] / 2.0))) % NbaseN[1] - for il3 in range(width2[2]): - global_il3 = (global_i3 + il3 - int(floor(width2[2] / 2.0))) % NbaseN[2] - kernel_0[global_i1, global_i2, global_i3, il1, il2, il3] += w * ( - lambdas[global_i1, global_i2, global_i3] - * lambdas[global_il1, global_il2, global_il3] - ) - - del mat_f - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================================== -def potential_kernel_0_form( - Np: "int", - p: "int[:]", - Nel: "int[:]", - p_shape: "int[:]", - p_size: "float[:]", - particle: "float[:,:]", - lambdas: "float[:,:,:]", - kernel_0: "float[:,:,:,:,:,:]", - num_cell: "int[:]", - coeff_x: "float[:]", - coeff_y: "float[:]", - coeff_z: "float[:]", - NbaseN: "int[:]", - related: "int[:]", - Np_loc: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, floor, zeros - - cell_left = zeros(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - cell_number = zeros(3, dtype=int) - compact = zeros(3, dtype=float) - width = zeros(3, dtype=int) - width2 = zeros(3, dtype=int) - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = empty((3, 3), dtype=float) - - lambdas[:, :, :] = 0.0 - det_df = params_map[0] * params_map[1] * params_map[2] - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : lambdas) private (ip, w, width, cell_left, point_left, point_right, cell_number, compact, mat_f, i1, i2, i3, il1, il2, il3, index1, index2, index3, value_x, value_y, value_z, final_1, final_2, final_3, eta1, eta2, eta3, lambda_index1, lambda_index2, lambda_index3) - for ip in range(Np_loc): - # lambdas[:,:,:] = 0.0 - w = particle[6, ip] / Np - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - point_left[0] = particle[0, ip] - 0.5 * compact[0] - point_right[0] = particle[0, ip] + 0.5 * compact[0] - point_left[1] = particle[1, ip] - 0.5 * compact[1] - point_right[1] = particle[1, ip] + 0.5 * compact[1] - point_left[2] = particle[2, ip] - 0.5 * compact[2] - point_right[2] = particle[2, ip] + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number[0] = int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1 - cell_number[1] = int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1 - cell_number[2] = int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1 - - for il1 in range(3): - if (p[il1] + cell_number[il1] - 1) > NbaseN[il1]: - width[il1] = NbaseN[il1] - else: - width[il1] = p[il1] + cell_number[il1] - 1 - - mat_f = empty( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], num_cell[2]), - dtype=float, - ) - mat_f[:, :, :, :, :, :] = 0.0 - - # evaluation of function at interpolation points - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): # num_cell = 1, p = 1; num_cell = 2, p >= 2 - index3 = cell_left[2] + i3 - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1 / Nel[1] / num_cell[1] * il2 - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1 / Nel[2] / num_cell[2] * il3 - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - mat_f[i1, i2, i3, il1, il2, il3] = ( - w * value_x * value_y * value_z / (p_size[0] * p_size[1] * p_size[2]) / det_df - ) # here should devided by det_df = abs(linalg.det(df)) - - # coefficients - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - for lambda_index1 in range(p[0]): - final_1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(num_cell[0]): - for il2 in range(num_cell[1]): - for il3 in range(num_cell[2]): - lambdas[final_1, final_2, final_3] += ( - coeff_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * mat_f[i1, i2, i3, il1, il2, il3] - ) - - del mat_f - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================================== -def kernel_1_form( - right1: "float[:,:,:]", - right2: "float[:,:,:]", - right3: "float[:,:,:]", - pts1: "float[:]", - pts2: "float[:]", - pts3: "float[:]", - wts1: "float[:]", - wts2: "float[:]", - wts3: "float[:]", - Np: "int", - quad: "int[:]", - p: "int[:]", - Nel: "int[:]", - p_shape: "int[:]", - p_size: "float[:]", - particle: "float[:,:]", - lambdas_11: "float[:,:,:]", - lambdas_12: "float[:,:,:]", - lambdas_13: "float[:,:,:]", - lambdas_21: "float[:,:,:]", - lambdas_22: "float[:,:,:]", - lambdas_23: "float[:,:,:]", - lambdas_31: "float[:,:,:]", - lambdas_32: "float[:,:,:]", - lambdas_33: "float[:,:,:]", - kernel_11: "float[:,:,:,:,:,:]", - kernel_12: "float[:,:,:,:,:,:]", - kernel_13: "float[:,:,:,:,:,:]", - kernel_22: "float[:,:,:,:,:,:]", - kernel_23: "float[:,:,:,:,:,:]", - kernel_33: "float[:,:,:,:,:,:]", - num_cell: "int[:]", - coeff_i_x: "float[:]", - coeff_i_y: "float[:]", - coeff_i_z: "float[:]", - coeff_h_x: "float[:]", - coeff_h_y: "float[:]", - coeff_h_z: "float[:]", - NbaseN: "int[:]", - NbaseD: "int[:]", - related: "int[:]", - Np_loc: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, floor, zeros - - cell_left = zeros(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - cell_number = zeros(3, dtype=int) - compact = zeros(3, dtype=float) - - width = zeros(3, dtype=int) - width[0] = p[0] + cell_number[0] - 1 # the number of coefficients obtained from this smoothed delta function - width[1] = p[1] + cell_number[1] - 1 # the number of coefficients obtained from this smoothed delta function - width[2] = p[2] + cell_number[2] - 1 # the number of coefficients obtained from this smoothed delta function - - width2 = zeros(3, dtype=int) - width2[0] = 2 * related[0] + 1 - width2[1] = 2 * related[1] + 1 - width2[2] = 2 * related[2] + 1 - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = zeros((3, 3), dtype=float) - dft = zeros((3, 3), dtype=float) - # ==================================== - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : kernel_11, kernel_12, kernel_13, kernel_22, kernel_23, kernel_33, right1, right2, right3) private (mid1, mid2, mid3, ip, w, det_df, vol, width2, lambdas_11, lambdas_22, lambdas_33, lambdas_12, lambdas_13, lambdas_21, lambdas_23, lambdas_31, lambdas_32, cell_left, point_left, point_right, cell_number, compact, width, mat_11, mat_12, mat_13, mat_21, mat_22, mat_23, mat_31, mat_32, mat_33, i1, i2, i3, il1, il2, il3, index1, index2, index3, value_x, value_y, value_z, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, dft, lambda_index1, lambda_index2, lambda_index3, global_i1, global_i2, global_i3, global_il1, global_il2, global_il3, f_int, jl1, eta1, eta2, eta3, final_index1, final_index2, final_index3) - for ip in range(Np_loc): - w = particle[6, ip] / Np - - lambdas_11[:, :, :] = 0.0 - lambdas_12[:, :, :] = 0.0 - lambdas_13[:, :, :] = 0.0 - - lambdas_21[:, :, :] = 0.0 - lambdas_22[:, :, :] = 0.0 - lambdas_23[:, :, :] = 0.0 - - lambdas_31[:, :, :] = 0.0 - lambdas_32[:, :, :] = 0.0 - lambdas_33[:, :, :] = 0.0 - - # ================================== - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - point_left[0] = particle[0, ip] - 0.5 * compact[0] - point_right[0] = particle[0, ip] + 0.5 * compact[0] - point_left[1] = particle[1, ip] - 0.5 * compact[1] - point_right[1] = particle[1, ip] + 0.5 * compact[1] - point_left[2] = particle[2, ip] - 0.5 * compact[2] - point_right[2] = particle[2, ip] + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number[0] = int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1 - cell_number[1] = int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1 - cell_number[2] = int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1 - - vol = 1.0 / (p_size[0] * p_size[1] * p_size[2]) - - # evaluation of function at interpolation/quadrature points - mat_11 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_21 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_31 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - - mat_12 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_22 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_32 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - - mat_13 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_23 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_33 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): # num_cell = 1, p = 1; num_cell = 2, p >= 2 - index3 = cell_left[2] + i3 - for il1 in range(2): - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1 / Nel[1] / num_cell[1] * il2 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1 / Nel[2] / num_cell[2] * il3 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[0]): - eta1 = 1.0 / Nel[0] * index1 + 1 / Nel[0] / 2.0 * il1 + pts1[jl1] - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - # ========= mapping evaluation ============= - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_11[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_21[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_31[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 2] * value_x * value_y * value_z / det_df * vol - ) - - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(2): - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / num_cell[2] * il3 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / 2.0 * il2 + pts2[jl1] - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - # ========= mapping evaluation ============= - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_12[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_22[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_32[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 2] * value_x * value_y * value_z / det_df * vol - ) - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / num_cell[1] * il2 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(2): - for jl1 in range(quad[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / 2.0 * il3 + pts3[jl1] - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - # ========= mapping evaluation ============= - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_13[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_23[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_33[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 2] * value_x * value_y * value_z / det_df * vol - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseD[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(2): - for il2 in range(num_cell[1]): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_11[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_11[final_index1, final_index2, final_index3] += mid1 - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_21[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_21[final_index1, final_index2, final_index3] += mid2 - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_31[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_31[final_index1, final_index2, final_index3] += mid3 - right1[final_index1, final_index2, final_index3] += w * ( - particle[3, ip] * mid1 + particle[4, ip] * mid2 + particle[5, ip] * mid3 - ) - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseD[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(num_cell[0]): - for il2 in range(2): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_12[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_12[final_index1, final_index2, final_index3] += mid1 - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_22[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_22[final_index1, final_index2, final_index3] += mid2 - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_32[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_32[final_index1, final_index2, final_index3] += mid3 - right2[final_index1, final_index2, final_index3] += w * ( - particle[3, ip] * mid1 + particle[4, ip] * mid2 + particle[5, ip] * mid3 - ) - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseD[2] - for il1 in range(num_cell[0]): - for il2 in range(num_cell[1]): - for il3 in range(2): - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_13[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_13[final_index1, final_index2, final_index3] += mid1 - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_23[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_23[final_index1, final_index2, final_index3] += mid2 - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_33[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_33[final_index1, final_index2, final_index3] += mid3 - right3[final_index1, final_index2, final_index3] += w * ( - particle[3, ip] * mid1 + particle[4, ip] * mid2 + particle[5, ip] * mid3 - ) - - # print('check_inside_lambda', lambdas_11) - for il1 in range(3): - width[il1] = p[il1] + cell_number[il1] - 1 - - if width[0] > NbaseD[0]: - width[0] = NbaseD[0] - if width[1] > NbaseN[1]: - width[1] = NbaseN[1] - if width[2] > NbaseN[2]: - width[2] = NbaseN[2] - for i1 in range(width[0]): - global_i1 = (cell_left[0] + i1) % NbaseD[0] - for i2 in range(width[1]): - global_i2 = (cell_left[1] + i2) % NbaseN[1] - for i3 in range(width[2]): - global_i3 = (cell_left[2] + i3) % NbaseN[2] - # ===== 11 compoponent ========== - for il1 in range(3): - width2[il1] = 2 * related[il1] + 1 - if width2[0] > NbaseD[0]: - width2[0] = NbaseD[0] - if width2[1] > NbaseN[1]: - width2[1] = NbaseN[1] - if width2[2] > NbaseN[2]: - width2[2] = NbaseN[2] - for il1 in range(width2[0]): - global_il1 = (global_i1 + il1 - int(floor(width2[0] / 2.0))) % NbaseD[0] - for il2 in range(width2[1]): - global_il2 = (global_i2 + il2 - int(floor(width2[1] / 2.0))) % NbaseN[1] - for il3 in range(width2[2]): - global_il3 = (global_i3 + il3 - int(floor(width2[2] / 2.0))) % NbaseN[2] - kernel_11[global_i1, global_i2, global_i3, il1, il2, il3] += w * ( - lambdas_11[global_i1, global_i2, global_i3] - * lambdas_11[global_il1, global_il2, global_il3] - + lambdas_21[global_i1, global_i2, global_i3] - * lambdas_21[global_il1, global_il2, global_il3] - + lambdas_31[global_i1, global_i2, global_i3] - * lambdas_31[global_il1, global_il2, global_il3] - ) - # ===== 12 compoponent ========== - for il1 in range(3): - width2[il1] = 2 * related[il1] + 1 - if width2[0] > NbaseN[0]: - width2[0] = NbaseN[0] - if width2[1] > NbaseD[1]: - width2[1] = NbaseD[1] - if width2[2] > NbaseN[2]: - width2[2] = NbaseN[2] - for il1 in range(width2[0]): - global_il1 = (global_i1 + il1 - int(floor(width2[0] / 2.0))) % NbaseN[0] - for il2 in range(width2[1]): - global_il2 = (global_i2 + il2 - int(floor(width2[1] / 2.0))) % NbaseD[1] - for il3 in range(width2[2]): - global_il3 = (global_i3 + il3 - int(floor(width2[2] / 2.0))) % NbaseN[2] - kernel_12[global_i1, global_i2, global_i3, il1, il2, il3] += w * ( - lambdas_11[global_i1, global_i2, global_i3] - * lambdas_12[global_il1, global_il2, global_il3] - + lambdas_21[global_i1, global_i2, global_i3] - * lambdas_22[global_il1, global_il2, global_il3] - + lambdas_31[global_i1, global_i2, global_i3] - * lambdas_32[global_il1, global_il2, global_il3] - ) - - # ===== 13 compoponent ========== - for il1 in range(3): - width2[il1] = 2 * related[il1] + 1 - if width2[0] > NbaseN[0]: - width2[0] = NbaseN[0] - if width2[1] > NbaseN[1]: - width2[1] = NbaseN[1] - if width2[2] > NbaseD[2]: - width2[2] = NbaseD[2] - for il1 in range(width2[0]): - global_il1 = (global_i1 + il1 - int(floor(width2[0] / 2.0))) % NbaseN[0] - for il2 in range(width2[1]): - global_il2 = (global_i2 + il2 - int(floor(width2[1] / 2.0))) % NbaseN[1] - for il3 in range(width2[2]): - global_il3 = (global_i3 + il3 - int(floor(width2[2] / 2.0))) % NbaseD[2] - kernel_13[global_i1, global_i2, global_i3, il1, il2, il3] += w * ( - lambdas_11[global_i1, global_i2, global_i3] - * lambdas_13[global_il1, global_il2, global_il3] - + lambdas_21[global_i1, global_i2, global_i3] - * lambdas_23[global_il1, global_il2, global_il3] - + lambdas_31[global_i1, global_i2, global_i3] - * lambdas_33[global_il1, global_il2, global_il3] - ) - - for il1 in range(3): - width[il1] = p[il1] + cell_number[il1] - 1 - if width[0] > NbaseN[0]: - width[0] = NbaseN[0] - if width[1] > NbaseD[1]: - width[1] = NbaseD[1] - if width[2] > NbaseN[2]: - width[2] = NbaseN[2] - for i1 in range(width[0]): - global_i1 = (cell_left[0] + i1) % NbaseN[0] - for i2 in range(width[1]): - global_i2 = (cell_left[1] + i2) % NbaseD[1] - for i3 in range(width[2]): - global_i3 = (cell_left[2] + i3) % NbaseN[2] - # ===== 22 compoponent ========== - for il1 in range(3): - width2[il1] = 2 * related[il1] + 1 - if width2[0] > NbaseN[0]: - width2[0] = NbaseN[0] - if width2[1] > NbaseD[1]: - width2[1] = NbaseD[1] - if width2[2] > NbaseN[2]: - width2[2] = NbaseN[2] - for il1 in range(width2[0]): - global_il1 = (global_i1 + il1 - int(floor(width2[0] / 2.0))) % NbaseN[0] - for il2 in range(width2[1]): - global_il2 = (global_i2 + il2 - int(floor(width2[1] / 2.0))) % NbaseD[1] - for il3 in range(width2[2]): - global_il3 = (global_i3 + il3 - int(floor(width2[2] / 2.0))) % NbaseN[2] - kernel_22[global_i1, global_i2, global_i3, il1, il2, il3] += w * ( - lambdas_12[global_i1, global_i2, global_i3] - * lambdas_12[global_il1, global_il2, global_il3] - + lambdas_22[global_i1, global_i2, global_i3] - * lambdas_22[global_il1, global_il2, global_il3] - + lambdas_32[global_i1, global_i2, global_i3] - * lambdas_32[global_il1, global_il2, global_il3] - ) - # ===== 23 compoponent ========== - for il1 in range(3): - width2[il1] = 2 * related[il1] + 1 - if width2[0] > NbaseN[0]: - width2[0] = NbaseN[0] - if width2[1] > NbaseN[1]: - width2[1] = NbaseN[1] - if width2[2] > NbaseD[2]: - width2[2] = NbaseD[2] - for il1 in range(width2[0]): - global_il1 = (global_i1 + il1 - int(floor(width2[0] / 2.0))) % NbaseN[0] - for il2 in range(width2[1]): - global_il2 = (global_i2 + il2 - int(floor(width2[1] / 2.0))) % NbaseN[1] - for il3 in range(width2[2]): - global_il3 = (global_i3 + il3 - int(floor(width2[2] / 2.0))) % NbaseD[2] - kernel_23[global_i1, global_i2, global_i3, il1, il2, il3] += w * ( - lambdas_12[global_i1, global_i2, global_i3] - * lambdas_13[global_il1, global_il2, global_il3] - + lambdas_22[global_i1, global_i2, global_i3] - * lambdas_23[global_il1, global_il2, global_il3] - + lambdas_32[global_i1, global_i2, global_i3] - * lambdas_33[global_il1, global_il2, global_il3] - ) - - for il1 in range(3): - width[il1] = p[il1] + cell_number[il1] - 1 - if width[0] > NbaseN[0]: - width[0] = NbaseN[0] - if width[1] > NbaseN[1]: - width[1] = NbaseN[1] - if width[2] > NbaseD[2]: - width[2] = NbaseD[2] - - for i1 in range(width[0]): - global_i1 = (cell_left[0] + i1) % NbaseN[0] - for i2 in range(width[1]): - global_i2 = (cell_left[1] + i2) % NbaseN[1] - for i3 in range(width[2]): - global_i3 = (cell_left[2] + i3) % NbaseD[2] - # ===== 33 compoponent ========== - for il1 in range(3): - width2[il1] = 2 * related[il1] + 1 - if width2[0] > NbaseN[0]: - width2[0] = NbaseN[0] - if width2[1] > NbaseN[1]: - width2[1] = NbaseN[1] - if width2[2] > NbaseD[2]: - width2[2] = NbaseD[2] - for il1 in range(width2[0]): - global_il1 = (global_i1 + il1 - int(floor(width2[0] / 2.0))) % NbaseN[0] - for il2 in range(width2[1]): - global_il2 = (global_i2 + il2 - int(floor(width2[1] / 2.0))) % NbaseN[1] - for il3 in range(width2[2]): - global_il3 = (global_i3 + il3 - int(floor(width2[2] / 2.0))) % NbaseD[2] - kernel_33[global_i1, global_i2, global_i3, il1, il2, il3] += w * ( - lambdas_13[global_i1, global_i2, global_i3] - * lambdas_13[global_il1, global_il2, global_il3] - + lambdas_23[global_i1, global_i2, global_i3] - * lambdas_23[global_il1, global_il2, global_il3] - + lambdas_33[global_i1, global_i2, global_i3] - * lambdas_33[global_il1, global_il2, global_il3] - ) - - del mat_11 - del mat_12 - del mat_13 - del mat_21 - del mat_22 - del mat_23 - del mat_31 - del mat_32 - del mat_33 - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ============================================================================================== -def bv_localproj_push( - dt: "float", - bb1: "float[:,:,:]", - bb2: "float[:,:,:]", - bb3: "float[:,:,:]", - pts1: "float[:]", - pts2: "float[:]", - pts3: "float[:]", - wts1: "float[:]", - wts2: "float[:]", - wts3: "float[:]", - Np: "int", - quad: "int[:]", - p: "int[:]", - Nel: "int[:]", - p_shape: "int[:]", - p_size: "float[:]", - particle: "float[:,:]", - lambdas_11: "float[:,:,:]", - lambdas_12: "float[:,:,:]", - lambdas_13: "float[:,:,:]", - lambdas_21: "float[:,:,:]", - lambdas_22: "float[:,:,:]", - lambdas_23: "float[:,:,:]", - lambdas_31: "float[:,:,:]", - lambdas_32: "float[:,:,:]", - lambdas_33: "float[:,:,:]", - num_cell: "int[:]", - coeff_i_x: "float[:]", - coeff_i_y: "float[:]", - coeff_i_z: "float[:]", - coeff_h_x: "float[:]", - coeff_h_y: "float[:]", - coeff_h_z: "float[:]", - NbaseN: "int[:]", - NbaseD: "int[:]", - related: "int[:]", - Np_loc: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, floor, zeros - - cell_left = zeros(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - cell_number = zeros(3, dtype=int) - compact = zeros(3, dtype=float) - - vel = zeros(3, dtype=float) - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = zeros((3, 3), dtype=float) - dft = zeros((3, 3), dtype=float) - - grids_shapex = zeros(p_shape[0] + 2, dtype=float) - grids_shapey = zeros(p_shape[1] + 2, dtype=float) - grids_shapez = zeros(p_shape[2] + 2, dtype=float) - # ==================================== - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (i, grids_shapex, grids_shapey, grids_shapez, vel, mid1, mid2, mid3, ip, w, det_df, vol, lambdas_11, lambdas_12, lambdas_13, lambdas_21, lambdas_22, lambdas_23, lambdas_31, lambdas_32, lambdas_33, cell_left, point_left, point_right, cell_number, compact, mat_11, mat_12, mat_13, mat_21, mat_22, mat_23, mat_31, mat_32, mat_33, i1, i2, i3, il1, il2, il3, index1, index2, index3, value_x, value_y, value_z, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, dft, f_int, jl1, eta1, eta2, eta3, final_index1, final_index2, final_index3, lambda_index1, lambda_index2, lambda_index3) - for ip in range(Np_loc): - vel[:] = 0.0 - - w = particle[6, ip] / Np - - lambdas_11[:, :, :] = 0.0 - lambdas_12[:, :, :] = 0.0 - lambdas_13[:, :, :] = 0.0 - - lambdas_21[:, :, :] = 0.0 - lambdas_22[:, :, :] = 0.0 - lambdas_23[:, :, :] = 0.0 - - lambdas_31[:, :, :] = 0.0 - lambdas_32[:, :, :] = 0.0 - lambdas_33[:, :, :] = 0.0 - - # ================================== - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - point_left[0] = particle[0, ip] - 0.5 * compact[0] - point_right[0] = particle[0, ip] + 0.5 * compact[0] - point_left[1] = particle[1, ip] - 0.5 * compact[1] - point_right[1] = particle[1, ip] + 0.5 * compact[1] - point_left[2] = particle[2, ip] - 0.5 * compact[2] - point_right[2] = particle[2, ip] + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number[0] = int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1 - cell_number[1] = int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1 - cell_number[2] = int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1 - - for i in range(p_shape[0] + 1): - grids_shapex[i] = point_left[0] + i * p_size[0] - grids_shapex[p_shape[0] + 1] = point_right[0] - - for i in range(p_shape[1] + 1): - grids_shapey[i] = point_left[1] + i * p_size[1] - grids_shapey[p_shape[1] + 1] = point_right[1] - - for i in range(p_shape[2] + 1): - grids_shapez[i] = point_left[2] + i * p_size[2] - grids_shapez[p_shape[2] + 1] = point_right[2] - - vol = 1.0 / (p_size[0] * p_size[1] * p_size[2]) - - # evaluation of function at interpolation/quadrature points - mat_11 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_21 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_31 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - - mat_12 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_22 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_32 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - - mat_13 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_23 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_33 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): # num_cell = 1, p = 1; num_cell = 2, p >= 2 - index3 = cell_left[2] + i3 - for il1 in range(2): - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / num_cell[1] * il2 - # value_y = bsp.convolution(p_shape[1], grids_shapey, eta2) - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / num_cell[2] * il3 - # value_z = bsp.convolution(p_shape[2], grids_shapez, eta3) - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / 2.0 * il1 + pts1[jl1] - value_x = bsp.convolution(p_shape[0], grids_shapex, eta1) - # value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - # ========= mapping evaluation ============= - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate inverse Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_11[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_21[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_31[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 2] * value_x * value_y * value_z / det_df * vol - ) - - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1 / Nel[0] / num_cell[0] * il1 - value_x = bsp.convolution(p_shape[0], grids_shapex, eta1) - # value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(2): - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1 / Nel[2] / num_cell[2] * il3 - # value_z = bsp.convolution(p_shape[2], grids_shapez, eta3) - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[1]): - eta2 = 1.0 / Nel[1] * index2 + 1 / Nel[1] / 2.0 * il2 + pts2[jl1] - # value_y = bsp.convolution(p_shape[1], grids_shapey, eta2) - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - # ========= mapping evaluation ============= - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate inverse Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_12[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_22[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_32[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 2] * value_x * value_y * value_z / det_df * vol - ) - - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - value_x = bsp.convolution(p_shape[0], grids_shapex, eta1) - # value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / num_cell[1] * il2 - # value_y = bsp.convolution(p_shape[1], grids_shapey, eta2) - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(2): - for jl1 in range(quad[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / 2.0 * il3 + pts3[jl1] - # value_z = bsp.convolution(p_shape[2], grids_shapez, eta3) - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - # ========= mapping evaluation ============= - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate inverse Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_13[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_23[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_33[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 2] * value_x * value_y * value_z / det_df * vol - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseD[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(2): - for il2 in range(num_cell[1]): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_11[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[0] += mid1 * bb1[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_21[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[1] += mid2 * bb1[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_31[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[2] += mid3 * bb1[final_index1, final_index2, final_index3] - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseD[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(num_cell[0]): - for il2 in range(2): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_12[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[0] += mid1 * bb2[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_22[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[1] += mid2 * bb2[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_32[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[2] += mid3 * bb2[final_index1, final_index2, final_index3] - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseD[2] - for il1 in range(num_cell[0]): - for il2 in range(num_cell[1]): - for il3 in range(2): - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_13[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[0] += mid1 * bb3[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_23[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[1] += mid2 * bb3[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_33[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[2] += mid3 * bb3[final_index1, final_index2, final_index3] - - particle[3, ip] += dt * vel[0] - particle[4, ip] += dt * vel[1] - particle[5, ip] += dt * vel[2] - - del mat_11 - del mat_12 - del mat_13 - del mat_21 - del mat_22 - del mat_23 - del mat_31 - del mat_32 - del mat_33 - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ============================================================================================== -def kernel_1_heavy( - pts1: "float[:]", - pts2: "float[:]", - pts3: "float[:]", - wts1: "float[:]", - wts2: "float[:]", - wts3: "float[:]", - out1: "float[:,:,:]", - out2: "float[:,:,:]", - out3: "float[:,:,:]", - in1: "float[:,:,:]", - in2: "float[:,:,:]", - in3: "float[:,:,:]", - Np: "int", - quad: "int[:]", - p: "int[:]", - Nel: "int[:]", - p_shape: "int[:]", - p_size: "float[:]", - particle: "float[:,:]", - lambdas_11: "float[:,:,:]", - lambdas_12: "float[:,:,:]", - lambdas_13: "float[:,:,:]", - lambdas_21: "float[:,:,:]", - lambdas_22: "float[:,:,:]", - lambdas_23: "float[:,:,:]", - lambdas_31: "float[:,:,:]", - lambdas_32: "float[:,:,:]", - lambdas_33: "float[:,:,:]", - num_cell: "int[:]", - coeff_i_x: "float[:]", - coeff_i_y: "float[:]", - coeff_i_z: "float[:]", - coeff_h_x: "float[:]", - coeff_h_y: "float[:]", - coeff_h_z: "float[:]", - NbaseN: "int[:]", - NbaseD: "int[:]", - Np_loc: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, floor, zeros - - cell_left = zeros(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - cell_number = zeros(3, dtype=int) - compact = zeros(3, dtype=float) - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = zeros((3, 3), dtype=float) - dft = zeros((3, 3), dtype=float) - - grids_shapex = zeros(p_shape[0] + 2, dtype=float) - grids_shapey = zeros(p_shape[1] + 2, dtype=float) - grids_shapez = zeros(p_shape[2] + 2, dtype=float) - # ==================================== - - out1[:, :, :] = 0.0 - out2[:, :, :] = 0.0 - out3[:, :, :] = 0.0 - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : out1, out2, out3) private (value1, value2, value3, i, grids_shapex, grids_shapey, grids_shapez, mid1, mid2, mid3, ip, w, det_df, vol, lambdas_11, lambdas_12, lambdas_13, lambdas_21, lambdas_22, lambdas_23, lambdas_31, lambdas_32, lambdas_33, cell_left, point_left, point_right, cell_number, compact, mat_11, mat_12, mat_13, mat_21, mat_22, mat_23, mat_31, mat_32, mat_33, i1, i2, i3, il1, il2, il3, index1, index2, index3, value_x, value_y, value_z, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, dft, lambda_index1, lambda_index2, lambda_index3, eta1, eta2, eta3, final_index1, final_index2, final_index3, f_int) - for ip in range(Np_loc): - w = particle[6, ip] / Np - - lambdas_11[:, :, :] = 0.0 - lambdas_22[:, :, :] = 0.0 - lambdas_33[:, :, :] = 0.0 - - lambdas_12[:, :, :] = 0.0 - lambdas_13[:, :, :] = 0.0 - - lambdas_21[:, :, :] = 0.0 - lambdas_23[:, :, :] = 0.0 - - lambdas_31[:, :, :] = 0.0 - lambdas_32[:, :, :] = 0.0 - - value1 = 0.0 - value2 = 0.0 - value3 = 0.0 - - # ================================== - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - point_left[0] = particle[0, ip] - 0.5 * compact[0] - point_right[0] = particle[0, ip] + 0.5 * compact[0] - point_left[1] = particle[1, ip] - 0.5 * compact[1] - point_right[1] = particle[1, ip] + 0.5 * compact[1] - point_left[2] = particle[2, ip] - 0.5 * compact[2] - point_right[2] = particle[2, ip] + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number[0] = int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1 - cell_number[1] = int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1 - cell_number[2] = int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1 - - for i in range(p_shape[0] + 1): - grids_shapex[i] = point_left[0] + i * p_size[0] - grids_shapex[p_shape[0] + 1] = point_right[0] - - for i in range(p_shape[1] + 1): - grids_shapey[i] = point_left[1] + i * p_size[1] - grids_shapey[p_shape[1] + 1] = point_right[1] - - for i in range(p_shape[2] + 1): - grids_shapez[i] = point_left[2] + i * p_size[2] - grids_shapez[p_shape[2] + 1] = point_right[2] - - vol = 1.0 / (p_size[0] * p_size[1] * p_size[2]) - - # evaluation of function at interpolation/quadrature points - mat_11 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_21 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_31 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - - mat_12 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_22 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_32 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - - mat_13 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_23 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_33 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): # num_cell = 1, p = 1; num_cell = 2, p >= 2 - index3 = cell_left[2] + i3 - for il1 in range(2): - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / num_cell[1] * il2 - # value_y = bsp.convolution(p_shape[1], grids_shapey, eta2) - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / num_cell[2] * il3 - # value_z = bsp.convolution(p_shape[2], grids_shapez, eta3) - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / 2.0 * il1 + pts1[jl1] - value_x = bsp.convolution(p_shape[0], grids_shapex, eta1) - # value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - # ========= mapping evaluation ============= - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate inverse Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_11[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_21[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_31[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 2] * value_x * value_y * value_z / det_df * vol - ) - - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1 / Nel[0] / num_cell[0] * il1 - value_x = bsp.convolution(p_shape[0], grids_shapex, eta1) - # value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(2): - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1 / Nel[2] / num_cell[2] * il3 - # value_z = bsp.convolution(p_shape[2], grids_shapez, eta3) - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[1]): - eta2 = 1.0 / Nel[1] * index2 + 1 / Nel[1] / 2.0 * il2 + pts2[jl1] - # value_y = bsp.convolution(p_shape[1], grids_shapey, eta2) - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - # ========= mapping evaluation ============= - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate inverse Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_12[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_22[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_32[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 2] * value_x * value_y * value_z / det_df * vol - ) - - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - value_x = bsp.convolution(p_shape[0], grids_shapex, eta1) - # value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / num_cell[1] * il2 - # value_y = bsp.convolution(p_shape[1], grids_shapey, eta2) - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(2): - for jl1 in range(quad[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / 2.0 * il3 + pts3[jl1] - # value_z = bsp.convolution(p_shape[2], grids_shapez, eta3) - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - # ========= mapping evaluation ============= - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate inverse Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_13[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_23[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_33[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 2] * value_x * value_y * value_z / det_df * vol - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseD[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(2): - for il2 in range(num_cell[1]): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_11[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_11[final_index1, final_index2, final_index3] += mid1 - value1 += mid1 * in1[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_21[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_21[final_index1, final_index2, final_index3] += mid2 - value2 += mid2 * in1[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_31[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_31[final_index1, final_index2, final_index3] += mid3 - value3 += mid3 * in1[final_index1, final_index2, final_index3] - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseD[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(num_cell[0]): - for il2 in range(2): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_12[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_12[final_index1, final_index2, final_index3] += mid1 - value1 += mid1 * in2[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_22[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_22[final_index1, final_index2, final_index3] += mid2 - value2 += mid2 * in2[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_32[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_32[final_index1, final_index2, final_index3] += mid3 - value3 += mid3 * in2[final_index1, final_index2, final_index3] - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseD[2] - for il1 in range(num_cell[0]): - for il2 in range(num_cell[1]): - for il3 in range(2): - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_13[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_13[final_index1, final_index2, final_index3] += mid1 - value1 += mid1 * in3[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_23[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_23[final_index1, final_index2, final_index3] += mid2 - value2 += mid2 * in3[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_33[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - lambdas_33[final_index1, final_index2, final_index3] += mid3 - value3 += mid3 * in3[final_index1, final_index2, final_index3] - - for il1 in range(NbaseN[0]): - for il2 in range(NbaseN[1]): - for il3 in range(NbaseN[2]): - out1[il1, il2, il3] += ( - w * value1 * (lambdas_11[il1, il2, il3] + lambdas_21[il1, il2, il3] + lambdas_31[il1, il2, il3]) - ) - out2[il1, il2, il3] += ( - w * value2 * (lambdas_12[il1, il2, il3] + lambdas_22[il1, il2, il3] + lambdas_32[il1, il2, il3]) - ) - out3[il1, il2, il3] += ( - w * value3 * (lambdas_13[il1, il2, il3] + lambdas_23[il1, il2, il3] + lambdas_33[il1, il2, il3]) - ) - - del mat_11 - del mat_12 - del mat_13 - del mat_21 - del mat_22 - del mat_23 - del mat_31 - del mat_32 - del mat_33 - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ============================================================================================== -def vv_1_form( - wts1: "float[:]", - wts2: "float[:]", - wts3: "float[:]", - pts1: "float[:]", - pts2: "float[:]", - pts3: "float[:]", - ddt: "float", - right1: "float[:,:,:]", - right2: "float[:,:,:]", - right3: "float[:,:,:]", - Np: "int", - quad: "int[:]", - p: "int[:]", - Nel: "int[:]", - p_shape: "int[:]", - p_size: "float[:]", - particle: "float[:,:]", - mid_particle: "float[:,:]", - lambdas_11: "float[:,:,:]", - lambdas_12: "float[:,:,:]", - lambdas_13: "float[:,:,:]", - lambdas_21: "float[:,:,:]", - lambdas_22: "float[:,:,:]", - lambdas_23: "float[:,:,:]", - lambdas_31: "float[:,:,:]", - lambdas_32: "float[:,:,:]", - lambdas_33: "float[:,:,:]", - num_cell: "int[:]", - coeff_i_x: "float[:]", - coeff_i_y: "float[:]", - coeff_i_z: "float[:]", - coeff_h_x: "float[:]", - coeff_h_y: "float[:]", - coeff_h_z: "float[:]", - NbaseN: "int[:]", - NbaseD: "int[:]", - related: "int[:]", - Np_loc: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, floor, zeros - - cell_left = zeros(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - cell_number = zeros(3, dtype=int) - compact = zeros(3, dtype=float) - - width = zeros(3, dtype=int) - width[0] = p[0] + cell_number[0] - 1 # the number of coefficients obtained from this smoothed delta function - width[1] = p[1] + cell_number[1] - 1 # the number of coefficients obtained from this smoothed delta function - width[2] = p[2] + cell_number[2] - 1 # the number of coefficients obtained from this smoothed delta function - - width2 = zeros(3, dtype=int) - width2[0] = 2 * related[0] + 1 - width2[1] = 2 * related[1] + 1 - width2[2] = 2 * related[2] + 1 - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = zeros((3, 3), dtype=float) - dft = zeros((3, 3), dtype=float) - - grids_shapex = zeros(p_shape[0] + 2, dtype=float) - grids_shapey = zeros(p_shape[1] + 2, dtype=float) - grids_shapez = zeros(p_shape[2] + 2, dtype=float) - - right1[:, :, :] = 0.0 - right2[:, :, :] = 0.0 - right3[:, :, :] = 0.0 - # ==================================== - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do reduction ( + : right1, right2, right3) private (i, grids_shapex, grids_shapey, grids_shapez, mid1, mid2, mid3, ip, w, det_df, vol, lambdas_11, lambdas_22, lambdas_33, lambdas_12, lambdas_13, lambdas_21, lambdas_23, lambdas_31, lambdas_32, cell_left, point_left, point_right, cell_number, compact, mat_11, mat_12, mat_13, mat_21, mat_22, mat_23, mat_31, mat_32, mat_33, i1, i2, i3, il1, il2, il3, jl1, index1, index2, index3, value_x, value_y, value_z, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, dft, lambda_index1, lambda_index2, lambda_index3, eta1, eta2, eta3, final_index1, final_index2, final_index3, f_int) - for ip in range(Np_loc): - w = particle[6, ip] / Np - - lambdas_11[:, :, :] = 0.0 - lambdas_12[:, :, :] = 0.0 - lambdas_13[:, :, :] = 0.0 - - lambdas_21[:, :, :] = 0.0 - lambdas_22[:, :, :] = 0.0 - lambdas_23[:, :, :] = 0.0 - - lambdas_31[:, :, :] = 0.0 - lambdas_32[:, :, :] = 0.0 - lambdas_33[:, :, :] = 0.0 - - # ================================== - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - point_left[0] = particle[0, ip] - 0.5 * compact[0] - point_right[0] = particle[0, ip] + 0.5 * compact[0] - point_left[1] = particle[1, ip] - 0.5 * compact[1] - point_right[1] = particle[1, ip] + 0.5 * compact[1] - point_left[2] = particle[2, ip] - 0.5 * compact[2] - point_right[2] = particle[2, ip] + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number[0] = int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1 - cell_number[1] = int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1 - cell_number[2] = int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1 - - for i in range(p_shape[0] + 1): - grids_shapex[i] = point_left[0] + i * p_size[0] - grids_shapex[p_shape[0] + 1] = point_right[0] - - for i in range(p_shape[1] + 1): - grids_shapey[i] = point_left[1] + i * p_size[1] - grids_shapey[p_shape[1] + 1] = point_right[1] - - for i in range(p_shape[2] + 1): - grids_shapez[i] = point_left[2] + i * p_size[2] - grids_shapez[p_shape[2] + 1] = point_right[2] - - vol = 1.0 / (p_size[0] * p_size[1] * p_size[2]) - - # evaluation of function at interpolation/quadrature points - mat_11 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_21 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_31 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - - mat_12 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_22 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_32 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - - mat_13 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_23 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_33 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): # num_cell = 1, p = 1; num_cell = 2, p >= 2 - index3 = cell_left[2] + i3 - for il1 in range(2): - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1 / Nel[1] / num_cell[1] * il2 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1 / Nel[2] / num_cell[2] * il3 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[0]): - eta1 = 1.0 / Nel[0] * index1 + 1 / Nel[0] / 2.0 * il1 + pts1[jl1] - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - # ========= mapping evaluation ============= - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_11[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_21[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_31[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 2] * value_x * value_y * value_z / det_df * vol - ) - - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(2): - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / num_cell[2] * il3 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / 2.0 * il2 + pts2[jl1] - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - # ========= mapping evaluation ============= - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_12[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_22[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_32[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 2] * value_x * value_y * value_z / det_df * vol - ) - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / num_cell[1] * il2 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(2): - for jl1 in range(quad[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / 2.0 * il3 + pts3[jl1] - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - # ========= mapping evaluation ============= - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_13[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_23[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_33[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 2] * value_x * value_y * value_z / det_df * vol - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseD[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(2): - for il2 in range(num_cell[1]): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_11[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_21[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_31[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - right1[final_index1, final_index2, final_index3] += w * ( - (particle[3, ip] + ddt * mid_particle[0, ip]) * mid1 - + (particle[4, ip] + ddt * mid_particle[1, ip]) * mid2 - + (particle[5, ip] + ddt * mid_particle[2, ip]) * mid3 - ) - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseD[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(num_cell[0]): - for il2 in range(2): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_12[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_22[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_32[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - right2[final_index1, final_index2, final_index3] += w * ( - (particle[3, ip] + ddt * mid_particle[0, ip]) * mid1 - + (particle[4, ip] + ddt * mid_particle[1, ip]) * mid2 - + (particle[5, ip] + ddt * mid_particle[2, ip]) * mid3 - ) - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseD[2] - for il1 in range(num_cell[0]): - for il2 in range(num_cell[1]): - for il3 in range(2): - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_13[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_23[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_33[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - right3[final_index1, final_index2, final_index3] += w * ( - (particle[3, ip] + ddt * mid_particle[0, ip]) * mid1 - + (particle[4, ip] + ddt * mid_particle[1, ip]) * mid2 - + (particle[5, ip] + ddt * mid_particle[2, ip]) * mid3 - ) - - del mat_11 - del mat_12 - del mat_13 - del mat_21 - del mat_22 - del mat_23 - del mat_31 - del mat_32 - del mat_33 - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 - - -# ============================================================================================== -def vv_push( - out: "float[:,:]", - dt: "float", - bb1: "float[:,:,:]", - bb2: "float[:,:,:]", - bb3: "float[:,:,:]", - pts1: "float[:]", - pts2: "float[:]", - pts3: "float[:]", - wts1: "float[:]", - wts2: "float[:]", - wts3: "float[:]", - Np: "int", - quad: "int[:]", - p: "int[:]", - Nel: "int[:]", - p_shape: "int[:]", - p_size: "float[:]", - particle: "float[:,:]", - lambdas_11: "float[:,:,:]", - lambdas_12: "float[:,:,:]", - lambdas_13: "float[:,:,:]", - lambdas_21: "float[:,:,:]", - lambdas_22: "float[:,:,:]", - lambdas_23: "float[:,:,:]", - lambdas_31: "float[:,:,:]", - lambdas_32: "float[:,:,:]", - lambdas_33: "float[:,:,:]", - num_cell: "int[:]", - coeff_i_x: "float[:]", - coeff_i_y: "float[:]", - coeff_i_z: "float[:]", - coeff_h_x: "float[:]", - coeff_h_y: "float[:]", - coeff_h_z: "float[:]", - NbaseN: "int[:]", - NbaseD: "int[:]", - related: "int[:]", - Np_loc: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, floor, zeros - - cell_left = zeros(3, dtype=int) - point_left = zeros(3, dtype=float) - point_right = zeros(3, dtype=float) - cell_number = zeros(3, dtype=int) - compact = zeros(3, dtype=float) - - vel = zeros(3, dtype=float) - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = zeros((3, 3), dtype=float) - dft = zeros((3, 3), dtype=float) - - grids_shapex = zeros(p_shape[0] + 2, dtype=float) - grids_shapey = zeros(p_shape[1] + 2, dtype=float) - grids_shapez = zeros(p_shape[2] + 2, dtype=float) - # ==================================== - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (i, grids_shapex, grids_shapey, grids_shapez, vel, mid1, mid2, mid3, ip, w, det_df, vol, lambdas_11, lambdas_12, lambdas_13, lambdas_21, lambdas_22, lambdas_23, lambdas_31, lambdas_32, lambdas_33, cell_left, point_left, point_right, cell_number, compact, mat_11, mat_12, mat_13, mat_21, mat_22, mat_23, mat_31, mat_32, mat_33, i1, i2, i3, il1, il2, il3, jl1, index1, index2, index3, value_x, value_y, value_z, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, dft, eta1, eta2, eta3, final_index1, final_index2, final_index3, lambda_index1, lambda_index2, lambda_index3, f_int) - for ip in range(Np_loc): - vel[:] = 0.0 - - w = particle[6, ip] / Np - - lambdas_11[:, :, :] = 0.0 - lambdas_12[:, :, :] = 0.0 - lambdas_13[:, :, :] = 0.0 - - lambdas_21[:, :, :] = 0.0 - lambdas_22[:, :, :] = 0.0 - lambdas_23[:, :, :] = 0.0 - - lambdas_31[:, :, :] = 0.0 - lambdas_32[:, :, :] = 0.0 - lambdas_33[:, :, :] = 0.0 - - # ================================== - compact[0] = (p_shape[0] + 1.0) * p_size[0] - compact[1] = (p_shape[1] + 1.0) * p_size[1] - compact[2] = (p_shape[2] + 1.0) * p_size[2] - - point_left[0] = particle[0, ip] - 0.5 * compact[0] - point_right[0] = particle[0, ip] + 0.5 * compact[0] - point_left[1] = particle[1, ip] - 0.5 * compact[1] - point_right[1] = particle[1, ip] + 0.5 * compact[1] - point_left[2] = particle[2, ip] - 0.5 * compact[2] - point_right[2] = particle[2, ip] + 0.5 * compact[2] - - cell_left[0] = int(floor(point_left[0] * Nel[0])) - cell_left[1] = int(floor(point_left[1] * Nel[1])) - cell_left[2] = int(floor(point_left[2] * Nel[2])) - - cell_number[0] = int(floor(point_right[0] * Nel[0])) - cell_left[0] + 1 - cell_number[1] = int(floor(point_right[1] * Nel[1])) - cell_left[1] + 1 - cell_number[2] = int(floor(point_right[2] * Nel[2])) - cell_left[2] + 1 - - for i in range(p_shape[0] + 1): - grids_shapex[i] = point_left[0] + i * p_size[0] - grids_shapex[p_shape[0] + 1] = point_right[0] - - for i in range(p_shape[1] + 1): - grids_shapey[i] = point_left[1] + i * p_size[1] - grids_shapey[p_shape[1] + 1] = point_right[1] - - for i in range(p_shape[2] + 1): - grids_shapez[i] = point_left[2] + i * p_size[2] - grids_shapez[p_shape[2] + 1] = point_right[2] - - vol = 1.0 / (p_size[0] * p_size[1] * p_size[2]) - - # evaluation of function at interpolation/quadrature points - mat_11 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_21 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - mat_31 = zeros( - (cell_number[0], cell_number[1], cell_number[2], 2, num_cell[1], num_cell[2], quad[0]), - dtype=float, - ) - - mat_12 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_22 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - mat_32 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], 2, num_cell[2], quad[1]), - dtype=float, - ) - - mat_13 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_23 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - mat_33 = zeros( - (cell_number[0], cell_number[1], cell_number[2], num_cell[0], num_cell[1], 2, quad[2]), - dtype=float, - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): # num_cell = 1, p = 1; num_cell = 2, p >= 2 - index3 = cell_left[2] + i3 - for il1 in range(2): - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1 / Nel[1] / num_cell[1] * il2 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1 / Nel[2] / num_cell[2] * il3 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[0]): - eta1 = 1.0 / Nel[0] * index1 + 1 / Nel[0] / 2.0 * il1 + pts1[jl1] - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - # ========= mapping evaluation ============= - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_11[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_21[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_31[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[0, 2] * value_x * value_y * value_z / det_df * vol - ) - - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(2): - for il3 in range(num_cell[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / num_cell[2] * il3 - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - for jl1 in range(quad[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / 2.0 * il2 + pts2[jl1] - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - # ========= mapping evaluation ============= - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_12[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_22[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_32[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[1, 2] * value_x * value_y * value_z / det_df * vol - ) - - for il1 in range(num_cell[0]): - eta1 = 1.0 / Nel[0] * index1 + 1.0 / Nel[0] / num_cell[0] * il1 - span1f = int((eta1 % 1.0) * nelf[0]) + pf1 - value_x = bsp.piecewise(p_shape[0], p_size[0], abs(eta1 - particle[0, ip])) - for il2 in range(num_cell[1]): - eta2 = 1.0 / Nel[1] * index2 + 1.0 / Nel[1] / num_cell[1] * il2 - span2f = int((eta2 % 1.0) * nelf[1]) + pf2 - value_y = bsp.piecewise(p_shape[1], p_size[1], abs(eta2 - particle[1, ip])) - for il3 in range(2): - for jl1 in range(quad[2]): - eta3 = 1.0 / Nel[2] * index3 + 1.0 / Nel[2] / 2.0 * il3 + pts3[jl1] - value_z = bsp.piecewise(p_shape[2], p_size[2], abs(eta3 - particle[2, ip])) - # ========= mapping evaluation ============= - span3f = int((eta3 % 1.0) * nelf[2]) + pf3 - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1 % 1.0, - eta2 % 1.0, - eta3 % 1.0, - df, - fx, - 0, - ) - # evaluate transpose of Jacobian matrix - linalg.transpose(df, dft) - det_df = abs(linalg.det(df)) - - mat_13[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 0] * value_x * value_y * value_z / det_df * vol - ) - mat_23[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 1] * value_x * value_y * value_z / det_df * vol - ) - mat_33[i1, i2, i3, il1, il2, il3, jl1] = ( - dft[2, 2] * value_x * value_y * value_z / det_df * vol - ) - - for i1 in range(cell_number[0]): - index1 = cell_left[0] + i1 - for i2 in range(cell_number[1]): - index2 = cell_left[1] + i2 - for i3 in range(cell_number[2]): - index3 = cell_left[2] + i3 - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseD[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(2): - for il2 in range(num_cell[1]): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_11[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[0] += mid1 * bb1[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_21[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[1] += mid2 * bb1[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[0]): - f_int += wts1[jl1] * mat_31[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_h_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[2] += mid3 * bb1[final_index1, final_index2, final_index3] - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseD[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseN[2] - for il1 in range(num_cell[0]): - for il2 in range(2): - for il3 in range(num_cell[2]): - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_12[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[0] += mid1 * bb2[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_22[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[1] += mid2 * bb2[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[1]): - f_int += wts2[jl1] * mat_32[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_h_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_i_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[2] += mid3 * bb2[final_index1, final_index2, final_index3] - - for lambda_index1 in range(p[0]): - final_index1 = (lambda_index1 + index1) % NbaseN[0] - for lambda_index2 in range(p[1]): - final_index2 = (lambda_index2 + index2) % NbaseN[1] - for lambda_index3 in range(p[2]): - final_index3 = (lambda_index3 + index3) % NbaseD[2] - for il1 in range(num_cell[0]): - for il2 in range(num_cell[1]): - for il3 in range(2): - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_13[i1, i2, i3, il1, il2, il3, jl1] - mid1 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[0] += mid1 * bb3[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_23[i1, i2, i3, il1, il2, il3, jl1] - mid2 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[1] += mid2 * bb3[final_index1, final_index2, final_index3] - f_int = 0.0 - for jl1 in range(quad[2]): - f_int += wts3[jl1] * mat_33[i1, i2, i3, il1, il2, il3, jl1] - mid3 = ( - coeff_i_x[2 * (p[0] - 1) - 2 * lambda_index1 + il1] - * coeff_i_y[2 * (p[1] - 1) - 2 * lambda_index2 + il2] - * coeff_h_z[2 * (p[2] - 1) - 2 * lambda_index3 + il3] - * f_int - ) - vel[2] += mid3 * bb3[final_index1, final_index2, final_index3] - - out[0, ip] = vel[0] - out[1, ip] = vel[1] - out[2, ip] = vel[2] - - del mat_11 - del mat_12 - del mat_13 - del mat_21 - del mat_22 - del mat_23 - del mat_31 - del mat_32 - del mat_33 - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - ierr = 0 diff --git a/src/struphy/eigenvalue_solvers/mass_matrices_1d.py b/src/struphy/eigenvalue_solvers/mass_matrices_1d.py deleted file mode 100644 index 3d9c665fb..000000000 --- a/src/struphy/eigenvalue_solvers/mass_matrices_1d.py +++ /dev/null @@ -1,256 +0,0 @@ -# coding: utf-8 -# -# Copyright 2020 Florian Holderied - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.bsplines.bsplines as bsp - - -# ======= mass matrices in 1D ==================== -def get_M(spline_space, phi_i=0, phi_j=0, fun=None): - """ - Assembles the 1d mass matrix [NN], [ND], [DN] or [DD] of the given B-spline space of degree p weighted with fun. - - Parameters - ---------- - spline_space : Spline_space_1d - a 1d B-spline space - - phi_i : int - kind of basis function phi_i (0 : B-spline of degree p (N), 1 : M-spline of degree p - 1 (D)) - - phi_j : int - kind of basis function phi_j (0 : B-spline of degree p (N), 1 : M-spline of degree p - 1 (D)) - - fun : callable - weight function (e.g. related to a mapping) - - Returns - ------- - M : csr matrix - Weigthed mass matrix for given basis product. - """ - - p = spline_space.p # spline degrees - Nel = spline_space.Nel # number of elements - NbaseN = spline_space.NbaseN # total number of basis functions (N) - NbaseD = spline_space.NbaseD # total number of basis functions (D) - - n_quad = spline_space.n_quad # number of quadrature points per element - pts = spline_space.pts # global quadrature points in format (element, local quad_point) - wts = spline_space.wts # global quadrature weights in format (element, local weight) - - basisN = spline_space.basisN # evaluated basis functions at quadrature points - basisD = spline_space.basisD # evaluated basis functions at quadrature points - - # evaluation of weight function at quadrature points (optional) - if fun is None: - mat_fun = xp.ones(pts.shape, dtype=float) - else: - mat_fun = fun(pts.flatten()).reshape(Nel, n_quad) - - # selection of phi_i basis functions - if phi_i == 0: - Ni = NbaseN - ni = 0 - bi = basisN[:, :, 0, :] - - elif phi_i == 1: - Ni = NbaseD - ni = 1 - bi = basisD[:, :, 0, :] - - # selection of phi_j basis functions - if phi_j == 0: - Nj = NbaseN - nj = 0 - bj = basisN[:, :, 0, :] - - elif phi_j == 1: - Nj = NbaseD - nj = 1 - bj = basisD[:, :, 0, :] - - # matrix assembly - M = xp.zeros((Ni, 2 * p + 1), dtype=float) - - for ie in range(Nel): - for il in range(p + 1 - ni): - for jl in range(p + 1 - nj): - value = 0.0 - - for q in range(n_quad): - value += wts[ie, q] * bi[ie, il, q] * bj[ie, jl, q] * mat_fun[ie, q] - - M[(ie + il) % Ni, p + jl - il] += value - - indices = xp.indices((Ni, 2 * p + 1)) - shift = xp.arange(Ni) - p - - row = indices[0].flatten() - col = (indices[1] + shift[:, None]) % Nj - - M = spa.csr_matrix((M.flatten(), (row, col.flatten())), shape=(Ni, Nj)) - M.eliminate_zeros() - - return M - - -# ======= general mass matrix ==================== -def get_M_gen(spline_space, phi_i=0, phi_j=0, fun=None, jac=None): - """ - General assembly of matrices of the form M_ij = phi_i(eta) * phi_j(eta) * fun(eta) under the jacobian jac = dF/deta. - - Parameters - ---------- - spline_space : Spline_space_1d - a 1d B-spline space - - phi_i : int - kind of basis function phi_i (0 : spline of degree p, 1 : derivative of splines of degree p, 2 : spline of degree p - 1) - - phi_j : int - kind of basis function phi_j (0 : spline of degree p, 1 : derivative of splines of degree p, 2 : spline of degree p - 1) - - fun : callable - weight function - - jac : callable - derivative of the mapping x = F(eta) - """ - - p = spline_space.p # spline degree - Nel = spline_space.Nel # number of elements - - NbaseN = spline_space.NbaseN # total number of basis functions (p) - NbaseD = spline_space.NbaseD # total number of basis functions (p-1) - - n_quad = spline_space.n_quad # number of quadrature points per element - pts = spline_space.pts # global quadrature points in format (element, local quad_point) - wts = spline_space.wts # global quadrature weights in format (element, local weight) - - # evaluation of basis functions at quadrature points in format (element, local function, derivative, local quad_point) - basis_T = bsp.basis_ders_on_quad_grid(spline_space.T, p, spline_space.pts, 1, normalize=False) - basis_t = bsp.basis_ders_on_quad_grid(spline_space.t, p - 1, spline_space.pts, 0, normalize=False) - - # evaluation of weight function at quadrature points (optional) - if fun is None: - mat_fun = xp.ones(pts.shape, dtype=float) - else: - mat_fun = fun(pts.flatten()).reshape(Nel, n_quad) - - # evaluation of jacobian at quadrature points - if jac is None: - mat_jac = xp.ones(pts.shape, dtype=float) - else: - mat_jac = jac(pts.flatten()).reshape(Nel, n_quad) - - # selection of phi_i basis functions - if phi_i == 0: - Ni = NbaseN - ni = 0 - bi = basis_T[:, :, 0, :] - - elif phi_i == 1: - Ni = NbaseN - ni = 0 - bi = basis_T[:, :, 1, :] / mat_jac[:, None, :] - - elif phi_i == 2: - Ni = NbaseD - ni = 1 - bi = basis_t[:, :, 0, :] - - # selection of phi_j basis functions - if phi_j == 0: - Nj = NbaseN - nj = 0 - bj = basis_T[:, :, 0, :] - - elif phi_j == 1: - Nj = NbaseN - nj = 0 - bj = basis_T[:, :, 1, :] / mat_jac[:, None, :] - - elif phi_j == 2: - Nj = NbaseD - nj = 1 - bj = basis_t[:, :, 0, :] - - # matrix assembly - M = xp.zeros((Ni, 2 * p + 1), dtype=float) - - for ie in range(Nel): - for il in range(p + 1 - ni): - for jl in range(p + 1 - nj): - value = 0.0 - - for q in range(n_quad): - value += wts[ie, q] * bi[ie, il, q] * bj[ie, jl, q] * mat_fun[ie, q] * mat_jac[ie, q] - - M[(ie + il) % Ni, p + jl - il] += value - - indices = xp.indices((Ni, 2 * p + 1)) - shift = xp.arange(Ni) - p - - row = indices[0].flatten() - col = (indices[1] + shift[:, None]) % Nj - - M = spa.csc_matrix((M.flatten(), (row, col.flatten())), shape=(Ni, Nj)) - M.eliminate_zeros() - - return M - - -# ======= test for general mass matrix ==================== -def test_M(spline_space, phi_i=0, phi_j=0, fun=lambda eta: 1.0, jac=lambda eta: 1.0): - from scipy.integrate import quad - - # selection of phi_i basis functions - if phi_i == 0: - Ni = spline_space.NbaseN - bi = lambda eta: spline_space.evaluate_N(eta, ci) - - elif phi_i == 1: - Ni = spline_space.NbaseN - bi = lambda eta: spline_space.evaluate_dN(eta, ci) / jac(eta) - - elif phi_i == 2: - Ni = spline_space.NbaseD - bi = lambda eta: spline_space.evaluate_D(eta, ci) / spline_space.Nel - - # selection of phi_j basis functions - if phi_j == 0: - Nj = spline_space.NbaseN - bj = lambda eta: spline_space.evaluate_N(eta, cj) - - elif phi_j == 1: - Nj = spline_space.NbaseN - bj = lambda eta: spline_space.evaluate_dN(eta, cj) / jac(eta) - - elif phi_j == 2: - Nj = spline_space.NbaseD - bj = lambda eta: spline_space.evaluate_D(eta, cj) / spline_space.Nel - - # coefficients - ci = xp.zeros(Ni, dtype=float) - cj = xp.zeros(Nj, dtype=float) - - # integration - M = xp.zeros((Ni, Nj), dtype=float) - - for i in range(Ni): - for j in range(Nj): - ci[:] = 0.0 - cj[:] = 0.0 - - ci[i] = 1.0 - cj[j] = 1.0 - - integrand = lambda eta: bi(eta) * bj(eta) * fun(eta) * jac(eta) - - M[i, j] = quad(integrand, 0.0, 1.0)[0] - - return M diff --git a/src/struphy/eigenvalue_solvers/mass_matrices_2d.py b/src/struphy/eigenvalue_solvers/mass_matrices_2d.py deleted file mode 100644 index b8f8943d4..000000000 --- a/src/struphy/eigenvalue_solvers/mass_matrices_2d.py +++ /dev/null @@ -1,534 +0,0 @@ -# coding: utf-8 -# -# Copyright 2020 Florian Holderied - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.eigenvalue_solvers.kernels_2d as ker - - -# ================ mass matrix in V0 =========================== -def get_M0(tensor_space_FEM, domain, apply_boundary_ops=False, weight=None): - """ - Assembles the 2D mass matrix [[NN NN]] * |det(DF)| of the given tensor product B-spline spaces of bi-degree (p1, p2) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - apply_boundary_ops : boolean - whether to include boundary operators (True) or not (False) - - weight : callable - optional additional weight function - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of local non-vanishing basis functions in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points in format (element, local quad_point) - wts = tensor_space_FEM.wts # global quadrature weights in format (element, local weight) - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points - - # evaluation of |det(DF)| at eta3 = 0 and quadrature points in format (Nel1, nq1, Nel2, nq2) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), 0.0)) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # evaluation of weight function at quadrature points - if weight is None: - mat_w = xp.ones(det_df.shape, dtype=float) - else: - mat_w = weight(pts[0].flatten(), pts[1].flatten(), 0.0) - mat_w = mat_w.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # assembly of global mass matrix - Ni = tensor_space_FEM.Nbase_0form - Nj = tensor_space_FEM.Nbase_0form - - M = xp.zeros((Ni[0], Ni[1], 2 * p[0] + 1, 2 * p[1] + 1), dtype=float) - - ker.kernel_mass( - xp.array(Nel), - xp.array(p), - xp.array(n_quad), - xp.array([0, 0]), - xp.array([0, 0]), - wts[0], - wts[1], - basisN[0], - basisN[1], - basisN[0], - basisN[1], - indN[0], - indN[1], - M, - mat_w * det_df, - ) - - # conversion to sparse matrix - indices = xp.indices((Ni[0], Ni[1], 2 * p[0] + 1, 2 * p[1] + 1)) - - shift = [xp.arange(Ni) - p for Ni, p in zip(Ni, p)] - - row = (Ni[1] * indices[0] + indices[1]).flatten() - - col1 = (indices[2] + shift[0][:, None, None, None]) % Nj[0] - col2 = (indices[3] + shift[1][None, :, None, None]) % Nj[1] - - col = Nj[1] * col1 + col2 - - M = spa.csr_matrix((M.flatten(), (row, col.flatten())), shape=(Ni[0] * Ni[1], Nj[0] * Nj[1])) - M.eliminate_zeros() - - # apply spline extraction operator and return - if apply_boundary_ops: - M = tensor_space_FEM.E0_pol_0.dot(M.dot(tensor_space_FEM.E0_pol_0.T)).tocsr() - else: - M = tensor_space_FEM.E0_pol.dot(M.dot(tensor_space_FEM.E0_pol.T)).tocsr() - - return M - - -# ================ mass matrix in V1 =========================== -def get_M1(tensor_space_FEM, domain, apply_boundary_ops=False, weight=None): - """ - Assembles the 2D mass matrix [[DN DN, DN ND, DN NN], [ND DN, ND ND, ND NN], [NN DN, NN ND, NN NN]] * G^(-1) * |det(DF)| of the given tensor product B-spline spaces of bi-degree (p1, p2) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - apply_boundary_ops : boolean - whether to include boundary operators (True) or not (False) - - weight : callable - optional additional weight functions - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - # indices and basis functions of components of a 1-form - ind = [[indD[0], indN[1]], [indN[0], indD[1]], [indN[0], indN[1]]] - basis = [[basisD[0], basisN[1]], [basisN[0], basisD[1]], [basisN[0], basisN[1]]] - ns = [[1, 0], [0, 1], [0, 0]] - - # evaluation of |det(DF)| at eta3 = 0 and quadrature points in format (Nel1, nq1, Nel2, nq2) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), 0.0)) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # evaluation of G^(-1) at eta3 = 0 and quadrature points in format (3, 3, Nel1*nq1, Nel2*nq2) - g_inv = domain.metric_inv(pts[0].flatten(), pts[1].flatten(), 0.0) - - # blocks of global mass matrix - M = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] - - # assembly of blocks - for a in range(3): - for b in range(3): - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - M[a][b] = xp.zeros((Ni[0], Ni[1], 2 * p[0] + 1, 2 * p[1] + 1), dtype=float) - - # evaluate inverse metric tensor at quadrature points - if weight is None: - mat_w = g_inv[a, b] - else: - mat_w = weight[a][b](pts[0].flatten(), pts[1].flatten(), 0.0) - - mat_w = mat_w.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # assemble block if weight is not zero - if xp.any(mat_w): - ker.kernel_mass( - xp.array(Nel), - xp.array(p), - xp.array(n_quad), - xp.array(ns[a]), - xp.array(ns[b]), - wts[0], - wts[1], - basis[a][0], - basis[a][1], - basis[b][0], - basis[b][1], - ind[a][0], - ind[a][1], - M[a][b], - mat_w * det_df, - ) - - # convert to sparse matrix - indices = xp.indices((Ni[0], Ni[1], 2 * p[0] + 1, 2 * p[1] + 1)) - - shift = [xp.arange(Ni) - p for Ni, p in zip(Ni, p)] - - row = (Ni[1] * indices[0] + indices[1]).flatten() - - col1 = (indices[2] + shift[0][:, None, None, None]) % Nj[0] - col2 = (indices[3] + shift[1][None, :, None, None]) % Nj[1] - - col = Nj[1] * col1 + col2 - - M[a][b] = spa.csr_matrix((M[a][b].flatten(), (row, col.flatten())), shape=(Ni[0] * Ni[1], Nj[0] * Nj[1])) - M[a][b].eliminate_zeros() - - # apply extraction operators - M11 = spa.bmat([[M[0][0], M[0][1]], [M[1][0], M[1][1]]]) - M22 = M[2][2] - - if apply_boundary_ops: - M11 = tensor_space_FEM.E1_pol_0.dot(M11.dot(tensor_space_FEM.E1_pol_0.T)).tocsr() - M22 = tensor_space_FEM.E0_pol_0.dot(M22.dot(tensor_space_FEM.E0_pol_0.T)).tocsr() - else: - M11 = tensor_space_FEM.E1_pol.dot(M11.dot(tensor_space_FEM.E1_pol.T)).tocsr() - M22 = tensor_space_FEM.E0_pol.dot(M22.dot(tensor_space_FEM.E0_pol.T)).tocsr() - - return M11, M22 - - -# ================ mass matrix in V2 =========================== -def get_M2(tensor_space_FEM, domain, apply_boundary_ops=False, weight=None): - """ - Assembles the 2D mass matrix [[ND ND, ND DN, ND DD], [DN ND, DN DN, DN DD], [DD ND, DD DN, DD DD]] * G / |det(DF)| of the given tensor product B-spline spaces of bi-degree (p1, p2) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - apply_boundary_ops : boolean - whether to include boundary operators (True) or not (False) - - weight : callable - optional additional weight functions - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - # indices and basis functions of components of a 2-form - ind = [[indN[0], indD[1]], [indD[0], indN[1]], [indD[0], indD[1]]] - basis = [[basisN[0], basisD[1]], [basisD[0], basisN[1]], [basisD[0], basisD[1]]] - ns = [[0, 1], [1, 0], [1, 1]] - - # evaluation of |det(DF)| at eta3 = 0 and quadrature points in format (Nel1, nq1, Nel2, nq2) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), 0.0)) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # evaluation of G at eta3 = 0 and quadrature points in format (3, 3, Nel1*nq1, Nel2*nq2) - g = domain.metric(pts[0].flatten(), pts[1].flatten(), 0.0) - - # blocks of global mass matrix - M = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] - - # assembly of blocks - for a in range(3): - for b in range(3): - Ni = tensor_space_FEM.Nbase_2form[a] - Nj = tensor_space_FEM.Nbase_2form[b] - - M[a][b] = xp.zeros((Ni[0], Ni[1], 2 * p[0] + 1, 2 * p[1] + 1), dtype=float) - - # evaluate metric tensor at quadrature points - if weight is None: - mat_w = g[a, b] - else: - mat_w = weight[a][b](pts[0].flatten(), pts[1].flatten(), 0.0) - - mat_w = mat_w.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # assemble block if weight is not zero - if xp.any(mat_w): - ker.kernel_mass( - xp.array(Nel), - xp.array(p), - xp.array(n_quad), - xp.array(ns[a]), - xp.array(ns[b]), - wts[0], - wts[1], - basis[a][0], - basis[a][1], - basis[b][0], - basis[b][1], - ind[a][0], - ind[a][1], - M[a][b], - mat_w / det_df, - ) - - # convert to sparse matrix - indices = xp.indices((Ni[0], Ni[1], 2 * p[0] + 1, 2 * p[1] + 1)) - - shift = [xp.arange(Ni) - p for Ni, p in zip(Ni, p)] - - row = (Ni[1] * indices[0] + indices[1]).flatten() - - col1 = (indices[2] + shift[0][:, None, None, None]) % Nj[0] - col2 = (indices[3] + shift[1][None, :, None, None]) % Nj[1] - - col = Nj[1] * col1 + col2 - - M[a][b] = spa.csr_matrix((M[a][b].flatten(), (row, col.flatten())), shape=(Ni[0] * Ni[1], Nj[0] * Nj[1])) - M[a][b].eliminate_zeros() - - # apply extraction operators - M11 = spa.bmat([[M[0][0], M[0][1]], [M[1][0], M[1][1]]]) - M22 = M[2][2] - - if apply_boundary_ops: - M11 = tensor_space_FEM.E2_pol_0.dot(M11.dot(tensor_space_FEM.E2_pol_0.T)).tocsr() - M22 = tensor_space_FEM.E3_pol_0.dot(M22.dot(tensor_space_FEM.E3_pol_0.T)).tocsr() - else: - M11 = tensor_space_FEM.E2_pol.dot(M11.dot(tensor_space_FEM.E2_pol.T)).tocsr() - M22 = tensor_space_FEM.E3_pol.dot(M22.dot(tensor_space_FEM.E3_pol.T)).tocsr() - - return M11, M22 - - -# ================ mass matrix in V3 =========================== -def get_M3(tensor_space_FEM, domain, apply_boundary_ops=False, weight=None): - """ - Assembles the 3D mass matrix [[DD DD]] / |det(DF)| of the given tensor product B-spline spaces of bi-degree (p1, p2) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - apply_boundary_ops : boolean - whether to include boundary operators (True) or not (False) - - weight : callable - optional additional weight function - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indD = ( - tensor_space_FEM.indD - ) # global indices of local non-vanishing basis functions in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points in format (element, local quad_point) - wts = tensor_space_FEM.wts # global quadrature weights in format (element, local weight) - - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points - - # evaluation of |det(DF)| at eta3 = 0 and quadrature points in format (Nel1, nq1, Nel2, nq2) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), 0.0)) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # evaluation of weight function at quadrature points - if weight is None: - mat_w = xp.ones(det_df.shape, dtype=float) - else: - mat_w = weight(pts[0].flatten(), pts[1].flatten(), 0.0) - mat_w = mat_w.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # assembly of global mass matrix - Ni = tensor_space_FEM.Nbase_3form - Nj = tensor_space_FEM.Nbase_3form - - M = xp.zeros((Ni[0], Ni[1], 2 * p[0] + 1, 2 * p[1] + 1), dtype=float) - - ker.kernel_mass( - xp.array(Nel), - xp.array(p), - xp.array(n_quad), - xp.array([1, 1]), - xp.array([1, 1]), - wts[0], - wts[1], - basisD[0], - basisD[1], - basisD[0], - basisD[1], - indD[0], - indD[1], - M, - mat_w / det_df, - ) - - # conversion to sparse matrix - indices = xp.indices((Ni[0], Ni[1], 2 * p[0] + 1, 2 * p[1] + 1)) - - shift = [xp.arange(Ni) - p for Ni, p in zip(Ni, p)] - - row = (Ni[1] * indices[0] + indices[1]).flatten() - - col1 = (indices[2] + shift[0][:, None, None, None]) % Nj[0] - col2 = (indices[3] + shift[1][None, :, None, None]) % Nj[1] - - col = Nj[1] * col1 + col2 - - M = spa.csr_matrix((M.flatten(), (row, col.flatten())), shape=(Ni[0] * Ni[1], Nj[0] * Nj[1])) - M.eliminate_zeros() - - # apply spline extraction operator and return - if apply_boundary_ops: - M = tensor_space_FEM.E3_pol_0.dot(M.dot(tensor_space_FEM.E3_pol_0.T)).tocsr() - else: - M = tensor_space_FEM.E3_pol.dot(M.dot(tensor_space_FEM.E3_pol.T)).tocsr() - - return M - - -# ============= mass matrix of vector field ========================= -def get_Mv(tensor_space_FEM, domain, apply_boundary_ops=False, weight=None): - """ - Assembles the 2D mass matrix [[NN NN, NN NN, NN NN], [NN NN, NN NN, NN NN], [NN NN, NN NN, NN NN]] * G * |det(DF)| of the given tensor product B-spline spaces of bi-degree (p1, p2) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - apply_boundary_ops : boolean - whether to include boundary operators (True) or not (False) - - weight : callable - optional additional weight functions - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - - # indices and basis functions of components of a 0-form - ind = [[indN[0], indN[1]], [indN[0], indN[1]], [indN[0], indN[1]]] - basis = [[basisN[0], basisN[1]], [basisN[0], basisN[1]], [basisN[0], basisN[1]]] - ns = [[0, 0], [0, 0], [0, 0]] - - # evaluation of |det(DF)| at eta3 = 0 and quadrature points in format (Nel1, nq1, Nel2, nq2) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), 0.0)) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # evaluation of G at eta3 = 0 and quadrature points in format (3, 3, Nel1*nq1, Nel2*nq2) - g = domain.metric(pts[0].flatten(), pts[1].flatten(), 0.0) - - # blocks of global mass matrix - M = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] - - # assembly of blocks - for a in range(3): - for b in range(3): - Ni = tensor_space_FEM.Nbase_0form - Nj = tensor_space_FEM.Nbase_0form - - M[a][b] = xp.zeros((Ni[0], Ni[1], 2 * p[0] + 1, 2 * p[1] + 1), dtype=float) - - # evaluate metric tensor at quadrature points - if weight is None: - mat_w = g[a, b] - else: - mat_w = weight[a][b](pts[0].flatten(), pts[1].flatten(), 0.0) - - mat_w = mat_w.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1]) - - # assemble block if weight is not zero - if xp.any(mat_w): - ker.kernel_mass( - xp.array(Nel), - xp.array(p), - xp.array(n_quad), - xp.array(ns[a]), - xp.array(ns[b]), - wts[0], - wts[1], - basis[a][0], - basis[a][1], - basis[b][0], - basis[b][1], - ind[a][0], - ind[a][1], - M[a][b], - mat_w * det_df, - ) - - # convert to sparse matrix - indices = xp.indices((Ni[0], Ni[1], 2 * p[0] + 1, 2 * p[1] + 1)) - - shift = [xp.arange(Ni) - p for Ni, p in zip(Ni, p)] - - row = (Ni[1] * indices[0] + indices[1]).flatten() - - col1 = (indices[2] + shift[0][:, None, None, None]) % Nj[0] - col2 = (indices[3] + shift[1][None, :, None, None]) % Nj[1] - - col = Nj[1] * col1 + col2 - - M[a][b] = spa.csr_matrix((M[a][b].flatten(), (row, col.flatten())), shape=(Ni[0] * Ni[1], Nj[0] * Nj[1])) - M[a][b].eliminate_zeros() - - # apply extraction operators - M11 = spa.bmat([[M[0][0], M[0][1]], [M[1][0], M[1][1]]]) - M22 = M[2][2] - - if apply_boundary_ops: - M11 = tensor_space_FEM.Ev_pol_0.dot(M11.dot(tensor_space_FEM.Ev_pol_0.T)).tocsr() - M22 = tensor_space_FEM.E0_pol.dot(M22.dot(tensor_space_FEM.E0_pol.T)).tocsr() - else: - M11 = tensor_space_FEM.Ev_pol.dot(M11.dot(tensor_space_FEM.Ev_pol.T)).tocsr() - M22 = tensor_space_FEM.E0_pol.dot(M22.dot(tensor_space_FEM.E0_pol.T)).tocsr() - - return M11, M22 diff --git a/src/struphy/eigenvalue_solvers/mass_matrices_3d.py b/src/struphy/eigenvalue_solvers/mass_matrices_3d.py deleted file mode 100644 index 49be830b5..000000000 --- a/src/struphy/eigenvalue_solvers/mass_matrices_3d.py +++ /dev/null @@ -1,581 +0,0 @@ -# coding: utf-8 -# -# Copyright 2020 Florian Holderied (florian.holderied@ipp.mpg.de) - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.eigenvalue_solvers.kernels_3d as ker - - -# ================ mass matrix in V0 =========================== -def get_M0(tensor_space_FEM, domain, apply_boundary_ops=False, weight=None): - """ - Assembles the 3D mass matrix with integrand [[NNN NNN]] * |det(DF)|. - - Parameters - ---------- - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - apply_boundary_ops : boolean - whether to include boundary operators (True) or not (False) - - weight : callable - optional additional weight function - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of local non-vanishing basis functions in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points in format (element, local quad_point) - wts = tensor_space_FEM.wts # global quadrature weights in format (element, local weight) - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points - - # evaluation of |det(DF)| at quadrature points in format (Nel1, nq1, Nel2, nq2, Nel3, nq3) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), pts[2].flatten())) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # evaluation of weight function at quadrature points - if weight is None: - mat_w = xp.ones(det_df.shape, dtype=float) - else: - mat_w = weight(pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - mat_w = mat_w.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # assembly of global mass matrix - Ni = tensor_space_FEM.Nbase_0form - Nj = tensor_space_FEM.Nbase_0form - - M = xp.zeros((Ni[0], Ni[1], Ni[2], 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1), dtype=float) - - ker.kernel_mass( - xp.array(Nel), - xp.array(p), - xp.array(n_quad), - xp.array([0, 0, 0]), - xp.array([0, 0, 0]), - wts[0], - wts[1], - wts[2], - basisN[0], - basisN[1], - basisN[2], - basisN[0], - basisN[1], - basisN[2], - indN[0], - indN[1], - indN[2], - M, - mat_w * det_df, - ) - - # conversion to sparse matrix - indices = xp.indices((Ni[0], Ni[1], Ni[2], 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1)) - - shift = [xp.arange(Ni) - p for Ni, p in zip(Ni, p)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Ni[2] * col1 + Ni[2] * col2 + col3 - - M = spa.csr_matrix((M.flatten(), (row, col.flatten())), shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2])) - M.eliminate_zeros() - - # apply spline extraction operator and return - if apply_boundary_ops: - M = tensor_space_FEM.E0_0.dot(M.dot(tensor_space_FEM.E0_0.T)).tocsr() - else: - M = tensor_space_FEM.E0.dot(M.dot(tensor_space_FEM.E0.T)).tocsr() - - return M - - -# ================ mass matrix in V1 =========================== -def get_M1(tensor_space_FEM, domain, apply_boundary_ops=False, weight=None): - """ - Assembles the 3D mass matrix with integrand - [[DNN DNN, DNN NDN, DNN NND], [NDN DNN, NDN NDN, NDN NND], [NND DNN, NND NDN, NND NND]] * G^(-1) * |det(DF)|. - - Parameters - ---------- - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - apply_boundary_ops : boolean - whether to include boundary operators (True) or not (False) - - weight : callable - optional additional weight functions - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - # indices and basis functions of components of a 2-form - ind = [[indD[0], indN[1], indN[2]], [indN[0], indD[1], indN[2]], [indN[0], indN[1], indD[2]]] - basis = [[basisD[0], basisN[1], basisN[2]], [basisN[0], basisD[1], basisN[2]], [basisN[0], basisN[1], basisD[2]]] - ns = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] - - # evaluation of |det(DF)| at quadrature points in format (Nel1, nq1, Nel2, nq2, Nel3, nq3) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), pts[2].flatten())) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # evaluation of G^(-1) at quadrature points in format (3, 3, Nel1*nq1, Nel2*nq2, Nel3*nq3) - g_inv = domain.metric_inv(pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - - # blocks of global mass matrix - M = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] - - for a in range(3): - for b in range(3): - Ni = tensor_space_FEM.Nbase_1form[a] - Nj = tensor_space_FEM.Nbase_1form[b] - - M[a][b] = xp.zeros((Ni[0], Ni[1], Ni[2], 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1), dtype=float) - - # evaluate metric tensor at quadrature points - if weight is None: - mat_w = g_inv[a, b] - else: - mat_w = weight[a][b](pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - - mat_w = mat_w.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # assemble block if weight is not zero - if xp.any(mat_w): - ker.kernel_mass( - xp.array(Nel), - xp.array(p), - xp.array(n_quad), - xp.array(ns[a]), - xp.array(ns[b]), - wts[0], - wts[1], - wts[2], - basis[a][0], - basis[a][1], - basis[a][2], - basis[b][0], - basis[b][1], - basis[b][2], - ind[a][0], - ind[a][1], - ind[a][2], - M[a][b], - mat_w * det_df, - ) - - # convert to sparse matrix - indices = xp.indices((Ni[0], Ni[1], Ni[2], 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1)) - - shift = [xp.arange(Ni) - p for Ni, p in zip(Ni, p)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M[a][b] = spa.csr_matrix( - (M[a][b].flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M[a][b].eliminate_zeros() - - M = spa.bmat([[M[0][0], M[0][1], M[0][2]], [M[1][0], M[1][1], M[1][2]], [M[2][0], M[2][1], M[2][2]]], format="csr") - - # apply spline extraction operator and return - if apply_boundary_ops: - M = tensor_space_FEM.E1_0.dot(M.dot(tensor_space_FEM.E1_0.T)).tocsr() - else: - M = tensor_space_FEM.E1.dot(M.dot(tensor_space_FEM.E1.T)).tocsr() - - return M - - -# ================ mass matrix in V2 =========================== -def get_M2(tensor_space_FEM, domain, apply_boundary_ops=False, weight=None): - """ - Assembles the 3D mass matrix [[NDD NDD, NDD DND, NDD DDN], [DND NDD, DND DND, DND DDN], [DDN NDD, DDN DND, DDN DDN]] * G / |det(DF)| of the given tensor product B-spline spaces of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - apply_boundary_ops : boolean - whether to include boundary operators (True) or not (False) - - weight : callable - optional additional weight functions - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - # indices and basis functions of components of a 2-form - ind = [[indN[0], indD[1], indD[2]], [indD[0], indN[1], indD[2]], [indD[0], indD[1], indN[2]]] - basis = [[basisN[0], basisD[1], basisD[2]], [basisD[0], basisN[1], basisD[2]], [basisD[0], basisD[1], basisN[2]]] - ns = [[0, 1, 1], [1, 0, 1], [1, 1, 0]] - - # evaluation of |det(DF)| at quadrature points in format (Nel1, nq1, Nel2, nq2, Nel3, nq3) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), pts[2].flatten())) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # evaluation of G at quadrature points in format (3, 3, Nel1*nq1, Nel2*nq2, Nel3*nq3) - g = domain.metric(pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - - # blocks of global mass matrix - M = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] - - for a in range(3): - for b in range(3): - Ni = tensor_space_FEM.Nbase_2form[a] - Nj = tensor_space_FEM.Nbase_2form[b] - - M[a][b] = xp.zeros((Ni[0], Ni[1], Ni[2], 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1), dtype=float) - - # evaluate metric tensor at quadrature points - if weight is None: - mat_w = g[a, b] - else: - mat_w = weight[a][b](pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - - mat_w = mat_w.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # assemble block if weight is not zero - if xp.any(mat_w): - ker.kernel_mass( - xp.array(Nel), - xp.array(p), - xp.array(n_quad), - xp.array(ns[a]), - xp.array(ns[b]), - wts[0], - wts[1], - wts[2], - basis[a][0], - basis[a][1], - basis[a][2], - basis[b][0], - basis[b][1], - basis[b][2], - ind[a][0], - ind[a][1], - ind[a][2], - M[a][b], - mat_w / det_df, - ) - - # convert to sparse matrix - indices = xp.indices((Ni[0], Ni[1], Ni[2], 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1)) - - shift = [xp.arange(Ni) - p for Ni, p in zip(Ni, p)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M[a][b] = spa.csr_matrix( - (M[a][b].flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M[a][b].eliminate_zeros() - - M = spa.bmat([[M[0][0], M[0][1], M[0][2]], [M[1][0], M[1][1], M[1][2]], [M[2][0], M[2][1], M[2][2]]], format="csr") - - # apply spline extraction operator and return - if apply_boundary_ops: - M = tensor_space_FEM.E2_0.dot(M.dot(tensor_space_FEM.E2_0.T)).tocsr() - else: - M = tensor_space_FEM.E2.dot(M.dot(tensor_space_FEM.E2.T)).tocsr() - - return M - - -# ================ mass matrix in V3 =========================== -def get_M3(tensor_space_FEM, domain, apply_boundary_ops=False, weight=None): - """ - Assembles the 3D mass matrix [[DDD DDD]] of the given tensor product B-spline spaces of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - apply_boundary_ops : boolean - whether to include boundary operators (True) or not (False) - - weight : callable - optional additional weight function - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indD = ( - tensor_space_FEM.indD - ) # global indices of local non-vanishing basis functions in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points in format (element, local quad_point) - wts = tensor_space_FEM.wts # global quadrature weights in format (element, local weight) - - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points - - # evaluation of |det(DF)| at quadrature points in format (Nel1, nq1, Nel2, nq2, Nel3, nq3) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), pts[2].flatten())) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # evaluation of weight function at quadrature points - if weight is None: - mat_w = xp.ones(det_df.shape, dtype=float) - else: - mat_w = weight(pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - mat_w = mat_w.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # assembly of global mass matrix - Ni = tensor_space_FEM.Nbase_3form - Nj = tensor_space_FEM.Nbase_3form - - M = xp.zeros((Ni[0], Ni[1], Ni[2], 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1), dtype=float) - - ker.kernel_mass( - xp.array(Nel), - xp.array(p), - xp.array(n_quad), - xp.array([1, 1, 1]), - xp.array([1, 1, 1]), - wts[0], - wts[1], - wts[2], - basisD[0], - basisD[1], - basisD[2], - basisD[0], - basisD[1], - basisD[2], - indD[0], - indD[1], - indD[2], - M, - mat_w / det_df, - ) - - # conversion to sparse matrix - indices = xp.indices((Ni[0], Ni[1], Ni[2], 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1)) - - shift = [xp.arange(Ni) - p for Ni, p in zip(Ni, p)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Ni[2] * col1 + Ni[2] * col2 + col3 - - M = spa.csr_matrix((M.flatten(), (row, col.flatten())), shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2])) - M.eliminate_zeros() - - # apply spline extraction operator and return - if apply_boundary_ops: - M = tensor_space_FEM.E3_0.dot(M.dot(tensor_space_FEM.E3_0.T)).tocsr() - else: - M = tensor_space_FEM.E3.dot(M.dot(tensor_space_FEM.E3.T)).tocsr() - - return M - - -# ================ mass matrix for vector fields in V2 =========================== -def get_Mv(tensor_space_FEM, domain, apply_boundary_ops=False, weight=None): - """ - Assembles the 3D mass matrix [[NNN NNN, NNN NNN, NNN NNN], [NNN NNN, NNN NNN, NNN NNN], [NNN NNN, NNN NNN, NNN NNN]] * G * |det(DF)| of the given tensor product B-spline spaces of tri-degree (p1, p2, p3) within a computational domain defined by the given object "domain" from struphy.geometry.domain. - - Parameters - ---------- - tensor_space_FEM : Tensor_spline_space - tensor product B-spline space for finite element spaces - - domain : domain - domain object defining the geometry - - apply_boundary_ops : boolean - whether to include boundary operators (True) or not (False) - - weight : callable - optional additional weight functions - """ - - p = tensor_space_FEM.p # spline degrees - Nel = tensor_space_FEM.Nel # number of elements - indN = ( - tensor_space_FEM.indN - ) # global indices of non-vanishing basis functions (N) in format (element, global index) - indD = ( - tensor_space_FEM.indD - ) # global indices of non-vanishing basis functions (D) in format (element, global index) - - n_quad = tensor_space_FEM.n_quad # number of quadrature points per element - pts = tensor_space_FEM.pts # global quadrature points - wts = tensor_space_FEM.wts # global quadrature weights - - basisN = tensor_space_FEM.basisN # evaluated basis functions at quadrature points (N) - basisD = tensor_space_FEM.basisD # evaluated basis functions at quadrature points (D) - - bs = 0 - - # indices and basis functions of components of a 2-form - if bs == 0: - ind = [[indN[0], indN[1], indN[2]], [indN[0], indN[1], indN[2]], [indN[0], indN[1], indN[2]]] - basis = [ - [basisN[0], basisN[1], basisN[2]], - [basisN[0], basisN[1], basisN[2]], - [basisN[0], basisN[1], basisN[2]], - ] - ns = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] - - elif bs == 2: - ind = [[indN[0], indD[1], indD[2]], [indD[0], indN[1], indD[2]], [indD[0], indD[1], indN[2]]] - basis = [ - [basisN[0], basisD[1], basisD[2]], - [basisD[0], basisN[1], basisD[2]], - [basisD[0], basisD[1], basisN[2]], - ] - ns = [[0, 1, 1], [1, 0, 1], [1, 1, 0]] - - # evaluation of |det(DF)| at quadrature points in format (Nel1, nq1, Nel2, nq2, Nel3, nq3) - det_df = abs(domain.jacobian_det(pts[0].flatten(), pts[1].flatten(), pts[2].flatten())) - det_df = det_df.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # evaluation of G at quadrature points in format (3, 3, Nel1*nq1, Nel2*nq2, Nel3*nq3) - g = domain.metric(pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - - # blocks of global mass matrix - M = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] - - for a in range(3): - for b in range(3): - if bs == 0: - Ni = tensor_space_FEM.Nbase_0form - Nj = tensor_space_FEM.Nbase_0form - elif bs == 2: - Ni = tensor_space_FEM.Nbase_2form[a] - Nj = tensor_space_FEM.Nbase_2form[b] - - M[a][b] = xp.zeros((Ni[0], Ni[1], Ni[2], 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1), dtype=float) - - # evaluate metric tensor at quadrature points - if weight is None: - mat_w = g[a, b] - else: - mat_w = weight[a][b](pts[0].flatten(), pts[1].flatten(), pts[2].flatten()) - - mat_w = mat_w.reshape(Nel[0], n_quad[0], Nel[1], n_quad[1], Nel[2], n_quad[2]) - - # assemble block if weight is not zero - if xp.any(mat_w): - ker.kernel_mass( - xp.array(Nel), - xp.array(p), - xp.array(n_quad), - xp.array(ns[a]), - xp.array(ns[b]), - wts[0], - wts[1], - wts[2], - basis[a][0], - basis[a][1], - basis[a][2], - basis[b][0], - basis[b][1], - basis[b][2], - ind[a][0], - ind[a][1], - ind[a][2], - M[a][b], - mat_w * det_df, - ) - - # convert to sparse matrix - indices = xp.indices((Ni[0], Ni[1], Ni[2], 2 * p[0] + 1, 2 * p[1] + 1, 2 * p[2] + 1)) - - shift = [xp.arange(Ni) - p for Ni, p in zip(Ni, p)] - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M[a][b] = spa.csr_matrix( - (M[a][b].flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M[a][b].eliminate_zeros() - - M = spa.bmat([[M[0][0], M[0][1], M[0][2]], [M[1][0], M[1][1], M[1][2]], [M[2][0], M[2][1], M[2][2]]], format="csr") - - # apply spline extraction operator and return - if apply_boundary_ops: - M = tensor_space_FEM.Ev_0.dot(M.dot(tensor_space_FEM.Ev_0.T)).tocsr() - else: - M = tensor_space_FEM.Ev.dot(M.dot(tensor_space_FEM.Ev.T)).tocsr() - - return M diff --git a/src/struphy/eigenvalue_solvers/mhd_axisymmetric_main.py b/src/struphy/eigenvalue_solvers/mhd_axisymmetric_main.py deleted file mode 100644 index 04a194c7f..000000000 --- a/src/struphy/eigenvalue_solvers/mhd_axisymmetric_main.py +++ /dev/null @@ -1,267 +0,0 @@ -def solve_mhd_ev_problem_2d(num_params, eq_mhd, n_tor, basis_tor="i", path_out=None): - """ - Numerical solution of the ideal MHD eigenvalue problem for a given 2D axisymmetric equilibrium and a fixed toroial mode number. - - Parameters - ---------- - num_params : dictionary - numerical parameters : - * Nel : list of ints, number of elements in [s, chi] direction - * p : list of ints, spline degrees in [s, chi] direction - * spl_kind : list of booleans, kind of splines in [s, chi] direction - * nq_el : list of ints, number of quadrature points per element in [s, chi] direction - * nq_pr : list of ints, number of quadrature points per projection interval in [s, chi] direction - * bc : list of strings, boundary conditions in [s, chi] direction - * polar_ck : int, C^k continuity at pole - - eq_mhd : MHD equilibrium object - the MHD equilibrium for which the spectrum shall be computed - - n_tor : int - toroidal mode number - - basis_tor : string - basis in toroidal direction : - * r : A(s, chi)*cos(n_tor*2*pi*phi) + B(s, chi)*sin(n_tor*2*pi*phi), - * i : A(s, chi)*exp(n_tor*2*pi*phi*i) - - path_out : string, optional - if given, directory where to save the .npy eigenspectrum. - """ - - import os - import time - - import cunumpy as xp - import scipy.sparse as spa - - from struphy.eigenvalue_solvers.mhd_operators import MHDOperators - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space - - print("\nStart of eigenspectrum calculation for toroidal mode number", n_tor) - print("") - print("MHD equilibrium:".ljust(20), eq_mhd) - print("domain:".ljust(20), eq_mhd.domain) - - # print grid info - print("\nGrid parameters:") - print("number of elements :", num_params["Nel"]) - print("spline degrees :", num_params["p"]) - print("periodic bcs :", num_params["spl_kind"]) - print("hom. Dirichlet bc :", num_params["bc"]) - print("GL quad pts (L2) :", num_params["nq_el"]) - print("GL quad pts (hist) :", num_params["nq_pr"]) - print("polar Ck :", num_params["polar_ck"]) - print("") - - # extract numerical parameters - Nel = num_params["Nel"] - p = num_params["p"] - spl_kind = num_params["spl_kind"] - nq_el = num_params["nq_el"] - nq_pr = num_params["nq_pr"] - bc = num_params["bc"] - polar_ck = num_params["polar_ck"] - - # set up 1d spline spaces and corresponding projectors - space_1d_1 = Spline_space_1d(Nel[0], p[0], spl_kind[0], nq_el[0], bc[0]) - space_1d_2 = Spline_space_1d(Nel[1], p[1], spl_kind[1], nq_el[1], bc[1]) - - space_1d_1.set_projectors(nq_pr[0]) - space_1d_2.set_projectors(nq_pr[1]) - - # set up 2d tensor-product space - space_2d = Tensor_spline_space( - [space_1d_1, space_1d_2], - polar_ck, - eq_mhd.domain.cx[:, :, 0], - eq_mhd.domain.cy[:, :, 0], - n_tor, - basis_tor, - ) - - # set up 2d projectors - space_2d.set_projectors("general") - - print("Initialization of FEM spaces done") - - # assemble mass matrix in V2 and V3 and apply boundary operators - space_2d.assemble_Mk(eq_mhd.domain, "V2") - space_2d.assemble_Mk(eq_mhd.domain, "V3") - - M2_0 = space_2d.B2.dot(space_2d.M2_mat.dot(space_2d.B2.T)) - M3_0 = space_2d.B3.dot(space_2d.M3_mat.dot(space_2d.B3.T)) - - print("Assembly of mass matrices done") - - # create linear MHD operators - mhd_ops = MHDOperators(space_2d, eq_mhd, 2) - - # assemble right-hand sides of degree of freedom projection matrices - mhd_ops.assemble_dofs("EF") - mhd_ops.assemble_dofs("MF") - mhd_ops.assemble_dofs("PF") - mhd_ops.assemble_dofs("PR") - - print("Assembly of projection matrices done") - - # assemble mass matrix weighted with 0-form density - timea = time.time() - mhd_ops.assemble_Mn() - timeb = time.time() - - print("Assembly of weighted mass matrix done (density), time : ", timeb - timea) - - # assemble mass matrix weighted with J_eq x - timea = time.time() - mhd_ops.assemble_MJ() - timeb = time.time() - - print("Assembly of weighted mass matrix done (current), time : ", timeb - timea) - - # final operators - I1_11 = spa.kron(space_2d.projectors.I1_pol_0, space_2d.projectors.I_tor) - I1_22 = spa.kron(space_2d.projectors.I0_pol_0, space_2d.projectors.H_tor) - - I2_11 = spa.kron(space_2d.projectors.I2_pol_0, space_2d.projectors.H_tor) - I2_22 = spa.kron(space_2d.projectors.I3_pol_0, space_2d.projectors.I_tor) - - I3 = spa.kron(space_2d.projectors.I3_pol_0, space_2d.projectors.H_tor) - - I1 = spa.bmat([[I1_11, None], [None, I1_22]], format="csc") - I2 = spa.bmat([[I2_11, None], [None, I2_22]], format="csc") - I3 = I3.tocsc() - - EF = spa.linalg.inv(I1).dot(mhd_ops.dofs_EF).tocsr() - PF = spa.linalg.inv(I2).dot(mhd_ops.dofs_PF).tocsr() - PR = spa.linalg.inv(I3).dot(mhd_ops.dofs_PR).tocsr() - - L = -space_2d.D0.dot(PF) - (5 / 3 - 1) * PR.dot(space_2d.D0) - - print("Application of inverse interpolation matrices on projection matrices done") - - # set up eigenvalue problem MAT*u = omega^2*u - MAT = ( - spa.linalg.inv(mhd_ops.Mn_mat.tocsc()) - .dot( - EF.T.dot(space_2d.C0.conjugate().T.dot(M2_0.dot(space_2d.C0.dot(EF)))) - + mhd_ops.MJ_mat.dot(space_2d.C0.dot(EF)) - - space_2d.D0.conjugate().T.dot(M3_0.dot(L)), - ) - .toarray() - ) - - print("Assembly of final system matrix done --> start of eigenvalue calculation") - - omega2, U2_eig = xp.linalg.eig(MAT) - - print("Eigenstates calculated") - - # save spectrum as .npy - if path_out is not None: - assert isinstance(path_out, str) - - if n_tor < 0: - n_tor_str = str(n_tor) - else: - n_tor_str = "+" + str(n_tor) - - xp.save( - os.path.join(path_out, "spec_n_" + n_tor_str + ".npy"), - xp.vstack((omega2.reshape(1, omega2.size), U2_eig)), - ) - - # or return eigenfrequencies, eigenvectors and system matrix - else: - return omega2, U2_eig, MAT - - -# command line interface -if __name__ == "__main__": - import argparse - import os - import shutil - - import yaml - - # parse arguments - parser = argparse.ArgumentParser( - description="Computes the complete eigenspectrum for a given axisymmetric MHD equilibrium.", - ) - - parser.add_argument("n_tor", type=int, help="the toroidal mode number") - - parser.add_argument( - "-i", - "--input", - type=str, - metavar="FILE", - help="parameter file (.yml) in current I/O path (default=parameters.yml)", - default="parameters.yml", - ) - - parser.add_argument("--input-abs", type=str, metavar="FILE", help="parameter file (.yml), absolute path") - - parser.add_argument( - "-o", - "--output", - type=str, - metavar="DIR", - help="output directory relative to current I/O path (default=sim_1)", - default="sim_1", - ) - - parser.add_argument("--output-abs", type=str, metavar="DIR", help="output directory, absolute path") - - args = parser.parse_args() - - import struphy.utils.utils as utils - - # Read struphy state file - state = utils.read_state() - - i_path = state["i_path"] - o_path = state["o_path"] - - # create absolute i/o paths - if args.input_abs is None: - input_abs = os.path.join(i_path, args.input) - else: - input_abs = args.input_abs - - if args.output_abs is None: - output_abs = os.path.join(o_path, args.output) - else: - output_abs = args.output_abs - - # create output folder (if it does not already exist) - if not os.path.exists(output_abs): - os.mkdir(output_abs) - print("\nCreated folder " + output_abs) - - # copy parameter file to output folder - if input_abs != os.path.join(output_abs, "parameters.yml"): - shutil.copy2(input_abs, os.path.join(output_abs, "parameters.yml")) - - # load parameter file - with open(input_abs) as file: - params = yaml.load(file, Loader=yaml.FullLoader) - - # create domain and MHD equilibrium - from struphy.io.setup import setup_domain_and_equil - - domain, mhd_equil = setup_domain_and_equil(params) - - # load grid parameters - num_params = { - "Nel": params["grid"]["Nel"][:2], - "p": params["grid"]["p"][:2], - "spl_kind": params["grid"]["spl_kind"][:2], - "nq_el": params["grid"]["nq_el"][:2], - "nq_pr": params["grid"]["nq_pr"][:2], - "bc": params["grid"]["bc"][:2], - "polar_ck": params["grid"]["polar_ck"], - } - - # calculate eigenspectrum for given toroidal mode number and save result - solve_mhd_ev_problem_2d(num_params, mhd_equil, n_tor=args.n_tor, basis_tor="i", path_out=output_abs) diff --git a/src/struphy/eigenvalue_solvers/mhd_axisymmetric_pproc.py b/src/struphy/eigenvalue_solvers/mhd_axisymmetric_pproc.py deleted file mode 100644 index 1685147e1..000000000 --- a/src/struphy/eigenvalue_solvers/mhd_axisymmetric_pproc.py +++ /dev/null @@ -1,73 +0,0 @@ -# command line interface -def main(): - import argparse - import os - - import cunumpy as xp - import yaml - - # parse arguments - parser = argparse.ArgumentParser(description="Restrict a full .npy eigenspectrum to a range of eigenfrequencies.") - - parser.add_argument("-n", type=int, help="toroidal mode number", required=True) - - parser.add_argument( - "-i", - "--input", - type=str, - metavar="DIR", - help="directory with eigenspectrum (.npy), relative to current I/O path (default=sim_1)", - default="sim_1", - ) - - parser.add_argument( - "--input-abs", - type=str, - metavar="DIR", - help="directory with eigenspectrum (.npy) file, absolute path", - ) - - parser.add_argument("lower", type=float, help="lower range of squared eigenfrequency") - - parser.add_argument("upper", type=float, help="upper range of squared eigenfrequency") - - args = parser.parse_args() - - import struphy.utils.utils as utils - - # Read struphy state file - state = utils.read_state() - - o_path = state["o_path"] - - # create absolute input folder path - if args.input_abs is None: - input_path = os.path.join(o_path, args.input) - else: - input_path = args.input_abs - - # load spectrum and restrict to range - if args.n < 0: - n_tor_str = str(args.n) - else: - n_tor_str = "+" + str(args.n) - - spec_path = os.path.join(input_path, "spec_n_" + n_tor_str + ".npy") - - omega2, U2_eig = xp.split(xp.load(spec_path), [1], axis=0) - omega2 = omega2.flatten() - - modes_ind = xp.where((xp.real(omega2) < args.upper) & (xp.real(omega2) > args.lower))[0] - - omega2 = omega2[modes_ind] - U2_eig = U2_eig[:, modes_ind] - - # save restricted spectrum - xp.save( - os.path.join(input_path, "spec_" + str(args.lower) + "_" + str(args.upper) + "_n_" + n_tor_str + ".npy"), - xp.vstack((omega2.reshape(1, omega2.size), U2_eig)), - ) - - -if __name__ == "__main__": - main() diff --git a/src/struphy/eigenvalue_solvers/mhd_operators.py b/src/struphy/eigenvalue_solvers/mhd_operators.py deleted file mode 100644 index 6f7325c6b..000000000 --- a/src/struphy/eigenvalue_solvers/mhd_operators.py +++ /dev/null @@ -1,1184 +0,0 @@ -# coding: utf-8 -# -# Copyright 2021 Florian Holderied (florian.holderied@ipp.mpg.de) - - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.eigenvalue_solvers.legacy.mass_matrices_3d_pre as mass_3d_pre -from struphy.eigenvalue_solvers.mhd_operators_core import MHDOperatorsCore - - -class MHDOperators: - """ - Class for degree of freedom matrices related to ideal MHD equations. - - Parameters - ---------- - space : tensor_spline_space - 2D or 3D B-spline finite element space. - - equilibrium : equilibrium_mhd - MHD equilibrium object. - - basis_u : int - representation of velocity field (0 : vector field where all components are treated as 0-forms, 2 : 2-form). - """ - - def __init__(self, space, equilibrium, basis_u): - # create MHD operators core object - self.core = MHDOperatorsCore(space, equilibrium, basis_u) - - # set adiabatic index - self.gamma = 5 / 3 - - # get 1D int_N and int_D matrices in third direction - if space.dim == 2: - self.ID_tor = spa.identity(space.NbaseN[2], format="csr") - - self.int_N3 = spa.identity(space.NbaseN[2], format="csr") - self.int_D3 = spa.identity(space.NbaseN[2], format="csr") - - self.his_N3 = spa.identity(space.NbaseN[2], format="csr") - self.his_D3 = spa.identity(space.NbaseN[2], format="csr") - - else: - B0 = space.spaces[2].B0 - B1 = space.spaces[2].B1 - - self.int_N3 = B0.dot(space.spaces[2].projectors.I.dot(B0.T)) - self.int_D3 = B0.dot(space.spaces[2].projectors.ID.dot(B1.T)) - - self.his_N3 = B1.dot(space.spaces[2].projectors.HN.dot(B0.T)) - self.his_D3 = B1.dot(space.spaces[2].projectors.H.dot(B1.T)) - - # ================================================================= - def __assemble_dofs_EF(self, as_tensor=False): - """ - Sets blocks related to the degree of freedom (DOF) matrix - - basis_u = 0 : dofs_EF_(ab,ijk lmn) = dofs^1_(a,ijk)( B^2_eq x Lambda^0_(b,lmn) ), - basis_u = 2 : dofs_EF_(ab,ijk lmn) = dofs^1_(a,ijk)( B^2_eq x Lambda^2_(b,lmn) / sqrt(g) ), - - while taking into account polar extraction operators and boundary operators. - - Parameters - ---------- - as_tensor : boolean - wheather to assemble the matrices in the form (poloidal x toroidal) (True). - """ - - self.EF_as_tensor = as_tensor - - EF_12, EF_13, EF_21, EF_23, EF_31, EF_32 = self.core.get_blocks_EF(self.EF_as_tensor) - - # ------------ full operator : 0-form -------- - if self.core.basis_u == 0: - if self.EF_as_tensor: - EF_11 = spa.bmat([[None, EF_12], [EF_21, None]]) - - EF_12 = spa.bmat([[EF_13], [EF_23]]) - EF_21 = spa.bmat([[EF_31, EF_32]]) - - self.dofs_EF = [] - - # self.dofs_EF_pol_11 = self.core.space.projectors.P1_pol_0.dot(EF_11.dot(self.core.space.Ev_pol_0.T)).tocsr() - # self.dofs_EF_pol_12 = self.core.space.projectors.P1_pol_0.dot(EF_12.dot(self.core.space.E0_pol.T )).tocsr() - # self.dofs_EF_pol_21 = self.core.space.projectors.P0_pol_0.dot(EF_21.dot(self.core.space.Ev_pol_0.T)).tocsr() - - self.dofs_EF += [self.core.space.projectors.P1_pol_0.dot(EF_11.dot(self.core.space.Ev_pol_0.T)).tocsr()] - self.dofs_EF += [self.core.space.projectors.P1_pol_0.dot(EF_12.dot(self.core.space.E0_pol.T)).tocsr()] - self.dofs_EF += [self.core.space.projectors.P0_pol_0.dot(EF_21.dot(self.core.space.Ev_pol_0.T)).tocsr()] - - else: - EF = spa.bmat([[None, EF_12, EF_13], [EF_21, None, EF_23], [EF_31, EF_32, None]]) - - if self.core.space.dim == 2: - EF = spa.kron(EF, self.ID_tor, format="csr") - - self.dofs_EF = self.core.space.projectors.P1_0.dot(EF.dot(self.core.space.Ev_0.T)).tocsr() - # -------------------------------------------- - - # ------------ full operator : 2-form -------- - elif self.core.basis_u == 2: - if self.EF_as_tensor: - EF_11 = spa.bmat([[None, EF_12], [EF_21, None]]) - - EF_12 = spa.bmat([[EF_13], [EF_23]]) - EF_21 = spa.bmat([[EF_31, EF_32]]) - - self.dofs_EF = [] - - # self.dofs_EF_pol_11 = self.core.space.projectors.P1_pol_0.dot(EF_11.dot(self.core.space.E2_pol_0.T)).tocsr() - # self.dofs_EF_pol_12 = self.core.space.projectors.P1_pol_0.dot(EF_12.dot(self.core.space.E3_pol_0.T)).tocsr() - # self.dofs_EF_pol_21 = self.core.space.projectors.P0_pol_0.dot(EF_21.dot(self.core.space.E2_pol_0.T)).tocsr() - - self.dofs_EF += [self.core.space.projectors.P1_pol_0.dot(EF_11.dot(self.core.space.E2_pol_0.T)).tocsr()] - self.dofs_EF += [self.core.space.projectors.P1_pol_0.dot(EF_12.dot(self.core.space.E3_pol_0.T)).tocsr()] - self.dofs_EF += [self.core.space.projectors.P0_pol_0.dot(EF_21.dot(self.core.space.E2_pol_0.T)).tocsr()] - - else: - EF = spa.bmat([[None, EF_12, EF_13], [EF_21, None, EF_23], [EF_31, EF_32, None]]) - - if self.core.space.dim == 2: - EF = spa.kron(EF, self.ID_tor, format="csr") - - self.dofs_EF = self.core.space.projectors.P1_0.dot(EF.dot(self.core.space.E2_0.T)).tocsr() - # -------------------------------------------- - - # ================================================================= - def __assemble_dofs_FL(self, which, as_tensor=False): - """ - Sets blocks related to the degree of freedom (DOF) matrix - - basis_u = 0 : dofs_FL_(aa,ijk lmn) = dofs^2_(a,ijk)( fun * Lambda^0_(a,lmn) ), - basis_u = 2 : dofs_FL_(aa,ijk lmn) = dofs^2_(a,ijk)( fun * Lambda^2_(a,lmn) / sqrt(g) ), - - while taking into account polar extraction operators and boundary operators. - - Parameters - ---------- - which : string - * 'm' : fun = n^3_eq - * 'p' : fun = p^3_eq - * 'j' : fun = det_df - - as_tensor : boolean - wheather to assemble the matrices in the form (poloidal x toroidal) (True). - """ - - assert which == "m" or which == "p" or which == "j" - - if which == "m": - self.MF_as_tensor = as_tensor - elif which == "p": - self.PF_as_tensor = as_tensor - elif which == "j": - self.JF_as_tensor = as_tensor - - FL_11, FL_22, FL_33 = self.core.get_blocks_FL(which, as_tensor) - - # ------------ full operator : 0-form -------- - if self.core.basis_u == 0: - if as_tensor: - FL_11 = spa.bmat([[FL_11, None], [None, FL_22]]) - - dofs_FL_pol_11 = self.core.space.projectors.P2_pol_0.dot(FL_11.dot(self.core.space.Ev_pol_0.T)).tocsr() - dofs_FL_pol_22 = self.core.space.projectors.P3_pol_0.dot(FL_33.dot(self.core.space.E0_pol.T)).tocsr() - - if which == "m": - self.dofs_MF = [] - - # self.dofs_MF_pol_11 = dofs_FL_pol_11 - # self.dofs_MF_pol_22 = dofs_FL_pol_22 - - self.dofs_MF[0] += [dofs_FL_pol_11] - self.dofs_MF[1] += [dofs_FL_pol_22] - - if which == "p": - self.dofs_PF = [] - - # self.dofs_PF_pol_11 = dofs_FL_pol_11 - # self.dofs_PF_pol_22 = dofs_FL_pol_22 - - self.dofs_PF[0] += [dofs_FL_pol_11] - self.dofs_PF[1] += [dofs_FL_pol_22] - - if which == "j": - self.dofs_JF = [] - - # self.dofs_JF_pol_11 = dofs_FL_pol_11 - # self.dofs_JF_pol_22 = dofs_FL_pol_22 - - self.dofs_JF[0] = [dofs_FL_pol_11] - self.dofs_JF[1] = [dofs_FL_pol_22] - - else: - FL = spa.bmat([[FL_11, None, None], [None, FL_22, None], [None, None, FL_33]]) - - if self.core.space.dim == 2: - FL = spa.kron(FL, self.ID_tor, format="csr") - - if which == "m": - self.dofs_MF = self.core.space.projectors.P2_0.dot(FL.dot(self.core.space.Ev_0.T)).tocsr() - - if which == "p": - self.dofs_PF = self.core.space.projectors.P2_0.dot(FL.dot(self.core.space.Ev_0.T)).tocsr() - - if which == "j": - self.dofs_JF = self.core.space.projectors.P2_0.dot(FL.dot(self.core.space.Ev_0.T)).tocsr() - # -------------------------------------------- - - # ------------ full operator : 2-form -------- - elif self.core.basis_u == 2: - if as_tensor: - FL_11 = spa.bmat([[FL_11, None], [None, FL_22]]) - - dofs_FL_pol_11 = self.core.space.projectors.P2_pol_0.dot(FL_11.dot(self.core.space.E2_pol_0.T)).tocsr() - dofs_FL_pol_22 = self.core.space.projectors.P3_pol_0.dot(FL_33.dot(self.core.space.E3_pol_0.T)).tocsr() - - if which == "m": - self.dofs_MF = [] - - # self.dofs_MF_pol_11 = dofs_FL_pol_11 - # self.dofs_MF_pol_22 = dofs_FL_pol_22 - - self.dofs_MF[0] += [dofs_FL_pol_11] - self.dofs_MF[1] += [dofs_FL_pol_22] - - if which == "p": - self.dofs_PF = [] - - # self.dofs_PF_pol_11 = dofs_FL_pol_11 - # self.dofs_PF_pol_22 = dofs_FL_pol_22 - - self.dofs_PF[0] += [dofs_FL_pol_11] - self.dofs_PF[1] += [dofs_FL_pol_22] - - else: - FL = spa.bmat([[FL_11, None, None], [None, FL_22, None], [None, None, FL_33]]) - - if self.core.space.dim == 2: - FL = spa.kron(FL, self.ID_tor, format="csr") - - if which == "m": - self.dofs_MF = self.core.space.projectors.P2_0.dot(FL.dot(self.core.space.E2_0.T)).tocsr() - - elif which == "p": - self.dofs_PF = self.core.space.projectors.P2_0.dot(FL.dot(self.core.space.E2_0.T)).tocsr() - # -------------------------------------------- - - # ================================================================= - def __assemble_dofs_PR(self, as_tensor=False): - """ - Sets degree of freedom (DOF) matrix - - PR_(ijk lmn) = dofs^3_(ijk)( p^3_eq * Lambda^3_(lmn) / sqrt(g) ), - - while taking into account polar extraction operators and boundary operators. - - Parameters - ---------- - as_tensor : boolean - wheather to assemble the matrices in the form (poloidal x toroidal) (True). - """ - - self.PR_as_tensor = as_tensor - - PR = self.core.get_blocks_PR(self.PR_as_tensor) - - if self.PR_as_tensor: - self.dofs_PR = self.core.space.projectors.P3_pol_0.dot(PR.dot(self.core.space.E3_pol_0.T)).tocsr() - - else: - if self.core.space.dim == 2: - PR = spa.kron(PR, self.ID_tor, format="csr") - - self.dofs_PR = self.core.space.projectors.P3_0.dot(PR.dot(self.core.space.E3_0.T)).tocsr() - - # ================================================================= - def assemble_dofs(self, which, as_tensor=False): - """ - Sets degree of freedom (DOF) matrix - - which = EF : dofs_EF_(ab,ijk lmn) = dofs^1_(a,ijk)( B^2_eq x Lambda^0_(b,lmn) ) if basis_u = 0, - which = EF : dofs_EF_(ab,ijk lmn) = dofs^1_(a,ijk)( B^2_eq x Lambda^2_(b,lmn) / sqrt(g)) if basis_u = 2, - - which = MF : dofs_MF_(aa,ijk lmn) = dofs^2_(a,ijk)( n^3_eq * Lambda^0_(a,lmn) ) if basis_u = 0, - which = MF : dofs_MF_(aa,ijk lmn) = dofs^2_(a,ijk)( n^3_eq * Lambda^2_(a,lmn) / sqrt(g) ) if basis_u = 2, - - which = PF : dofs_PF_(aa,ijk lmn) = dofs^2_(a,ijk)( p^3_eq * Lambda^0_(a,lmn) ) if basis_u = 0, - which = PF : dofs_PF_(aa,ijk lmn) = dofs^2_(a,ijk)( p^3_eq * Lambda^2_(a,lmn) / sqrt(g) ) if basis_u = 2, - - which = JF : dofs_JF_(aa,ijk lmn) = dofs^2_(a,ijk)( det_df * Lambda^0_(a,lmn) ), - - which = PR : PR_(ijk lmn) = dofs^3_(ijk)( p^3_eq * Lambda^3_(lmn) / sqrt(g) ), - - while taking into account polar extraction operators and boundary operators. - - Parameters - ---------- - as_tensor : boolean - wheather to assemble the matrices in the form (poloidal x toroidal) (True). - """ - - if which == "EF": - self.__assemble_dofs_EF(as_tensor) - elif which == "MF": - self.__assemble_dofs_FL("m", as_tensor) - elif which == "PF": - self.__assemble_dofs_FL("p", as_tensor) - elif which == "JF": - self.__assemble_dofs_FL("j", as_tensor) - elif which == "PR": - self.__assemble_dofs_PR(as_tensor) - - # ================================================================= - def assemble_Mn(self, as_tensor=False): - """ - Sets the weighted mass matrix - - basis_u = 0 : Mn_(ab, ijk lmn) = integral( Lambda^0_(a,ijk) * G_ab * Lambda^0_(b,lmn) * n^0_eq * sqrt(g) ), - basis_u = 2 : Mn_(ab, ijk lmn) = integral( Lambda^2_(a,ijk) * G_ab * Lambda^2_(b,lmn) * n^0_eq / sqrt(g) ). - - while taking into account polar extraction operators and boundary operators. - - Parameters - ---------- - as_tensor : boolean - wheather to assemble the matrices in the form (poloidal x toroidal) (True). - """ - - self.Mn_as_tensor = as_tensor - - Mn = self.core.get_blocks_Mn(self.Mn_as_tensor) - - if self.Mn_as_tensor: - self.Mn_mat = Mn - - else: - if self.core.space.dim == 2: - if self.core.basis_u == 0: - M11 = spa.kron(Mn[0], self.core.space.M0_tor) - M22 = spa.kron(Mn[1], self.core.space.M0_tor) - - if self.core.basis_u == 2: - M11 = spa.kron(Mn[0], self.core.space.M1_tor) - M22 = spa.kron(Mn[1], self.core.space.M0_tor) - - self.Mn_mat = spa.bmat([[M11, None], [None, M22]], format="csr") - - else: - self.Mn_mat = Mn - - # ================================================================= - def assemble_MJ(self, as_tensor=False): - """ - Sets the weighted mass matrix - - basis_u = 0 : not implemented yet --> MJ = 0, - basis_u = 2 : MJ_(ab, ijk lmn) = integral( Lambda^2_(a,ijk) * G_ab * Lambda^2_(b,lmn) * epsilon_(acb) * J^2_c_eq / sqrt(g) ). - - while taking into account polar extraction operators and boundary operators. - - Parameters - ---------- - as_tensor : boolean - wheather to assemble the matrices in the form (poloidal x toroidal) (True). - """ - - self.MJ_as_tensor = as_tensor - - MJ = self.core.get_blocks_MJ(self.MJ_as_tensor) - - if self.core.basis_u == 2: - if self.MJ_as_tensor: - self.MJ_mat = MJ - - else: - if self.core.space.dim == 2: - M11 = spa.kron(MJ[0], self.core.space.M1_tor) - M22 = spa.kron(MJ[1], self.core.space.M0_tor) - - self.MJ_mat = spa.bmat([[M11, None], [None, M22]], format="csr") - - else: - self.MJ_mat = MJ - - else: - print("MJ matrix for vector MHD is not yet implemented (and is therefore set to zero)!") - - # ====================================== - def __EF(self, u): - """ - TODO - """ - - if self.EF_as_tensor: - if self.core.basis_u == 0: - u1, u3 = self.core.space.reshape_pol_v(u) - - out1 = self.int_N3.dot(self.dofs_EF[0].dot(u1).T).T + self.int_N3.dot(self.dofs_EF[1].dot(u3).T).T - out3 = self.his_N3.dot(self.dofs_EF[2].dot(u1).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - elif self.core.basis_u == 2: - u1, u3 = self.core.space.reshape_pol_2(u) - - out1 = self.int_D3.dot(self.dofs_EF[0].dot(u1).T).T + self.int_N3.dot(self.dofs_EF[1].dot(u3).T).T - out3 = self.his_D3.dot(self.dofs_EF[2].dot(u1).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - else: - out = self.dofs_EF.dot(u) - - return self.core.space.projectors.solve_V1(out, False) - - # ====================================== - def __EF_transposed(self, e): - """ - TODO - """ - - e = self.core.space.projectors.apply_IinvT_V1(e) - - if self.EF_as_tensor: - e1, e3 = self.core.space.reshape_pol_1(e) - - if self.core.basis_u == 0: - out1 = ( - self.int_N3.T.dot(self.dofs_EF[0].T.dot(e1).T).T + self.his_N3.T.dot(self.dofs_EF[2].T.dot(e3).T).T - ) - out3 = self.int_N3.T.dot(self.dofs_EF[1].T.dot(e1).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - elif self.core.basis_u == 2: - out1 = ( - self.int_D3.T.dot(self.dofs_EF[0].T.dot(e1).T).T + self.his_D3.T.dot(self.dofs_EF[2].T.dot(e3).T).T - ) - out3 = self.int_N3.T.dot(self.dofs_EF[1].T.dot(e1).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - else: - out = self.dofs_EF.T.dot(e) - - return out - - # ====================================== - def __MF(self, u): - """ - TODO - """ - - if self.MF_as_tensor: - if self.core.basis_u == 0: - u1, u3 = self.core.space.reshape_pol_v(u) - - out1 = self.his_N3.dot(self.dofs_MF[0].dot(u1).T).T - out3 = self.int_N3.dot(self.dofs_MF[1].dot(u3).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - elif self.core.basis_u == 2: - u1, u3 = self.core.space.reshape_pol_2(u) - - out1 = self.his_D3.dot(self.dofs_MF[0].dot(u1).T).T - out3 = self.int_N3.dot(self.dofs_MF[1].dot(u3).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - else: - out = self.dofs_MF.dot(u) - - return self.core.space.projectors.solve_V2(out, False) - - # ====================================== - def __MF_transposed(self, f): - """ - TODO - """ - - f = self.core.space.projectors.apply_IinvT_V2(f) - - if self.MF_as_tensor: - f1, f3 = self.core.space.reshape_pol_2(f) - - if self.core.basis_u == 0: - out1 = self.his_N3.T.dot(self.dofs_MF[0].T.dot(f1).T).T - out3 = self.int_N3.T.dot(self.dofs_MF[1].T.dot(f3).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - elif self.core.basis_u == 2: - out1 = self.his_D3.T.dot(self.dofs_MF[0].T.dot(f1).T).T - out3 = self.int_N3.T.dot(self.dofs_MF[1].T.dot(f3).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - else: - out = self.dofs_MF.T.dot(f) - - return out - - # ====================================== - def __PF(self, u): - """ - TODO - """ - - if self.PF_as_tensor: - if self.core.basis_u == 0: - u1, u3 = self.core.space.reshape_pol_v(u) - - out1 = self.his_N3.dot(self.dofs_PF[0].dot(u1).T).T - out3 = self.int_N3.dot(self.dofs_PF[1].dot(u3).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - elif self.core.basis_u == 2: - u1, u3 = self.core.space.reshape_pol_2(u) - - out1 = self.his_D3.dot(self.dofs_PF[0].dot(u1).T).T - out3 = self.int_N3.dot(self.dofs_PF[1].dot(u3).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - else: - out = self.dofs_PF.dot(u) - - return self.core.space.projectors.solve_V2(out, False) - - # ====================================== - def __PF_transposed(self, f): - """ - TODO - """ - - f = self.core.space.projectors.apply_IinvT_V2(f) - - if self.PF_as_tensor: - f1, f3 = self.core.space.reshape_pol_2(f) - - if self.core.basis_u == 0: - out1 = self.his_N3.T.dot(self.dofs_PF[0].T.dot(f1).T).T - out3 = self.int_N3.T.dot(self.dofs_PF[1].T.dot(f3).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - elif self.core.basis_u == 2: - out1 = self.his_D3.T.dot(self.dofs_PF[0].T.dot(f1).T).T - out3 = self.int_N3.T.dot(self.dofs_PF[1].T.dot(f3).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - else: - out = self.dofs_PF.T.dot(f) - - return out - - # ====================================== - def __JF(self, u): - """ - TODO - """ - - if self.JF_as_tensor: - if self.core.basis_u == 0: - u1, u3 = self.core.space.reshape_pol_v(u) - - out1 = self.his_N3.dot(self.dofs_JF[0].dot(u1).T).T - out3 = self.int_N3.dot(self.dofs_JF[1].dot(u3).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - elif self.core.basis_u == 2: - u1, u3 = self.core.space.reshape_pol_2(u) - - out1 = self.his_D3.dot(self.dofs_JF[0].dot(u1).T).T - out3 = self.int_N3.dot(self.dofs_JF[1].dot(u3).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - else: - out = self.dofs_JF.dot(u) - - return self.core.space.projectors.solve_V2(out, False) - - # ====================================== - def __JF_transposed(self, f): - """ - TODO - """ - - f = self.core.space.projectors.apply_IinvT_V2(f) - - if self.JF_as_tensor: - f1, f3 = self.core.space.reshape_pol_2(f) - - if self.core.basis_u == 0: - out1 = self.his_N3.T.dot(self.dofs_JF[0].T.dot(f1).T).T - out3 = self.int_N3.T.dot(self.dofs_JF[1].T.dot(f3).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - elif self.core.basis_u == 2: - out1 = self.his_D3.T.dot(self.dofs_JF[0].T.dot(f1).T).T - out3 = self.int_N3.T.dot(self.dofs_JF[1].T.dot(f3).T).T - - out = xp.concatenate((out1.flatten(), out3.flatten())) - - else: - out = self.dofs_JF.T.dot(f) - - return out - - # ====================================== - def __PR(self, d): - """ - TODO - """ - - if self.PR_as_tensor: - d = self.core.space.reshape_pol_3(d) - out = self.his_D3.dot(self.dofs_PR.dot(d).T).T.flatten() - - else: - out = self.dofs_PR.dot(d) - - return self.core.space.projectors.solve_V3(out, False) - - # ====================================== - def __PR_transposed(self, d): - """ - TODO - """ - - d = self.core.space.projectors.apply_IinvT_V3(d) - - if self.PR_as_tensor: - d = self.core.space.reshape_pol_3(d) - out = self.his_D3.T.dot(self.dofs_PR.T.dot(d).T).T.flatten() - - else: - out = self.dofs_PR.T.dot(d) - - return out - - # ====================================== - def __Mn(self, u): - """ - TODO - """ - - if self.Mn_as_tensor: - if self.core.basis_u == 0: - out = self.core.space.apply_Mv_ten( - u, - [[self.Mn_mat[0], self.core.space.M0_tor], [self.Mn_mat[1], self.core.space.M0_tor]], - ) - elif self.core.basis_u == 2: - out = self.core.space.apply_M2_ten( - u, - [[self.Mn_mat[0], self.core.space.M1_tor], [self.Mn_mat[1], self.core.space.M0_tor]], - ) - - else: - out = self.Mn_mat.dot(u) - - return out - - # ====================================== - def __MJ(self, b): - """ - TODO - """ - - if self.MJ_as_tensor: - if self.core.basis_u == 0: - out = xp.zeros(self.core.space.Ev_0.shape[0], dtype=float) - elif self.core.basis_u == 2: - out = self.core.space.apply_M2_ten( - b, - [[self.MJ_mat[0], self.core.space.M1_tor], [self.MJ_mat[1], self.core.space.M0_tor]], - ) - - else: - if self.core.basis_u == 0: - out = xp.zeros(self.core.space.Ev_0.shape[0], dtype=float) - elif self.core.basis_u == 2: - out = self.MJ_mat.dot(b) - - return out - - # ====================================== - def __L(self, u): - """ - TODO - """ - - if self.core.basis_u == 0: - out = -self.core.space.D0.dot(self.__PF(u)) - (self.gamma - 1) * self.__PR( - self.core.space.D0.dot(self.__JF(u)), - ) - elif self.core.basis_u == 2: - out = -self.core.space.D0.dot(self.__PF(u)) - (self.gamma - 1) * self.__PR(self.core.space.D0.dot(u)) - - return out - - # ====================================== - def __S2(self, u): - """ - TODO - """ - - bu = self.core.space.C0.dot(self.__EF(u)) - - out = self.__Mn(u) - out += self.dt_2**2 / 4 * self.__EF_transposed(self.core.space.C0.T.dot(self.core.space.M2_0(bu))) - - return out - - # ====================================== - def __S6(self, u): - """ - TODO - """ - - out = self.__Mn(u) - - if self.core.basis_u == 0: - out -= self.dt_6**2 / 4 * self.__JF_transposed(self.core.space.D0.T.dot(self.core.space.M3_0(self.__L(u)))) - elif self.core.basis_u == 2: - out -= self.dt_6**2 / 4 * self.core.space.D0.T.dot(self.core.space.M3_0(self.__L(u))) - - return out - - # ====================================== - def set_operators(self, dt_2=1.0, dt_6=1.0): - """ - TODO - """ - - self.dt_2 = dt_2 - self.dt_6 = dt_6 - - if self.core.basis_u == 0: - if hasattr(self, "dofs_MF"): - self.MF = spa.linalg.LinearOperator( - (self.core.space.E2_0.shape[0], self.core.space.Ev_0.shape[0]), - matvec=self.__MF, - rmatvec=self.__MF_transposed, - ) - - if hasattr(self, "dofs_PF"): - self.PF = spa.linalg.LinearOperator( - (self.core.space.E2_0.shape[0], self.core.space.Ev_0.shape[0]), - matvec=self.__PF, - rmatvec=self.__PF_transposed, - ) - - if hasattr(self, "dofs_JF"): - self.JF = spa.linalg.LinearOperator( - (self.core.space.E2_0.shape[0], self.core.space.Ev_0.shape[0]), - matvec=self.__JF, - rmatvec=self.__JF_transposed, - ) - - if hasattr(self, "dofs_EF"): - self.EF = spa.linalg.LinearOperator( - (self.core.space.E1_0.shape[0], self.core.space.Ev_0.shape[0]), - matvec=self.__EF, - rmatvec=self.__EF_transposed, - ) - - if hasattr(self, "dofs_PR"): - self.PR = spa.linalg.LinearOperator( - (self.core.space.E3_0.shape[0], self.core.space.E3_0.shape[0]), - matvec=self.__PR, - rmatvec=self.__PR_transposed, - ) - - if hasattr(self, "dofs_Mn"): - self.Mn = spa.linalg.LinearOperator( - (self.core.space.Ev_0.shape[0], self.core.space.Ev_0.shape[0]), - matvec=self.__Mn, - ) - - if hasattr(self, "dofs_MJ"): - self.MJ = spa.linalg.LinearOperator( - (self.core.space.Ev_0.shape[0], self.core.space.E2_0.shape[0]), - matvec=self.__MJ, - ) - - if hasattr(self, "dofs_PF") and hasattr(self, "dofs_PR") and hasattr(self, "dofs_JF"): - self.L = spa.linalg.LinearOperator( - (self.core.space.E3_0.shape[0], self.core.space.Ev_0.shape[0]), - matvec=self.__L, - ) - - if hasattr(self, "Mn_mat") and hasattr(self, "dofs_EF"): - self.S2 = spa.linalg.LinearOperator( - (self.core.space.Ev_0.shape[0], self.core.space.Ev_0.shape[0]), - matvec=self.__S2, - ) - - if hasattr(self, "Mn_mat") and hasattr(self, "L"): - self.S6 = spa.linalg.LinearOperator( - (self.core.space.Ev_0.shape[0], self.core.space.Ev_0.shape[0]), - matvec=self.__S6, - ) - - elif self.core.basis_u == 2: - if hasattr(self, "dofs_MF"): - self.MF = spa.linalg.LinearOperator( - (self.core.space.E2_0.shape[0], self.core.space.E2_0.shape[0]), - matvec=self.__MF, - rmatvec=self.__MF_transposed, - ) - - if hasattr(self, "dofs_PF"): - self.PF = spa.linalg.LinearOperator( - (self.core.space.E2_0.shape[0], self.core.space.E2_0.shape[0]), - matvec=self.__PF, - rmatvec=self.__PF_transposed, - ) - - if hasattr(self, "dofs_EF"): - self.EF = spa.linalg.LinearOperator( - (self.core.space.E1_0.shape[0], self.core.space.E2_0.shape[0]), - matvec=self.__EF, - rmatvec=self.__EF_transposed, - ) - - if hasattr(self, "dofs_PR"): - self.PR = spa.linalg.LinearOperator( - (self.core.space.E3_0.shape[0], self.core.space.E3_0.shape[0]), - matvec=self.__PR, - rmatvec=self.__PR_transposed, - ) - - if hasattr(self, "Mn_mat"): - self.Mn = spa.linalg.LinearOperator( - (self.core.space.E2_0.shape[0], self.core.space.E2_0.shape[0]), - matvec=self.__Mn, - ) - - if hasattr(self, "MJ_mat"): - self.MJ = spa.linalg.LinearOperator( - (self.core.space.E2_0.shape[0], self.core.space.E2_0.shape[0]), - matvec=self.__MJ, - ) - - if hasattr(self, "dofs_PF") and hasattr(self, "dofs_PR"): - self.L = spa.linalg.LinearOperator( - (self.core.space.E3_0.shape[0], self.core.space.E2_0.shape[0]), - matvec=self.__L, - ) - - if hasattr(self, "Mn_mat") and hasattr(self, "dofs_EF"): - self.S2 = spa.linalg.LinearOperator( - (self.core.space.E2_0.shape[0], self.core.space.E2_0.shape[0]), - matvec=self.__S2, - ) - - if hasattr(self, "Mn_mat") and hasattr(self, "L"): - self.S6 = spa.linalg.LinearOperator( - (self.core.space.E2_0.shape[0], self.core.space.E2_0.shape[0]), - matvec=self.__S6, - ) - - # ====================================== - def rhs2(self, u, b): - """ - TODO - """ - - bu = self.core.space.C0.dot(self.EF(u)) - - out = self.Mn(u) - out -= self.dt_2**2 / 4 * self.EF.T(self.core.space.C0.T.dot(self.core.space.M2_0(bu))) - out += self.dt_2 * self.EF.T(self.core.space.C0.T.dot(self.core.space.M2_0(b))) - - return out - - # ====================================== - def rhs6(self, u, p, b): - """ - TODO - """ - - out = self.Mn(u) - - if self.core.basis_u == 0: - out += self.dt_6**2 / 4 * self.JF.T(self.core.space.D0.T.dot(self.core.space.M3_0(self.L(u)))) - out += self.dt_6 * self.JF.T(self.core.space.D0.T.dot(self.core.space.M3_0(p))) - out += self.dt_6 * self.MJ(b) - - elif self.core.basis_u == 2: - out += self.dt_6**2 / 4 * self.core.space.D0.T.dot(self.core.space.M3_0(self.L(u))) - out += self.dt_6 * self.core.space.D0.T.dot(self.core.space.M3_0(p)) - out += self.dt_6 * self.MJ(b) - # -------------------------------------- - - return out - - # ====================================== - def guess_S2(self, u, b, kind): - """ - TODO - """ - - if kind == "Euler": - k1_u = self.Mn_inv(self.EF.T(self.core.space.C0.T.dot(self.core.space.M2_0(b)))) - - u_guess = u + self.dt_2 * k1_u - - elif kind == "Heun": - k1_u = self.Mn_inv(self.EF.T(self.core.space.C0.T.dot(self.core.space.M2_0(b)))) - k1_b = -self.core.space.C0.dot(self.EF(u)) - - k2_u = self.Mn_inv(self.EF.T(self.core.space.C0.T.dot(self.core.space.M2_0(b + self.dt_2 * k1_b)))) - - u_guess = u + self.dt_2 / 2 * (k1_u + k2_u) - - elif kind == "RK4": - k1_u = self.Mn_inv(self.EF.T(self.core.space.C0.T.dot(self.core.space.M2_0(b)))) - k1_b = -self.core.space.C0.dot(self.EF(u)) - - k2_u = self.Mn_inv(self.EF.T(self.core.space.C0.T.dot(self.core.space.M2_0(b + self.dt_2 / 2 * k1_b)))) - k2_b = -self.core.space.C0.dot(self.EF(u + self.dt_2 / 2 * k1_u)) - - k3_u = self.Mn_inv(self.EF.T(self.core.space.C0.T.dot(self.core.space.M2_0(b + self.dt_2 / 2 * k2_b)))) - k3_b = -self.core.space.C0.dot(self.EF(u + self.dt_2 / 2 * k2_u)) - - k4_u = self.Mn_inv(self.EF.T(self.core.space.C0.T.dot(self.core.space.M2_0(b + self.dt_2 * k3_b)))) - k4_b = -self.core.space.C0.dot(self.EF(u + self.dt_2 * k3_u)) - - u_guess = u + self.dt_2 / 6 * (k1_u + 2 * k2_u + 2 * k3_u + k4_u) - - else: - u_guess = xp.copy(u) - - return u_guess - - # ====================================== - def guess_S6(self, u, p, b, kind): - """ - TODO - """ - - u_guess = u.copy() - - return u_guess - - # ====================================== - def set_inverse_Mn(self): - """ - TODO - """ - - if self.core.basis_u == 0: - self.Mn_inv = mass_3d_pre.get_Mv_PRE_3(self.core.space, [self.Mn_mat[0], self.Mn_mat[1]]) - - if self.core.basis_u == 2: - self.Mn_inv = mass_3d_pre.get_M2_PRE_3(self.core.space, [self.Mn_mat[0], self.Mn_mat[1]]) - - # ====================================== - def set_preconditioner_S2(self, which, tol_inv=1e-15, drop_tol=1e-4, fill_fac=10.0): - assert which == "LU" or which == "ILU" or which == "FFT" - - # ------------------- LU/ILU preconditioner ------------------------ - if which == "ILU" or which == "LU": - # assemble full weighted mass matrix Mn - if self.Mn_as_tensor: - if self.core.basis_u == 0: - Mn = spa.bmat( - [ - [spa.kron(self.Mn_mat[0], self.core.space.M0_tor), None], - [None, spa.kron(self.Mn_mat[1], self.core.space.M0_tor)], - ], - format="csr", - ) - - if self.core.basis_u == 2: - Mn = spa.bmat( - [ - [spa.kron(self.Mn_mat[0], self.core.space.M1_tor), None], - [None, spa.kron(self.Mn_mat[1], self.core.space.M0_tor)], - ], - format="csr", - ) - - else: - Mn = self.Mn_mat.copy() - - # assemble approximations for inverse interpolation matrices - self.core.space.projectors.assemble_approx_inv(tol_inv) - - # assemble approximate EF matrix - if self.EF_as_tensor: - if self.core.basis_u == 0: - EF_11 = spa.kron(self.dofs_EF[0], self.int_N3) - EF_12 = spa.kron(self.dofs_EF[1], self.int_N3) - EF_21 = spa.kron(self.dofs_EF[2], self.his_N3) - - if self.core.basis_u == 2: - EF_11 = spa.kron(self.dofs_EF[0], self.int_D3) - EF_12 = spa.kron(self.dofs_EF[1], self.int_N3) - EF_21 = spa.kron(self.dofs_EF[2], self.his_D3) - - EF_approx = spa.bmat([[EF_11, EF_12], [EF_21, None]], format="csr") - - del EF_11, EF_12, EF_21 - - EF_approx = self.core.space.projectors.I1_0_inv_approx.dot(EF_approx) - - else: - EF_approx = self.core.space.projectors.I1_0_inv_approx.dot(self.dofs_EF) - - # assemble full mass matrix M2_0 - if self.core.space.M2_as_tensor: - M2_11 = spa.kron(self.core.space.M2_pol_mat[0], self.core.space.M1_tor) - M2_22 = spa.kron(self.core.space.M2_pol_mat[1], self.core.space.M0_tor) - - M2_0 = spa.bmat([[M2_11, None], [None, M2_22]], format="csr") - - del M2_11, M2_22 - - else: - M2_0 = self.core.space.M2_mat - - M2_0 = self.core.space.B2.dot(M2_0.dot(self.core.space.B2.T)).tocsr() - - # assemble approximate S2 matrix - S2_approx = Mn + self.dt_2**2 / 4 * EF_approx.T.dot( - self.core.space.C0.T.dot(M2_0.dot(self.core.space.C0.dot(EF_approx))), - ) - - del Mn, EF_approx, M2_0 - - # compute LU/ILU of approximate S2 matrix - if which == "LU": - S2_LU = spa.linalg.splu(S2_approx.tocsc()) - else: - S2_LU = spa.linalg.spilu(S2_approx.tocsc(), drop_tol=drop_tol, fill_factor=fill_fac) - - self.S2_PRE = spa.linalg.LinearOperator(S2_approx.shape, S2_LU.solve) - # --------------------------------------------------------------------- - - # ----------------------- FFT preconditioner -------------------------- - elif which == "FFT": - - def solve_S2(x): - return self.Mn_inv(x) - - self.S2_PRE = spa.linalg.LinearOperator(self.Mn_inv.shape, solve_S2) - # --------------------------------------------------------------------- - - # ====================================== - def set_preconditioner_S6(self, which, tol_inv=1e-15, drop_tol=1e-4, fill_fac=10.0): - assert which == "LU" or which == "ILU" or which == "FFT" - - # -------------------------- LU/ILU preconditioner ------------------------- - if which == "ILU" or which == "LU": - # assemble full weighted mass matrix Mn - if self.Mn_as_tensor: - if self.core.basis_u == 0: - Mn = spa.bmat( - [ - [spa.kron(self.Mn_mat[0], self.core.space.M0_tor), None], - [None, spa.kron(self.Mn_mat[1], self.core.space.M0_tor)], - ], - format="csr", - ) - - if self.core.basis_u == 2: - Mn = spa.bmat( - [ - [spa.kron(self.Mn_mat[0], self.core.space.M1_tor), None], - [None, spa.kron(self.Mn_mat[1], self.core.space.M0_tor)], - ], - format="csr", - ) - - else: - Mn = self.Mn_mat.copy() - - # assemble approximations for inverse interpolation matrices - self.core.space.projectors.assemble_approx_inv(tol_inv) - - # assemble approximate PF matrix - if self.PF_as_tensor: - if self.core.basis_u == 0: - PF_11 = spa.kron(self.dofs_PF[0], self.his_N3) - PF_22 = spa.kron(self.dofs_PF[1], self.int_N3) - if self.core.basis_u == 2: - PF_11 = spa.kron(self.dofs_PF[0], self.his_D3) - PF_22 = spa.kron(self.dofs_PF[1], self.int_N3) - - PF_approx = spa.bmat([[PF_11, None], [None, PF_22]], format="csr") - - del PF_11, PF_22 - - PF_approx = self.core.space.projectors.I2_0_inv_approx.dot(PF_approx) - - else: - PF_approx = self.core.space.projectors.I2_0_inv_approx.dot(self.dofs_PF) - - # assemble approximate JF matrix (only for 0-form MHD) - if self.core.basis_u == 0: - if self.JF_as_tensor: - JF_11 = spa.kron(self.dofs_JF[0], self.his_N3) - JF_22 = spa.kron(self.dofs_JF[1], self.int_N3) - - JF_approx = spa.bmat([[JF_11, None], [None, JF_22]], format="csr") - - del JF_11, JF_22 - - JF_approx = self.core.space.projectors.I2_0_inv_approx.dot(JF_approx) - - else: - JF_approx = self.core.space.projectors.I2_0_inv_approx.dot(self.dofs_JF) - - # assemble approximate PR matrix - if self.PR_as_tensor: - PR_approx = spa.kron(self.dofs_PF, self.his_D3) - PR_approx = self.core.space.projectors.I3_0_inv_approx.dot(PR_approx) - - else: - PR_approx = self.core.space.projectors.I3_0_inv_approx.dot(self.dofs_PR) - - # assemble approximate L matrix - if self.core.basis_u == 0: - L_approx = -self.core.space.D0.dot(PF_approx) - (self.gamma - 1) * PR_approx.dot( - self.core.space.D0.dot(JF_approx), - ) - - del PF_approx, PR_approx - - if self.core.basis_u == 2: - L_approx = -self.core.space.D0.dot(PF_approx) - (self.gamma - 1) * PR_approx.dot(self.core.space.D0) - - del PF_approx, PR_approx - - # assemble full mass matrix M3 - if self.core.space.M3_as_tensor: - M3_0 = spa.kron(self.core.space.M3_pol_mat, self.core.space.M1_tor) - else: - M3_0 = self.core.space.M3_mat - - M3_0 = self.core.space.B3.dot(M3_0.dot(self.core.space.B3.T)).tocsr() - - # assemble approximate S6 matrix - if self.core.basis_u == 0: - S6_approx = Mn - self.dt_6**2 / 4 * JF_approx.T.dot(self.core.space.D0.T.dot(M3_0.dot(L_approx))) - - del Mn, JF_approx, M3_0, L_approx - - if self.core.basis_u == 2: - S6_approx = Mn - self.dt_6**2 / 4 * self.core.space.D0.T.dot(M3_0.dot(L_approx)) - - del Mn, M3_0, L_approx - - # compute LU/ILU of approximate S6 matrix - if which == "LU": - S6_LU = spa.linalg.splu(S6_approx.tocsc()) - else: - S6_LU = spa.linalg.spilu(S6_approx.tocsc(), drop_tol=drop_tol, fill_factor=fill_fac) - - self.S6_PRE = spa.linalg.LinearOperator(S6_approx.shape, S6_LU.solve) - # --------------------------------------------------------------------------- - - # -------------------------- FFT preconditioner ----------------------------- - elif which == "FFT": - - def solve_S6(x): - return self.Mn_inv(x) - - self.S6_PRE = spa.linalg.LinearOperator(self.Mn_inv.shape, solve_S6) - # --------------------------------------------------------------------------- diff --git a/src/struphy/eigenvalue_solvers/mhd_operators_core.py b/src/struphy/eigenvalue_solvers/mhd_operators_core.py deleted file mode 100644 index 61d534148..000000000 --- a/src/struphy/eigenvalue_solvers/mhd_operators_core.py +++ /dev/null @@ -1,2009 +0,0 @@ -# coding: utf-8 -# -# Copyright 2021 Florian Holderied (florian.holderied@ipp.mpg.de) - - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.eigenvalue_solvers.kernels_projectors_global_mhd as ker -import struphy.eigenvalue_solvers.mass_matrices_2d as mass_2d -import struphy.eigenvalue_solvers.mass_matrices_3d as mass_3d - - -class MHDOperatorsCore: - """ - Core class for degree of freedom matrices related to ideal MHD equations. - - Parameters - ---------- - space : tensor_spline_space - 2D or 3D B-spline finite element space. - - equilibrium : equilibrium_mhd - MHD equilibrium object. - - basis_u : int - representation of velocity field (0 : vector field where all components are treated as 0-forms, 2 : 2-form). - """ - - def __init__(self, space, equilibrium, basis_u): - # tensor-product spline space (either 3D or 2D x Fourier) - self.space = space - - # MHD equilibrium object for evaluation of equilibrium fields - self.equilibrium = equilibrium - - # bulk veloctiy formulation (either vector field or 2-form) - assert basis_u == 0 or basis_u == 2 - self.basis_u = basis_u - - # get 1D interpolation points (copies) and shift first point in raidla (eta_1) direction for polar domains - self.eta_int = [space.projectors.x_int.copy() for space in self.space.spaces] - - if self.space.ck == 0 or self.space.ck == 1: - self.eta_int[0][0] += 0.00001 - - self.nint = [eta_int.size for eta_int in self.eta_int] - - # get 1D quadrature points and weights - self.eta_his = [space.projectors.pts for space in self.space.spaces] - self.wts = [space.projectors.wts for space in self.space.spaces] - - self.nhis = [eta_his.shape[0] for eta_his in self.eta_his] - self.nq = [eta_his.shape[1] for eta_his in self.eta_his] - - # get 1D number of sub-integration intervals - self.subs = [space.projectors.subs for space in self.space.spaces] - self.subs_cum = [space.projectors.subs_cum for space in self.space.spaces] - - # get 1D indices of non-vanishing values of expressions dofs_0(N), dofs_0(D), dofs_1(N) and dofs_1(D) - self.dofs_0_N_i = [list(xp.nonzero(space.projectors.I.toarray())) for space in self.space.spaces] - self.dofs_1_D_i = [list(xp.nonzero(space.projectors.H.toarray())) for space in self.space.spaces] - - self.dofs_0_D_i = [list(xp.nonzero(space.projectors.ID.toarray())) for space in self.space.spaces] - self.dofs_1_N_i = [list(xp.nonzero(space.projectors.HN.toarray())) for space in self.space.spaces] - - for i in range(self.space.dim): - for j in range(2): - self.dofs_0_N_i[i][j] = self.dofs_0_N_i[i][j].copy() - self.dofs_1_D_i[i][j] = self.dofs_1_D_i[i][j].copy() - - self.dofs_0_D_i[i][j] = self.dofs_0_D_i[i][j].copy() - self.dofs_1_N_i[i][j] = self.dofs_1_N_i[i][j].copy() - - # get 1D collocation matrices for interpolation and histopolation - self.basis_int_N = [space.projectors.N_int.toarray() for space in self.space.spaces] - self.basis_int_D = [space.projectors.D_int.toarray() for space in self.space.spaces] - - self.basis_his_N = [ - space.projectors.N_pts.toarray().reshape(nhis, nq, space.NbaseN) - for space, nhis, nq in zip(self.space.spaces, self.nhis, self.nq) - ] - self.basis_his_D = [ - space.projectors.D_pts.toarray().reshape(nhis, nq, space.NbaseD) - for space, nhis, nq in zip(self.space.spaces, self.nhis, self.nq) - ] - - # number of basis functions in third dimension - self.N3 = self.space.NbaseN[2] - self.D3 = self.space.NbaseD[2] - - # ================================================================= - def get_blocks_EF(self, pol=True): - """ - Returns blocks related to the degree of freedom (DOF) matrix - - basis_u = 0 : EF_(ab,ijk lmn) = dofs^1_(a,ijk)( B^2_eq x Lambda^0_(b,lmn) ), - basis_u = 2 : EF_(ab,ijk lmn) = dofs^1_(a,ijk)( B^2_eq x Lambda^2_(b,lmn) / sqrt(g) ). - - Parameters - ---------- - pol : boolean - wheather to assemble the matrices in the form (poloidal x toroidal) (True). - - Returns - ------- - EF : list of six scipy.sparse.csr_matrices - the DOF matrices. - """ - - if self.basis_u == 0: - if pol or self.space.dim == 2: - # ---------- 12 - block ([his, int] of NN) ----------- - # evaluate equilibrium magnetic field (3-component) at interpolation and quadrature points - B2_3_pts = self.equilibrium.b2_3(self.eta_his[0].flatten(), self.eta_int[1], 0.0) - B2_3_pts = B2_3_pts.reshape(self.nhis[0], self.nq[0], self.nint[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - - ker.rhs11_2d( - self.dofs_1_N_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_1_N_i[0][1], - self.dofs_0_N_i[1][1], - self.subs[0], - self.subs_cum[0], - self.wts[0], - self.basis_his_N[0], - self.basis_int_N[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - -B2_3_pts, - val, - row, - col, - ) - - EF_12 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_1form[0] // self.N3, self.space.Ntot_0form // self.N3), - ) - EF_12.eliminate_zeros() - # ---------------------------------------------------- - - # ---------- 13 - block ([his, int] of NN) ----------- - # evaluate equilibrium magnetic field (2-component) at interpolation and quadrature points - B2_2_pts = self.equilibrium.b2_2(self.eta_his[0].flatten(), self.eta_int[1], 0.0) - B2_2_pts = B2_2_pts.reshape(self.nhis[0], self.nq[0], self.nint[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - - ker.rhs11_2d( - self.dofs_1_N_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_1_N_i[0][1], - self.dofs_0_N_i[1][1], - self.subs[0], - self.subs_cum[0], - self.wts[0], - self.basis_his_N[0], - self.basis_int_N[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - B2_2_pts, - val, - row, - col, - ) - - EF_13 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_1form[0] // self.N3, self.space.Ntot_0form // self.N3), - ) - EF_13.eliminate_zeros() - # ---------------------------------------------------- - - # ---------- 21 - block ([int, his] of NN) ---------- - # evaluate equilibrium magnetic field (3-component) at interpolation and quadrature points - B2_3_pts = self.equilibrium.b2_3(self.eta_int[0], self.eta_his[1].flatten(), 0.0) - B2_3_pts = B2_3_pts.reshape(self.nint[0], self.nhis[1], self.nq[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size, dtype=int) - - ker.rhs12_2d( - self.dofs_0_N_i[0][0], - self.dofs_1_N_i[1][0], - self.dofs_0_N_i[0][1], - self.dofs_1_N_i[1][1], - self.subs[1], - self.subs_cum[1], - self.wts[1], - self.basis_int_N[0], - self.basis_his_N[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - B2_3_pts, - val, - row, - col, - ) - - EF_21 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_1form[1] // self.N3, self.space.Ntot_0form // self.N3), - ) - EF_21.eliminate_zeros() - # ---------------------------------------------------- - - # ---------- 23 - block ([int, his] of NN) ---------- - # evaluate equilibrium magnetic field (1-component) at interpolation and quadrature points - B2_1_pts = self.equilibrium.b2_1(self.eta_int[0], self.eta_his[1].flatten(), 0.0) - B2_1_pts = B2_1_pts.reshape(self.nint[0], self.nhis[1], self.nq[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size, dtype=int) - - ker.rhs12_2d( - self.dofs_0_N_i[0][0], - self.dofs_1_N_i[1][0], - self.dofs_0_N_i[0][1], - self.dofs_1_N_i[1][1], - self.subs[1], - self.subs_cum[1], - self.wts[1], - self.basis_int_N[0], - self.basis_his_N[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - -B2_1_pts, - val, - row, - col, - ) - - EF_23 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_1form[1] // self.N3, self.space.Ntot_0form // self.N3), - ) - EF_23.eliminate_zeros() - # ---------------------------------------------------- - - # ---------- 31 - block ([int, int] of NN) ----------- - # evaluate equilibrium magnetic field (2-component) at interpolation and quadrature points - B2_2_pts = self.equilibrium.b2_2(self.eta_int[0], self.eta_int[1], 0.0) - - # assemble sparse matrix - val = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - - ker.rhs0_2d( - self.dofs_0_N_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_0_N_i[0][1], - self.dofs_0_N_i[1][1], - self.basis_int_N[0], - self.basis_int_N[1], - -B2_2_pts, - val, - row, - col, - ) - - EF_31 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_1form[2] // self.D3, self.space.Ntot_0form // self.N3), - ) - EF_31.eliminate_zeros() - # ---------------------------------------------------- - - # ---------- 32 - block ([int, int] of NN) ---------- - # evaluate equilibrium magnetic field (1-component) at interpolation and quadrature points - B2_1_pts = self.equilibrium.b2_1(self.eta_int[0], self.eta_int[1], 0.0) - - # assemble sparse matrix - val = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - - ker.rhs0_2d( - self.dofs_0_N_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_0_N_i[0][1], - self.dofs_0_N_i[1][1], - self.basis_int_N[0], - self.basis_int_N[1], - B2_1_pts, - val, - row, - col, - ) - - EF_32 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_1form[2] // self.D3, self.space.Ntot_0form // self.N3), - ) - EF_32.eliminate_zeros() - # ---------------------------------------------------- - - else: - # ------- 12 - block ([his, int, int] of NNN) -------- - # evaluate equilibrium magnetic field (3-component) at interpolation and quadrature points - B2_3_pts = self.equilibrium.b2_3(self.eta_his[0].flatten(), self.eta_int[1], self.eta_int[2]) - B2_3_pts = B2_3_pts.reshape(self.nhis[0], self.nq[0], self.nint[1], self.nint[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - - ker.rhs11( - self.dofs_1_N_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_0_N_i[2][0], - self.dofs_1_N_i[0][1], - self.dofs_0_N_i[1][1], - self.dofs_0_N_i[2][1], - self.subs[0], - self.subs_cum[0], - self.wts[0], - self.basis_his_N[0], - self.basis_int_N[1], - self.basis_int_N[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - -B2_3_pts, - val, - row, - col, - ) - - EF_12 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_1form[0], self.space.Ntot_0form)) - EF_12.eliminate_zeros() - # ---------------------------------------------------- - - # ------- 13 - block ([his, int, int] of NNN) -------- - # evaluate equilibrium magnetic field (2-component) at interpolation and quadrature points - B2_2_pts = self.equilibrium.b2_2(self.eta_his[0].flatten(), self.eta_int[1], self.eta_int[2]) - B2_2_pts = B2_2_pts.reshape(self.nhis[0], self.nq[0], self.nint[1], self.nint[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - - ker.rhs11( - self.dofs_1_N_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_0_N_i[2][0], - self.dofs_1_N_i[0][1], - self.dofs_0_N_i[1][1], - self.dofs_0_N_i[2][1], - self.subs[0], - self.subs_cum[0], - self.wts[0], - self.basis_his_N[0], - self.basis_int_N[1], - self.basis_int_N[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - B2_2_pts, - val, - row, - col, - ) - - EF_13 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_1form[0], self.space.Ntot_0form)) - EF_13.eliminate_zeros() - # ---------------------------------------------------- - - # ------- 21 - block ([int, his, int] of NNN) -------- - # evaluate equilibrium magnetic field (3-component) at interpolation and quadrature points - B2_3_pts = self.equilibrium.b2_3(self.eta_int[0], self.eta_his[1].flatten(), self.eta_int[2]) - B2_3_pts = B2_3_pts.reshape(self.nint[0], self.nhis[1], self.nq[1], self.nint[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - - ker.rhs12( - self.dofs_0_N_i[0][0], - self.dofs_1_N_i[1][0], - self.dofs_0_N_i[2][0], - self.dofs_0_N_i[0][1], - self.dofs_1_N_i[1][1], - self.dofs_0_N_i[2][1], - self.subs[1], - self.subs_cum[1], - self.wts[1], - self.basis_int_N[0], - self.basis_his_N[1], - self.basis_int_N[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - B2_3_pts, - val, - row, - col, - ) - - EF_21 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_1form[1], self.space.Ntot_0form)) - EF_21.eliminate_zeros() - # ---------------------------------------------------- - - # ------- 23 - block ([int, his, int] of NNN) -------- - # evaluate equilibrium magnetic field (1-component) at interpolation and quadrature points - B2_1_pts = self.equilibrium.b2_1(self.eta_int[0], self.eta_his[1].flatten(), self.eta_int[2]) - B2_1_pts = B2_1_pts.reshape(self.nint[0], self.nhis[1], self.nq[1], self.nint[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - - ker.rhs12( - self.dofs_0_N_i[0][0], - self.dofs_1_N_i[1][0], - self.dofs_0_N_i[2][0], - self.dofs_0_N_i[0][1], - self.dofs_1_N_i[1][1], - self.dofs_0_N_i[2][1], - self.subs[1], - self.subs_cum[1], - self.wts[1], - self.basis_int_N[0], - self.basis_his_N[1], - self.basis_int_N[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - -B2_1_pts, - val, - row, - col, - ) - - EF_23 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_1form[1], self.space.Ntot_0form)) - EF_23.eliminate_zeros() - # ---------------------------------------------------- - - # ------- 31 - block ([int, int, his] of NNN) -------- - # evaluate equilibrium magnetic field (2-component) at interpolation and quadrature points - B2_2_pts = self.equilibrium.b2_2(self.eta_int[0], self.eta_int[1], self.eta_his[2].flatten()) - B2_2_pts = B2_2_pts.reshape(self.nint[0], self.nint[1], self.nhis[2], self.nq[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_N_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_N_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_N_i[2][0].size, - dtype=int, - ) - - ker.rhs13( - self.dofs_0_N_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_1_N_i[2][0], - self.dofs_0_N_i[0][1], - self.dofs_0_N_i[1][1], - self.dofs_1_N_i[2][1], - self.subs[2], - self.subs_cum[2], - self.wts[2], - self.basis_int_N[0], - self.basis_int_N[1], - self.basis_his_N[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - -B2_2_pts, - val, - row, - col, - ) - - EF_31 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_1form[2], self.space.Ntot_0form)) - EF_31.eliminate_zeros() - # ---------------------------------------------------- - - # ------- 32 - block ([int, int, his] of NNN) -------- - # evaluate equilibrium magnetic field (1-component) at interpolation and quadrature points - B2_1_pts = self.equilibrium.b2_1(self.eta_int[0], self.eta_int[1], self.eta_his[2].flatten()) - B2_1_pts = B2_1_pts.reshape(self.nint[0], self.nint[1], self.nhis[2], self.nq[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_N_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_N_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_N_i[2][0].size, - dtype=int, - ) - - ker.rhs13( - self.dofs_0_N_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_1_N_i[2][0], - self.dofs_0_N_i[0][1], - self.dofs_0_N_i[1][1], - self.dofs_1_N_i[2][1], - self.subs[2], - self.subs_cum[2], - self.wts[2], - self.basis_int_N[0], - self.basis_int_N[1], - self.basis_his_N[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - B2_1_pts, - val, - row, - col, - ) - - EF_32 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_1form[2], self.space.Ntot_0form)) - EF_32.eliminate_zeros() - # ---------------------------------------------------- - - elif self.basis_u == 2: - if pol or self.space.dim == 2: - # ---------- 12 - block ([his, int] of DN) ----------- - # evaluate equilibrium magnetic field (3-component) at interpolation and quadrature points - B2_3_pts = self.equilibrium.b2_3(self.eta_his[0].flatten(), self.eta_int[1], 0.0) - B2_3_pts = B2_3_pts.reshape(self.nhis[0], self.nq[0], self.nint[1]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs(self.equilibrium.domain.jacobian_det(self.eta_his[0].flatten(), self.eta_int[1], 0.0)) - det_dF = det_dF.reshape(self.nhis[0], self.nq[0], self.nint[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - - ker.rhs11_2d( - self.dofs_1_D_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_1_D_i[0][1], - self.dofs_0_N_i[1][1], - self.subs[0], - self.subs_cum[0], - self.wts[0], - self.basis_his_D[0], - self.basis_int_N[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - -B2_3_pts / det_dF, - val, - row, - col, - ) - - EF_12 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_1form[0] // self.N3, self.space.Ntot_2form[1] // self.D3), - ) - EF_12.eliminate_zeros() - # ---------------------------------------------------- - - # ---------- 13 - block ([his, int] of DD) ----------- - # evaluate equilibrium magnetic field (2-component) at interpolation and quadrature points - B2_2_pts = self.equilibrium.b2_2(self.eta_his[0].flatten(), self.eta_int[1], 0.0) - B2_2_pts = B2_2_pts.reshape(self.nhis[0], self.nq[0], self.nint[1]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs(self.equilibrium.domain.jacobian_det(self.eta_his[0].flatten(), self.eta_int[1], 0.0)) - det_dF = det_dF.reshape(self.nhis[0], self.nq[0], self.nint[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_0_D_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_0_D_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_0_D_i[1][0].size, dtype=int) - - ker.rhs11_2d( - self.dofs_1_D_i[0][0], - self.dofs_0_D_i[1][0], - self.dofs_1_D_i[0][1], - self.dofs_0_D_i[1][1], - self.subs[0], - self.subs_cum[0], - self.wts[0], - self.basis_his_D[0], - self.basis_int_D[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - B2_2_pts / det_dF, - val, - row, - col, - ) - - EF_13 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_1form[0] // self.N3, self.space.Ntot_2form[2] // self.N3), - ) - EF_13.eliminate_zeros() - # ---------------------------------------------------- - - # ---------- 21 - block ([int, his] of ND) ----------- - # evaluate equilibrium magnetic field (3-component) at interpolation and quadrature points - B2_3_pts = self.equilibrium.b2_3(self.eta_int[0], self.eta_his[1].flatten(), 0.0) - B2_3_pts = B2_3_pts.reshape(self.nint[0], self.nhis[1], self.nq[1]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs(self.equilibrium.domain.jacobian_det(self.eta_int[0], self.eta_his[1].flatten(), 0.0)) - det_dF = det_dF.reshape(self.nint[0], self.nhis[1], self.nq[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=int) - - ker.rhs12_2d( - self.dofs_0_N_i[0][0], - self.dofs_1_D_i[1][0], - self.dofs_0_N_i[0][1], - self.dofs_1_D_i[1][1], - self.subs[1], - self.subs_cum[1], - self.wts[1], - self.basis_int_N[0], - self.basis_his_D[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - B2_3_pts / det_dF, - val, - row, - col, - ) - - EF_21 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_1form[1] // self.N3, self.space.Ntot_2form[0] // self.D3), - ) - EF_21.eliminate_zeros() - # ---------------------------------------------------- - - # ---------- 23 - block ([int, his] of DD) ----------- - # evaluate equilibrium magnetic field (1-component) at interpolation and quadrature points - B2_1_pts = self.equilibrium.b2_1(self.eta_int[0], self.eta_his[1].flatten(), 0.0) - B2_1_pts = B2_1_pts.reshape(self.nint[0], self.nhis[1], self.nq[1]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs(self.equilibrium.domain.jacobian_det(self.eta_int[0], self.eta_his[1].flatten(), 0.0)) - det_dF = det_dF.reshape(self.nint[0], self.nhis[1], self.nq[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_0_D_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_0_D_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_0_D_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=int) - - ker.rhs12_2d( - self.dofs_0_D_i[0][0], - self.dofs_1_D_i[1][0], - self.dofs_0_D_i[0][1], - self.dofs_1_D_i[1][1], - self.subs[1], - self.subs_cum[1], - self.wts[1], - self.basis_int_D[0], - self.basis_his_D[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - -B2_1_pts / det_dF, - val, - row, - col, - ) - - EF_23 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_1form[1] // self.N3, self.space.Ntot_2form[2] // self.N3), - ) - EF_23.eliminate_zeros() - # ---------------------------------------------------- - - # ---------- 31 - block ([int, int] of ND) ----------- - # evaluate equilibrium magnetic field (2-component) at interpolation and quadrature points - B2_2_pts = self.equilibrium.b2_2(self.eta_int[0], self.eta_int[1], 0.0) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs(self.equilibrium.domain.jacobian_det(self.eta_int[0], self.eta_int[1], 0.0)) - - # assemble sparse matrix - val = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_0_D_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_0_D_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_0_D_i[1][0].size, dtype=int) - - ker.rhs0_2d( - self.dofs_0_N_i[0][0], - self.dofs_0_D_i[1][0], - self.dofs_0_N_i[0][1], - self.dofs_0_D_i[1][1], - self.basis_int_N[0], - self.basis_int_D[1], - -B2_2_pts / det_dF, - val, - row, - col, - ) - - EF_31 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_1form[2] // self.D3, self.space.Ntot_2form[0] // self.D3), - ) - EF_31.eliminate_zeros() - # ---------------------------------------------------- - - # ---------- 32 - block ([int, int] of DN) ----------- - # evaluate equilibrium magnetic field (1-component) at interpolation and quadrature points - B2_1_pts = self.equilibrium.b2_1(self.eta_int[0], self.eta_int[1], 0.0) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs(self.equilibrium.domain.jacobian_det(self.eta_int[0], self.eta_int[1], 0.0)) - - # assemble sparse matrix - val = xp.empty(self.dofs_0_D_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_0_D_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_0_D_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - - ker.rhs0_2d( - self.dofs_0_D_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_0_D_i[0][1], - self.dofs_0_N_i[1][1], - self.basis_int_D[0], - self.basis_int_N[1], - B2_1_pts / det_dF, - val, - row, - col, - ) - - EF_32 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_1form[2] // self.D3, self.space.Ntot_2form[1] // self.D3), - ) - EF_32.eliminate_zeros() - # ---------------------------------------------------- - - else: - # ------- 12 - block ([his, int, int] of DND) -------- - # evaluate equilibrium magnetic field (3-component) at interpolation and quadrature points - B2_3_pts = self.equilibrium.b2_3(self.eta_his[0].flatten(), self.eta_int[1], self.eta_int[2]) - B2_3_pts = B2_3_pts.reshape(self.nhis[0], self.nq[0], self.nint[1], self.nint[2]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs( - self.equilibrium.domain.jacobian_det(self.eta_his[0].flatten(), self.eta_int[1], self.eta_int[2]), - ) - det_dF = det_dF.reshape(self.nhis[0], self.nq[0], self.nint[1], self.nint[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_0_D_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_0_D_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_0_D_i[2][0].size, - dtype=int, - ) - - ker.rhs11( - self.dofs_1_D_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_0_D_i[2][0], - self.dofs_1_D_i[0][1], - self.dofs_0_N_i[1][1], - self.dofs_0_D_i[2][1], - self.subs[0], - self.subs_cum[0], - self.wts[0], - self.basis_his_D[0], - self.basis_int_N[1], - self.basis_int_D[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - -B2_3_pts / det_dF, - val, - row, - col, - ) - - EF_12 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_1form[0], self.space.Ntot_2form[1])) - EF_12.eliminate_zeros() - # ---------------------------------------------------- - - # ------- 13 - block ([his, int, int] of DDN) -------- - # evaluate equilibrium magnetic field (2-component) at interpolation and quadrature points - B2_2_pts = self.equilibrium.b2_2(self.eta_his[0].flatten(), self.eta_int[1], self.eta_int[2]) - B2_2_pts = B2_2_pts.reshape(self.nhis[0], self.nq[0], self.nint[1], self.nint[2]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs( - self.equilibrium.domain.jacobian_det(self.eta_his[0].flatten(), self.eta_int[1], self.eta_int[2]), - ) - det_dF = det_dF.reshape(self.nhis[0], self.nq[0], self.nint[1], self.nint[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_0_D_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_0_D_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_0_D_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - - ker.rhs11( - self.dofs_1_D_i[0][0], - self.dofs_0_D_i[1][0], - self.dofs_0_N_i[2][0], - self.dofs_1_D_i[0][1], - self.dofs_0_D_i[1][1], - self.dofs_0_N_i[2][1], - self.subs[0], - self.subs_cum[0], - self.wts[0], - self.basis_his_D[0], - self.basis_int_D[1], - self.basis_int_N[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - B2_2_pts / det_dF, - val, - row, - col, - ) - - EF_13 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_1form[0], self.space.Ntot_2form[2])) - EF_13.eliminate_zeros() - # ---------------------------------------------------- - - # ------- 21 - block ([int, his, int] of NDD) -------- - # evaluate equilibrium magnetic field (3-component) at interpolation and quadrature points - B2_3_pts = self.equilibrium.b2_3(self.eta_int[0], self.eta_his[1].flatten(), self.eta_int[2]) - B2_3_pts = B2_3_pts.reshape(self.nint[0], self.nhis[1], self.nq[1], self.nint[2]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs( - self.equilibrium.domain.jacobian_det(self.eta_int[0], self.eta_his[1].flatten(), self.eta_int[2]), - ) - det_dF = det_dF.reshape(self.nint[0], self.nhis[1], self.nq[1], self.nint[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_0_D_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_0_D_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_0_D_i[2][0].size, - dtype=int, - ) - - ker.rhs12( - self.dofs_0_N_i[0][0], - self.dofs_1_D_i[1][0], - self.dofs_0_D_i[2][0], - self.dofs_0_N_i[0][1], - self.dofs_1_D_i[1][1], - self.dofs_0_D_i[2][1], - self.subs[1], - self.subs_cum[1], - self.wts[1], - self.basis_int_N[0], - self.basis_his_D[1], - self.basis_int_D[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - B2_3_pts / det_dF, - val, - row, - col, - ) - - EF_21 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_1form[1], self.space.Ntot_2form[0])) - EF_21.eliminate_zeros() - # ---------------------------------------------------- - - # ------- 23 - block ([int, his, int] of DDN) -------- - # evaluate equilibrium magnetic field (1-component) at interpolation and quadrature points - B2_1_pts = self.equilibrium.b2_1(self.eta_int[0], self.eta_his[1].flatten(), self.eta_int[2]) - B2_1_pts = B2_1_pts.reshape(self.nint[0], self.nhis[1], self.nq[1], self.nint[2]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs( - self.equilibrium.domain.jacobian_det(self.eta_int[0], self.eta_his[1].flatten(), self.eta_int[2]), - ) - det_dF = det_dF.reshape(self.nint[0], self.nhis[1], self.nq[1], self.nint[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_0_D_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_0_D_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_0_D_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - - ker.rhs12( - self.dofs_0_D_i[0][0], - self.dofs_1_D_i[1][0], - self.dofs_0_N_i[2][0], - self.dofs_0_D_i[0][1], - self.dofs_1_D_i[1][1], - self.dofs_0_N_i[2][1], - self.subs[1], - self.subs_cum[1], - self.wts[1], - self.basis_int_D[0], - self.basis_his_D[1], - self.basis_int_N[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - -B2_1_pts / det_dF, - val, - row, - col, - ) - - EF_23 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_1form[1], self.space.Ntot_2form[2])) - EF_23.eliminate_zeros() - # ---------------------------------------------------- - - # ------- 31 - block ([int, int, his] of NDD) -------- - # evaluate equilibrium magnetic field (2-component) at interpolation and quadrature points - B2_2_pts = self.equilibrium.b2_2(self.eta_int[0], self.eta_int[1], self.eta_his[2].flatten()) - B2_2_pts = B2_2_pts.reshape(self.nint[0], self.nint[1], self.nhis[2], self.nq[2]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs( - self.equilibrium.domain.jacobian_det(self.eta_int[0], self.eta_int[1], self.eta_his[2].flatten()), - ) - det_dF = det_dF.reshape(self.nint[0], self.nint[1], self.nhis[2], self.nq[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_0_D_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_0_D_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_0_D_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=int, - ) - - ker.rhs13( - self.dofs_0_N_i[0][0], - self.dofs_0_D_i[1][0], - self.dofs_1_D_i[2][0], - self.dofs_0_N_i[0][1], - self.dofs_0_D_i[1][1], - self.dofs_1_D_i[2][1], - self.subs[2], - self.subs_cum[2], - self.wts[2], - self.basis_int_N[0], - self.basis_int_D[1], - self.basis_his_D[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - -B2_2_pts / det_dF, - val, - row, - col, - ) - - EF_31 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_1form[2], self.space.Ntot_2form[0])) - EF_31.eliminate_zeros() - # ---------------------------------------------------- - - # ------- 32 - block ([int, int, his] of DND) -------- - # evaluate equilibrium magnetic field (1-component) at interpolation and quadrature points - B2_1_pts = self.equilibrium.b2_1(self.eta_int[0], self.eta_int[1], self.eta_his[2].flatten()) - B2_1_pts = B2_1_pts.reshape(self.nint[0], self.nint[1], self.nhis[2], self.nq[2]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs( - self.equilibrium.domain.jacobian_det(self.eta_int[0], self.eta_int[1], self.eta_his[2].flatten()), - ) - det_dF = det_dF.reshape(self.nint[0], self.nint[1], self.nhis[2], self.nq[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_0_D_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_0_D_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_0_D_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=int, - ) - - ker.rhs13( - self.dofs_0_D_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_1_D_i[2][0], - self.dofs_0_D_i[0][1], - self.dofs_0_N_i[1][1], - self.dofs_1_D_i[2][1], - self.subs[2], - self.subs_cum[2], - self.wts[2], - self.basis_int_D[0], - self.basis_int_N[1], - self.basis_his_D[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - B2_1_pts / det_dF, - val, - row, - col, - ) - - EF_32 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_1form[2], self.space.Ntot_2form[1])) - EF_32.eliminate_zeros() - # ---------------------------------------------------- - - return EF_12, EF_13, EF_21, EF_23, EF_31, EF_32 - - # ================================================================= - def get_blocks_FL(self, which, pol=True): - """ - Returns blocks related to the degree of freedom (DOF) matrix - - basis_u = 0 : FL_(aa,ijk lmn) = dofs^2_(a,ijk)( fun * Lambda^0_(a,lmn) ), - basis_u = 2 : FL_(aa,ijk lmn) = dofs^2_(a,ijk)( fun * Lambda^2_(a,lmn) / sqrt(g) ). - - Parameters - ---------- - which : string - * 'm' : fun = n^3_eq - * 'p' : fun = p^3_eq - * 'j' : fun = det_df - - pol : boolean - wheather to assemble the matrices in the form (poloidal x toroidal) (True). - - Returns - ------- - F : list of three scipy.sparse.csr_matrices - the DOF matrices. - """ - - if self.basis_u == 2: - assert which == "m" or which == "p" - else: - assert which == "m" or which == "p" or which == "j" - - if self.basis_u == 0: - if pol or self.space.dim == 2: - # ------------- 11 - block ([int, his] of NN) --------------- - # evaluate equilibrium density/pressure at interpolation and quadrature points - if which == "m": - EQ = self.equilibrium.n3(self.eta_int[0], self.eta_his[1].flatten(), 0.0) - elif which == "p": - EQ = self.equilibrium.p3(self.eta_int[0], self.eta_his[1].flatten(), 0.0) - else: - EQ = self.equilibrium.domain.jacobian_det(self.eta_int[0], self.eta_his[1].flatten(), 0.0) - - EQ = EQ.reshape(self.nint[0], self.nhis[1], self.nq[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size, dtype=int) - - ker.rhs12_2d( - self.dofs_0_N_i[0][0], - self.dofs_1_N_i[1][0], - self.dofs_0_N_i[0][1], - self.dofs_1_N_i[1][1], - self.subs[1], - self.subs_cum[1], - self.wts[1], - self.basis_int_N[0], - self.basis_his_N[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - EQ, - val, - row, - col, - ) - - F_11 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_2form[0] // self.D3, self.space.Ntot_0form // self.N3), - ) - F_11.eliminate_zeros() - # ------------------------------------------------------------ - - # ------------- 22 - block ([his, int] of NN) ---------------- - # evaluate equilibrium density/pressure at interpolation and quadrature points - if which == "m": - EQ = self.equilibrium.n3(self.eta_his[0].flatten(), self.eta_int[1], 0.0) - elif which == "p": - EQ = self.equilibrium.p3(self.eta_his[0].flatten(), self.eta_int[1], 0.0) - else: - EQ = self.equilibrium.domain.jacobian_det(self.eta_his[0].flatten(), self.eta_int[1], 0.0) - - EQ = EQ.reshape(self.nhis[0], self.nq[0], self.nint[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - - ker.rhs11_2d( - self.dofs_1_N_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_1_N_i[0][1], - self.dofs_0_N_i[1][1], - self.subs[0], - self.subs_cum[0], - self.wts[0], - self.basis_his_N[0], - self.basis_int_N[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - EQ, - val, - row, - col, - ) - - F_22 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_2form[1] // self.D3, self.space.Ntot_0form // self.N3), - ) - F_22.eliminate_zeros() - # ------------------------------------------------------------ - - # ------------- 33 - block ([his, his] of NN) ---------------- - # evaluate equilibrium density/pressure at interpolation and quadrature points - if which == "m": - EQ = self.equilibrium.n3(self.eta_his[0].flatten(), self.eta_his[1].flatten(), 0.0) - elif which == "p": - EQ = self.equilibrium.p3(self.eta_his[0].flatten(), self.eta_his[1].flatten(), 0.0) - else: - EQ = self.equilibrium.domain.jacobian_det(self.eta_his[0].flatten(), self.eta_his[1].flatten(), 0.0) - - EQ = EQ.reshape(self.nhis[0], self.nq[0], self.nhis[1], self.nq[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_1_N_i[0][0].size * self.dofs_1_N_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_1_N_i[0][0].size * self.dofs_1_N_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_1_N_i[0][0].size * self.dofs_1_N_i[1][0].size, dtype=int) - - ker.rhs2_2d( - self.dofs_1_N_i[0][0], - self.dofs_1_N_i[1][0], - self.dofs_1_N_i[0][1], - self.dofs_1_N_i[1][1], - self.subs[0], - self.subs[1], - self.subs_cum[0], - self.subs_cum[1], - self.wts[0], - self.wts[1], - self.basis_his_N[0], - self.basis_his_N[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - EQ, - val, - row, - col, - ) - - F_33 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_2form[2] // self.N3, self.space.Ntot_0form // self.N3), - ) - F_33.eliminate_zeros() - # ------------------------------------------------------------ - - else: - # -------- 11 - block ([int, his, his] of NNN) --------------- - # evaluate equilibrium density/pressure at interpolation and quadrature points - if which == "m": - EQ = self.equilibrium.n3(self.eta_int[0], self.eta_his[1].flatten(), self.eta_his[2].flatten()) - elif which == "p": - EQ = self.equilibrium.p3(self.eta_int[0], self.eta_his[1].flatten(), self.eta_his[2].flatten()) - else: - EQ = self.equilibrium.domain.jacobian_det( - self.eta_int[0], - self.eta_his[1].flatten(), - self.eta_his[2].flatten(), - ) - - EQ = EQ.reshape(self.nint[0], self.nhis[1], self.nq[1], self.nhis[2], self.nq[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size * self.dofs_1_N_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size * self.dofs_1_N_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_N_i[1][0].size * self.dofs_1_N_i[2][0].size, - dtype=int, - ) - - ker.rhs21( - self.dofs_0_N_i[0][0], - self.dofs_1_N_i[1][0], - self.dofs_1_N_i[2][0], - self.dofs_0_N_i[0][1], - self.dofs_1_N_i[1][1], - self.dofs_1_N_i[2][1], - self.subs[1], - self.subs[2], - self.subs_cum[1], - self.subs_cum[2], - self.wts[1], - self.wts[2], - self.basis_int_N[0], - self.basis_his_N[1], - self.basis_his_N[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - EQ, - val, - row, - col, - ) - - F_11 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_2form[0], self.space.Ntot_0form)) - F_11.eliminate_zeros() - # ------------------------------------------------------------ - - # -------- 22 - block ([his, int, his] of NNN) --------------- - # evaluate equilibrium density/pressure at interpolation and quadrature points - if which == "m": - EQ = self.equilibrium.n3(self.eta_his[0].flatten(), self.eta_int[1], self.eta_his[2].flatten()) - elif which == "p": - EQ = self.equilibrium.p3(self.eta_his[0].flatten(), self.eta_int[1], self.eta_his[2].flatten()) - else: - EQ = self.equilibrium.domain.jacobian_det( - self.eta_his[0].flatten(), - self.eta_int[1], - self.eta_his[2].flatten(), - ) - - EQ = EQ.reshape(self.nhis[0], self.nq[0], self.nint[1], self.nhis[2], self.nq[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_N_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_N_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_1_N_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_N_i[2][0].size, - dtype=int, - ) - - ker.rhs22( - self.dofs_1_N_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_1_N_i[2][0], - self.dofs_1_N_i[0][1], - self.dofs_0_N_i[1][1], - self.dofs_1_N_i[2][1], - self.subs[0], - self.subs[2], - self.subs_cum[0], - self.subs_cum[2], - self.wts[0], - self.wts[2], - self.basis_his_N[0], - self.basis_int_N[1], - self.basis_his_N[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - EQ, - val, - row, - col, - ) - - F_22 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_2form[1], self.space.Ntot_0form)) - F_22.eliminate_zeros() - # ------------------------------------------------------------ - - # -------- 33 - block ([his, his, int] of NNN) --------------- - # evaluate equilibrium density/pressure at interpolation and quadrature points - if which == "m": - EQ = self.equilibrium.n3(self.eta_his[0].flatten(), self.eta_his[1].flatten(), self.eta_int[2]) - elif which == "p": - EQ = self.equilibrium.p3(self.eta_his[0].flatten(), self.eta_his[1].flatten(), self.eta_int[2]) - else: - EQ = self.equilibrium.domain.jacobian_det( - self.eta_his[0].flatten(), - self.eta_his[1].flatten(), - self.eta_int[2], - ) - - EQ = EQ.reshape(self.nhis[0], self.nq[0], self.nhis[1], self.nq[1], self.nint[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_1_N_i[0][0].size * self.dofs_1_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_1_N_i[0][0].size * self.dofs_1_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_1_N_i[0][0].size * self.dofs_1_N_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - - ker.rhs23( - self.dofs_1_N_i[0][0], - self.dofs_1_N_i[1][0], - self.dofs_0_N_i[2][0], - self.dofs_1_N_i[0][1], - self.dofs_1_N_i[1][1], - self.dofs_0_N_i[2][1], - self.subs[0], - self.subs[1], - self.subs_cum[0], - self.subs_cum[1], - self.wts[0], - self.wts[1], - self.basis_his_N[0], - self.basis_his_N[1], - self.basis_int_N[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - EQ, - val, - row, - col, - ) - - F_33 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_2form[2], self.space.Ntot_0form)) - F_33.eliminate_zeros() - # ------------------------------------------------------------ - - elif self.basis_u == 2: - if pol or self.space.dim == 2: - # ------------- 11 - block ([int, his] of ND) --------------- - # evaluate equilibrium density/pressure at interpolation and quadrature points - if which == "m": - EQ = self.equilibrium.n3(self.eta_int[0], self.eta_his[1].flatten(), 0.0) - else: - EQ = self.equilibrium.p3(self.eta_int[0], self.eta_his[1].flatten(), 0.0) - - EQ = EQ.reshape(self.nint[0], self.nhis[1], self.nq[1]) - - # evaluate Jacobian determinant at interpolation and quadrature points - det_dF = abs(self.equilibrium.domain.jacobian_det(self.eta_int[0], self.eta_his[1].flatten(), 0.0)) - det_dF = det_dF.reshape(self.nint[0], self.nhis[1], self.nq[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_0_N_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=int) - - ker.rhs12_2d( - self.dofs_0_N_i[0][0], - self.dofs_1_D_i[1][0], - self.dofs_0_N_i[0][1], - self.dofs_1_D_i[1][1], - self.subs[1], - self.subs_cum[1], - self.wts[1], - self.basis_int_N[0], - self.basis_his_D[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - EQ / det_dF, - val, - row, - col, - ) - - F_11 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_2form[0] // self.D3, self.space.Ntot_2form[0] // self.D3), - ) - F_11.eliminate_zeros() - # ------------------------------------------------------------ - - # ------------- 22 - block ([his, int] of DN) ---------------- - # evaluate equilibrium density/pressure at interpolation and quadrature points - if which == "m": - EQ = self.equilibrium.n3(self.eta_his[0].flatten(), self.eta_int[1], 0.0) - else: - EQ = self.equilibrium.p3(self.eta_his[0].flatten(), self.eta_int[1], 0.0) - - EQ = EQ.reshape(self.nhis[0], self.nq[0], self.nint[1]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs(self.equilibrium.domain.jacobian_det(self.eta_his[0].flatten(), self.eta_int[1], 0.0)) - det_dF = det_dF.reshape(self.nhis[0], self.nq[0], self.nint[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_0_N_i[1][0].size, dtype=int) - - ker.rhs11_2d( - self.dofs_1_D_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_1_D_i[0][1], - self.dofs_0_N_i[1][1], - self.subs[0], - self.subs_cum[0], - self.wts[0], - self.basis_his_D[0], - self.basis_int_N[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - EQ / det_dF, - val, - row, - col, - ) - - F_22 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_2form[1] // self.D3, self.space.Ntot_2form[1] // self.D3), - ) - F_22.eliminate_zeros() - # ------------------------------------------------------------ - - # ------------- 33 - block ([his, his] of DD) ---------------- - # evaluate equilibrium density/pressure at interpolation and quadrature points - if which == "m": - EQ = self.equilibrium.n3(self.eta_his[0].flatten(), self.eta_his[1].flatten(), 0.0) - else: - EQ = self.equilibrium.p3(self.eta_his[0].flatten(), self.eta_his[1].flatten(), 0.0) - - EQ = EQ.reshape(self.nhis[0], self.nq[0], self.nhis[1], self.nq[1]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs( - self.equilibrium.domain.jacobian_det(self.eta_his[0].flatten(), self.eta_his[1].flatten(), 0.0), - ) - det_dF = det_dF.reshape(self.nhis[0], self.nq[0], self.nhis[1], self.nq[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=int) - - ker.rhs2_2d( - self.dofs_1_D_i[0][0], - self.dofs_1_D_i[1][0], - self.dofs_1_D_i[0][1], - self.dofs_1_D_i[1][1], - self.subs[0], - self.subs[1], - self.subs_cum[0], - self.subs_cum[1], - self.wts[0], - self.wts[1], - self.basis_his_D[0], - self.basis_his_D[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - EQ / det_dF, - val, - row, - col, - ) - - F_33 = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_2form[2] // self.N3, self.space.Ntot_2form[2] // self.N3), - ) - F_33.eliminate_zeros() - # ------------------------------------------------------------ - - else: - # -------- 11 - block ([int, his, his] of NDD) --------------- - # evaluate equilibrium density/pressure at interpolation and quadrature points - if which == "m": - EQ = self.equilibrium.n3(self.eta_int[0], self.eta_his[1].flatten(), self.eta_his[2].flatten()) - else: - EQ = self.equilibrium.p3(self.eta_int[0], self.eta_his[1].flatten(), self.eta_his[2].flatten()) - - EQ = EQ.reshape(self.nint[0], self.nhis[1], self.nq[1], self.nhis[2], self.nq[2]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs( - self.equilibrium.domain.jacobian_det( - self.eta_int[0], - self.eta_his[1].flatten(), - self.eta_his[2].flatten(), - ), - ) - det_dF = det_dF.reshape(self.nint[0], self.nhis[1], self.nq[1], self.nhis[2], self.nq[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_0_N_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=int, - ) - - ker.rhs21( - self.dofs_0_N_i[0][0], - self.dofs_1_D_i[1][0], - self.dofs_1_D_i[2][0], - self.dofs_0_N_i[0][1], - self.dofs_1_D_i[1][1], - self.dofs_1_D_i[2][1], - self.subs[1], - self.subs[2], - self.subs_cum[1], - self.subs_cum[2], - self.wts[1], - self.wts[2], - self.basis_int_N[0], - self.basis_his_D[1], - self.basis_his_D[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - EQ / det_dF, - val, - row, - col, - ) - - F_11 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_2form[0], self.space.Ntot_2form[0])) - F_11.eliminate_zeros() - # ------------------------------------------------------------ - - # -------- 22 - block ([his, int, his] of DND) --------------- - # evaluate equilibrium density/pressure at interpolation and quadrature points - if which == "m": - EQ = self.equilibrium.n3(self.eta_his[0].flatten(), self.eta_int[1], self.eta_his[2].flatten()) - else: - EQ = self.equilibrium.p3(self.eta_his[0].flatten(), self.eta_int[1], self.eta_his[2].flatten()) - - EQ = EQ.reshape(self.nhis[0], self.nq[0], self.nint[1], self.nhis[2], self.nq[2]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs( - self.equilibrium.domain.jacobian_det( - self.eta_his[0].flatten(), - self.eta_int[1], - self.eta_his[2].flatten(), - ), - ) - det_dF = det_dF.reshape(self.nhis[0], self.nq[0], self.nint[1], self.nhis[2], self.nq[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_0_N_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=int, - ) - - ker.rhs22( - self.dofs_1_D_i[0][0], - self.dofs_0_N_i[1][0], - self.dofs_1_D_i[2][0], - self.dofs_1_D_i[0][1], - self.dofs_0_N_i[1][1], - self.dofs_1_D_i[2][1], - self.subs[0], - self.subs[2], - self.subs_cum[0], - self.subs_cum[2], - self.wts[0], - self.wts[2], - self.basis_his_D[0], - self.basis_int_N[1], - self.basis_his_D[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - EQ / det_dF, - val, - row, - col, - ) - - F_22 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_2form[1], self.space.Ntot_2form[1])) - F_22.eliminate_zeros() - # ------------------------------------------------------------ - - # -------- 33 - block ([his, his, int] of DDN) --------------- - # evaluate equilibrium density/pressure at interpolation and quadrature points - if which == "m": - EQ = self.equilibrium.n3(self.eta_his[0].flatten(), self.eta_his[1].flatten(), self.eta_int[2]) - else: - EQ = self.equilibrium.p3(self.eta_his[0].flatten(), self.eta_his[1].flatten(), self.eta_int[2]) - - EQ = EQ.reshape(self.nhis[0], self.nq[0], self.nhis[1], self.nq[1], self.nint[2]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs( - self.equilibrium.domain.jacobian_det( - self.eta_his[0].flatten(), - self.eta_his[1].flatten(), - self.eta_int[2], - ), - ) - det_dF = det_dF.reshape(self.nhis[0], self.nq[0], self.nhis[1], self.nq[1], self.nint[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_0_N_i[2][0].size, - dtype=int, - ) - - ker.rhs23( - self.dofs_1_D_i[0][0], - self.dofs_1_D_i[1][0], - self.dofs_0_N_i[2][0], - self.dofs_1_D_i[0][1], - self.dofs_1_D_i[1][1], - self.dofs_0_N_i[2][1], - self.subs[0], - self.subs[1], - self.subs_cum[0], - self.subs_cum[1], - self.wts[0], - self.wts[1], - self.basis_his_D[0], - self.basis_his_D[1], - self.basis_int_N[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - EQ / det_dF, - val, - row, - col, - ) - - F_33 = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_2form[2], self.space.Ntot_2form[2])) - F_33.eliminate_zeros() - # ------------------------------------------------------------ - - return F_11, F_22, F_33 - - # ================================================================= - def get_blocks_PR(self, pol=True): - """ - Returns the degree of freedom (DOF) matrix - - PR_(ijk lmn) = dofs^3_(ijk)( p^3_eq * Lambda^3_(lmn) / sqrt(g) ). - - Parameters - ---------- - pol : boolean - wheather to assemble the matrices in the form (poloidal x toroidal) (True). - - Returns - ------- - PR : scipy.sparse.csr_matrix - the DOF matrix. - """ - - if pol or self.space.dim == 2: - # ------------ ([his, his] of DD) -------------------- - # evaluate equilibrium pressure at quadrature points - P3_pts = self.equilibrium.p3(self.eta_his[0].flatten(), self.eta_his[1].flatten(), 0.0) - P3_pts = P3_pts.reshape(self.nhis[0], self.nq[0], self.nhis[1], self.nq[1]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs( - self.equilibrium.domain.jacobian_det(self.eta_his[0].flatten(), self.eta_his[1].flatten(), 0.0), - ) - det_dF = det_dF.reshape(self.nhis[0], self.nq[0], self.nhis[1], self.nq[1]) - - # assemble sparse matrix - val = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=float) - row = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=int) - col = xp.empty(self.dofs_1_D_i[0][0].size * self.dofs_1_D_i[1][0].size, dtype=int) - - ker.rhs2_2d( - self.dofs_1_D_i[0][0], - self.dofs_1_D_i[1][0], - self.dofs_1_D_i[0][1], - self.dofs_1_D_i[1][1], - self.subs[0], - self.subs[1], - self.subs_cum[0], - self.subs_cum[1], - self.wts[0], - self.wts[1], - self.basis_his_D[0], - self.basis_his_D[1], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - P3_pts / det_dF, - val, - row, - col, - ) - - PR = spa.csr_matrix( - (val, (row, col)), - shape=(self.space.Ntot_3form // self.D3, self.space.Ntot_3form // self.D3), - ) - PR.eliminate_zeros() - # ----------------------------------------------------- - - else: - # --------------- ([his, his, his] of DDD) ------------ - # evaluate equilibrium pressure at quadrature points - P3_pts = self.equilibrium.p3( - self.eta_his[0].flatten(), - self.eta_his[1].flatten(), - self.eta_his[2].flatten(), - ) - - P3_pts = P3_pts.reshape(self.nhis[0], self.nq[0], self.nhis[1], self.nq[1], self.nhis[2], self.nq[2]) - - # evaluate Jacobian determinant at at interpolation and quadrature points - det_dF = abs( - self.equilibrium.domain.jacobian_det( - self.eta_his[0].flatten(), - self.eta_his[1].flatten(), - self.eta_his[2].flatten(), - ), - ) - det_dF = det_dF.reshape(self.nhis[0], self.nq[0], self.nhis[1], self.nq[1], self.nhis[2], self.nq[2]) - - # assemble sparse matrix - val = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=float, - ) - row = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=int, - ) - col = xp.empty( - self.dofs_1_D_i[0][0].size * self.dofs_1_D_i[1][0].size * self.dofs_1_D_i[2][0].size, - dtype=int, - ) - - ker.rhs3( - self.dofs_1_D_i[0][0], - self.dofs_1_D_i[1][0], - self.dofs_1_D_i[2][0], - self.dofs_1_D_i[0][1], - self.dofs_1_D_i[1][1], - self.dofs_1_D_i[2][1], - self.subs[0], - self.subs[1], - self.subs[2], - self.subs_cum[0], - self.subs_cum[1], - self.subs_cum[2], - self.wts[0], - self.wts[1], - self.wts[2], - self.basis_his_D[0], - self.basis_his_D[1], - self.basis_his_D[2], - xp.array(self.space.NbaseN), - xp.array(self.space.NbaseD), - P3_pts / det_dF, - val, - row, - col, - ) - - PR = spa.csr_matrix((val, (row, col)), shape=(self.space.Ntot_3form, self.space.Ntot_3form)) - PR.eliminate_zeros() - # ---------------------------------------------------- - - return PR - - # ==================================================================== - def get_blocks_Mn(self, pol=True): - """ - Returns the weighted mass matrix - - basis_u = 0 : Mn_(ab, ijk lmn) = integral( Lambda^0_(a,ijk) * G_ab * Lambda^0_(b,lmn) * n^0_eq * sqrt(g) ), - basis_u = 2 : Mn_(ab, ijk lmn) = integral( Lambda^2_(a,ijk) * G_ab * Lambda^2_(b,lmn) * n^0_eq / sqrt(g) ). - - Parameters - ---------- - pol : boolean - wheather to assemble the matrices in the form (poloidal x toroidal) (True). - - Returns - ------- - Mn : scipy.sparse.csr_matrix - the weighted mass matrix. - """ - - weight11 = ( - lambda s, chi, phi: self.equilibrium.n0(s, chi, phi) * self.equilibrium.domain.metric(s, chi, phi)[0, 0] - ) - weight12 = ( - lambda s, chi, phi: self.equilibrium.n0(s, chi, phi) * self.equilibrium.domain.metric(s, chi, phi)[0, 1] - ) - weight13 = ( - lambda s, chi, phi: self.equilibrium.n0(s, chi, phi) * self.equilibrium.domain.metric(s, chi, phi)[0, 2] - ) - - weight21 = ( - lambda s, chi, phi: self.equilibrium.n0(s, chi, phi) * self.equilibrium.domain.metric(s, chi, phi)[1, 0] - ) - weight22 = ( - lambda s, chi, phi: self.equilibrium.n0(s, chi, phi) * self.equilibrium.domain.metric(s, chi, phi)[1, 1] - ) - weight23 = ( - lambda s, chi, phi: self.equilibrium.n0(s, chi, phi) * self.equilibrium.domain.metric(s, chi, phi)[1, 2] - ) - - weight31 = ( - lambda s, chi, phi: self.equilibrium.n0(s, chi, phi) * self.equilibrium.domain.metric(s, chi, phi)[2, 0] - ) - weight32 = ( - lambda s, chi, phi: self.equilibrium.n0(s, chi, phi) * self.equilibrium.domain.metric(s, chi, phi)[2, 1] - ) - weight33 = ( - lambda s, chi, phi: self.equilibrium.n0(s, chi, phi) * self.equilibrium.domain.metric(s, chi, phi)[2, 2] - ) - - self.weights_Mn = [ - [weight11, weight12, weight13], - [weight21, weight22, weight23], - [weight31, weight32, weight33], - ] - - # ----------- 0-form ---------------------- - if self.basis_u == 0: - if pol or self.space.dim == 2: - Mn = mass_2d.get_Mv(self.space, self.equilibrium.domain, True, self.weights_Mn) - else: - Mn = mass_3d.get_Mv(self.space, self.equilibrium.domain, True, self.weights_Mn) - # ----------------------------------------- - - # ----------- 2-form ---------------------- - elif self.basis_u == 2: - if pol or self.space.dim == 2: - Mn = mass_2d.get_M2(self.space, self.equilibrium.domain, True, self.weights_Mn) - else: - Mn = mass_3d.get_M2(self.space, self.equilibrium.domain, True, self.weights_Mn) - # ----------------------------------------- - - return Mn - - # ================================================================= - def get_blocks_MJ(self, pol=True): - """ - Returns the weighted mass matrix - - basis_u = 0 : not implemented yet --> MJ = 0, - basis_u = 2 : MJ_(ab, ijk lmn) = integral( Lambda^2_(a,ijk) * G_ab * Lambda^2_(b,lmn) * epsilon_(acb) * J^2_c_eq / sqrt(g) ). - - Parameters - ---------- - pol : boolean - wheather to assemble the matrices in the form (poloidal x toroidal) (True). - - Returns - ------- - MJ : scipy.sparse.csr_matrix - the weighted mass matrix. - """ - - weight11 = lambda s, chi, phi: 0 * self.equilibrium.j2_1(s, chi, phi) - weight12 = lambda s, chi, phi: -self.equilibrium.j2_3(s, chi, phi) - weight13 = lambda s, chi, phi: self.equilibrium.j2_2(s, chi, phi) - - weight21 = lambda s, chi, phi: self.equilibrium.j2_3(s, chi, phi) - weight22 = lambda s, chi, phi: 0 * self.equilibrium.j2_2(s, chi, phi) - weight23 = lambda s, chi, phi: -self.equilibrium.j2_1(s, chi, phi) - - weight31 = lambda s, chi, phi: -self.equilibrium.j2_2(s, chi, phi) - weight32 = lambda s, chi, phi: self.equilibrium.j2_1(s, chi, phi) - weight33 = lambda s, chi, phi: 0 * self.equilibrium.j2_3(s, chi, phi) - - self.weights_MJ = [ - [weight11, weight12, weight13], - [weight21, weight22, weight23], - [weight31, weight32, weight33], - ] - - # ----------- 0-form ---------------------- - if self.basis_u == 0: - if pol or self.space.dim == 2: - MJ = mass_2d.get_M2(self.space, self.equilibrium.domain, True, self.weights_MJ) - else: - MJ = mass_3d.get_M2(self.space, self.equilibrium.domain, True, self.weights_MJ) - # ----------------------------------------- - - # ----------- 2-form ---------------------- - elif self.basis_u == 2: - if pol or self.space.dim == 2: - MJ = mass_2d.get_M2(self.space, self.equilibrium.domain, True, self.weights_MJ) - else: - MJ = mass_3d.get_M2(self.space, self.equilibrium.domain, True, self.weights_MJ) - # ----------------------------------------- - - return MJ diff --git a/src/struphy/eigenvalue_solvers/projectors_global.py b/src/struphy/eigenvalue_solvers/projectors_global.py deleted file mode 100644 index 9d246cdac..000000000 --- a/src/struphy/eigenvalue_solvers/projectors_global.py +++ /dev/null @@ -1,2215 +0,0 @@ -# coding: utf-8 -# -# Copyright 2021 Florian Holderied (florian.holderied@ipp.mpg.de) - -""" -Classes for commuting projectors in 1D, 2D and 3D based on global spline interpolation and histopolation. -""" - -import cunumpy as xp -import scipy.sparse as spa - -import struphy.bsplines.bsplines as bsp -from struphy.linear_algebra.linalg_kron import kron_lusolve_2d, kron_lusolve_3d, kron_matvec_2d, kron_matvec_3d - - -# ======================= 1d ==================================== -class Projectors_global_1d: - """ - Global commuting projectors pi_0 and pi_1 in 1d based on interpolation and histopolation. - - Parameters - ----------- - spline_space : Spline_space_1d - A 1d space of B-splines and corresponding D-splines. - - n_quad : int - Number of Gauss-Legendre quadrature points per integration interval for histopolation. - - Attributes - ----------- - n_quad : int - The input number of quadrature points per integration interval. - - pts_loc : 1d array - Gauss-Legendre quadrature points in (-1, 1). - - wts_loc : 1d array - Gauss-Legendre quadrature weights in (-1, 1). - - x_int : 1d array - Interpolation points in [0, 1] = Greville points of space. - - x_his : 1d array - Integration boundaries for histopolation (including breakpoints if there is one between two Greville points). - - subs : 1d array - Number of sub-integration intervals per histopolation interval to achieve exact integration of splines (1 or 2). - - subs_cum : list - Cumulative sum of subs, starting with 0. - - pts : 2d array (float) - Gauss-Legendre quadrature points in format (integration interval, local quadrature point) - - wts : 2d array (float) - Gauss-Legendre quadrature weights in format (integration interval, local quadrature weight) - - ptsG : 2d array (float) - Gauss-Legendre quadrature points in format (integration interval, local quadrature point), - ignoring subs (less accurate integration for even degree) - - wtsG : 2d array (float) - Gauss-Legendre quadrature weights in format (integration interval, local quadrature weight), - ignoring subs (less accurate integration for even degree) - - span_x_int_N : 2d float array - Knot span indices of B-splines at Greville points in format (greville, 0) - - span_x_int_D : 2d float array - Knot span indices of M-splines at Greville points in format (greville, 0) - - span_ptsG_N : 2d float array - Knot span indices of B-splines at quadrature points in format of ptsG. - - span_ptsG_D : 2d float array - Knot span indices of M-splines at quadrature points in format of ptsG. - - basis_x_int_N : 3d float array - Values of p + 1 non-zero B-spline basis functions at Greville points in format (greville, 0, basis function) - - basis_x_int_D : 3d float array - Values of p non-zero M-spline basis functions at Greville points in format (greville, 0, basis function) - - basis_ptsG_N : 3d float array - Values of p + 1 non-zero B-spline basis functions at ptsG in format (i, iq, basis function) - - basis_ptsG_D : 3d float array - Values of p non-zero M-spline basis functions at ptsG in format (i, iq, basis function) - - Q : sparse csr matrix - Quadrature matrix that performs quadrature integrations as matrix-vector product - - QG : sparse csr matrix - Quadrature matrix that performs quadrature integrations as matrix-vector product, - ignoring subs (less accurate integration for even degree) - - N_int : sparse csr matrix - Collocation matrix for B-splines at interpolation points - - D_int : sparse csr matrix - Collocation matrix for M-splines at interpolation points - - N_pts : sparse csr matrix - Collocation matrix for B-splines at quadrature points - - D_pts : sparse csr matrix - Collocation matrix for M-splines at quadrature points - - I : sparse csr matrix - Interpolation matrix N_j(x_i). - - ID : sparse csr matrix - Interpolation-like matrix D_j(x_i) - - I0 : sparse csr matrix - Interpolation matrix B0 * I * B0^T including boundary operators. - - H : sparse csr matrix - Histopolation matrix int_(x_i)^(x_i + 1) D_j dx. - - HN : sparse csr matrix - Histopolation-like matrix int_(x_i)^(x_i + 1) N_j dx. - - H0 : sparse csr matrix - Histopolation matrix B1 * H * B1^T including boundary operators. - - I_LU : Super LU - LU decompositions of I. - - H_LU : Super LU - LU decompositions of H. - - I0_LU : Super LU - LU decompositions of I0. - - H0_LU : Super LU - LU decompositions of H0. - - I_T_LU : Super LU - LU decompositions of transpose I. - - H_T_LU : Super LU - LU decompositions of transpose H. - - I0_T_LU : Super LU - LU decompositions of transpose I0. - - H0_T_LU : Super LU - LU decompositions of transpose H0. - """ - - def __init__(self, spline_space, n_quad=6): - self.space = spline_space - - # number of quadrature points per integration interval - self.n_quad = n_quad - - # Gauss - Legendre quadrature points and weights in (-1, 1) - self.pts_loc = xp.polynomial.legendre.leggauss(self.n_quad)[0] - self.wts_loc = xp.polynomial.legendre.leggauss(self.n_quad)[1] - - # set interpolation points (Greville points) - self.x_int = spline_space.greville.copy() - - # set number of sub-intervals per integration interval between Greville points and integration boundaries - self.subs = xp.ones(spline_space.NbaseD, dtype=int) - self.x_his = xp.array([self.x_int[0]]) - - for i in range(spline_space.NbaseD): - for br in spline_space.el_b: - # left and right integration boundaries - if not spline_space.spl_kind: - xl = self.x_int[i] - xr = self.x_int[i + 1] - else: - xl = self.x_int[i] - xr = self.x_int[(i + 1) % spline_space.NbaseD] - if i == spline_space.NbaseD - 1: - xr += spline_space.el_b[-1] - - # compute subs and x_his - if (br > xl + 1e-10) and (br < xr - 1e-10): - self.subs[i] += 1 - self.x_his = xp.append(self.x_his, br) - elif br >= xr - 1e-10: - self.x_his = xp.append(self.x_his, xr) - break - - if spline_space.spl_kind and spline_space.p % 2 == 0: - self.x_his = xp.append(self.x_his, spline_space.el_b[-1] + self.x_his[0]) - - # cumulative number of sub-intervals for conversion local interval --> global interval - self.subs_cum = xp.append(0, xp.cumsum(self.subs - 1)[:-1]) - - # quadrature points and weights - self.pts, self.wts = bsp.quadrature_grid(self.x_his, self.pts_loc, self.wts_loc) - self.pts = self.pts % spline_space.el_b[-1] - - # quadrature points and weights, ignoring subs (less accurate integration for even degree) - self.x_hisG = self.x_int - if spline_space.spl_kind: - if spline_space.p % 2 == 0: - self.x_hisG = xp.append(self.x_hisG, spline_space.el_b[-1] + self.x_hisG[0]) - else: - self.x_hisG = xp.append(self.x_hisG, spline_space.el_b[-1]) - - self.ptsG, self.wtsG = bsp.quadrature_grid(self.x_hisG, self.pts_loc, self.wts_loc) - self.ptsG = self.ptsG % spline_space.el_b[-1] - - # Knot span indices at interpolation points in format (greville, 0) - self.span_x_int_N = xp.zeros(self.x_int[:, None].shape, dtype=int) - self.span_x_int_D = xp.zeros(self.x_int[:, None].shape, dtype=int) - for i in range(self.x_int.shape[0]): - self.span_x_int_N[i, 0] = bsp.find_span(self.space.T, self.space.p, self.x_int[i]) - self.span_x_int_D[i, 0] = bsp.find_span(self.space.t, self.space.p - 1, self.x_int[i]) - - # Knot span indices at quadrature points between x_int in format (i, iq) - self.span_ptsG_N = xp.zeros(self.ptsG.shape, dtype=int) - self.span_ptsG_D = xp.zeros(self.ptsG.shape, dtype=int) - for i in range(self.ptsG.shape[0]): - for iq in range(self.ptsG.shape[1]): - self.span_ptsG_N[i, iq] = bsp.find_span(self.space.T, self.space.p, self.ptsG[i, iq]) - self.span_ptsG_D[i, iq] = bsp.find_span(self.space.t, self.space.p - 1, self.ptsG[i, iq]) - - # Values of p + 1 non-zero basis functions at Greville points in format (greville, 0, basis function) - self.basis_x_int_N = xp.zeros((*self.x_int[:, None].shape, self.space.p + 1), dtype=float) - self.basis_x_int_D = xp.zeros((*self.x_int[:, None].shape, self.space.p), dtype=float) - - N_temp = bsp.basis_ders_on_quad_grid(self.space.T, self.space.p, self.x_int[:, None], 0, normalize=False) - D_temp = bsp.basis_ders_on_quad_grid(self.space.t, self.space.p - 1, self.x_int[:, None], 0, normalize=True) - - for i in range(self.x_int.shape[0]): - for b in range(self.space.p + 1): - self.basis_x_int_N[i, 0, b] = N_temp[i, b, 0, 0] - for b in range(self.space.p): - self.basis_x_int_D[i, 0, b] = D_temp[i, b, 0, 0] - - # Values of p + 1 non-zero basis functions at quadrature points points between x_int in format (i, iq, basis function) - self.basis_ptsG_N = xp.zeros((*self.ptsG.shape, self.space.p + 1), dtype=float) - self.basis_ptsG_D = xp.zeros((*self.ptsG.shape, self.space.p), dtype=float) - - N_temp = bsp.basis_ders_on_quad_grid(self.space.T, self.space.p, self.ptsG, 0, normalize=False) - D_temp = bsp.basis_ders_on_quad_grid(self.space.t, self.space.p - 1, self.ptsG, 0, normalize=True) - - for i in range(self.ptsG.shape[0]): - for iq in range(self.ptsG.shape[1]): - for b in range(self.space.p + 1): - self.basis_ptsG_N[i, iq, b] = N_temp[i, b, 0, iq] - for b in range(self.space.p): - self.basis_ptsG_D[i, iq, b] = D_temp[i, b, 0, iq] - - # quadrature matrix for performing integrations as matrix-vector products - self.Q = xp.zeros((spline_space.NbaseD, self.wts.shape[0] * self.n_quad), dtype=float) - - for i in range(spline_space.NbaseD): - for j in range(self.subs[i]): - ie = i + j + self.subs_cum[i] - self.Q[i, self.n_quad * ie : self.n_quad * (ie + 1)] = self.wts[ie] - - self.Q = spa.csr_matrix(self.Q) - - # quadrature matrix for performing integrations as matrix-vector products, ignoring subs (less accurate integration for even degree) - self.QG = xp.zeros((spline_space.NbaseD, self.wtsG.shape[0] * self.n_quad), dtype=float) - - for i in range(spline_space.NbaseD): - self.QG[i, self.n_quad * i : self.n_quad * (i + 1)] = self.wtsG[i] - - self.QG = spa.csr_matrix(self.QG) - - # collocation matrices for B-/M-splines at interpolation/quadrature points - BM_splines = [False, True] - - self.N_int = bsp.collocation_matrix( - spline_space.T, - spline_space.p - 0, - self.x_int, - spline_space.spl_kind, - BM_splines[0], - ) - self.D_int = bsp.collocation_matrix( - spline_space.t, - spline_space.p - 1, - self.x_int, - spline_space.spl_kind, - BM_splines[1], - ) - - self.N_int[self.N_int < 1e-12] = 0.0 - self.D_int[self.D_int < 1e-12] = 0.0 - - self.N_int = spa.csr_matrix(self.N_int) - self.D_int = spa.csr_matrix(self.D_int) - - self.N_pts = bsp.collocation_matrix( - spline_space.T, - spline_space.p - 0, - self.pts.flatten(), - spline_space.spl_kind, - BM_splines[0], - ) - self.D_pts = bsp.collocation_matrix( - spline_space.t, - spline_space.p - 1, - self.pts.flatten(), - spline_space.spl_kind, - BM_splines[1], - ) - - self.N_pts = spa.csr_matrix(self.N_pts) - self.D_pts = spa.csr_matrix(self.D_pts) - - # interpolation matrices - self.I = self.N_int.copy() - self.ID = self.D_int.copy() - self.I0 = self.space.B0.dot(self.I.dot(self.space.B0.T)).tocsr() - - # histopolation matrices - self.H = self.Q.dot(self.D_pts) - self.HN = self.Q.dot(self.N_pts) - self.H0 = self.space.B1.dot(self.H.dot(self.space.B1.T)).tocsr() - - # LU decompositions - self.I_LU = spa.linalg.splu(self.I.tocsc()) - self.H_LU = spa.linalg.splu(self.H.tocsc()) - - self.I0_LU = spa.linalg.splu(self.I0.tocsc()) - self.H0_LU = spa.linalg.splu(self.H0.tocsc()) - - self.I_T_LU = spa.linalg.splu(self.I.T.tocsc()) - self.H_T_LU = spa.linalg.splu(self.H.T.tocsc()) - - self.I0_T_LU = spa.linalg.splu(self.I0.T.tocsc()) - self.H0_T_LU = spa.linalg.splu(self.H0.T.tocsc()) - - # degrees of freedoms: V_0 --> R^n - - def dofs_0(self, fun): - """ - Returns the degrees of freedom for functions in V_0: dofs_0[i] = fun(x_i). - """ - - dofs = fun(self.x_int) - - return dofs - - # degrees of freedom: V_1 --> R^n - def dofs_1(self, fun, with_subs=True): - """ - Returns the degrees of freedom for functions in V_1: dofs_1[i] = int_(eta_i)^(eta_i + 1) fun(eta) deta. - """ - - if with_subs: - dofs = self.Q.dot(fun(self.pts.flatten())) - else: - dofs = self.QG.dot(fun(self.ptsG.flatten())) - - return dofs - - # projector pi_0: V_0 --> R^n (callable in V_0 as input) - def pi_0(self, fun): - """ - Returns the solution of the interpolation problem I.coeffs = dofs_0 (spline coefficients). - """ - - coeffs = self.I_LU.solve(self.dofs_0(fun)) - - return coeffs - - # projector pi_1: V_1 --> R^n (callable in V_1 as input) - def pi_1(self, fun, with_subs=True): - """ - Returns the solution of the interpolation problem H.coeffs = dofs_1 (spline coefficients). - """ - - coeffs = self.H_LU.solve(self.dofs_1(fun, with_subs)) - - return coeffs - - # projector pi_0: R^n --> R^n (dofs_0 as input) - def pi_0_mat(self, dofs_0): - """ - Returns the solution of the interpolation problem I.coeffs = dofs_0 (spline coefficients). - """ - - coeffs = self.I_LU.solve(dofs_0) - - return coeffs - - # projector pi_1: R^n --> R^n (dofs_1 as input) - def pi_1_mat(self, dofs_1): - """ - Returns the solution of the interpolation problem H.coeffs = dofs_1 (spline coefficients). - """ - - coeffs = self.H_LU.solve(dofs_1) - - return coeffs - - # degrees of freedom of products of basis functions - - def dofs_1d_bases_products(self, space): - """ - DISCLAIMER: this routine is not finished and should not be used. - - Computes indices of non-vanishing degrees of freedom of products of basis functions: - - dofs_0_i(N_j*N_k), - dofs_0_i(D_j*N_k), - dofs_0_i(N_j*D_k), - dofs_0_i(D_j*D_k), - - dofs_1_i(N_j*N_k), - dofs_1_i(D_j*N_k), - dofs_1_i(N_j*D_k), - dofs_1_i(D_j*D_k). - """ - - dofs_0_NN = xp.empty((space.NbaseN, space.NbaseN, space.NbaseN), dtype=float) - dofs_0_DN = xp.empty((space.NbaseN, space.NbaseD, space.NbaseN), dtype=float) - dofs_0_DD = xp.empty((space.NbaseN, space.NbaseD, space.NbaseD), dtype=float) - - dofs_1_NN = xp.empty((space.NbaseD, space.NbaseN, space.NbaseN), dtype=float) - dofs_1_DN = xp.empty((space.NbaseD, space.NbaseD, space.NbaseN), dtype=float) - dofs_1_DD = xp.empty((space.NbaseD, space.NbaseD, space.NbaseD), dtype=float) - - # ========= dofs_0_NN and dofs_1_NN ============== - cj = xp.zeros(space.NbaseN, dtype=float) - ck = xp.zeros(space.NbaseN, dtype=float) - - for j in range(space.NbaseN): - for k in range(space.NbaseN): - cj[:] = 0.0 - ck[:] = 0.0 - - cj[j] = 1.0 - ck[k] = 1.0 - - def N_jN_k(eta): - return space.evaluate_N(eta, cj) * space.evaluate_N(eta, ck) - - dofs_0_NN[:, j, k] = self.dofs_0(N_jN_k) - dofs_1_NN[:, j, k] = self.dofs_1(N_jN_k) - - # ========= dofs_0_DN and dofs_1_DN ============== - cj = xp.zeros(space.NbaseD, dtype=float) - ck = xp.zeros(space.NbaseN, dtype=float) - - for j in range(space.NbaseD): - for k in range(space.NbaseN): - cj[:] = 0.0 - ck[:] = 0.0 - - cj[j] = 1.0 - ck[k] = 1.0 - - def D_jN_k(eta): - return space.evaluate_D(eta, cj) * space.evaluate_N(eta, ck) - - dofs_0_DN[:, j, k] = self.dofs_0(D_jN_k) - dofs_1_DN[:, j, k] = self.dofs_1(D_jN_k) - - # ========= dofs_0_DD and dofs_1_DD ============= - cj = xp.zeros(space.NbaseD, dtype=float) - ck = xp.zeros(space.NbaseD, dtype=float) - - for j in range(space.NbaseD): - for k in range(space.NbaseD): - cj[:] = 0.0 - ck[:] = 0.0 - - cj[j] = 1.0 - ck[k] = 1.0 - - def D_jD_k(eta): - return space.evaluate_D(eta, cj) * space.evaluate_D(eta, ck) - - dofs_0_DD[:, j, k] = self.dofs_0(D_jD_k) - dofs_1_DD[:, j, k] = self.dofs_1(D_jD_k) - - dofs_0_ND = xp.transpose(dofs_0_DN, (0, 2, 1)) - dofs_1_ND = xp.transpose(dofs_1_DN, (0, 2, 1)) - - # find non-zero entries - dofs_0_NN_indices = xp.nonzero(dofs_0_NN) - dofs_0_DN_indices = xp.nonzero(dofs_0_DN) - dofs_0_ND_indices = xp.nonzero(dofs_0_ND) - dofs_0_DD_indices = xp.nonzero(dofs_0_DD) - - dofs_1_NN_indices = xp.nonzero(dofs_1_NN) - dofs_1_DN_indices = xp.nonzero(dofs_1_DN) - dofs_1_ND_indices = xp.nonzero(dofs_1_ND) - dofs_1_DD_indices = xp.nonzero(dofs_1_DD) - - dofs_0_NN_i_red = xp.empty(dofs_0_NN_indices[0].size, dtype=int) - dofs_0_DN_i_red = xp.empty(dofs_0_DN_indices[0].size, dtype=int) - dofs_0_ND_i_red = xp.empty(dofs_0_ND_indices[0].size, dtype=int) - dofs_0_DD_i_red = xp.empty(dofs_0_DD_indices[0].size, dtype=int) - - dofs_1_NN_i_red = xp.empty(dofs_1_NN_indices[0].size, dtype=int) - dofs_1_DN_i_red = xp.empty(dofs_1_DN_indices[0].size, dtype=int) - dofs_1_ND_i_red = xp.empty(dofs_1_ND_indices[0].size, dtype=int) - dofs_1_DD_i_red = xp.empty(dofs_1_DD_indices[0].size, dtype=int) - - # ================================ - nv = space.NbaseN * dofs_0_NN_indices[1] + dofs_0_NN_indices[2] - un = xp.unique(nv) - - for i in range(dofs_0_NN_indices[0].size): - dofs_0_NN_i_red[i] = xp.nonzero(un == nv[i])[0] - - # ================================ - nv = space.NbaseN * dofs_0_DN_indices[1] + dofs_0_DN_indices[2] - un = xp.unique(nv) - - for i in range(dofs_0_DN_indices[0].size): - dofs_0_DN_i_red[i] = xp.nonzero(un == nv[i])[0] - - # ================================ - nv = space.NbaseD * dofs_0_ND_indices[1] + dofs_0_ND_indices[2] - un = xp.unique(nv) - - for i in range(dofs_0_ND_indices[0].size): - dofs_0_ND_i_red[i] = xp.nonzero(un == nv[i])[0] - - # ================================ - nv = space.NbaseD * dofs_0_DD_indices[1] + dofs_0_DD_indices[2] - un = xp.unique(nv) - - for i in range(dofs_0_DD_indices[0].size): - dofs_0_DD_i_red[i] = xp.nonzero(un == nv[i])[0] - - # ================================ - nv = space.NbaseN * dofs_1_NN_indices[1] + dofs_1_NN_indices[2] - un = xp.unique(nv) - - for i in range(dofs_1_NN_indices[0].size): - dofs_1_NN_i_red[i] = xp.nonzero(un == nv[i])[0] - - # ================================ - nv = space.NbaseN * dofs_1_DN_indices[1] + dofs_1_DN_indices[2] - un = xp.unique(nv) - - for i in range(dofs_1_DN_indices[0].size): - dofs_1_DN_i_red[i] = xp.nonzero(un == nv[i])[0] - - # ================================ - nv = space.NbaseD * dofs_1_ND_indices[1] + dofs_1_ND_indices[2] - un = xp.unique(nv) - - for i in range(dofs_1_ND_indices[0].size): - dofs_1_ND_i_red[i] = xp.nonzero(un == nv[i])[0] - - # ================================ - nv = space.NbaseD * dofs_1_DD_indices[1] + dofs_1_DD_indices[2] - un = xp.unique(nv) - - for i in range(dofs_1_DD_indices[0].size): - dofs_1_DD_i_red[i] = xp.nonzero(un == nv[i])[0] - - dofs_0_NN_indices = xp.vstack( - (dofs_0_NN_indices[0], dofs_0_NN_indices[1], dofs_0_NN_indices[2], dofs_0_NN_i_red), - ) - dofs_0_DN_indices = xp.vstack( - (dofs_0_DN_indices[0], dofs_0_DN_indices[1], dofs_0_DN_indices[2], dofs_0_DN_i_red), - ) - dofs_0_ND_indices = xp.vstack( - (dofs_0_ND_indices[0], dofs_0_ND_indices[1], dofs_0_ND_indices[2], dofs_0_ND_i_red), - ) - dofs_0_DD_indices = xp.vstack( - (dofs_0_DD_indices[0], dofs_0_DD_indices[1], dofs_0_DD_indices[2], dofs_0_DD_i_red), - ) - - dofs_1_NN_indices = xp.vstack( - (dofs_1_NN_indices[0], dofs_1_NN_indices[1], dofs_1_NN_indices[2], dofs_1_NN_i_red), - ) - dofs_1_DN_indices = xp.vstack( - (dofs_1_DN_indices[0], dofs_1_DN_indices[1], dofs_1_DN_indices[2], dofs_1_DN_i_red), - ) - dofs_1_ND_indices = xp.vstack( - (dofs_1_ND_indices[0], dofs_1_ND_indices[1], dofs_1_ND_indices[2], dofs_1_ND_i_red), - ) - dofs_1_DD_indices = xp.vstack( - (dofs_1_DD_indices[0], dofs_1_DD_indices[1], dofs_1_DD_indices[2], dofs_1_DD_i_red), - ) - - return ( - dofs_0_NN_indices, - dofs_0_DN_indices, - dofs_0_ND_indices, - dofs_0_DD_indices, - dofs_1_NN_indices, - dofs_1_DN_indices, - dofs_1_ND_indices, - dofs_1_DD_indices, - ) - - -# ============= 2d for pure tensor product splines ======================== -class Projectors_tensor_2d: - """ - Global commuting projectors pi_0, pi_1, pi_2 in 2d corresponding to the sequence grad = [d_1 f, d2_f] --> curl = [d_1 f_2 - d_2 f_1]. - - Parameters - ---------- - proj_1d : list of two "Projectors_global_1d" objects - - Attributes - ---------- - TODO - """ - - def __init__(self, proj_1d): - self.pts_PI = {"0": None, "11": None, "12": None, "2": None} - - # collection of the point sets for different 2D projectors - self.pts_PI["0"] = [proj_1d[0].x_int, proj_1d[1].x_int] - - self.pts_PI["11"] = [proj_1d[0].pts.flatten(), proj_1d[1].x_int] - - self.pts_PI["12"] = [proj_1d[0].x_int, proj_1d[1].pts.flatten()] - - self.pts_PI["2"] = [proj_1d[0].pts.flatten(), proj_1d[1].pts.flatten()] - - self.Q1 = proj_1d[0].Q - self.Q2 = proj_1d[1].Q - - self.n1 = proj_1d[0].I.shape[1] - self.n2 = proj_1d[1].I.shape[1] - - self.d1 = proj_1d[0].H.shape[1] - self.d2 = proj_1d[1].H.shape[1] - - self.I_LU1 = proj_1d[0].I_LU - self.I_LU2 = proj_1d[1].I_LU - - self.H_LU1 = proj_1d[0].H_LU - self.H_LU2 = proj_1d[1].H_LU - - # ====================================== - - def eval_for_PI(self, comp, fun): - """ - Evaluate the callable fun at the points corresponding to the projector comp. - - Parameters - ---------- - comp : string - Which projector: '0', '11', '12' or '2'. - - fun : callable - fun(eta1, eta2). - - Returns - ------- - fun(pts1, pts2) : 2d numpy array - Function evaluated at point set needed for the chosen projector. - """ - - pts_PI = self.pts_PI[comp] - - pts1, pts2 = xp.meshgrid(pts_PI[0], pts_PI[1], indexing="ij") - # pts1, pts2 = xp.meshgrid(pts_PI[0], pts_PI[1], indexing='ij', sparse=True) # numpy >1.7 - - return fun(pts1, pts2) - - # ====================================== - - def dofs(self, comp, mat_f): - """ - Compute the degrees of freedom for the projector comp. - - Parameters - ---------- - comp: string - Which projector: '0', '11', '12' or '2'. - - mat_f : 2d numpy array - Function values f(eta1_i, eta2_j) at the points set of the projector (from eval_for_PI). - - Returns - ------- - dofs : 2d numpy array - The degrees of freedom sigma_ij. - """ - - assert mat_f.shape == (self.pts_PI[comp][0].size, self.pts_PI[comp][1].size) - - if comp == "0": - dofs = kron_matvec_2d([spa.identity(mat_f.shape[0]), spa.identity(mat_f.shape[1])], mat_f) - - elif comp == "11": - dofs = kron_matvec_2d([self.Q1, spa.identity(mat_f.shape[1])], mat_f) - elif comp == "12": - dofs = kron_matvec_2d([spa.identity(mat_f.shape[0]), self.Q2], mat_f) - - elif comp == "2": - dofs = kron_matvec_2d([self.Q1, self.Q2], mat_f) - else: - raise ValueError("wrong projector specified") - - return dofs - - # ====================================== - - def PI_mat(self, comp, dofs): - """ - Kronecker solve of the projection problem I.coeffs = dofs. - - Parameters - ---------- - comp : string - Which projector: '0', '11', '12' or '2'. - - dofs : 2d numpy array - The degrees of freedom sigma_ij. - - Returns - ------- - coeffs : 2d numpy array - The spline coefficients c_ij obtained by projection. - """ - - if comp == "0": - assert dofs.shape == (self.n1, self.n2) - coeffs = kron_lusolve_2d([self.I_LU1, self.I_LU2], dofs) - elif comp == "11": - assert dofs.shape == (self.d1, self.n2) - coeffs = kron_lusolve_2d([self.H_LU1, self.I_LU2], dofs) - elif comp == "12": - assert dofs.shape == (self.n1, self.d2) - coeffs = kron_lusolve_2d([self.I_LU1, self.H_LU2], dofs) - elif comp == "2": - assert dofs.shape == (self.d1, self.d2) - coeffs = kron_lusolve_2d([self.H_LU1, self.H_LU2], dofs) - else: - raise ValueError("wrong projector specified") - - return coeffs - - # ====================================== - - def PI(self, comp, fun): - """ - De Rham commuting projectors. - - Parameters - ---------- - comp : string - Which projector: '0', '11', '12' or '2'. - - fun : callable - fun(eta1, eta2). - - Returns - ------- - coeffs : 2d numpy array - The spline coefficients c_ij obtained by projection. - """ - - mat_f = self.eval_for_PI(comp, fun) - dofs = self.dofs(comp, mat_f) - - if comp == "0": - assert dofs.shape == (self.n1, self.n2) - coeffs = kron_lusolve_2d([self.I_LU1, self.I_LU2], dofs) - elif comp == "11": - assert dofs.shape == (self.d1, self.n2) - coeffs = kron_lusolve_2d([self.H_LU1, self.I_LU2], dofs) - elif comp == "12": - assert dofs.shape == (self.n1, self.d2) - coeffs = kron_lusolve_2d([self.I_LU1, self.H_LU2], dofs) - elif comp == "2": - assert dofs.shape == (self.d1, self.d2) - coeffs = kron_lusolve_2d([self.H_LU1, self.H_LU2], dofs) - else: - raise ValueError("wrong projector specified") - - return coeffs - - # ====================================== - - def PI_0(self, fun): - """ - De Rham commuting projector Pi_0. - - Parameters - ---------- - fun : callable - Element in V_0 continuous space, fun(eta1, eta2). - - Returns - ------- - coeffs : 2d numpy array - The spline coefficients c_ij obtained by projection. - """ - - coeffs = self.PI("0", fun) - - return coeffs - - # ====================================== - - def PI_1(self, fun1, fun2): - """ - De Rham commuting projector Pi_1 acting on fun = (fun1, fun2) in V_1. - - Parameters - ---------- - fun1 : callable - First component of element in V_1 continuous space, fun1(eta1, eta2). - fun2 : callable - Second component of element in V_1 continuous space, fun2(eta1, eta2). - - Returns - ------- - coeffs1 : 2d numpy array - The spline coefficients c_ij obtained by projection of fun1 on DN. - coeffs2 : 2d numpy array - The spline coefficients c_ij obtained by projection of fun2 on ND. - """ - - coeffs1 = self.PI("11", fun1) - coeffs2 = self.PI("12", fun2) - - return coeffs1, coeffs2 - - # ====================================== - - def PI_2(self, fun): - """ - De Rham commuting projector Pi_2. - - Parameters - ---------- - fun : callable - Element in V_2 continuous space, fun(eta1, eta2). - - Returns - ------- - coeffs : 2d numpy array - The spline coefficients c_ij obtained by projection. - """ - - coeffs = self.PI("2", fun) - - return coeffs - - -# ============== 3d for pure tensor product splines ======================= -class Projectors_tensor_3d: - """ - Global commuting projectors pi_0, pi_1, pi_2, pi_3 in 3d corresponding to the sequence grad --> curl --> div. - - Parameters - ---------- - proj_1d : list of three "projectors_global_1d" objects - - Attributes - ---------- - TODO - """ - - def __init__(self, proj_1d): - self.pts_PI = {"0": None, "11": None, "12": None, "13": None, "21": None, "22": None, "23": None, "3": None} - - # collection of the point sets for different 2D projectors - self.pts_PI["0"] = [proj_1d[0].x_int, proj_1d[1].x_int, proj_1d[2].x_int] - - self.pts_PI["11"] = [proj_1d[0].pts.flatten(), proj_1d[1].x_int, proj_1d[2].x_int] - - self.pts_PI["12"] = [proj_1d[0].x_int, proj_1d[1].pts.flatten(), proj_1d[2].x_int] - - self.pts_PI["13"] = [proj_1d[0].x_int, proj_1d[1].x_int, proj_1d[2].pts.flatten()] - - self.pts_PI["21"] = [proj_1d[0].x_int, proj_1d[1].pts.flatten(), proj_1d[2].pts.flatten()] - - self.pts_PI["22"] = [proj_1d[0].pts.flatten(), proj_1d[1].x_int, proj_1d[2].pts.flatten()] - - self.pts_PI["23"] = [proj_1d[0].pts.flatten(), proj_1d[1].pts.flatten(), proj_1d[2].x_int] - - self.pts_PI["3"] = [proj_1d[0].pts.flatten(), proj_1d[1].pts.flatten(), proj_1d[2].pts.flatten()] - - self.Q1 = proj_1d[0].Q - self.Q2 = proj_1d[1].Q - self.Q3 = proj_1d[2].Q - - self.n1 = proj_1d[0].I.shape[1] - self.n2 = proj_1d[1].I.shape[1] - self.n3 = proj_1d[2].I.shape[1] - - self.d1 = proj_1d[0].H.shape[1] - self.d2 = proj_1d[1].H.shape[1] - self.d3 = proj_1d[2].H.shape[1] - - self.I_LU1 = proj_1d[0].I_LU - self.I_LU2 = proj_1d[1].I_LU - self.I_LU3 = proj_1d[2].I_LU - - self.H_LU1 = proj_1d[0].H_LU - self.H_LU2 = proj_1d[1].H_LU - self.H_LU3 = proj_1d[2].H_LU - - # ====================================== - - def eval_for_PI(self, comp, fun): - """ - Evaluate the callable fun at the points corresponding to the projector comp. - - Parameters - ---------- - comp: string - Which projector: '0', '11', '12', '13', '21', '22', '23' or '3'. - - fun : callable - fun(eta1, eta2, eta3) - - Returns - ------- - fun(pts1, pts2, pts3) : 3d numpy array - Function evaluated at point set needed for chosen projector. - """ - - pts_PI = self.pts_PI[comp] - - pts1, pts2, pts3 = xp.meshgrid(pts_PI[0], pts_PI[1], pts_PI[2], indexing="ij") - # pts1, pts2, pts3 = xp.meshgrid(pts_PI[0], pts_PI[1], pts_PI[2], indexing='ij', sparse=True) # numpy >1.7 - - return fun(pts1, pts2, pts3) - - # ====================================== - # def dofs_kernel(self, comp, mat_f): - # """ - # Compute the degrees of freedom (rhs) for the projector comp. - # - # Parameters - # ---------- - # comp: str - # Which projector: '0', '11', '12', '13', '21', '22', '23' or '3'. - # - # mat_f : 3d numpy array - # Function values f(eta1_i, eta2_j, eta3_k) at the points set of the projector (from eval_for_PI). - # - # Returns - # ------- - # rhs : 3d numpy array - # The degrees of freedom sigma_ijk. - # """ - # - # assert mat_f.shape==(self.pts_PI[comp][0].size, - # self.pts_PI[comp][1].size, - # self.pts_PI[comp][2].size - # ) - # - # if comp=='0': - # rhs = mat_f - # - # elif comp=='11': - # rhs = xp.empty( (self.d1, self.n2, self.n3) ) - # - # ker_glob.kernel_int_3d_eta1(self.subs1, self.subs_cum1, self.wts1, - # mat_f.reshape(self.ne1, self.nq1, self.n2, self.n3), rhs - # ) - # elif comp=='12': - # rhs = xp.empty( (self.n1, self.d2, self.n3) ) - # - # ker_glob.kernel_int_3d_eta2(self.subs2, self.subs_cum2, self.wts2, - # mat_f.reshape(self.n1, self.ne2, self.nq2, self.n3), rhs - # ) - # elif comp=='13': - # rhs = xp.empty( (self.n1, self.n2, self.d3) ) - # - # ker_glob.kernel_int_3d_eta3(self.subs3, self.subs_cum3, self.wts3, - # mat_f.reshape(self.n1, self.n2, self.ne3, self.nq3), rhs - # ) - # elif comp=='21': - # rhs = xp.empty( (self.n1, self.d2, self.d3) ) - # - # ker_glob.kernel_int_3d_eta2_eta3(self.subs2, self.subs3, - # self.subs_cum2, self.subs_cum3, - # self.wts2, self.wts3, - # mat_f.reshape(self.n1, self.ne2, self.nq2, self.ne3, self.nq3), rhs - # ) - # elif comp=='22': - # rhs = xp.empty( (self.d1, self.n2, self.d3) ) - # - # ker_glob.kernel_int_3d_eta1_eta3(self.subs1, self.subs3, - # self.subs_cum1, self.subs_cum3, - # self.wts1, self.wts3, - # mat_f.reshape(self.ne1, self.nq1, self.n2, self.ne3, self.nq3), rhs - # ) - # elif comp=='23': - # rhs = xp.empty( (self.d1, self.d2, self.n3) ) - # - # ker_glob.kernel_int_3d_eta1_eta2(self.subs1, self.subs2, - # self.subs_cum1, self.subs_cum2, - # self.wts1, self.wts2, - # mat_f.reshape(self.ne1, self.nq1, self.ne2, self.nq2, self.n3), rhs - # ) - # elif comp=='3': - # rhs = xp.empty( (self.d1, self.d2, self.d3) ) - # - # ker_glob.kernel_int_3d_eta1_eta2_eta3(self.subs1, self.subs2, self.subs3, - # self.subs_cum1, self.subs_cum2, self.subs_cum3, - # self.wts1, self.wts2, self.wts3, - # mat_f.reshape(self.ne1, self.nq1, self.ne2, self.nq2, self.ne3, self.nq3), rhs - # ) - # else: - # raise ValueError ("wrong projector specified") - # - # return rhs - - # ====================================== - # def dofs_T_kernel(self, comp, mat_dofs): - # """ - # Transpose of dofs - # - # Parameters - # ---------- - # comp: str - # Which projector: '0', '11', '12', '13', '21', '22', '23' or '3'. - # - # mat_dofs : 3d numpy array - # Degrees of freedom. - # - # Returns - # ------- - # mat_pts : numpy array - # comp == '0' 3d of the form(n1, n2, n3) - # comp == '11' 4d of the form(ne1, nq1, n2, n3) - # comp == '12' 4d of the form(n1, n2, nq2, n3) - # comp == '13' 4d of the form(n1, n2, n3, nq3) - # comp == '21' 5d of the form(n1, ne2, nq2, ne3, nq3) - # comp == '22' 5d of the form(ne1, nq1, n2, ne3, nq3) - # comp == '23' 5d of the form(ne1, nq1, ne2, nq2, n3) - # comp == '3' 6d of the form(ne1, nq1, ne2, nq2, n3, nq3) - # - # ''' - # - # if comp=='0': - # rhs = mat_dofs - # - # elif comp=='11': - # assert mat_dofs.shape == (self.d1, self.n2, self.n3) - # rhs = xp.empty( (self.ne1, self.nq1, self.n2, self.n3) ) - # - # ker_glob.kernel_int_3d_eta1_transpose(self.subs1, self.subs_cum1, self.wts1, - # mat_dofs, rhs) - # - # rhs = rhs.reshape(self.ne1 * self.nq1, self.n2, self.n3) - # - # elif comp=='12': - # assert mat_dofs.shape == (self.n1, self.d2, self.n3) - # rhs = xp.empty( (self.n1, self.ne2, self.nq2, self.n3) ) - # - # ker_glob.kernel_int_3d_eta2_transpose(self.subs2, self.subs_cum2, self.wts2, - # mat_dofs, rhs) - # - # rhs = rhs.reshape(self.n1, self.ne2 * self.nq2, self.n3) - # - # elif comp=='13': - # assert mat_dofs.shape == (self.n1, self.n2, self.d3) - # rhs = xp.empty( (self.n1, self.n2, self.ne3, self.nq3) ) - # - # ker_glob.kernel_int_3d_eta3_transpose(self.subs3, self.subs_cum3, self.wts3, - # mat_dofs, rhs) - # - # rhs = rhs.reshape(self.n1, self.n2, self.ne3 * self.nq3) - # - # elif comp=='21': - # assert mat_dofs.shape == (self.n1, self.d2, self.d3) - # rhs = xp.empty( (self.n1, self.ne2, self.nq2, self.ne3, self.nq3) ) - # - # ker_glob.kernel_int_3d_eta2_eta3_transpose(self.subs2, self.subs3, - # self.subs_cum2, self.subs_cum3, - # self.wts2, self.wts3, - # mat_dofs, rhs) - # rhs = rhs.reshape(self.n1, self.ne2 * self.nq2, self.ne3 * self.nq3) - # - # elif comp=='22': - # assert mat_dofs.shape == (self.d1, self.n2, self.d3) - # rhs = xp.empty( (self.ne1, self.nq1, self.n2, self.ne3, self.nq3) ) - # - # ker_glob.kernel_int_3d_eta1_eta3_transpose(self.subs1, self.subs3, - # self.subs_cum1, self.subs_cum3, - # self.wts1, self.wts3, - # mat_dofs, rhs) - # rhs = rhs.reshape(self.ne1 * self.nq1, self.n2, self.ne3 * self.nq3) - # - # elif comp=='23': - # assert mat_dofs.shape == (self.d1, self.d2, self.n3) - # rhs = xp.empty( (self.ne1, self.nq1, self.ne2, self.nq2, self.n3) ) - # - # ker_glob.kernel_int_3d_eta1_eta2_transpose(self.subs1, self.subs2, - # self.subs_cum1, self.subs_cum2, - # self.wts1, self.wts2, - # mat_dofs, rhs) - # rhs = rhs.reshape(self.ne1 * self.nq1, self.ne2 * self.nq2, self.n3) - # - # elif comp=='3': - # assert mat_dofs.shape == (self.d1, self.d2, self.d3) - # rhs = xp.empty( (self.ne1, self.nq1, self.ne2, self.nq2, self.ne3, self.nq3) ) - # - # ker_glob.kernel_int_3d_eta1_eta2_eta3_transpose(self.subs1, self.subs2, self.subs3, - # self.subs_cum1, self.subs_cum2, self.subs_cum3, - # self.wts1, self.wts2, self.wts3, - # mat_dofs, rhs) - # rhs = rhs.reshape(self.ne1 * self.nq1, self.ne2 * self.nq2, self.ne3 * self.nq3) - # - # else: - # raise ValueError ("wrong projector specified") - # - # return rhs - - # ====================================== - - def dofs(self, comp, mat_f): - """ - Compute the degrees of freedom for the projector comp. - - Parameters - ---------- - comp: string - Which projector: '0', '11', '12', '13', '21', '22', '23' or '3'. - - mat_f : 3d numpy array - Function values f(eta1_i, eta2_j, eta3_k) at the points set of the projector (from eval_for_PI). - - Returns - ------- - dofs : 3d numpy array - The degrees of freedom sigma_ijk. - """ - - assert mat_f.shape == (self.pts_PI[comp][0].size, self.pts_PI[comp][1].size, self.pts_PI[comp][2].size) - - if comp == "0": - dofs = kron_matvec_3d( - [spa.identity(mat_f.shape[0]), spa.identity(mat_f.shape[1]), spa.identity(mat_f.shape[2])], - mat_f, - ) - - elif comp == "11": - dofs = kron_matvec_3d([self.Q1, spa.identity(mat_f.shape[1]), spa.identity(mat_f.shape[2])], mat_f) - elif comp == "12": - dofs = kron_matvec_3d([spa.identity(mat_f.shape[0]), self.Q2, spa.identity(mat_f.shape[2])], mat_f) - elif comp == "13": - dofs = kron_matvec_3d([spa.identity(mat_f.shape[0]), spa.identity(mat_f.shape[1]), self.Q3], mat_f) - - elif comp == "21": - dofs = kron_matvec_3d([spa.identity(mat_f.shape[0]), self.Q2, self.Q3], mat_f) - elif comp == "22": - dofs = kron_matvec_3d([self.Q1, spa.identity(mat_f.shape[1]), self.Q3], mat_f) - elif comp == "23": - dofs = kron_matvec_3d([self.Q1, self.Q2, spa.identity(mat_f.shape[2])], mat_f) - - elif comp == "3": - dofs = kron_matvec_3d([self.Q1, self.Q2, self.Q3], mat_f) - - else: - raise ValueError("wrong projector specified") - - return dofs - - # ====================================== - - def dofs_T(self, comp, mat_dofs): - """ - Transpose of degrees of freedom. - - Parameters - ---------- - comp: str - Which projector: '0', '11', '12', '13', '21', '22', '23' or '3'. - - mat_dofs : 3d numpy array - Degrees of freedom. - - Returns - ------- - rhs : 3d numpy array - The degrees of freedom sigma_ijk. - """ - - if comp == "0": - rhs = kron_matvec_3d( - [spa.identity(mat_dofs.shape[0]), spa.identity(mat_dofs.shape[1]), spa.identity(mat_dofs.shape[2])], - mat_dofs, - ) - - elif comp == "11": - rhs = kron_matvec_3d( - [self.Q1.T, spa.identity(mat_dofs.shape[1]), spa.identity(mat_dofs.shape[2])], - mat_dofs, - ) - elif comp == "12": - rhs = kron_matvec_3d( - [spa.identity(mat_dofs.shape[0]), self.Q2.T, spa.identity(mat_dofs.shape[2])], - mat_dofs, - ) - elif comp == "13": - rhs = kron_matvec_3d( - [spa.identity(mat_dofs.shape[0]), spa.identity(mat_dofs.shape[1]), self.Q3.T], - mat_dofs, - ) - - elif comp == "21": - rhs = kron_matvec_3d([spa.identity(mat_dofs.shape[0]), self.Q2.T, self.Q3.T], mat_dofs) - elif comp == "22": - rhs = kron_matvec_3d([self.Q1.T, spa.identity(mat_dofs.shape[1]), self.Q3.T], mat_dofs) - elif comp == "23": - rhs = kron_matvec_3d([self.Q1.T, self.Q2.T, spa.identity(mat_dofs.shape[2])], mat_dofs) - - elif comp == "3": - rhs = kron_matvec_3d([self.Q1.T, self.Q2.T, self.Q3.T], mat_dofs) - - else: - raise ValueError("wrong projector specified") - - return rhs - - # ====================================== - - def PI_mat(self, comp, dofs): - """ - Kronecker solve of the projection problem I.coeffs = dofs. - - Parameters - ---------- - comp : string - Which projector: '0', '11', '12', '13', '21', '22', '23' or '3'. - - dofs : 3d numpy array - The degrees of freedom sigma_ijk. - - Returns - ------- - coeffs : 3d numpy array - The spline coefficients c_ijk obtained by projection. - """ - - if comp == "0": - assert dofs.shape == (self.n1, self.n2, self.n3) - coeffs = kron_lusolve_3d([self.I_LU1, self.I_LU2, self.I_LU3], dofs) - - elif comp == "11": - assert dofs.shape == (self.d1, self.n2, self.n3) - coeffs = kron_lusolve_3d([self.H_LU1, self.I_LU2, self.I_LU3], dofs) - elif comp == "12": - assert dofs.shape == (self.n1, self.d2, self.n3) - coeffs = kron_lusolve_3d([self.I_LU1, self.H_LU2, self.I_LU3], dofs) - elif comp == "13": - assert dofs.shape == (self.n1, self.n2, self.d3) - coeffs = kron_lusolve_3d([self.I_LU1, self.I_LU2, self.H_LU3], dofs) - - elif comp == "21": - assert dofs.shape == (self.n1, self.d2, self.d3) - coeffs = kron_lusolve_3d([self.I_LU1, self.H_LU2, self.H_LU3], dofs) - elif comp == "22": - assert dofs.shape == (self.d1, self.n2, self.d3) - coeffs = kron_lusolve_3d([self.H_LU1, self.I_LU2, self.H_LU3], dofs) - elif comp == "23": - assert dofs.shape == (self.d1, self.d2, self.n3) - coeffs = kron_lusolve_3d([self.H_LU1, self.H_LU2, self.I_LU3], dofs) - - elif comp == "3": - assert dofs.shape == (self.d1, self.d2, self.d3) - coeffs = kron_lusolve_3d([self.H_LU1, self.H_LU2, self.H_LU3], dofs) - - else: - raise ValueError("wrong projector specified") - - return coeffs - - # ====================================== - - def PI(self, comp, fun): - """ - De Rham commuting projectors. - - Parameters - ---------- - comp : string - Which projector: '0', '11', '12', '13', '21', '22', '23' or '3'. - - fun : callable - f(eta1, eta2, eta3). - - Returns - ------- - coeffs : 3d numpy array - The spline coefficients c_ijk obtained by projection. - """ - - mat_f = self.eval_for_PI(comp, fun) - dofs = self.dofs(comp, mat_f) - - if comp == "0": - assert dofs.shape == (self.n1, self.n2, self.n3) - coeffs = kron_lusolve_3d([self.I_LU1, self.I_LU2, self.I_LU3], dofs) - - elif comp == "11": - assert dofs.shape == (self.d1, self.n2, self.n3) - coeffs = kron_lusolve_3d([self.H_LU1, self.I_LU2, self.I_LU3], dofs) - elif comp == "12": - assert dofs.shape == (self.n1, self.d2, self.n3) - coeffs = kron_lusolve_3d([self.I_LU1, self.H_LU2, self.I_LU3], dofs) - elif comp == "13": - assert dofs.shape == (self.n1, self.n2, self.d3) - coeffs = kron_lusolve_3d([self.I_LU1, self.I_LU2, self.H_LU3], dofs) - - elif comp == "21": - assert dofs.shape == (self.n1, self.d2, self.d3) - coeffs = kron_lusolve_3d([self.I_LU1, self.H_LU2, self.H_LU3], dofs) - elif comp == "22": - assert dofs.shape == (self.d1, self.n2, self.d3) - coeffs = kron_lusolve_3d([self.H_LU1, self.I_LU2, self.H_LU3], dofs) - elif comp == "23": - assert dofs.shape == (self.d1, self.d2, self.n3) - coeffs = kron_lusolve_3d([self.H_LU1, self.H_LU2, self.I_LU3], dofs) - - elif comp == "3": - assert dofs.shape == (self.d1, self.d2, self.d3) - coeffs = kron_lusolve_3d([self.H_LU1, self.H_LU2, self.H_LU3], dofs) - - else: - raise ValueError("wrong projector specified") - - return coeffs - - # ====================================== - - def PI_0(self, fun): - """ - De Rham commuting projector Pi_0. - - Parameters - ---------- - fun : callable - Element in V_0 continuous space, f(eta1, eta2, eta3). - - Returns - ------- - coeffs : 3d numpy array - The spline coefficients c_ijk obtained by projection. - """ - - coeffs = self.PI("0", fun) - - return coeffs - - # ====================================== - - def PI_1(self, fun1, fun2, fun3): - """ - De Rham commuting projector Pi_1 acting on fun = (fun1, fun2, fun3) in V_1. - - Parameters - ---------- - fun1 : callable - 1st component of element in V_1 continuous space, fun1(eta1, eta2, eta3). - fun2 : callable - 2nd component of element in V_1 continuous space, fun2(eta1, eta2, eta3). - fun3 : callable - 3rd component of element in V_1 continuous space, fun3(eta1, eta2, eta3). - - Returns - ------- - coeffs1 : 3d numpy array - The spline coefficients c_ijk obtained by projection of fun1 on DNN. - coeffs2 : 3d numpy array - The spline coefficients c_ijk obtained by projection of fun2 on NDN. - coeffs3 : 3d numpy array - The spline coefficients c_ijk obtained by projection of fun3 on NND. - """ - - coeffs1 = self.PI("11", fun1) - coeffs2 = self.PI("12", fun2) - coeffs3 = self.PI("13", fun3) - - return coeffs1, coeffs2, coeffs3 - - # ====================================== - - def PI_2(self, fun1, fun2, fun3): - """ - De Rham commuting projector Pi_2 acting on fun = (fun1, fun2, fun3) in V_2. - - Parameters - ---------- - fun1 : callable - 1st component of element in V_2 continuous space, fun1(eta1, eta2, eta3). - fun2 : callable - 2nd component of element in V_2 continuous space, fun2(eta1, eta2, eta3). - fun3 : callable - 3rd component of element in V_2 continuous space, fun3(eta1, eta2, eta3). - - Returns - ------- - coeffs1 : 3d numpy array - The spline coefficients c_ijk obtained by projection of fun1 on NDD. - coeffs2 : 3d numpy array - The spline coefficients c_ijk obtained by projection of fun2 on DND. - coeffs3 : 3d numpy array - The spline coefficients c_ijk obtained by projection of fun3 on DDN. - """ - - coeffs1 = self.PI("21", fun1) - coeffs2 = self.PI("22", fun2) - coeffs3 = self.PI("23", fun3) - - return coeffs1, coeffs2, coeffs3 - - # ====================================== - - def PI_3(self, fun): - """ - De Rham commuting projector Pi_3. - - Parameters - ---------- - fun : callable - Element in V_3 continuous space, f(eta1, eta2, eta3). - - Returns - ------- - coeffs : 3d numpy array - The spline coefficients c_ijk obtained by projection. - """ - - coeffs = self.PI("3", fun) - - return coeffs - - -# =============================================================== -class ProjectorsGlobal3D: - """ - Global commuting projectors in 3 dimensions. - - Parameters - ---------- - tensor_space : Tensor_spline_space - the 3d or (2d x Fourier) B-spline finite element space - - """ - - def __init__(self, tensor_space): - # assemble extraction operators P^k for degrees of freedom - - # ----------- standard tensor-product splines in eta_1 x eta_2 plane ----------- - if tensor_space.ck == -1: - n1, n2 = tensor_space.NbaseN[:2] - d1, d2 = tensor_space.NbaseD[:2] - - # with boundary dofs - self.P0_pol = spa.identity(n1 * n2, dtype=float, format="csr") - self.P1_pol = spa.identity(d1 * n2 + n1 * d2, dtype=float, format="csr") - self.P2_pol = spa.identity(n1 * d2 + d1 * n2, dtype=float, format="csr") - self.P3_pol = spa.identity(d1 * d2, dtype=float, format="csr") - - # without boundary dofs - self.P0_pol_0 = tensor_space.B0_pol.dot(self.P0_pol).tocsr() - self.P1_pol_0 = tensor_space.B1_pol.dot(self.P1_pol).tocsr() - self.P2_pol_0 = tensor_space.B2_pol.dot(self.P2_pol).tocsr() - self.P3_pol_0 = tensor_space.B3_pol.dot(self.P3_pol).tocsr() - # --------------------------------------------------------------------------------- - - # ----------------- C^k polar splines in eta_1 x eta_2 plane ---------------------- - else: - # with boundary dofs - self.P0_pol = tensor_space.polar_splines.P0.copy() - self.P1_pol = tensor_space.polar_splines.P1C.copy() - self.P2_pol = tensor_space.polar_splines.P1D.copy() - self.P3_pol = tensor_space.polar_splines.P2.copy() - - # without boundary dofs - self.P0_pol_0 = tensor_space.B0_pol.dot(self.P0_pol).tocsr() - self.P1_pol_0 = tensor_space.B1_pol.dot(self.P1_pol).tocsr() - self.P2_pol_0 = tensor_space.B2_pol.dot(self.P2_pol).tocsr() - self.P3_pol_0 = tensor_space.B3_pol.dot(self.P3_pol).tocsr() - # --------------------------------------------------------------------------------- - - # 3D operators: with boundary dofs - if tensor_space.dim == 2: - self.P0 = self.P0_pol.copy() - self.P1 = spa.bmat([[self.P1_pol, None], [None, self.P0_pol]], format="csr") - self.P2 = spa.bmat([[self.P2_pol, None], [None, self.P3_pol]], format="csr") - self.P3 = self.P3_pol.copy() - - self.P0 = spa.kron(self.P0, spa.identity(tensor_space.NbaseN[2]), format="csr") - self.P1 = spa.kron(self.P1, spa.identity(tensor_space.NbaseN[2]), format="csr") - self.P2 = spa.kron(self.P2, spa.identity(tensor_space.NbaseN[2]), format="csr") - self.P3 = spa.kron(self.P3, spa.identity(tensor_space.NbaseN[2]), format="csr") - - else: - n3 = tensor_space.NbaseN[2] - d3 = tensor_space.NbaseD[2] - - self.P0 = spa.kron(self.P0_pol, spa.identity(n3), format="csr") - self.P1 = spa.bmat( - [[spa.kron(self.P1_pol, spa.identity(n3)), None], [None, spa.kron(self.P0_pol, spa.identity(d3))]], - format="csr", - ) - self.P2 = spa.bmat( - [[spa.kron(self.P2_pol, spa.identity(d3)), None], [None, spa.kron(self.P3_pol, spa.identity(n3))]], - format="csr", - ) - self.P3 = spa.kron(self.P3_pol, spa.identity(d3), format="csr") - - # 3D operators: without boundary dofs - self.P0_0 = tensor_space.B0.dot(self.P0).tocsr() - self.P1_0 = tensor_space.B1.dot(self.P1).tocsr() - self.P2_0 = tensor_space.B2.dot(self.P2).tocsr() - self.P3_0 = tensor_space.B3.dot(self.P3).tocsr() - - # if tensor_space.ck == 1: - # - # # blocks of I0 matrix - # self.I0_11 = spa.kron(self.projectors_1d[0].N[:2, :2], self.projectors_1d[1].N) - # self.I0_11 = tensor_space.polar_splines.P0_11.dot(self.I0_11.dot(tensor_space.polar_splines.E0_11.T)).tocsr() - # - # self.I0_12 = spa.kron(self.projectors_1d[0].N[:2, 2:], self.projectors_1d[1].N) - # self.I0_12 = tensor_space.polar_splines.P0_11.dot(self.I0_12).tocsr() - # - # self.I0_21 = spa.kron(self.projectors_1d[0].N[2:, :2], self.projectors_1d[1].N) - # self.I0_21 = self.I0_21.dot(tensor_space.polar_splines.E0_11.T).tocsr() - # - # self.I0_22 = spa.kron(self.projectors_1d[0].N[2:, 2:], self.projectors_1d[1].N, format='csr') - # - # self.I0_22_LUs = [spa.linalg.splu(self.projectors_1d[0].N[2:, 2:].tocsc()), self.projectors_1d[1].N_LU] - - # 2D interpolation/histopolation matrices in poloidal plane - II = spa.kron(tensor_space.spaces[0].projectors.I, tensor_space.spaces[1].projectors.I, format="csr") - HI = spa.kron(tensor_space.spaces[0].projectors.H, tensor_space.spaces[1].projectors.I, format="csr") - IH = spa.kron(tensor_space.spaces[0].projectors.I, tensor_space.spaces[1].projectors.H, format="csr") - HH = spa.kron(tensor_space.spaces[0].projectors.H, tensor_space.spaces[1].projectors.H, format="csr") - - HI_IH = spa.bmat([[HI, None], [None, IH]], format="csr") - IH_HI = spa.bmat([[IH, None], [None, HI]], format="csr") - - # including boundary splines - self.I0_pol = self.P0_pol.dot(II.dot(tensor_space.E0_pol.T)).tocsr() - self.I1_pol = self.P1_pol.dot(HI_IH.dot(tensor_space.E1_pol.T)).tocsr() - self.I2_pol = self.P2_pol.dot(IH_HI.dot(tensor_space.E2_pol.T)).tocsr() - self.I3_pol = self.P3_pol.dot(HH.dot(tensor_space.E3_pol.T)).tocsr() - - # without boundary splines - self.I0_pol_0 = self.P0_pol_0.dot(II.dot(tensor_space.E0_pol_0.T)).tocsr() - self.I1_pol_0 = self.P1_pol_0.dot(HI_IH.dot(tensor_space.E1_pol_0.T)).tocsr() - self.I2_pol_0 = self.P2_pol_0.dot(IH_HI.dot(tensor_space.E2_pol_0.T)).tocsr() - self.I3_pol_0 = self.P3_pol_0.dot(HH.dot(tensor_space.E3_pol_0.T)).tocsr() - - # LU decompositions in poloidal plane (including boundary splines) - self.I0_pol_LU = spa.linalg.splu(self.I0_pol.tocsc()) - self.I1_pol_LU = spa.linalg.splu(self.I1_pol.tocsc()) - self.I2_pol_LU = spa.linalg.splu(self.I2_pol.tocsc()) - self.I3_pol_LU = spa.linalg.splu(self.I3_pol.tocsc()) - - # LU decompositions in poloidal plane (without boundary splines) - self.I0_pol_0_LU = spa.linalg.splu(self.I0_pol_0.tocsc()) - self.I1_pol_0_LU = spa.linalg.splu(self.I1_pol_0.tocsc()) - self.I2_pol_0_LU = spa.linalg.splu(self.I2_pol_0.tocsc()) - self.I3_pol_0_LU = spa.linalg.splu(self.I3_pol_0.tocsc()) - - self.I0_pol_0_T_LU = spa.linalg.splu(self.I0_pol_0.T.tocsc()) - self.I1_pol_0_T_LU = spa.linalg.splu(self.I1_pol_0.T.tocsc()) - self.I2_pol_0_T_LU = spa.linalg.splu(self.I2_pol_0.T.tocsc()) - self.I3_pol_0_T_LU = spa.linalg.splu(self.I3_pol_0.T.tocsc()) - - # whether approximate inverse interpolation matrices were computed already - self.approx_Ik_0_inv = False - self.approx_Ik_0_tol = -1.0 - - # get 1D interpolation points - x_i1 = tensor_space.spaces[0].projectors.x_int.copy() - x_i2 = tensor_space.spaces[1].projectors.x_int.copy() - - # get 1D quadrature points - x_q1 = tensor_space.spaces[0].projectors.pts.flatten() - x_q2 = tensor_space.spaces[1].projectors.pts.flatten() - - x_q1G = tensor_space.spaces[0].projectors.ptsG.flatten() - x_q2G = tensor_space.spaces[1].projectors.ptsG.flatten() - - # get 1D quadrature weight matrices - self.Q1 = tensor_space.spaces[0].projectors.Q - self.Q2 = tensor_space.spaces[1].projectors.Q - - self.Q1G = tensor_space.spaces[0].projectors.QG - self.Q2G = tensor_space.spaces[1].projectors.QG - - # 1D interpolation/histopolation points and matrices in third direction - if tensor_space.dim == 3: - x_i3 = tensor_space.spaces[2].projectors.x_int - x_q3 = tensor_space.spaces[2].projectors.pts.flatten() - x_q3G = tensor_space.spaces[2].projectors.ptsG.flatten() - - self.Q3 = tensor_space.spaces[2].projectors.Q - self.Q3G = tensor_space.spaces[2].projectors.QG - - self.I_tor = tensor_space.spaces[2].projectors.I - self.H_tor = tensor_space.spaces[2].projectors.H - - self.I0_tor = tensor_space.spaces[2].projectors.I0 - self.H0_tor = tensor_space.spaces[2].projectors.H0 - - self.I_tor_LU = tensor_space.spaces[2].projectors.I_LU - self.H_tor_LU = tensor_space.spaces[2].projectors.H_LU - - self.I0_tor_LU = tensor_space.spaces[2].projectors.I0_LU - self.H0_tor_LU = tensor_space.spaces[2].projectors.H0_LU - - self.I0_tor_T_LU = tensor_space.spaces[2].projectors.I0_T_LU - self.H0_tor_T_LU = tensor_space.spaces[2].projectors.H0_T_LU - - else: - if tensor_space.n_tor == 0: - x_i3 = xp.array([0.0]) - x_q3 = xp.array([0.0]) - x_q3G = xp.array([0.0]) - - else: - if tensor_space.basis_tor == "r": - if tensor_space.n_tor > 0: - x_i3 = xp.array([1.0, 0.25 / tensor_space.n_tor]) - x_q3 = xp.array([1.0, 0.25 / tensor_space.n_tor]) - x_q3G = xp.array([1.0, 0.25 / tensor_space.n_tor]) - - else: - x_i3 = xp.array([1.0, 0.75 / (-tensor_space.n_tor)]) - x_q3 = xp.array([1.0, 0.75 / (-tensor_space.n_tor)]) - x_q3G = xp.array([1.0, 0.75 / (-tensor_space.n_tor)]) - - else: - x_i3 = xp.array([0.0]) - x_q3 = xp.array([0.0]) - x_q3G = xp.array([0.0]) - - self.Q3 = spa.identity(tensor_space.NbaseN[2], format="csr") - self.Q3G = spa.identity(tensor_space.NbaseN[2], format="csr") - - self.I_tor = spa.identity(tensor_space.NbaseN[2], format="csr") - self.H_tor = spa.identity(tensor_space.NbaseN[2], format="csr") - - self.I0_tor = spa.identity(tensor_space.NbaseN[2], format="csr") - self.H0_tor = spa.identity(tensor_space.NbaseN[2], format="csr") - - self.I_tor_LU = spa.linalg.splu(self.I_tor.tocsc()) - self.H_tor_LU = spa.linalg.splu(self.H_tor.tocsc()) - - self.I0_tor_LU = spa.linalg.splu(self.I0_tor.tocsc()) - self.H0_tor_LU = spa.linalg.splu(self.H0_tor.tocsc()) - - self.I0_tor_T_LU = spa.linalg.splu(self.I0_tor.T.tocsc()) - self.H0_tor_T_LU = spa.linalg.splu(self.H0_tor.T.tocsc()) - - # collection of the point sets for different projectors in poloidal plane - self.pts_PI_0 = [x_i1, x_i2, x_i3] - - self.pts_PI_11 = [x_q1, x_i2, x_i3] - self.pts_PI_12 = [x_i1, x_q2, x_i3] - self.pts_PI_13 = [x_i1, x_i2, x_q3] - - self.pts_PI_21 = [x_i1, x_q2, x_q3] - self.pts_PI_22 = [x_q1, x_i2, x_q3] - self.pts_PI_23 = [x_q1, x_q2, x_i3] - - self.pts_PI_3 = [x_q1, x_q2, x_q3] - - # without subs - self.pts_PI_0G = [x_i1, x_i2, x_i3] - - self.pts_PI_11G = [x_q1G, x_i2, x_i3] - self.pts_PI_12G = [x_i1, x_q2G, x_i3] - self.pts_PI_13G = [x_i1, x_i2, x_q3G] - - self.pts_PI_21G = [x_i1, x_q2G, x_q3G] - self.pts_PI_22G = [x_q1G, x_i2, x_q3G] - self.pts_PI_23G = [x_q1G, x_q2G, x_i3] - - self.pts_PI_3G = [x_q1G, x_q2G, x_q3G] - - # ======================================== - - def getpts_for_PI(self, comp, with_subs=True): - """ - Get the needed point sets for a given projector. - - Parameters - ---------- - comp: int - which projector, one of (0, 11, 12, 13, 21, 22, 23, 3). - - Returns - ------- - pts_PI : list of 1d arrays - the 1D point sets. - """ - - if with_subs: - if comp == 0: - pts_PI = self.pts_PI_0 - - elif comp == 11: - pts_PI = self.pts_PI_11 - elif comp == 12: - pts_PI = self.pts_PI_12 - elif comp == 13: - pts_PI = self.pts_PI_13 - - elif comp == 21: - pts_PI = self.pts_PI_21 - elif comp == 22: - pts_PI = self.pts_PI_22 - elif comp == 23: - pts_PI = self.pts_PI_23 - - elif comp == 3: - pts_PI = self.pts_PI_3 - - else: - raise ValueError("wrong projector specified") - - else: - if comp == 0: - pts_PI = self.pts_PI_0G - - elif comp == 11: - pts_PI = self.pts_PI_11G - elif comp == 12: - pts_PI = self.pts_PI_12G - elif comp == 13: - pts_PI = self.pts_PI_13G - - elif comp == 21: - pts_PI = self.pts_PI_21G - elif comp == 22: - pts_PI = self.pts_PI_22G - elif comp == 23: - pts_PI = self.pts_PI_23G - - elif comp == 3: - pts_PI = self.pts_PI_3G - - else: - raise ValueError("wrong projector specified") - - return pts_PI - - # ====================================== - - def eval_for_PI(self, comp, fun, eval_kind, with_subs=True): - """ - Evaluates the callable "fun" at the points corresponding to the projector, and returns the result as 3d array "mat_f". - - Parameters - ---------- - comp: int - which projector, one of (0, 11, 12, 13, 21, 22, 23, 3). - - fun : callable - the function fun(eta1, eta2, eta3) to project - - eval_kind : string - kind of function evaluation at interpolation/quadrature points ('meshgrid' or 'tensor_product', point-wise else) - - Returns - ------- - mat_f : 3d array - function evaluated on a 3d meshgrid contstructed from the 1d point sets. - """ - - assert callable(fun) - - # get intepolation and quadrature points - pts_PI = self.getpts_for_PI(comp, with_subs) - - # array of evaluated function - mat_f = xp.empty((pts_PI[0].size, pts_PI[1].size, pts_PI[2].size), dtype=float) - - # create a meshgrid and evaluate function on point set - if eval_kind == "meshgrid": - pts1, pts2, pts3 = xp.meshgrid(pts_PI[0], pts_PI[1], pts_PI[2], indexing="ij") - mat_f[:, :, :] = fun(pts1, pts2, pts3) - - # tensor-product evaluation is done by input function - elif eval_kind == "tensor_product": - mat_f[:, :, :] = fun(pts_PI[0], pts_PI[1], pts_PI[2]) - - # point-wise evaluation - else: - for i1 in range(pts_PI[0].size): - for i2 in range(pts_PI[1].size): - for i3 in range(pts_PI[2].size): - mat_f[i1, i2, i3] = fun(pts_PI[0][i1], pts_PI[1][i2], pts_PI[2][i3]) - - return mat_f - - # ====================================== - # def assemble_Schur0_inv(self): - # - # n1 = self.pts_PI_0[0].size - # n2 = self.pts_PI_0[1].size - # - # # apply (I0_22) to each column - # self.S0 = xp.zeros(((n1 - 2)*n2, 3), dtype=float) - # - # for i in range(3): - # self.S0[:, i] = kron_lusolve_2d(self.I0_22_LUs, self.I0_21[:, i].toarray().reshape(n1 - 2, n2)).flatten() - # - # # 3 x 3 matrix - # self.S0 = xp.linalg.inv(self.I0_11.toarray() - self.I0_12.toarray().dot(self.S0)) - # - # - # ====================================== - # def I0_inv(self, rhs, include_bc): - # - # n1 = self.pts_PI_0[0].size - # n2 = self.pts_PI_0[1].size - # - # if include_bc: - # rhs1 = rhs[:3] - # rhs2 = rhs[3:].reshape(n1 - 2, n2) - # - # # solve pure 3x3 polar contribution - # out1 = self.S0.dot(rhs1) - # - # # solve pure tensor-product contribution I0_22^(-1)*rhs2 - # out2 = kron_lusolve_2d(self.I0_22_LUs, rhs2) - # - # # solve for polar coefficients - # out1 -= self.S0.dot(self.I0_12.dot(out2.flatten())) - # - # # solve for tensor-product coefficients - # out2 = out2 - kron_lusolve_2d(self.I0_22_LUs, self.I0_21.dot(self.S0.dot(rhs1)).reshape(n1 - 2, n2)) + kron_lusolve_2d(self.I0_22_LUs, self.I0_21.dot(self.S0.dot(self.I0_12.dot(out2.flatten()))).reshape(n1 - 2, n2)) - # - # return xp.concatenate((out1, out2.flatten())) - - # ====================================== - - def solve_V0(self, dofs_0, include_bc): - # with boundary splines - if include_bc: - dofs_0 = dofs_0.reshape(self.P0_pol.shape[0], self.I_tor.shape[0]) - coeffs = self.I_tor_LU.solve(self.I0_pol_LU.solve(dofs_0).T).T - - # without boundary splines - else: - dofs_0 = dofs_0.reshape(self.P0_pol_0.shape[0], self.I0_tor.shape[0]) - coeffs = self.I0_tor_LU.solve(self.I0_pol_0_LU.solve(dofs_0).T).T - - return coeffs.flatten() - - # ====================================== - def solve_V1(self, dofs_1, include_bc): - # with boundary splines - if include_bc: - dofs_11 = dofs_1[: self.P1_pol.shape[0] * self.I_tor.shape[0]].reshape( - self.P1_pol.shape[0], - self.I_tor.shape[0], - ) - dofs_12 = dofs_1[self.P1_pol.shape[0] * self.I_tor.shape[0] :].reshape( - self.P0_pol.shape[0], - self.H_tor.shape[0], - ) - - coeffs1 = self.I_tor_LU.solve(self.I1_pol_LU.solve(dofs_11).T).T - coeffs2 = self.H_tor_LU.solve(self.I0_pol_LU.solve(dofs_12).T).T - - # without boundary splines - else: - dofs_11 = dofs_1[: self.P1_pol_0.shape[0] * self.I0_tor.shape[0]].reshape( - self.P1_pol_0.shape[0], - self.I0_tor.shape[0], - ) - dofs_12 = dofs_1[self.P1_pol_0.shape[0] * self.I0_tor.shape[0] :].reshape( - self.P0_pol_0.shape[0], - self.H0_tor.shape[0], - ) - - coeffs1 = self.I0_tor_LU.solve(self.I1_pol_0_LU.solve(dofs_11).T).T - coeffs2 = self.H0_tor_LU.solve(self.I0_pol_0_LU.solve(dofs_12).T).T - - return xp.concatenate((coeffs1.flatten(), coeffs2.flatten())) - - # ====================================== - def solve_V2(self, dofs_2, include_bc): - # with boundary splines - if include_bc: - dofs_21 = dofs_2[: self.P2_pol.shape[0] * self.H_tor.shape[0]].reshape( - self.P2_pol.shape[0], - self.H_tor.shape[0], - ) - dofs_22 = dofs_2[self.P2_pol.shape[0] * self.H_tor.shape[0] :].reshape( - self.P3_pol.shape[0], - self.I_tor.shape[0], - ) - - coeffs1 = self.H_tor_LU.solve(self.I2_pol_LU.solve(dofs_21).T).T - coeffs2 = self.I_tor_LU.solve(self.I3_pol_LU.solve(dofs_22).T).T - - # without boundary splines - else: - dofs_21 = dofs_2[: self.P2_pol_0.shape[0] * self.H0_tor.shape[0]].reshape( - self.P2_pol_0.shape[0], - self.H0_tor.shape[0], - ) - dofs_22 = dofs_2[self.P2_pol_0.shape[0] * self.H0_tor.shape[0] :].reshape( - self.P3_pol_0.shape[0], - self.I0_tor.shape[0], - ) - - coeffs1 = self.H0_tor_LU.solve(self.I2_pol_0_LU.solve(dofs_21).T).T - coeffs2 = self.I0_tor_LU.solve(self.I3_pol_0_LU.solve(dofs_22).T).T - - return xp.concatenate((coeffs1.flatten(), coeffs2.flatten())) - - # ====================================== - def solve_V3(self, dofs_3, include_bc): - # with boundary splines - if include_bc: - dofs_3 = dofs_3.reshape(self.P3_pol.shape[0], self.H_tor.shape[0]) - coeffs = self.H_tor_LU.solve(self.I3_pol_LU.solve(dofs_3).T).T - - # without boundary splines - else: - dofs_3 = dofs_3.reshape(self.P3_pol_0.shape[0], self.H0_tor.shape[0]) - coeffs = self.H0_tor_LU.solve(self.I3_pol_0_LU.solve(dofs_3).T).T - - return coeffs.flatten() - - # ====================================== - - def apply_IinvT_V0(self, rhs, include_bc=False): - # with boundary splines - if include_bc: - if not hasattr(self, "I0_pol_T_LU"): - self.I0_pol_T_LU = spa.linalg.splu(self.I0_pol.T.tocsc()) - - rhs = rhs.reshape(self.P0_pol.shape[0], self.I_tor.shape[0]) - rhs = self.I0_pol_T_LU.solve(self.I_tor_T_LU.solve(rhs.T).T) - - # without boundary splines - else: - rhs = rhs.reshape(self.P0_pol_0.shape[0], self.I0_tor.shape[0]) - rhs = self.I0_pol_0_T_LU.solve(self.I0_tor_T_LU.solve(rhs.T).T) - - return rhs.flatten() - - # ====================================== - def apply_IinvT_V1(self, rhs, include_bc=False): - # with boundary splines - if include_bc: - if not hasattr(self, "I0_pol_T_LU"): - self.I0_pol_T_LU = spa.linalg.splu(self.I0_pol.T.tocsc()) - - if not hasattr(self, "I1_pol_T_LU"): - self.I1_pol_T_LU = spa.linalg.splu(self.I1_pol.T.tocsc()) - - rhs1 = rhs[: self.P1_pol.shape[0] * self.I_tor.shape[0]].reshape(self.P1_pol.shape[0], self.I_tor.shape[0]) - rhs2 = rhs[self.P1_pol.shape[0] * self.I_tor.shape[0] :].reshape(self.P0_pol.shape[0], self.H_tor.shape[0]) - - rhs1 = self.I1_pol_T_LU.solve(self.I_tor_T_LU.solve(rhs1.T).T) - rhs2 = self.I0_pol_T_LU.solve(self.H_tor_T_LU.solve(rhs2.T).T) - - # without boundary splines - else: - rhs1 = rhs[: self.P1_pol_0.shape[0] * self.I0_tor.shape[0]].reshape( - self.P1_pol_0.shape[0], - self.I0_tor.shape[0], - ) - rhs2 = rhs[self.P1_pol_0.shape[0] * self.I0_tor.shape[0] :].reshape( - self.P0_pol_0.shape[0], - self.H0_tor.shape[0], - ) - - rhs1 = self.I1_pol_0_T_LU.solve(self.I0_tor_T_LU.solve(rhs1.T).T) - rhs2 = self.I0_pol_0_T_LU.solve(self.H0_tor_T_LU.solve(rhs2.T).T) - - return xp.concatenate((rhs1.flatten(), rhs2.flatten())) - - # ====================================== - def apply_IinvT_V2(self, rhs, include_bc=False): - # with boundary splines - if include_bc: - if not hasattr(self, "I2_pol_T_LU"): - self.I2_pol_T_LU = spa.linalg.splu(self.I2_pol.T.tocsc()) - - if not hasattr(self, "I3_pol_T_LU"): - self.I3_pol_T_LU = spa.linalg.splu(self.I3_pol.T.tocsc()) - - rhs1 = rhs[: self.P2_pol.shape[0] * self.H_tor.shape[0]].reshape(self.P2_pol.shape[0], self.H_tor.shape[0]) - rhs2 = rhs[self.P2_pol.shape[0] * self.H_tor.shape[0] :].reshape(self.P3_pol.shape[0], self.I_tor.shape[0]) - - rhs1 = self.I2_pol_T_LU.solve(self.H_tor_T_LU.solve(rhs1.T).T) - rhs2 = self.I3_pol_T_LU.solve(self.I_tor_T_LU.solve(rhs2.T).T) - - # without boundary splines - else: - rhs1 = rhs[: self.P2_pol_0.shape[0] * self.H0_tor.shape[0]].reshape( - self.P2_pol_0.shape[0], - self.H0_tor.shape[0], - ) - rhs2 = rhs[self.P2_pol_0.shape[0] * self.H0_tor.shape[0] :].reshape( - self.P3_pol_0.shape[0], - self.I0_tor.shape[0], - ) - - rhs1 = self.I2_pol_0_T_LU.solve(self.H0_tor_T_LU.solve(rhs1.T).T) - rhs2 = self.I3_pol_0_T_LU.solve(self.I0_tor_T_LU.solve(rhs2.T).T) - - return xp.concatenate((rhs1.flatten(), rhs2.flatten())) - - # ====================================== - def apply_IinvT_V3(self, rhs, include_bc=False): - # with boundary splines - if include_bc: - if not hasattr(self, "I3_pol_T_LU"): - self.I3_pol_T_LU = spa.linalg.splu(self.I3_pol.T.tocsc()) - - rhs = rhs.reshape(self.P3_pol.shape[0], self.H_tor.shape[0]) - rhs = self.I3_pol_T_LU.solve(self.H_tor_T_LU.solve(rhs.T).T) - - # without boundary splines - else: - rhs = rhs.reshape(self.P3_pol_0.shape[0], self.H0_tor.shape[0]) - rhs = self.I3_pol_0_T_LU.solve(self.H0_tor_T_LU.solve(rhs.T).T) - - return rhs.flatten() - - # ====================================== - - def dofs_0(self, fun, include_bc=True, eval_kind="meshgrid"): - # get function values at point sets - dofs = self.eval_for_PI(0, fun, eval_kind) - - # get dofs on tensor-product grid - dofs = kron_matvec_3d( - [spa.identity(dofs.shape[0]), spa.identity(dofs.shape[1]), spa.identity(dofs.shape[2])], - dofs, - ) - - # apply extraction operator for dofs - if include_bc: - dofs = self.P0.dot(dofs.flatten()) - else: - dofs = self.P0_0.dot(dofs.flatten()) - - return dofs - - # ====================================== - def dofs_1(self, fun, include_bc=True, eval_kind="meshgrid", with_subs=True): - # get function values at point sets - dofs_1 = self.eval_for_PI(11, fun[0], eval_kind, with_subs) - dofs_2 = self.eval_for_PI(12, fun[1], eval_kind, with_subs) - dofs_3 = self.eval_for_PI(13, fun[2], eval_kind, with_subs) - - # get dofs_1 on tensor-product grid: integrate along 1-direction - if with_subs: - dofs_1 = kron_matvec_3d([self.Q1, spa.identity(dofs_1.shape[1]), spa.identity(dofs_1.shape[2])], dofs_1) - else: - dofs_1 = kron_matvec_3d([self.Q1G, spa.identity(dofs_1.shape[1]), spa.identity(dofs_1.shape[2])], dofs_1) - - # get dofs_2 on tensor-product grid: integrate along 2-direction - if with_subs: - dofs_2 = kron_matvec_3d([spa.identity(dofs_2.shape[0]), self.Q2, spa.identity(dofs_2.shape[2])], dofs_2) - else: - dofs_2 = kron_matvec_3d([spa.identity(dofs_2.shape[0]), self.Q2G, spa.identity(dofs_2.shape[2])], dofs_2) - - # get dofs_3 on tensor-product grid: integrate along 3-direction - if with_subs: - dofs_3 = kron_matvec_3d([spa.identity(dofs_3.shape[0]), spa.identity(dofs_3.shape[1]), self.Q3], dofs_3) - else: - dofs_3 = kron_matvec_3d([spa.identity(dofs_3.shape[0]), spa.identity(dofs_3.shape[1]), self.Q3G], dofs_3) - - # apply extraction operator for dofs - if include_bc: - dofs = self.P1.dot(xp.concatenate((dofs_1.flatten(), dofs_2.flatten(), dofs_3.flatten()))) - else: - dofs = self.P1_0.dot(xp.concatenate((dofs_1.flatten(), dofs_2.flatten(), dofs_3.flatten()))) - - return dofs - - # ====================================== - def dofs_2(self, fun, include_bc=True, eval_kind="meshgrid", with_subs=True): - # get function values at point sets - dofs_1 = self.eval_for_PI(21, fun[0], eval_kind, with_subs) - dofs_2 = self.eval_for_PI(22, fun[1], eval_kind, with_subs) - dofs_3 = self.eval_for_PI(23, fun[2], eval_kind, with_subs) - - # get dofs_1 on tensor-product grid: integrate in 2-3-plane - if with_subs: - dofs_1 = kron_matvec_3d([spa.identity(dofs_1.shape[0]), self.Q2, self.Q3], dofs_1) - else: - dofs_1 = kron_matvec_3d([spa.identity(dofs_1.shape[0]), self.Q2G, self.Q3G], dofs_1) - - # get dofs_2 on tensor-product grid: integrate in 1-3-plane - if with_subs: - dofs_2 = kron_matvec_3d([self.Q1, spa.identity(dofs_2.shape[1]), self.Q3], dofs_2) - else: - dofs_2 = kron_matvec_3d([self.Q1G, spa.identity(dofs_2.shape[1]), self.Q3G], dofs_2) - - # get dofs_3 on tensor-product grid: integrate in 1-2-plane - if with_subs: - dofs_3 = kron_matvec_3d([self.Q1, self.Q2, spa.identity(dofs_3.shape[2])], dofs_3) - else: - dofs_3 = kron_matvec_3d([self.Q1G, self.Q2G, spa.identity(dofs_3.shape[2])], dofs_3) - - # apply extraction operator for dofs - if include_bc: - dofs = self.P2.dot(xp.concatenate((dofs_1.flatten(), dofs_2.flatten(), dofs_3.flatten()))) - else: - dofs = self.P2_0.dot(xp.concatenate((dofs_1.flatten(), dofs_2.flatten(), dofs_3.flatten()))) - - return dofs - - # ====================================== - def dofs_3(self, fun, include_bc=True, eval_kind="meshgrid", with_subs=True): - # get function values at point sets - dofs = self.eval_for_PI(3, fun, eval_kind, with_subs) - - # get dofs on tensor-product grid: integrate in 1-2-3-cell - if with_subs: - dofs = kron_matvec_3d([self.Q1, self.Q2, self.Q3], dofs) - else: - dofs = kron_matvec_3d([self.Q1G, self.Q2G, self.Q3G], dofs) - - # apply extraction operator for dofs - if include_bc: - dofs = self.P3.dot(dofs.flatten()) - else: - dofs = self.P3_0.dot(dofs.flatten()) - - return dofs - - # ====================================== - - def pi_0(self, fun, include_bc=True, eval_kind="meshgrid"): - return self.solve_V0(self.dofs_0(fun, include_bc, eval_kind), include_bc) - - # ====================================== - def pi_1(self, fun, include_bc=True, eval_kind="meshgrid", with_subs=True): - return self.solve_V1(self.dofs_1(fun, include_bc, eval_kind, with_subs), include_bc) - - # ====================================== - def pi_2(self, fun, include_bc=True, eval_kind="meshgrid", with_subs=True): - return self.solve_V2(self.dofs_2(fun, include_bc, eval_kind, with_subs), include_bc) - - # ====================================== - def pi_3(self, fun, include_bc=True, eval_kind="meshgrid", with_subs=True): - return self.solve_V3(self.dofs_3(fun, include_bc, eval_kind, with_subs), include_bc) - - # ======================================== - - def assemble_approx_inv(self, tol): - if not self.approx_Ik_0_inv or (self.approx_Ik_0_inv and self.approx_Ik_0_tol != tol): - # poloidal plane - I0_pol_0_inv_approx = xp.linalg.inv(self.I0_pol_0.toarray()) - I1_pol_0_inv_approx = xp.linalg.inv(self.I1_pol_0.toarray()) - I2_pol_0_inv_approx = xp.linalg.inv(self.I2_pol_0.toarray()) - I3_pol_0_inv_approx = xp.linalg.inv(self.I3_pol_0.toarray()) - I0_pol_inv_approx = xp.linalg.inv(self.I0_pol.toarray()) - - if tol > 1e-14: - I0_pol_0_inv_approx[xp.abs(I0_pol_0_inv_approx) < tol] = 0.0 - I1_pol_0_inv_approx[xp.abs(I1_pol_0_inv_approx) < tol] = 0.0 - I2_pol_0_inv_approx[xp.abs(I2_pol_0_inv_approx) < tol] = 0.0 - I3_pol_0_inv_approx[xp.abs(I3_pol_0_inv_approx) < tol] = 0.0 - I0_pol_inv_approx[xp.abs(I0_pol_inv_approx) < tol] = 0.0 - - I0_pol_0_inv_approx = spa.csr_matrix(I0_pol_0_inv_approx) - I1_pol_0_inv_approx = spa.csr_matrix(I1_pol_0_inv_approx) - I2_pol_0_inv_approx = spa.csr_matrix(I2_pol_0_inv_approx) - I3_pol_0_inv_approx = spa.csr_matrix(I3_pol_0_inv_approx) - I0_pol_inv_approx = spa.csr_matrix(I0_pol_inv_approx) - - # toroidal direction - I_inv_tor_approx = xp.linalg.inv(self.I_tor.toarray()) - H_inv_tor_approx = xp.linalg.inv(self.H_tor.toarray()) - - if tol > 1e-14: - I_inv_tor_approx[xp.abs(I_inv_tor_approx) < tol] = 0.0 - H_inv_tor_approx[xp.abs(H_inv_tor_approx) < tol] = 0.0 - - I_inv_tor_approx = spa.csr_matrix(I_inv_tor_approx) - H_inv_tor_approx = spa.csr_matrix(H_inv_tor_approx) - - # tensor-product poloidal x toroidal - self.I0_0_inv_approx = spa.kron(I0_pol_0_inv_approx, I_inv_tor_approx, format="csr") - - self.I1_0_inv_approx = spa.bmat( - [ - [spa.kron(I1_pol_0_inv_approx, I_inv_tor_approx), None], - [None, spa.kron(I0_pol_0_inv_approx, H_inv_tor_approx)], - ], - format="csr", - ) - - self.I2_0_inv_approx = spa.bmat( - [ - [spa.kron(I2_pol_0_inv_approx, H_inv_tor_approx), None], - [None, spa.kron(I3_pol_0_inv_approx, I_inv_tor_approx)], - ], - format="csr", - ) - - self.I3_0_inv_approx = spa.kron(I3_pol_0_inv_approx, H_inv_tor_approx, format="csr") - - self.I0_inv_approx = spa.kron(I0_pol_inv_approx, I_inv_tor_approx, format="csr") - - self.approx_Ik_0_inv = True - self.approx_Ik_0_tol = tol - - else: - print("Approximations for inverse interpolation matrices already exist!") diff --git a/src/struphy/eigenvalue_solvers/spline_space.py b/src/struphy/eigenvalue_solvers/spline_space.py deleted file mode 100644 index c10124e57..000000000 --- a/src/struphy/eigenvalue_solvers/spline_space.py +++ /dev/null @@ -1,3284 +0,0 @@ -# coding: utf-8 -# -# Copyright 2020 Florian Holderied - -""" -Basic modules to create tensor-product finite element spaces of univariate B-splines. -""" - -import cunumpy as xp -import matplotlib -import scipy.sparse as spa - -matplotlib.rcParams.update({"font.size": 16}) -import matplotlib.pyplot as plt - -import struphy.bsplines.bsplines as bsp -import struphy.bsplines.evaluation_kernels_1d as eva_1d -import struphy.bsplines.evaluation_kernels_2d as eva_2d -import struphy.bsplines.evaluation_kernels_3d as eva_3d -import struphy.eigenvalue_solvers.derivatives as der -import struphy.eigenvalue_solvers.mass_matrices_1d as mass_1d -import struphy.eigenvalue_solvers.mass_matrices_2d as mass_2d -import struphy.eigenvalue_solvers.mass_matrices_3d as mass_3d -import struphy.eigenvalue_solvers.projectors_global as pro -import struphy.polar.extraction_operators as pol - - -# =============== 1d B-spline space ====================== -class Spline_space_1d: - """ - Defines a 1d space of B-splines. - - Parameters - ---------- - Nel : int - number of elements of discretized 1D domain [0, 1] - - p : int - spline degree - - spl_kind : boolean - kind of spline space (True = periodic, False = clamped) - - n_quad : int - number of Gauss-Legendre quadrature points per grid cell (defined by break points) - - bc : [str, str] - boundary conditions at eta1=0.0 and eta1=1.0, 'f' free, 'd' dirichlet (remove boundary spline) - - Attributes - ---------- - el_b : xp.array - Element boundaries, equally spaced. - - delta : float - Uniform grid spacing - - T : xp.array - Knot vector of 0-space. - - t : xp.arrray - Knot vector of 1-space. - - greville : xp.array - Greville points. - - NbaseN : int - Dimension of 0-space. - - NbaseD : int - Dimension of 1-space. - - indN : xp.array - Global indices of non-vanishing B-splines in each element in format (element, local basis function) - - indD : xp.array - Global indices of non-vanishing M-splines in each element in format (element, local basis function) - - pts : xp.array - Global GL quadrature points in format (element, local point). - - wts : xp.array - Global GL quadrature weights in format (element, local point). - - basisN : xp.array - N-basis functions evaluated at quadrature points in format (element, local basis function, derivative, local point) - - basisD : xp.array - D-basis functions evaluated at quadrature points in format (element, local basis function, derivative, local point) - - E0 : csr_matrix - Identity matrix of rank NbaseN. - - E1 : csr_matrix - Identity matrix of rank NbaseD. - - B0 : csr_matrix - Boundary operator for 0-space: removes interpolatory B-spline at eta=0 if bc[0]='d', at eta=1 if bc[1]='d'. - - B1 : csr_matrix - Boundary operator for 1-space, same as E1 (identity). - - E0_0 : csr_matrix - Extraction operator for 0-space, with bc applied: E0_0 = B0 * E0 - - E1_0 : csr_matrix - Extraction operator for 1-space, same as E1 (identity). - - M0 : csr_matrix - NN-mass-matrix with boundary conditions, M0 = E0_0 * M0_full * E0_0^T. - - M01 : csr_matrix - ND-mass-matrix with boundary conditions, M01_0 = E0_0 * M0. - - M10 : csr_matrix - DN-mass-matrix (csr) with boundary conditions, M10_0 = M0 * E0_0^T. - - M1 : csr_matrix - DD-mass-matrix. - - G : csr_matrix - Derivative matrix. - - G0 : csr_matrix - Derivative matrix with boundary conditions, G0 = B1 * G * B0^T. - - projectors : object - 1D projectors object from struphy.feec.projectors.pro_global.projectors_global.Projectors_global_1d - """ - - def __init__(self, Nel, p, spl_kind, n_quad=6, bc=["f", "f"]): - self.Nel = Nel # number of elements - self.p = p # spline degree - self.spl_kind = spl_kind # kind of spline space (periodic or clamped) - - # boundary conditions at eta=0. and eta=1. in case of clamped splines - if spl_kind: - self.bc = [None, None] - else: - self.bc = bc - - self.el_b = xp.linspace(0.0, 1.0, Nel + 1) # element boundaries - self.delta = 1 / self.Nel # element length - - self.T = bsp.make_knots(self.el_b, self.p, self.spl_kind) # spline knot vector for B-splines (N) - self.t = self.T[1:-1] # spline knot vector for M-splines (D) - - self.greville = bsp.greville(self.T, self.p, self.spl_kind) # greville points - - self.NbaseN = len(self.T) - self.p - 1 - self.spl_kind * self.p # total number of B-splines (N) - self.NbaseD = self.NbaseN - 1 + self.spl_kind # total number of M-splines (D) - - # global indices of non-vanishing splines in each element in format (Nel, p + 1) - self.indN = (xp.indices((self.Nel, self.p + 1 - 0))[1] + xp.arange(self.Nel)[:, None]) % self.NbaseN - self.indD = (xp.indices((self.Nel, self.p + 1 - 1))[1] + xp.arange(self.Nel)[:, None]) % self.NbaseD - - self.n_quad = n_quad # number of Gauss-Legendre points per grid cell (defined by break points) - - self.pts_loc = xp.polynomial.legendre.leggauss(self.n_quad)[0] # Gauss-Legendre points (GLQP) in (-1, 1) - self.wts_loc = xp.polynomial.legendre.leggauss(self.n_quad)[1] # Gauss-Legendre weights (GLQW) in (-1, 1) - - # global GLQP in format (element, local point) and total number of GLQP - self.pts = bsp.quadrature_grid(self.el_b, self.pts_loc, self.wts_loc)[0] - self.n_pts = self.pts.flatten().size - - # global GLQW in format (element, local point) - self.wts = bsp.quadrature_grid(self.el_b, self.pts_loc, self.wts_loc)[1] - - # basis functions evaluated at quadrature points in format (element, local basis function, derivative, local point) - self.basisN = bsp.basis_ders_on_quad_grid(self.T, self.p, self.pts, 0, normalize=False) - self.basisD = bsp.basis_ders_on_quad_grid(self.t, self.p - 1, self.pts, 0, normalize=True) - - # ------------------------------------------------- - # Set extraction operators for boundary conditions: - # ------------------------------------------------- - n1 = self.NbaseN - d1 = self.NbaseD - - # boundary operators - self.B0 = xp.identity(n1, dtype=float) - self.B1 = xp.identity(d1, dtype=float) - - # extraction operators without boundary conditions - self.E0 = spa.csr_matrix(self.B0.copy()) - self.E1 = spa.csr_matrix(self.B1.copy()) - - # remove contributions from N-splines at eta = 0 - if self.bc[0] == "d": - self.B0 = self.B0[1:, :] - - # remove contributions from N-splines at eta = 1 - if self.bc[1] == "d": - self.B0 = self.B0[:-1, :] - - self.B0 = spa.csr_matrix(self.B0) - self.B1 = spa.csr_matrix(self.B1) - - self.E0_0 = self.B0.dot(self.E0) - self.E1_0 = self.B1.dot(self.E1) - - # ------------------------------------------------- - # Set discrete derivatives: - # ------------------------------------------------- - self.G, self.G0 = der.discrete_derivatives_1d(self) - - # print('Spline space set up (1d) done.') - - # functions for setting mass matrices: - # ================================================= - def assemble_M0(self, weight=None): - """Assembles NN-mass-matrix (csr) with boundary conditions, M0_0 = E0_0 * M0 * E0_0^T.""" - self.M0 = self.E0_0.dot(mass_1d.get_M(self, 0, 0, weight).dot(self.E0_0.T)) - print("Assembly of M0 (1d) done.") - - # ================================================= - def assemble_M1(self, weight=None): - """Assembles DD-mass-matrix (csr).""" - self.M1 = self.E1_0.dot(mass_1d.get_M(self, 1, 1, weight).dot(self.E1_0.T)) - print("Assembly of M1 (1d) done.") - - # ================================================= - def assemble_M01(self, weight=None): - """Assembles ND-mass-matrix (csr) with boundary conditions, M01_0 = E0_0 * M0.""" - self.M01 = self.E0_0.dot(mass_1d.get_M(self, 0, 1, weight).dot(self.E1_0.T)) - print("Assembly of M01 (1d) done.") - - # ================================================= - def assemble_M10(self, weight=None): - """Assembles DN-mass-matrix (csr) with boundary conditions, M10_0 = M0 * E0_0^T.""" - self.M10 = self.E1_0.dot(mass_1d.get_M(self, 1, 0, weight).dot(self.E0_0.T)) - print("Assembly of M10 (1d) done.") - - # functions for setting projectors: - # ================================================= - def set_projectors(self, nq=6): - """Initialize 1d projectors object.""" - self.projectors = pro.Projectors_global_1d(self, nq) - # print('Set projectors (1d) done.') - - # spline evaluation and plotting: - # ================================================= - def evaluate_N(self, eta, coeff, kind=0): - """ - Evaluates the spline space (N) at the point(s) eta for given coefficients coeff. - - Parameters - ---------- - eta : double or array_like - evaluation point(s) - - coeff : array_like - FEM coefficients - - kind : int - kind of evaluation (0: N, 2: dN/deta, 3: ddN/deta^2) - - Returns - ------- - value : double or array_like - evaluated FEM field at the point(s) eta - """ - - assert (coeff.size == self.E0.shape[0]) or (coeff.size == self.E0_0.shape[0]) - assert (kind == 0) or (kind == 2) or (kind == 3) - - if coeff.size == self.E0_0.shape[0]: - coeff = self.E0_0.T.dot(coeff) - - if isinstance(eta, float): - pts = xp.array([eta]) - elif isinstance(eta, xp.ndarray): - pts = eta.flatten() - - values = xp.empty(pts.size, dtype=float) - eva_1d.evaluate_vector(self.T, self.p, self.indN, coeff, pts, values, kind) - - if isinstance(eta, float): - values = values[0] - elif isinstance(eta, xp.ndarray): - values = values.reshape(eta.shape) - - return values - - # ================================================= - def evaluate_D(self, eta, coeff): - """ - Evaluates the spline space (D) at the point(s) eta for given coefficients coeff. - - Parameters - ---------- - eta : double or array_like - evaluation point(s) - - coeff : array_like - FEM coefficients - - Returns - ------- - value : double or array_like - evaluated FEM field at the point(s) eta - """ - - assert coeff.size == self.E1.shape[0] - - if isinstance(eta, float): - pts = xp.array([eta]) - elif isinstance(eta, xp.ndarray): - pts = eta.flatten() - - values = xp.empty(pts.size, dtype=float) - eva_1d.evaluate_vector(self.t, self.p - 1, self.indD, coeff, pts, values, 1) - - if isinstance(eta, float): - values = values[0] - elif isinstance(eta, xp.ndarray): - values = values.reshape(eta.shape) - - return values - - # ================================================= - def plot_splines(self, n_pts=500, which="N"): - """ - Plots all basis functions. - - Parameters - ---------- - n_pts : int - number of points for plotting (optinal, default=500) - - which : string - which basis to plot. 'N', 'D' or 'dN' (optional, default='N') - """ - - etaplot = xp.linspace(0.0, 1.0, n_pts) - - degree = self.p - - if which == "N": - coeff = xp.zeros(self.NbaseN, dtype=float) - - for i in range(self.NbaseN): - coeff[:] = 0.0 - coeff[i] = 1.0 - plt.plot(etaplot, self.evaluate_N(etaplot, coeff), label=str(i)) - - elif which == "D": - coeff = xp.zeros(self.NbaseD, dtype=float) - - for i in range(self.NbaseD): - coeff[:] = 0.0 - coeff[i] = 1.0 - plt.plot(etaplot, self.evaluate_D(etaplot, coeff), label=str(i)) - - degree = self.p - 1 - - elif which == "dN": - coeff = xp.zeros(self.NbaseN, dtype=float) - - for i in range(self.NbaseN): - coeff[:] = 0.0 - coeff[i] = 1.0 - plt.plot(etaplot, self.evaluate_N(etaplot, coeff, 2), label=str(i)) - - else: - print("Only N, D and dN available") - - if self.spl_kind: - bcs = "periodic" - else: - bcs = "clamped" - - (greville,) = plt.plot(self.greville, xp.zeros(self.greville.shape), "ro", label="greville") - (breaks,) = plt.plot(self.el_b, xp.zeros(self.el_b.shape), "k+", label="breaks") - plt.title(which + f"$^{degree}$-splines, " + bcs + f", Nel={self.Nel}") - plt.legend(handles=[greville, breaks]) - - -# =============== 2d/3d tensor-product B-spline space ====================== -class Tensor_spline_space: - """ - Defines a tensor product space of 1d B-spline spaces in higher dimensions (2d and 3d). - - Parameters - ---------- - spline_spaces : list of spline_space_1d - 1d B-spline spaces from which the tensor_product B-spline space is built - - ck : int - smoothness contraint at eta_1=0 (pole): -1 (no constraints), 0 or 1 (polar splines) - - cx, cy : 2D arrays - control points for spline mapping in case of polar splines - - n_tor : int - mode number in third direction for a 2D spline space (default n_tor = 0) - - basis_tor : string - basis in third direction for a 2D spline space if |n_tor| > 0 (r: real sin/cos, i: complex Fourier) - - - Attributes - ---------- - E0_0 : csr_matrix - 3D Extraction operator for 0-space with boundary conditions, E0_0 = B0 * E0. - - E1_0 : csr_matrix - 3D Extraction operator for 1-space (as block matrix) with boundary conditions, E1_0 = B1 * E1. - - E2_0 : csr_matrix - 3D Extraction operator for 2-space (as block matrix) with boundary conditions, E2_0 = B2 * E2. - - E3_0 : csr_matrix - 3D Extraction operator for 3-space with boundary conditions, E3_0 = B3 * E3. - - Ev_0 : csr_matrix - 3D Extraction operator for vector-feild-space (as block matrix) with boundary conditions, Ev_0 = Bv * Ev. - - M0 : lin. operator - (NNN)-(NNN)-|detDF|-mass-matrix with extraction, M0 = E0_0 * M0_ * E0_0^T. - - M0_mat : csr_matrix - (NNN)-(NNN)-|detDF|-mass-matrix with extraction, M0 = E0_0 * M0_ * E0_0^T. - - M1 : lin. operator - V1-mass-matrix with extraction, M1 = E1_0 * M1_ * E1_0^T, in format M1_11 = (DNN)-Ginv_11-(DNN)-|detDF|, - M1_12 = (DNN)-Ginv_12-(NDN)-|detDF|, etc. - - M1_mat : csr_matrix - V1-mass-matrix with extraction, M1 = E1_0 * M1_ * E1_0^T, in format M1_11 = (DNN)-Ginv_11-(DNN)-|detDF|, - M1_12 = (DNN)-Ginv_12-(NDN)-|detDF|, etc. - - M2 : linear operator - V2-mass-matrix with extraction, M2 = E2_0 * M2_ * E2_0^T, in format M2_11 = (NDD)-G_11-(NDD)-|detDFinv|, - M2_12 = (NDD)-G_12-(DND)-|detDFinv|, etc. - - M2_mat : csr_matrix - V2-mass-matrix with extraction, M2 = E2_0 * M2_ * E2_0^T, in format M2_11 = (NDD)-G_11-(NDD)-|detDFinv|, - M2_12 = (NDD)-G_12-(DND)-|detDFinv|, etc. - - M3 : linear operator - (DDD)-(DDD)-|detDFinv|-mass-matrix with extraction, M3 = E3_0 * M3_ * E3_0^T. - - M3_mat : csr_matrix - (DDD)-(DDD)-|detDFinv|-mass-matrix with extraction, M3 = E3_0 * M3_ * E3_0^T. - - Mv : linear operator - Vector-field-mass-matrix in format Mv_ij = (NNN)-G_ij-(NNN)-|detDF|. - - Mv_mat : csr_matrix - Vector-field-mass-matrix in format Mv_ij = (NNN)-G_ij-(NNN)-|detDF|. - - G : csr_matrix - Gradient (block) matrix. - - G0 : csr_matrix - Gradient (block) matrix with boundary conditions, G0 = B1 * G * B0^T. - - C : csr_matrix - Curl (block) matrix. - - C0 : csr_matrix - Curl (block) matrix with boundary conditions, C0 = B2 * C * B1^T. - - D : csr_matrix - Divergence (block) matrix. - - D0 : csr_matrix - Divergence (block) matrix with boundary conditions, D0 = B3 * D * B2^T. - - projectors : object - 3D projectors object from struphy.feec.projectors.pro_global.projectors_global.Projectors_global_3d. - """ - - def __init__(self, spline_spaces, ck=-1, cx=None, cy=None, n_tor=0, basis_tor="r"): - # 1D B-spline spaces - assert len(spline_spaces) == 2 or len(spline_spaces) == 3 - - self.spaces = spline_spaces - self.dim = len(self.spaces) - - # set basis in 3rd dimension if |n_tor| > 0 (2D space): sin(2*pi*n*eta_3)/cos(2*pi*n*eta_3) or exp(i*2*pi*n*eta_3) - if self.dim == 2: - self.n_tor = 0 - - if abs(n_tor) > 0: - assert isinstance(n_tor, int) - self.n_tor = n_tor - - assert basis_tor == "r" or basis_tor == "i" - self.basis_tor = basis_tor - - # C^k smoothness constraint at eta_1 = 0 - assert ck == -1 or ck == 0 or ck == 1 - - self.ck = ck - - if self.ck == 1: - assert cx.ndim == 2 - assert cy.ndim == 2 - - # input from 1d spaces - # ==================== - self.Nel = [spl.Nel for spl in self.spaces] # number of elements - self.p = [spl.p for spl in self.spaces] # spline degree - self.spl_kind = [spl.spl_kind for spl in self.spaces] # kind of spline space (periodic or clamped) - - self.bc = [spl.bc for spl in self.spaces] # boundary conditions at eta = 0 and eta = 1 - - self.el_b = [spl.el_b for spl in self.spaces] # element boundaries - self.delta = [spl.delta for spl in self.spaces] # element lengths - - self.T = [spl.T for spl in self.spaces] # spline knot vector for B-splines (N) - self.t = [spl.t for spl in self.spaces] # spline knot vector for M-splines (D) - - self.NbaseN = [spl.NbaseN for spl in self.spaces] # total number of B-splines (N) - self.NbaseD = [spl.NbaseD for spl in self.spaces] # total number of M-splines (D) - - self.indN = [spl.indN for spl in self.spaces] # global indices of non-vanishing B-splines (N) per element - self.indD = [spl.indD for spl in self.spaces] # global indices of non-vanishing M-splines (D) per element - - self.n_quad = [spl.n_quad for spl in self.spaces] # number of Gauss-Legendre quadrature points per element - - self.pts_loc = [spl.pts_loc for spl in self.spaces] # Gauss-Legendre quadrature points (GLQP) in (-1, 1) - self.wts_loc = [spl.wts_loc for spl in self.spaces] # Gauss-Legendre quadrature weights (GLQW) in (-1, 1) - - self.pts = [spl.pts for spl in self.spaces] # global GLQP in format (element, local point) - self.wts = [spl.wts for spl in self.spaces] # global GLQW in format (element, local weight) - - self.n_pts = [spl.n_pts for spl in self.spaces] # total number of quadrature points - - # basis functions evaluated at quadrature points in format (element, local basis function, derivative, local point) - self.basisN = [spl.basisN for spl in self.spaces] - self.basisD = [spl.basisD for spl in self.spaces] - - # set number of basis function in 3rd direction for 2D space - if self.dim == 2: - if self.n_tor == 0: - self.NbaseN = self.NbaseN + [1] - self.NbaseD = self.NbaseD + [1] - - else: - if self.basis_tor == "r": - self.NbaseN = self.NbaseN + [2] - self.NbaseD = self.NbaseD + [2] - - else: - self.NbaseN = self.NbaseN + [1] - self.NbaseD = self.NbaseD + [1] - - # set mass matrices in 3rd direction - if self.dim == 2: - if self.n_tor == 0 or self.basis_tor == "i": - self.M0_tor = spa.identity(1, format="csr") - self.M1_tor = spa.identity(1, format="csr") - - else: - self.M0_tor = spa.csr_matrix(xp.identity(2) / 2) - self.M1_tor = spa.csr_matrix(xp.identity(2) / 2) - - else: - self.M0_tor = mass_1d.get_M(self.spaces[2], 0, 0) - self.M1_tor = mass_1d.get_M(self.spaces[2], 1, 1) - - # number of basis functions of discrete tensor-product p-forms in 2D x analytical third dimension - self.Nbase_0form = [self.NbaseN[0], self.NbaseN[1], self.NbaseN[2]] - - self.Nbase_1form = [ - [self.NbaseD[0], self.NbaseN[1], self.NbaseN[2]], - [self.NbaseN[0], self.NbaseD[1], self.NbaseN[2]], - [self.NbaseN[0], self.NbaseN[1], self.NbaseD[2]], - ] - - self.Nbase_2form = [ - [self.NbaseN[0], self.NbaseD[1], self.NbaseD[2]], - [self.NbaseD[0], self.NbaseN[1], self.NbaseD[2]], - [self.NbaseD[0], self.NbaseD[1], self.NbaseN[2]], - ] - - self.Nbase_3form = [self.NbaseD[0], self.NbaseD[1], self.NbaseD[2]] - - # total number of basis functions - self.Ntot_0form = self.NbaseN[0] * self.NbaseN[1] * self.NbaseN[2] - - self.Ntot_1form = [ - self.NbaseD[0] * self.NbaseN[1] * self.NbaseN[2], - self.NbaseN[0] * self.NbaseD[1] * self.NbaseN[2], - self.NbaseN[0] * self.NbaseN[1] * self.NbaseD[2], - ] - - self.Ntot_2form = [ - self.NbaseN[0] * self.NbaseD[1] * self.NbaseD[2], - self.NbaseD[0] * self.NbaseN[1] * self.NbaseD[2], - self.NbaseD[0] * self.NbaseD[1] * self.NbaseN[2], - ] - - self.Ntot_3form = self.NbaseD[0] * self.NbaseD[1] * self.NbaseD[2] - - # cumulative number of basis functions for vector-valued spaces - self.Ntot_1form_cum = [ - self.Ntot_1form[0], - self.Ntot_1form[0] + self.Ntot_1form[1], - self.Ntot_1form[0] + self.Ntot_1form[1] + self.Ntot_1form[2], - ] - - self.Ntot_2form_cum = [ - self.Ntot_2form[0], - self.Ntot_2form[0] + self.Ntot_2form[1], - self.Ntot_2form[0] + self.Ntot_2form[1] + self.Ntot_2form[2], - ] - - # ------------------------------------------------- - # Set extraction operators for boundary conditions: - # ------------------------------------------------- - - # standard tensor-product splines in eta_1-eta_2 plane - if self.ck == -1: - # extraction operators without boundary conditions - ENN = spa.kron(self.spaces[0].E0, self.spaces[1].E0, format="csr") - EDN = spa.kron(self.spaces[0].E1, self.spaces[1].E0, format="csr") - END = spa.kron(self.spaces[0].E0, self.spaces[1].E1, format="csr") - EDD = spa.kron(self.spaces[0].E1, self.spaces[1].E1, format="csr") - - self.E0_pol = ENN - self.E3_pol = EDD - - self.E1_pol = spa.bmat([[EDN, None], [None, END]], format="csr") - self.E2_pol = spa.bmat([[END, None], [None, EDN]], format="csr") - - self.Ev_pol = spa.bmat([[ENN, None], [None, ENN]], format="csr") - - # boundary operators - BNN = spa.kron(self.spaces[0].B0, self.spaces[1].B0, format="csr") - BDN = spa.kron(self.spaces[0].B1, self.spaces[1].B0, format="csr") - BND = spa.kron(self.spaces[0].B0, self.spaces[1].B1, format="csr") - BDD = spa.kron(self.spaces[0].B1, self.spaces[1].B1, format="csr") - - self.B0_pol = BNN - self.B3_pol = BDD - - self.B1_pol = spa.bmat([[BDN, None], [None, BND]], format="csr") - self.B2_pol = spa.bmat([[BND, None], [None, BDN]], format="csr") - - Bv1 = spa.kron(self.spaces[0].B0, spa.identity(self.spaces[1].NbaseN), format="csr") - Bv2 = spa.kron(spa.identity(self.spaces[0].NbaseN), self.spaces[1].B0, format="csr") - Bv3 = spa.kron(spa.identity(self.spaces[0].NbaseN), spa.identity(self.spaces[1].NbaseN), format="csr") - - self.Bv_pol = spa.bmat([[Bv1, None], [None, Bv2]], format="csr") - - # C^k polar splines in eta_1-eta_2 plane - else: - if self.ck == 0: - self.polar_splines = pol.PolarSplines_C0_2D(self.spaces[0].NbaseN, self.spaces[1].NbaseN) - elif self.ck == 1: - self.polar_splines = pol.PolarSplines_C1_2D(cx, cy) - - # extraction operators without boundary conditions - self.E0_pol = self.polar_splines.E0.copy() - self.E1_pol = self.polar_splines.E1C.copy() - self.E2_pol = self.polar_splines.E1D.copy() - self.E3_pol = self.polar_splines.E2.copy() - - self.Ev_pol = spa.bmat([[self.E0_pol, None], [None, self.E0_pol]], format="csr") - - # boundary operators - BNN = spa.identity(self.polar_splines.Nbase0, format="lil") - BDD = spa.identity(self.polar_splines.Nbase2, format="lil") - - BDN = spa.identity(self.polar_splines.Nbase1C_1, format="lil") - BND = spa.identity(self.polar_splines.Nbase1C_2, format="lil") - - if self.bc[0][1] == "d": - BNN = BNN[: -self.spaces[1].NbaseN, :] - BND = BND[: -self.spaces[1].NbaseD, :] - - self.B0_pol = BNN.tocsr() - self.B3_pol = BDD.tocsr() - - self.B1_pol = spa.bmat([[BDN, None], [None, BND]], format="csr") - self.B2_pol = spa.bmat([[BND, None], [None, BDN]], format="csr") - - Bv1 = self.B0_pol - Bv2 = spa.identity(self.polar_splines.Nbase0, format="csr") - Bv3 = spa.identity(self.polar_splines.Nbase0, format="csr") - - self.Bv_pol = spa.bmat([[Bv1, None], [None, Bv2]], format="csr") - - # extraction operators with boundary conditions - self.E0_pol_0 = self.B0_pol.dot(self.E0_pol).tocsr() - self.E1_pol_0 = self.B1_pol.dot(self.E1_pol).tocsr() - self.E2_pol_0 = self.B2_pol.dot(self.E2_pol).tocsr() - self.E3_pol_0 = self.B3_pol.dot(self.E3_pol).tocsr() - self.Ev_pol_0 = self.Bv_pol.dot(self.Ev_pol).tocsr() - - # toroidal eta_3 direction - if self.dim == 2: - self.E0_tor = spa.identity(self.NbaseN[2]) - self.E1_tor = spa.identity(self.NbaseD[2]) - - self.B0_tor = spa.identity(self.NbaseN[2]) - self.B1_tor = spa.identity(self.NbaseD[2]) - - else: - self.E0_tor = self.spaces[2].E0 - self.E1_tor = self.spaces[2].E1 - - self.B0_tor = self.spaces[2].B0 - self.B1_tor = self.spaces[2].B1 - - self.E0_tor_0 = self.B0_tor.dot(self.E0_tor).tocsr() - self.E1_tor_0 = self.B1_tor.dot(self.E1_tor).tocsr() - - # extraction operators for 3D diagram: without boundary conditions - self.E0 = spa.kron(self.E0_pol, self.E0_tor, format="csr") - self.E1 = spa.bmat( - [[spa.kron(self.E1_pol, self.E0_tor), None], [None, spa.kron(self.E0_pol, self.E1_tor)]], - format="csr", - ) - self.E2 = spa.bmat( - [[spa.kron(self.E2_pol, self.E1_tor), None], [None, spa.kron(self.E3_pol, self.E0_tor)]], - format="csr", - ) - self.E3 = spa.kron(self.E3_pol, self.E1_tor, format="csr") - self.Ev = spa.bmat( - [[spa.kron(self.Ev_pol, self.E0_tor), None], [None, spa.kron(self.E0_pol, self.E0_tor)]], - format="csr", - ) - - # boundary operators for 3D diagram - self.B0 = spa.kron(self.B0_pol, self.B0_tor, format="csr") - self.B1 = spa.bmat( - [[spa.kron(self.B1_pol, self.B0_tor), None], [None, spa.kron(self.B0_pol, self.B1_tor)]], - format="csr", - ) - self.B2 = spa.bmat( - [[spa.kron(self.B2_pol, self.B1_tor), None], [None, spa.kron(self.B3_pol, self.B0_tor)]], - format="csr", - ) - self.B3 = spa.kron(self.B3_pol, self.B1_tor, format="csr") - self.Bv = spa.bmat( - [[spa.kron(self.Bv_pol, self.E0_tor), None], [None, spa.kron(Bv3, self.B0_tor)]], - format="csr", - ) - - # extraction operators for 3D diagram: with boundary conditions - self.E0_0 = self.B0.dot(self.E0).tocsr() - self.E1_0 = self.B1.dot(self.E1).tocsr() - self.E2_0 = self.B2.dot(self.E2).tocsr() - self.E3_0 = self.B3.dot(self.E3).tocsr() - self.Ev_0 = self.Bv.dot(self.Ev).tocsr() - - # ------------------------------------------------- - # Set discrete derivatives: - # ------------------------------------------------- - self.G, self.G0, self.C, self.C0, self.D, self.D0 = der.discrete_derivatives_3d(self) - - # function for setting projectors: - # ================================================= - def set_projectors(self, which="tensor"): - # tensor-product projectors (no polar splines possible) - if which == "tensor": - if self.dim == 2: - self.projectors = pro.Projectors_tensor_2d([space.projectors for space in self.spaces]) - elif self.dim == 3: - self.projectors = pro.Projectors_tensor_3d([space.projectors for space in self.spaces]) - else: - raise NotImplementedError("Only 2d and 3d supported.") - - # general projectors (polar splines possible) - elif which == "general": - self.projectors = pro.ProjectorsGlobal3D(self) - - # ============== mass matrices ======================= - def apply_M0_ten(self, x, mats): - """ - TODO - """ - - x = self.reshape_pol_0(x) - - out = mats[1].dot(mats[0].dot(x).T).T - - return out.flatten() - - def apply_M1_ten(self, x, mats): - """ - TODO - """ - - x1, x2 = self.reshape_pol_1(x) - - out1 = mats[0][1].dot(mats[0][0].dot(x1).T).T - out2 = mats[1][1].dot(mats[1][0].dot(x2).T).T - - return xp.concatenate((out1.flatten(), out2.flatten())) - - def apply_M2_ten(self, x, mats): - """ - TODO - """ - - x1, x2 = self.reshape_pol_2(x) - - out1 = mats[0][1].dot(mats[0][0].dot(x1).T).T - out2 = mats[1][1].dot(mats[1][0].dot(x2).T).T - - return xp.concatenate((out1.flatten(), out2.flatten())) - - def apply_M3_ten(self, x, mats): - """ - TODO - """ - - x = self.reshape_pol_3(x) - - out = mats[1].dot(mats[0].dot(x).T).T - - return out.flatten() - - def apply_Mv_ten(self, x, mats): - """ - TODO - """ - - x1, x2 = self.reshape_pol_v(x) - - out1 = mats[0][1].dot(mats[0][0].dot(x1).T).T - out2 = mats[1][1].dot(mats[1][0].dot(x2).T).T - - return xp.concatenate((out1.flatten(), out2.flatten())) - - def apply_M0_0_ten(self, x, mats): - """ - TODO - """ - - x = self.reshape_pol_0(x) - - out = self.B0_tor.dot(mats[1].dot(self.B0_tor.T.dot(self.B0_pol.dot(mats[0].dot(self.B0_pol.T.dot(x))).T))).T - - return out.flatten() - - def apply_M1_0_ten(self, x, mats): - """ - TODO - """ - - x1, x2 = self.reshape_pol_1(x) - - out1 = self.B0_tor.dot( - mats[0][1].dot(self.B0_tor.T.dot(self.B1_pol.dot(mats[0][0].dot(self.B1_pol.T.dot(x1))).T)), - ).T - out2 = self.B1_tor.dot( - mats[1][1].dot(self.B1_tor.T.dot(self.B0_pol.dot(mats[1][0].dot(self.B0_pol.T.dot(x2))).T)), - ).T - - return xp.concatenate((out1.flatten(), out2.flatten())) - - def apply_M2_0_ten(self, x, mats): - """ - TODO - """ - - x1, x2 = self.reshape_pol_2(x) - - out1 = self.B1_tor.dot( - mats[0][1].dot(self.B1_tor.T.dot(self.B2_pol.dot(mats[0][0].dot(self.B2_pol.T.dot(x1))).T)), - ).T - out2 = self.B0_tor.dot( - mats[1][1].dot(self.B0_tor.T.dot(self.B3_pol.dot(mats[1][0].dot(self.B3_pol.T.dot(x2))).T)), - ).T - - return xp.concatenate((out1.flatten(), out2.flatten())) - - def apply_M3_0_ten(self, x, mats): - """ - TODO - """ - - x = self.reshape_pol_3(x) - - out = self.B1_tor.dot(mats[1].dot(self.B1_tor.T.dot(self.B3_pol.dot(mats[0].dot(self.B3_pol.T.dot(x))).T))).T - - return out.flatten() - - def apply_Mv_0_ten(self, x, mats): - """ - TODO - """ - - x1, x2 = self.reshape_pol_v(x) - - out1 = mats[0][1].dot(self.Bv_pol.dot(mats[0][0].dot(self.Bv_pol.T.dot(x1))).T).T - out2 = self.B0_tor.dot(mats[1][1].dot(self.B0_tor.T.dot(mats[1][0].dot(x2).T))).T - - return xp.concatenate((out1.flatten(), out2.flatten())) - - def __assemble_M0(self, domain, as_tensor=False): - """ - TODO - """ - - self.M0_as_tensor = as_tensor - - # tensor product 2D poloidal x 1D toroidal - if as_tensor: - self.M0_pol_mat = mass_2d.get_M0(self, domain) - - matvec = lambda x: self.apply_M0_ten(x, [self.M0_pol_mat, self.M0_tor]) - matvec_0 = lambda x: self.apply_M0_0_ten(x, [self.M0_pol_mat, self.M0_tor]) - - # 3D - else: - if self.dim == 2: - self.M0_mat = spa.kron(mass_2d.get_M0(self, domain), self.M0_tor, format="csr") - else: - self.M0_mat = mass_3d.get_M0(self, domain) - - matvec = lambda x: self.M0_mat.dot(x) - matvec_0 = lambda x: self.B0.dot(self.M0_mat.dot(self.B0.T.dot(x))) - - # linear operators - self.M0 = spa.linalg.LinearOperator((self.E0.shape[0], self.E0.shape[0]), matvec=matvec) - self.M0_0 = spa.linalg.LinearOperator((self.E0_0.shape[0], self.E0_0.shape[0]), matvec=matvec_0) - - def __assemble_M1(self, domain, as_tensor=False): - """ - TODO - """ - - self.M1_as_tensor = as_tensor - - # tensor product 2D poloidal x 1D toroidal - if as_tensor: - self.M1_pol_mat = mass_2d.get_M1(self, domain) - - matvec = lambda x: self.apply_M1_ten( - x, - [[self.M1_pol_mat[0], self.M0_tor], [self.M1_pol_mat[1], self.M1_tor]], - ) - matvec_0 = lambda x: self.apply_M1_0_ten( - x, - [[self.M1_pol_mat[0], self.M0_tor], [self.M1_pol_mat[1], self.M1_tor]], - ) - - # 3D - else: - if self.dim == 2: - M11, M22 = mass_2d.get_M1(self, domain) - self.M1_mat = spa.bmat( - [[spa.kron(M11, self.M0_tor), None], [None, spa.kron(M22, self.M1_tor)]], - format="csr", - ) - else: - self.M1_mat = mass_3d.get_M1(self, domain) - - matvec = lambda x: self.M1_mat.dot(x) - matvec_0 = lambda x: self.B1.dot(self.M1_mat.dot(self.B1.T.dot(x))) - - # linaer operators - self.M1 = spa.linalg.LinearOperator((self.E1.shape[0], self.E1.shape[0]), matvec=matvec) - self.M1_0 = spa.linalg.LinearOperator((self.E1_0.shape[0], self.E1_0.shape[0]), matvec=matvec_0) - - def __assemble_M2(self, domain, as_tensor=False): - """ - TODO - """ - - self.M2_as_tensor = as_tensor - - # tensor product 2D poloidal x 1D toroidal - if as_tensor: - self.M2_pol_mat = mass_2d.get_M2(self, domain) - - matvec = lambda x: self.apply_M2_ten( - x, - [[self.M2_pol_mat[0], self.M1_tor], [self.M2_pol_mat[1], self.M0_tor]], - ) - matvec_0 = lambda x: self.apply_M2_0_ten( - x, - [[self.M2_pol_mat[0], self.M1_tor], [self.M2_pol_mat[1], self.M0_tor]], - ) - - # 3D - else: - if self.dim == 2: - M11, M22 = mass_2d.get_M2(self, domain) - self.M2_mat = spa.bmat( - [[spa.kron(M11, self.M1_tor), None], [None, spa.kron(M22, self.M0_tor)]], - format="csr", - ) - else: - self.M2_mat = mass_3d.get_M2(self, domain) - - matvec = lambda x: self.M2_mat.dot(x) - matvec_0 = lambda x: self.B2.dot(self.M2_mat.dot(self.B2.T.dot(x))) - - # linear operators - self.M2 = spa.linalg.LinearOperator((self.E2.shape[0], self.E2.shape[0]), matvec=matvec) - self.M2_0 = spa.linalg.LinearOperator((self.E2_0.shape[0], self.E2_0.shape[0]), matvec=matvec_0) - - def __assemble_M3(self, domain, as_tensor=False): - """ - TODO - """ - - self.M3_as_tensor = as_tensor - - # tensor product 2D poloidal x 1D toroidal - if as_tensor: - self.M3_pol_mat = mass_2d.get_M3(self, domain) - - matvec = lambda x: self.apply_M3_ten(x, [self.M3_pol_mat, self.M1_tor]) - matvec_0 = lambda x: self.apply_M3_0_ten(x, [self.M3_pol_mat, self.M1_tor]) - - # 3D - else: - if self.dim == 2: - self.M3_mat = spa.kron(mass_2d.get_M3(self, domain), self.M1_tor, format="csr") - else: - self.M3_mat = mass_3d.get_M3(self, domain) - - matvec = lambda x: self.M3_mat.dot(x) - matvec_0 = lambda x: self.B3.dot(self.M3_mat.dot(self.B3.T.dot(x))) - - # linear operators - self.M3 = spa.linalg.LinearOperator((self.E3.shape[0], self.E3.shape[0]), matvec=matvec) - self.M3_0 = spa.linalg.LinearOperator((self.E3_0.shape[0], self.E3_0.shape[0]), matvec=matvec_0) - - def __assemble_Mv(self, domain, as_tensor=False): - """ - TODO - """ - - self.Mv_as_tensor = as_tensor - - # tensor product 2D poloidal x 1D toroidal - if as_tensor: - self.Mv_pol_mat = mass_2d.get_Mv(self, domain) - - matvec = lambda x: self.apply_Mv_ten( - x, - [[self.Mv_pol_mat[0], self.M0_tor], [self.Mv_pol_mat[1], self.M0_tor]], - ) - matvec_0 = lambda x: self.apply_Mv_0_ten( - x, - [[self.Mv_pol_mat[0], self.M0_tor], [self.Mv_pol_mat[1], self.M0_tor]], - ) - - # 3D - else: - if self.dim == 2: - M11, M22 = mass_2d.get_Mv(self, domain) - self.Mv_mat = spa.bmat( - [[spa.kron(M11, self.M0_tor), None], [None, spa.kron(M22, self.M0_tor)]], - format="csr", - ) - else: - self.Mv_mat = mass_3d.get_Mv(self, domain) - - matvec = lambda x: self.Mv_mat.dot(x) - matvec_0 = lambda x: self.Bv.dot(self.Mv_mat.dot(self.Bv.T.dot(x))) - - # linear operators - self.Mv = spa.linalg.LinearOperator((self.Ev.shape[0], self.Ev.shape[0]), matvec=matvec) - self.Mv_0 = spa.linalg.LinearOperator((self.Ev_0.shape[0], self.Ev_0.shape[0]), matvec=matvec_0) - - def assemble_Mk(self, domain, space, as_tensor=False): - """ - TODO - """ - - if space == "V0": - self.__assemble_M0(domain, as_tensor) - elif space == "V1": - self.__assemble_M1(domain, as_tensor) - elif space == "V2": - self.__assemble_M2(domain, as_tensor) - elif space == "V3": - self.__assemble_M3(domain, as_tensor) - elif space == "Vv": - self.__assemble_Mv(domain, as_tensor) - - # == reshape of flattened 3D coefficients to structure (2D poloidal x 1D toroidal) === - def reshape_pol_0(self, coeff): - """ - TODO - """ - - c_size = coeff.size - - assert c_size == self.E0.shape[0] or c_size == self.E0_0.shape[0] - - if c_size == self.E0.shape[0]: - coeff0_pol = coeff.reshape(self.E0_pol.shape[0], self.E0_tor.shape[0]) - else: - coeff0_pol = coeff.reshape(self.E0_pol_0.shape[0], self.E0_tor_0.shape[0]) - - return coeff0_pol - - def reshape_pol_1(self, coeff): - """ - TODO - """ - - c_size = coeff.size - - assert c_size == self.E1.shape[0] or c_size == self.E1_0.shape[0] - - if c_size == self.E1.shape[0]: - coeff1_pol_1 = coeff[: self.E1_pol.shape[0] * self.E0_tor.shape[0]].reshape( - self.E1_pol.shape[0], - self.E0_tor.shape[0], - ) - coeff1_pol_3 = coeff[self.E1_pol.shape[0] * self.E0_tor.shape[0] :].reshape( - self.E0_pol.shape[0], - self.E1_tor.shape[0], - ) - else: - coeff1_pol_1 = coeff[: self.E1_pol_0.shape[0] * self.E0_tor_0.shape[0]].reshape( - self.E1_pol_0.shape[0], - self.E0_tor_0.shape[0], - ) - coeff1_pol_3 = coeff[self.E1_pol_0.shape[0] * self.E0_tor_0.shape[0] :].reshape( - self.E0_pol_0.shape[0], - self.E1_tor_0.shape[0], - ) - - return coeff1_pol_1, coeff1_pol_3 - - def reshape_pol_2(self, coeff): - """ - TODO - """ - - c_size = coeff.size - - assert c_size == self.E2.shape[0] or c_size == self.E2_0.shape[0] - - if c_size == self.E2.shape[0]: - coeff2_pol_1 = coeff[: self.E2_pol.shape[0] * self.E1_tor.shape[0]].reshape( - self.E2_pol.shape[0], - self.E1_tor.shape[0], - ) - coeff2_pol_3 = coeff[self.E2_pol.shape[0] * self.E1_tor.shape[0] :].reshape( - self.E3_pol.shape[0], - self.E0_tor.shape[0], - ) - else: - coeff2_pol_1 = coeff[: self.E2_pol_0.shape[0] * self.E1_tor_0.shape[0]].reshape( - self.E2_pol_0.shape[0], - self.E1_tor_0.shape[0], - ) - coeff2_pol_3 = coeff[self.E2_pol_0.shape[0] * self.E1_tor_0.shape[0] :].reshape( - self.E3_pol_0.shape[0], - self.E0_tor_0.shape[0], - ) - - return coeff2_pol_1, coeff2_pol_3 - - def reshape_pol_3(self, coeff): - """ - TODO - """ - - c_size = coeff.size - - assert c_size == self.E3.shape[0] or c_size == self.E3_0.shape[0] - - if c_size == self.E3.shape[0]: - coeff3_pol = coeff.reshape(self.E3_pol.shape[0], self.E1_tor.shape[0]) - else: - coeff3_pol = coeff.reshape(self.E3_pol_0.shape[0], self.E1_tor_0.shape[0]) - - return coeff3_pol - - def reshape_pol_v(self, coeff): - """ - TODO - """ - - c_size = coeff.size - - assert c_size == self.Ev.shape[0] or c_size == self.Ev_0.shape[0] - - if c_size == self.Ev.shape[0]: - coeffv_pol_1 = coeff[: self.Ev_pol.shape[0] * self.E0_tor.shape[0]].reshape( - self.Ev_pol.shape[0], - self.E0_tor.shape[0], - ) - coeffv_pol_3 = coeff[self.Ev_pol.shape[0] * self.E0_tor.shape[0] :].reshape( - self.E0_pol.shape[0], - self.E0_tor.shape[0], - ) - - else: - coeffv_pol_1 = coeff[: self.Ev_pol_0.shape[0] * self.E0_tor.shape[0]].reshape( - self.Ev_pol_0.shape[0], - self.E0_tor.shape[0], - ) - coeffv_pol_3 = coeff[self.Ev_pol_0.shape[0] * self.E0_tor.shape[0] :].reshape( - self.E0_pol.shape[0], - self.E0_tor_0.shape[0], - ) - - return coeffv_pol_1, coeffv_pol_3 - - # ========= extraction of flattened 3D coefficients to tensor-product space ========= - def extract_0(self, coeff): - """Reshape flattened 3D 0-form coefficients to tensor-product space. - - Parameters - ---------- - coeff : numpy.ndarray - Flattened 3D coefficients. - - Returns - ------- - coeff0 : numpy.ndarray - Coefficients in tensor-produce space. - """ - - c_size = coeff.size - - assert c_size == self.E0.shape[0] or c_size == self.E0_0.shape[0] - - if c_size == self.E0.shape[0]: - coeff0 = self.E0.T.dot(coeff) - else: - coeff0 = self.E0_0.T.dot(coeff) - - coeff0 = coeff0.reshape(self.Nbase_0form) - - return coeff0 - - def extract_1(self, coeff): - """Reshape flattened 3D 1-form coefficients to tensor-product space. - - Parameters - ---------- - coeff : numpy.ndarray - Flattened 3D coefficients. - - Returns - ------- - (coeff1_1, coeff1_2, coeff1_3) : tuple of numpy.ndarray - Coefficients in tensor-produce space. - """ - - c_size = coeff.size - - assert c_size == self.E1.shape[0] or c_size == self.E1_0.shape[0] - - if c_size == self.E1.shape[0]: - coeff1 = self.E1.T.dot(coeff) - else: - coeff1 = self.E1_0.T.dot(coeff) - - coeff1_1, coeff1_2, coeff1_3 = xp.split(coeff1, [self.Ntot_1form_cum[0], self.Ntot_1form_cum[1]]) - - coeff1_1 = coeff1_1.reshape(self.Nbase_1form[0]) - coeff1_2 = coeff1_2.reshape(self.Nbase_1form[1]) - coeff1_3 = coeff1_3.reshape(self.Nbase_1form[2]) - - return coeff1_1, coeff1_2, coeff1_3 - - def extract_2(self, coeff): - """Reshape flattened 3D 2-form coefficients to tensor-product space. - - Parameters - ---------- - coeff : numpy.ndarray - Flattened 3D coefficients. - - Returns - ------- - (coeff2_1, coeff2_2, coeff2_3) : tuple of numpy.ndarray - Coefficients in tensor-produce space. - """ - - c_size = coeff.size - - assert c_size == self.E2.shape[0] or c_size == self.E2_0.shape[0] - - if c_size == self.E2.shape[0]: - coeff2 = self.E2.T.dot(coeff) - else: - coeff2 = self.E2_0.T.dot(coeff) - - coeff2_1, coeff2_2, coeff2_3 = xp.split(coeff2, [self.Ntot_2form_cum[0], self.Ntot_2form_cum[1]]) - - coeff2_1 = coeff2_1.reshape(self.Nbase_2form[0]) - coeff2_2 = coeff2_2.reshape(self.Nbase_2form[1]) - coeff2_3 = coeff2_3.reshape(self.Nbase_2form[2]) - - return coeff2_1, coeff2_2, coeff2_3 - - def extract_3(self, coeff): - """Reshape flattened 3D 3-form coefficients to tensor-product space. - - Parameters - ---------- - coeff : numpy.ndarray - Flattened 3D coefficients. - - Returns - ------- - coeff3 : numpy.ndarray - Coefficients in tensor-produce space. - """ - - c_size = coeff.size - - assert c_size == self.E3.shape[0] or c_size == self.E3_0.shape[0] - - if c_size == self.E3.shape[0]: - coeff3 = self.E3.T.dot(coeff) - else: - coeff3 = self.E3_0.T.dot(coeff) - - coeff3 = coeff3.reshape(self.Nbase_3form) - - return coeff3 - - def extract_v(self, coeff): - c_size = coeff.size - - assert c_size == self.Ev.shape[0] or c_size == self.Ev_0.shape[0] - - if c_size == self.Ev.shape[0]: - coeffv = self.Ev.T.dot(coeff) - else: - coeffv = self.Ev_0.T.dot(coeff) - - coeffv_1, coeffv_2, coeffv_3 = xp.split(coeffv, [self.Ntot_0form, 2 * self.Ntot_0form]) - - coeffv_1 = coeffv_1.reshape(self.Nbase_0form) - coeffv_2 = coeffv_2.reshape(self.Nbase_0form) - coeffv_3 = coeffv_3.reshape(self.Nbase_0form) - - return coeffv_1, coeffv_2, coeffv_3 - - # ================================================= - def evaluate_NN(self, eta1, eta2, eta3, coeff, which="V0", part="r"): - """ - Evaluates the spline space [(NN) x Fourier] with coefficients 'coeff' at the point(s) eta = (eta1, eta2, eta3). - - Parameters - ---------- - eta1 : double or array_like - 1st component of logical evaluation point(s) - - eta2 : double or array_like - 2nd component of logical evaluation point(s) - - eta3 : double or array_like - 3rd component of logical evaluation point(s) - - coeff : array_like - FEM coefficients - - which : string - which space (V0 or V1) - - part : string - real (r) or imaginary (i) part to return - - Returns - ------- - out : double or array_like - evaluated FEM field at the point(s) eta = (eta1, eta2, eta3) - """ - - assert part == "r" or part == "i" - assert which == "V0" or which == "V1" - - # extract coefficients if flattened - if coeff.ndim == 1: - if which == "V0": - coeff = self.extract_0(coeff) - else: - coeff = self.extract_1(coeff)[2] - - # check if coefficients have correct shape - assert coeff.shape[:2] == (self.NbaseN[0], self.NbaseN[1]) - - # get real and imaginary part - coeff_r = xp.real(coeff) - coeff_i = xp.imag(coeff) - - # ------ evaluate FEM field at given points -------- - if isinstance(eta1, xp.ndarray): - # tensor-product evaluation - if eta1.ndim == 1: - values_r_1 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - values_i_1 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - - eva_2d.evaluate_tensor_product_2d( - self.T[0], - self.T[1], - self.p[0], - self.p[1], - self.indN[0], - self.indN[1], - coeff_r[:, :, 0].copy(), - eta1, - eta2, - values_r_1, - 0, - ) - eva_2d.evaluate_tensor_product_2d( - self.T[0], - self.T[1], - self.p[0], - self.p[1], - self.indN[0], - self.indN[1], - coeff_i[:, :, 0].copy(), - eta1, - eta2, - values_i_1, - 0, - ) - - if self.n_tor != 0 and self.basis_tor == "r": - values_r_2 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - values_i_2 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - - eva_2d.evaluate_tensor_product_2d( - self.T[0], - self.T[1], - self.p[0], - self.p[1], - self.indN[0], - self.indN[1], - coeff_r[:, :, 1], - eta1, - eta2, - values_r_2, - 0, - ) - eva_2d.evaluate_tensor_product_2d( - self.T[0], - self.T[1], - self.p[0], - self.p[1], - self.indN[0], - self.indN[1], - coeff_i[:, :, 1], - eta1, - eta2, - values_i_2, - 0, - ) - - # matrix evaluation - else: - values_r_1 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - values_i_1 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - - eva_2d.evaluate_matrix_2d( - self.T[0], - self.T[1], - self.p[0], - self.p[1], - self.indN[0], - self.indN[1], - coeff_r[:, :, 0].copy(), - eta1, - eta2, - values_r_1, - 0, - ) - eva_2d.evaluate_matrix_2d( - self.T[0], - self.T[1], - self.p[0], - self.p[1], - self.indN[0], - self.indN[1], - coeff_i[:, :, 0].copy(), - eta1, - eta2, - values_i_1, - 0, - ) - - if self.n_tor != 0 and self.basis_tor == "r": - values_r_2 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - values_i_2 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - - eva_2d.evaluate_matrix_2d( - self.T[0], - self.T[1], - self.p[0], - self.p[1], - self.indN[0], - self.indN[1], - coeff_r[:, :, 1], - eta1, - eta2, - values_r_2, - 0, - ) - eva_2d.evaluate_matrix_2d( - self.T[0], - self.T[1], - self.p[0], - self.p[1], - self.indN[0], - self.indN[1], - coeff_i[:, :, 1], - eta1, - eta2, - values_i_2, - 0, - ) - - # multiply with Fourier basis in third direction - if self.n_tor == 0: - out = (values_r_1 + 1j * values_i_1)[:, :, None] * xp.ones(eta3.shape, dtype=float) - - else: - if self.basis_tor == "r": - out = (values_r_1 + 1j * values_i_1)[:, :, None] * xp.cos(2 * xp.pi * self.n_tor * eta3) - out += (values_r_2 + 1j * values_i_2)[:, :, None] * xp.sin(2 * xp.pi * self.n_tor * eta3) - - else: - out = (values_r_1 + 1j * values_i_1)[:, :, None] * xp.exp(1j * 2 * xp.pi * self.n_tor * eta3) - - # --------- evaluate FEM field at given point ------- - else: - real_1 = eva_2d.evaluate_n_n( - self.T[0], - self.T[1], - self.p[0], - self.p[1], - self.indN[0], - self.indN[1], - coeff_r[:, :, 0].copy(), - eta1, - eta2, - ) - imag_1 = eva_2d.evaluate_n_n( - self.T[0], - self.T[1], - self.p[0], - self.p[1], - self.indN[0], - self.indN[1], - coeff_i[:, :, 0].copy(), - eta1, - eta2, - ) - - if self.n_tor != 0 and self.basis_tor == "r": - real_2 = eva_2d.evaluate_n_n( - self.T[0], - self.T[1], - self.p[0], - self.p[1], - self.indN[0], - self.indN[1], - coeff_r[:, :, 1], - eta1, - eta2, - ) - imag_2 = eva_2d.evaluate_n_n( - self.T[0], - self.T[1], - self.p[0], - self.p[1], - self.indN[0], - self.indN[1], - coeff_i[:, :, 1], - eta1, - eta2, - ) - - # multiply with Fourier basis in third direction if |n_tor| > 0 - if self.n_tor == 0: - out = real_1 + 1j * imag_1 - - else: - if self.basis_tor == "r": - out = (real_1 + 1j * imag_1) * xp.cos(2 * xp.pi * self.n_tor * eta3) - out += (real_2 + 1j * imag_2) * xp.sin(2 * xp.pi * self.n_tor * eta3) - - else: - out = (real_1 + 1j * imag_1) * xp.exp(1j * 2 * xp.pi * self.n_tor * eta3) - - # return real or imaginary part - if part == "r": - out = xp.real(out) - else: - out = xp.imag(out) - - return out - - # ================================================= - def evaluate_DN(self, eta1, eta2, eta3, coeff, which="V1", part="r"): - """ - Evaluates the spline space [(DN) x Fourier] with coefficients 'coeff' at the point(s) eta = (eta1, eta2, eta3). - - Parameters - ---------- - eta1 : double or array_like - 1st component of logical evaluation point(s) - - eta2 : double or array_like - 2nd component of logical evaluation point(s) - - eta3 : double or array_like - 3rd component of logical evaluation point(s) - - coeff : array_like - FEM coefficients - - which : string - which space (V1 or V2) - - part : string - real (r) or imaginary (i) part to return - - Returns - ------- - out : double or array_like - evaluated FEM field at the point(s) eta = (eta1, eta2, eta3) - """ - - assert part == "r" or part == "i" - assert which == "V1" or which == "V2" - - # extract coefficients if flattened - if coeff.ndim == 1: - if which == "V1": - coeff = self.extract_1(coeff)[0] - else: - coeff = self.extract_2(coeff)[1] - - # check if coefficients have correct shape - assert coeff.shape[:2] == (self.NbaseD[0], self.NbaseN[1]) - - # get real and imaginary part - coeff_r = xp.real(coeff) - coeff_i = xp.imag(coeff) - - # ------ evaluate FEM field at given points -------- - if isinstance(eta1, xp.ndarray): - # tensor-product evaluation - if eta1.ndim == 1: - values_r_1 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - values_i_1 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - - eva_2d.evaluate_tensor_product_2d( - self.t[0], - self.T[1], - self.p[0] - 1, - self.p[1], - self.indD[0], - self.indN[1], - coeff_r[:, :, 0].copy(), - eta1, - eta2, - values_r_1, - 11, - ) - eva_2d.evaluate_tensor_product_2d( - self.t[0], - self.T[1], - self.p[0] - 1, - self.p[1], - self.indD[0], - self.indN[1], - coeff_i[:, :, 0].copy(), - eta1, - eta2, - values_i_1, - 11, - ) - - if self.n_tor != 0 and self.basis_tor == "r": - values_r_2 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - values_i_2 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - - eva_2d.evaluate_tensor_product_2d( - self.t[0], - self.T[1], - self.p[0] - 1, - self.p[1], - self.indD[0], - self.indN[1], - coeff_r[:, :, 1], - eta1, - eta2, - values_r_2, - 11, - ) - eva_2d.evaluate_tensor_product_2d( - self.t[0], - self.T[1], - self.p[0] - 1, - self.p[1], - self.indD[0], - self.indN[1], - coeff_i[:, :, 1], - eta1, - eta2, - values_i_2, - 11, - ) - - # matrix evaluation - else: - values_r_1 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - values_i_1 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - - eva_2d.evaluate_matrix_2d( - self.t[0], - self.T[1], - self.p[0] - 1, - self.p[1], - self.indD[0], - self.indN[1], - coeff_r[:, :, 0].copy(), - eta1, - eta2, - values_r_1, - 11, - ) - eva_2d.evaluate_matrix_2d( - self.t[0], - self.T[1], - self.p[0] - 1, - self.p[1], - self.indD[0], - self.indN[1], - coeff_i[:, :, 0].copy(), - eta1, - eta2, - values_i_1, - 11, - ) - - if self.n_tor != 0 and self.basis_tor == "r": - values_r_2 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - values_i_2 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - - eva_2d.evaluate_matrix_2d( - self.t[0], - self.T[1], - self.p[0] - 1, - self.p[1], - self.indD[0], - self.indN[1], - coeff_r[:, :, 1], - eta1, - eta2, - values_r_2, - 11, - ) - eva_2d.evaluate_matrix_2d( - self.t[0], - self.T[1], - self.p[0] - 1, - self.p[1], - self.indD[0], - self.indN[1], - coeff_i[:, :, 1], - eta1, - eta2, - values_i_2, - 11, - ) - - # multiply with Fourier basis in third direction - if self.n_tor == 0: - out = (values_r_1 + 1j * values_i_1)[:, :, None] * xp.ones(eta3.shape, dtype=float) - - else: - if self.basis_tor == "r": - out = (values_r_1 + 1j * values_i_1)[:, :, None] * xp.cos(2 * xp.pi * self.n_tor * eta3) - out += (values_r_2 + 1j * values_i_2)[:, :, None] * xp.sin(2 * xp.pi * self.n_tor * eta3) - - else: - out = (values_r_1 + 1j * values_i_1)[:, :, None] * xp.exp(1j * 2 * xp.pi * self.n_tor * eta3) - - # --------- evaluate FEM field at given point ------- - else: - real_1 = eva_2d.evaluate_d_n( - self.t[0], - self.T[1], - self.p[0] - 1, - self.p[1], - self.indD[0], - self.indN[1], - coeff_r[:, :, 0].copy(), - eta1, - eta2, - ) - imag_1 = eva_2d.evaluate_d_n( - self.t[0], - self.T[1], - self.p[0] - 1, - self.p[1], - self.indD[0], - self.indN[1], - coeff_i[:, :, 0].copy(), - eta1, - eta2, - ) - - if self.n_tor != 0 and self.basis_tor == "r": - real_2 = eva_2d.evaluate_d_n( - self.t[0], - self.T[1], - self.p[0] - 1, - self.p[1], - self.indD[0], - self.indN[1], - coeff_r[:, :, 1], - eta1, - eta2, - ) - imag_2 = eva_2d.evaluate_d_n( - self.t[0], - self.T[1], - self.p[0] - 1, - self.p[1], - self.indD[0], - self.indN[1], - coeff_i[:, :, 1], - eta1, - eta2, - ) - - # multiply with Fourier basis in third direction if |n_tor| > 0 - if self.n_tor == 0: - out = real_1 + 1j * imag_1 - - else: - if self.basis_tor == "r": - out = (real_1 + 1j * imag_1) * xp.cos(2 * xp.pi * self.n_tor * eta3) - out += (real_2 + 1j * imag_2) * xp.sin(2 * xp.pi * self.n_tor * eta3) - - else: - out = (real_1 + 1j * imag_1) * xp.exp(1j * 2 * xp.pi * self.n_tor * eta3) - - # return real or imaginary part - if part == "r": - out = xp.real(out) - else: - out = xp.imag(out) - - return out - - # ================================================= - def evaluate_ND(self, eta1, eta2, eta3, coeff, which="V2", part="r"): - """ - Evaluates the spline space [(ND) x Fourier] with coefficients 'coeff' at the point(s) eta = (eta1, eta2, eta3). - - Parameters - ---------- - eta1 : double or array_like - 1st component of logical evaluation point(s) - - eta2 : double or array_like - 2nd component of logical evaluation point(s) - - eta3 : double or array_like - 3rd component of logical evaluation point(s) - - coeff : array_like - FEM coefficients - - which : string - which space (V1 or V2) - - part : string - real (r) or imaginary (i) part to return - - Returns - ------- - out : double or array_like - evaluated FEM field at the point(s) eta = (eta1, eta2, eta3) - """ - - assert part == "r" or part == "i" - assert which == "V1" or which == "V2" - - # extract coefficients if flattened - if coeff.ndim == 1: - if which == "V1": - coeff = self.extract_1(coeff)[1] - else: - coeff = self.extract_2(coeff)[0] - - # check if coefficients have correct shape - assert coeff.shape[:2] == (self.NbaseN[0], self.NbaseD[1]) - - # get real and imaginary part - coeff_r = xp.real(coeff) - coeff_i = xp.imag(coeff) - - # ------ evaluate FEM field at given points -------- - if isinstance(eta1, xp.ndarray): - # tensor-product evaluation - if eta1.ndim == 1: - values_r_1 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - values_i_1 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - - eva_2d.evaluate_tensor_product_2d( - self.T[0], - self.t[1], - self.p[0], - self.p[1] - 1, - self.indN[0], - self.indD[1], - coeff_r[:, :, 0].copy(), - eta1, - eta2, - values_r_1, - 12, - ) - eva_2d.evaluate_tensor_product_2d( - self.T[0], - self.t[1], - self.p[0], - self.p[1] - 1, - self.indN[0], - self.indD[1], - coeff_i[:, :, 0].copy(), - eta1, - eta2, - values_i_1, - 12, - ) - - if self.n_tor != 0 and self.basis_tor == "r": - values_r_2 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - values_i_2 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - - eva_2d.evaluate_tensor_product_2d( - self.T[0], - self.t[1], - self.p[0], - self.p[1] - 1, - self.indN[0], - self.indD[1], - coeff_r[:, :, 1].copy(), - eta1, - eta2, - values_r_2, - 12, - ) - eva_2d.evaluate_tensor_product_2d( - self.T[0], - self.t[1], - self.p[0], - self.p[1] - 1, - self.indN[0], - self.indD[1], - coeff_i[:, :, 1].copy(), - eta1, - eta2, - values_i_2, - 12, - ) - - # matrix evaluation - else: - values_r_1 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - values_i_1 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - - eva_2d.evaluate_matrix_2d( - self.T[0], - self.t[1], - self.p[0], - self.p[1] - 1, - self.indN[0], - self.indD[1], - coeff_r[:, :, 0].copy(), - eta1, - eta2, - values_r_1, - 12, - ) - eva_2d.evaluate_matrix_2d( - self.T[0], - self.t[1], - self.p[0], - self.p[1] - 1, - self.indN[0], - self.indD[1], - coeff_i[:, :, 0].copy(), - eta1, - eta2, - values_i_1, - 12, - ) - - if self.n_tor != 0 and self.basis_tor == "r": - values_r_2 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - values_i_2 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - - eva_2d.evaluate_matrix_2d( - self.T[0], - self.t[1], - self.p[0], - self.p[1] - 1, - self.indN[0], - self.indD[1], - coeff_r[:, :, 1].copy(), - eta1, - eta2, - values_r_2, - 12, - ) - eva_2d.evaluate_matrix_2d( - self.T[0], - self.t[1], - self.p[0], - self.p[1] - 1, - self.indN[0], - self.indD[1], - coeff_i[:, :, 1].copy(), - eta1, - eta2, - values_i_2, - 12, - ) - - # multiply with Fourier basis in third direction - if self.n_tor == 0: - out = (values_r_1 + 1j * values_i_1)[:, :, None] * xp.ones(eta3.shape, dtype=float) - - else: - if self.basis_tor == "r": - out = (values_r_1 + 1j * values_i_1)[:, :, None] * xp.cos(2 * xp.pi * self.n_tor * eta3) - out += (values_r_2 + 1j * values_i_2)[:, :, None] * xp.sin(2 * xp.pi * self.n_tor * eta3) - - else: - out = (values_r_1 + 1j * values_i_1)[:, :, None] * xp.exp(1j * 2 * xp.pi * self.n_tor * eta3) - - # --------- evaluate FEM field at given point ------- - else: - real_1 = eva_2d.evaluate_n_d( - self.T[0], - self.t[1], - self.p[0], - self.p[1] - 1, - self.indN[0], - self.indD[1], - coeff_r[:, :, 0].copy(), - eta1, - eta2, - ) - imag_1 = eva_2d.evaluate_n_d( - self.T[0], - self.t[1], - self.p[0], - self.p[1] - 1, - self.indN[0], - self.indD[1], - coeff_i[:, :, 0].copy(), - eta1, - eta2, - ) - - if self.n_tor != 0 and self.basis_tor == "r": - real_2 = eva_2d.evaluate_n_d( - self.T[0], - self.t[1], - self.p[0], - self.p[1] - 1, - self.indN[0], - self.indD[1], - coeff_r[:, :, 1].copy(), - eta1, - eta2, - ) - imag_2 = eva_2d.evaluate_n_d( - self.T[0], - self.t[1], - self.p[0], - self.p[1] - 1, - self.indN[0], - self.indD[1], - coeff_i[:, :, 1].copy(), - eta1, - eta2, - ) - - # multiply with Fourier basis in third direction if |n_tor| > 0 - if self.n_tor == 0: - out = real_1 + 1j * imag_1 - - else: - if self.basis_tor == "r": - out = (real_1 + 1j * imag_1) * xp.cos(2 * xp.pi * self.n_tor * eta3) - out += (real_2 + 1j * imag_2) * xp.sin(2 * xp.pi * self.n_tor * eta3) - - else: - out = (real_1 + 1j * imag_1) * xp.exp(1j * 2 * xp.pi * self.n_tor * eta3) - - # return real or imaginary part - if part == "r": - out = xp.real(out) - else: - out = xp.imag(out) - - return out - - # ================================================= - def evaluate_DD(self, eta1, eta2, eta3, coeff, which="V3", part="r"): - """ - Evaluates the spline space [(DD) x Fourier] with coefficients 'coeff' at the point(s) eta = (eta1, eta2, eta3). - - Parameters - ---------- - eta1 : double or array_like - 1st component of logical evaluation point(s) - - eta2 : double or array_like - 2nd component of logical evaluation point(s) - - eta3 : double or array_like - 3rd component of logical evaluation point(s) - - coeff : array_like - FEM coefficients - - part : string - real (r) or imaginary (i) part to return - - which : string - which space (V2 or V3) - - part : string - real (r) or imaginary (i) part to return - - Returns - ------- - out : double or array_like - evaluated FEM field at the point(s) eta = (eta1, eta2, eta3) - """ - - assert part == "r" or part == "i" - assert which == "V2" or which == "V3" - - # extract coefficients if flattened - if coeff.ndim == 1: - if which == "V2": - coeff = self.extract_2(coeff)[2] - else: - coeff = self.extract_3(coeff) - - # check if coefficients have correct shape - assert coeff.shape[:2] == (self.NbaseD[0], self.NbaseD[1]) - - # get real and imaginary part - coeff_r = xp.real(coeff) - coeff_i = xp.imag(coeff) - - # ------ evaluate FEM field at given points -------- - if isinstance(eta1, xp.ndarray): - # tensor-product evaluation - if eta1.ndim == 1: - values_r_1 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - values_i_1 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - - eva_2d.evaluate_tensor_product_2d( - self.t[0], - self.t[1], - self.p[0] - 1, - self.p[1] - 1, - self.indD[0], - self.indD[1], - coeff_r[:, :, 0].copy(), - eta1, - eta2, - values_r_1, - 2, - ) - eva_2d.evaluate_tensor_product_2d( - self.t[0], - self.t[1], - self.p[0] - 1, - self.p[1] - 1, - self.indD[0], - self.indD[1], - coeff_i[:, :, 0].copy(), - eta1, - eta2, - values_i_1, - 2, - ) - - if self.n_tor != 0 and self.basis_tor == "r": - values_r_2 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - values_i_2 = xp.empty((eta1.shape[0], eta2.shape[0]), dtype=float) - - eva_2d.evaluate_tensor_product_2d( - self.t[0], - self.t[1], - self.p[0] - 1, - self.p[1] - 1, - self.indD[0], - self.indD[1], - coeff_r[:, :, 1], - eta1, - eta2, - values_r_2, - 2, - ) - eva_2d.evaluate_tensor_product_2d( - self.t[0], - self.t[1], - self.p[0] - 1, - self.p[1] - 1, - self.indD[0], - self.indD[1], - coeff_i[:, :, 1], - eta1, - eta2, - values_i_2, - 2, - ) - - # matrix evaluation - else: - values_r_1 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - values_i_1 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - - eva_2d.evaluate_matrix_2d( - self.t[0], - self.t[1], - self.p[0] - 1, - self.p[1] - 1, - self.indD[0], - self.indD[1], - coeff_r[:, :, 0].copy(), - eta1, - eta2, - values_r_1, - 2, - ) - eva_2d.evaluate_matrix_2d( - self.t[0], - self.t[1], - self.p[0] - 1, - self.p[1] - 1, - self.indD[0], - self.indD[1], - coeff_i[:, :, 0].copy(), - eta1, - eta2, - values_i_1, - 2, - ) - - if self.n_tor != 0 and self.basis_tor == "r": - values_r_2 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - values_i_2 = xp.empty((eta1.shape[0], eta2.shape[1]), dtype=float) - - eva_2d.evaluate_matrix_2d( - self.t[0], - self.t[1], - self.p[0] - 1, - self.p[1] - 1, - self.indD[0], - self.indD[1], - coeff_r[:, :, 1], - eta1, - eta2, - values_r_2, - 2, - ) - eva_2d.evaluate_matrix_2d( - self.t[0], - self.t[1], - self.p[0] - 1, - self.p[1] - 1, - self.indD[0], - self.indD[1], - coeff_i[:, :, 1], - eta1, - eta2, - values_i_2, - 2, - ) - - # multiply with Fourier basis in third direction - if self.n_tor == 0: - out = (values_r_1 + 1j * values_i_1)[:, :, None] * xp.ones(eta3.shape, dtype=float) - - else: - if self.basis_tor == "r": - out = (values_r_1 + 1j * values_i_1)[:, :, None] * xp.cos(2 * xp.pi * self.n_tor * eta3) - out += (values_r_2 + 1j * values_i_2)[:, :, None] * xp.sin(2 * xp.pi * self.n_tor * eta3) - - else: - out = (values_r_1 + 1j * values_i_1)[:, :, None] * xp.exp(1j * 2 * xp.pi * self.n_tor * eta3) - - # --------- evaluate FEM field at given point ------- - else: - real_1 = eva_2d.evaluate_d_d( - self.t[0], - self.t[1], - self.p[0] - 1, - self.p[1] - 1, - self.indD[0], - self.indD[1], - coeff_r[:, :, 0].copy(), - eta1, - eta2, - ) - imag_1 = eva_2d.evaluate_d_d( - self.t[0], - self.t[1], - self.p[0] - 1, - self.p[1] - 1, - self.indD[0], - self.indD[1], - coeff_i[:, :, 0].copy(), - eta1, - eta2, - ) - - if self.n_tor != 0 and self.basis_tor == "r": - real_2 = eva_2d.evaluate_d_d( - self.t[0], - self.t[1], - self.p[0] - 1, - self.p[1] - 1, - self.indD[0], - self.indD[1], - coeff_r[:, :, 1], - eta1, - eta2, - ) - imag_2 = eva_2d.evaluate_d_d( - self.t[0], - self.t[1], - self.p[0] - 1, - self.p[1] - 1, - self.indD[0], - self.indD[1], - coeff_i[:, :, 1], - eta1, - eta2, - ) - - # multiply with Fourier basis in third direction if |n_tor| > 0 - if self.n_tor == 0: - out = real_1 + 1j * imag_1 - - else: - if self.basis_tor == "r": - out = (real_1 + 1j * imag_1) * xp.cos(2 * xp.pi * self.n_tor * eta3) - out += (real_2 + 1j * imag_2) * xp.sin(2 * xp.pi * self.n_tor * eta3) - - else: - out = (real_1 + 1j * imag_1) * xp.exp(1j * 2 * xp.pi * self.n_tor * eta3) - - # return real or imaginary part - if part == "r": - out = xp.real(out) - else: - out = xp.imag(out) - - return out - - # ================================================= - def evaluate_NNN(self, eta1, eta2, eta3, coeff): - """ - Evaluates the spline space (NNN) with coefficients 'coeff' at the point eta = (eta1, eta2, eta3). - - Parameters - ---------- - eta1 : double or xp.ndarray - 1st component of logical evaluation point - - eta2 : double or xp.ndarray - 2nd component of logical evaluation point - - eta3 : double or xp.ndarray - 3rd component of logical evaluation point - - coeff : array_like - FEM coefficients - - Returns - ------- - value : double - evaluated FEM field at the point eta = (eta1, eta2, eta3) - """ - - if coeff.ndim == 1: - coeff = self.extract_0(coeff) - - if isinstance(eta1, xp.ndarray): - # tensor-product evaluation - if eta1.ndim == 1: - values = xp.empty((eta1.size, eta2.size, eta3.size), dtype=float) - eva_3d.evaluate_tensor_product( - self.T[0], - self.T[1], - self.T[2], - self.p[0], - self.p[1], - self.p[2], - self.indN[0], - self.indN[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - values, - 0, - ) - - # matrix evaluation - else: - values = xp.empty((eta1.shape[0], eta2.shape[1], eta3.shape[2]), dtype=float) - # `eta1` is a sparse meshgrid. - if max(eta1.shape) == eta1.size: - eva_3d.evaluate_sparse( - self.T[0], - self.T[1], - self.T[2], - self.p[0], - self.p[1], - self.p[2], - self.indN[0], - self.indN[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - eta1.shape[0], - eta2.shape[1], - eta3.shape[2], - values, - 0, - ) - - # `eta1` is a dense meshgrid. Process each point as default. - else: - eva_3d.evaluate_matrix( - self.T[0], - self.T[1], - self.T[2], - self.p[0], - self.p[1], - self.p[2], - self.indN[0], - self.indN[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - values, - 0, - ) - - return values - - else: - return eva_3d.evaluate_n_n_n( - self.T[0], - self.T[1], - self.T[2], - self.p[0], - self.p[1], - self.p[2], - self.indN[0], - self.indN[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - ) - - # ================================================= - def evaluate_DNN(self, eta1, eta2, eta3, coeff): - """ - Evaluates the spline space (DNN) with coefficients 'coeff' at the point eta = (eta1, eta2, eta3). - - Parameters - ---------- - eta1 : double or xp.ndarray - 1st component of logical evaluation point - - eta2 : double or xp.ndarray - 2nd component of logical evaluation point - - eta3 : double or xp.ndarray - 3rd component of logical evaluation point - - coeff : array_like - FEM coefficients - - Returns - ------- - value : double - evaluated FEM field at the point eta = (eta1, eta2, eta3) - """ - - if coeff.ndim == 1: - coeff = self.extract_1(coeff)[0] - - if isinstance(eta1, xp.ndarray): - # tensor product evaluation - if eta1.ndim == 1: - values = xp.empty((eta1.size, eta2.size, eta3.size), dtype=float) - eva_3d.evaluate_tensor_product( - self.t[0], - self.T[1], - self.T[2], - self.p[0] - 1, - self.p[1], - self.p[2], - self.indD[0], - self.indN[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - values, - 11, - ) - - # matrix evaluation - else: - values = xp.empty((eta1.shape[0], eta2.shape[1], eta3.shape[2]), dtype=float) - # `eta1` is a sparse meshgrid. - if max(eta1.shape) == eta1.size: - eva_3d.evaluate_sparse( - self.t[0], - self.T[1], - self.T[2], - self.p[0] - 1, - self.p[1], - self.p[2], - self.indD[0], - self.indN[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - eta1.shape[0], - eta2.shape[1], - eta3.shape[2], - values, - 11, - ) - # `eta1` is a dense meshgrid. Process each point as default. - else: - eva_3d.evaluate_matrix( - self.t[0], - self.T[1], - self.T[2], - self.p[0] - 1, - self.p[1], - self.p[2], - self.indD[0], - self.indN[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - values, - 11, - ) - - return values - - else: - return eva_3d.evaluate_d_n_n( - self.t[0], - self.T[1], - self.T[2], - self.p[0] - 1, - self.p[1], - self.p[2], - self.indD[0], - self.indN[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - ) - - # ================================================= - def evaluate_NDN(self, eta1, eta2, eta3, coeff): - """ - Evaluates the spline space (NDN) with coefficients 'coeff' at the point eta = (eta1, eta2, eta3). - - Parameters - ---------- - eta1 : double or xp.ndarray - 1st component of logical evaluation point - - eta2 : double or xp.ndarray - 2nd component of logical evaluation point - - eta3 : double or xp.ndarray - 3rd component of logical evaluation point - - coeff : array_like - FEM coefficients - - Returns - ------- - value : double - evaluated FEM field at the point eta = (eta1, eta2, eta3) - """ - - if coeff.ndim == 1: - coeff = self.extract_1(coeff)[1] - - if isinstance(eta1, xp.ndarray): - # tensor product evaluation - if eta1.ndim == 1: - values = xp.empty((eta1.size, eta2.size, eta3.size), dtype=float) - eva_3d.evaluate_tensor_product( - self.T[0], - self.t[1], - self.T[2], - self.p[0], - self.p[1] - 1, - self.p[2], - self.indN[0], - self.indD[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - values, - 12, - ) - - # matrix evaluation - else: - values = xp.empty((eta1.shape[0], eta2.shape[1], eta3.shape[2]), dtype=float) - # `eta1` is a sparse meshgrid. - if max(eta1.shape) == eta1.size: - eva_3d.evaluate_sparse( - self.T[0], - self.t[1], - self.T[2], - self.p[0], - self.p[1] - 1, - self.p[2], - self.indN[0], - self.indD[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - eta1.shape[0], - eta2.shape[1], - eta3.shape[2], - values, - 12, - ) - # `eta1` is a dense meshgrid. Process each point as default. - else: - eva_3d.evaluate_matrix( - self.T[0], - self.t[1], - self.T[2], - self.p[0], - self.p[1] - 1, - self.p[2], - self.indN[0], - self.indD[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - values, - 12, - ) - - return values - - else: - return eva_3d.evaluate_n_d_n( - self.T[0], - self.t[1], - self.T[2], - self.p[0], - self.p[1] - 1, - self.p[2], - self.indN[0], - self.indD[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - ) - - # ================================================= - def evaluate_NND(self, eta1, eta2, eta3, coeff): - """ - Evaluates the spline space (NND) with coefficients 'coeff' at the point eta = (eta1, eta2, eta3). - - Parameters - ---------- - eta1 : double or xp.ndarray - 1st component of logical evaluation point - - eta2 : double or xp.ndarray - 2nd component of logical evaluation point - - eta3 : double or xp.ndarray - 3rd component of logical evaluation point - - coeff : array_like - FEM coefficients - - Returns - ------- - value : double - evaluated FEM field at the point eta = (eta1, eta2, eta3) - """ - - if coeff.ndim == 1: - coeff = self.extract_1(coeff)[2] - - if isinstance(eta1, xp.ndarray): - # tensor product evaluation - if eta1.ndim == 1: - values = xp.empty((eta1.size, eta2.size, eta3.size), dtype=float) - eva_3d.evaluate_tensor_product( - self.T[0], - self.T[1], - self.t[2], - self.p[0], - self.p[1], - self.p[2] - 1, - self.indN[0], - self.indN[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - values, - 13, - ) - - # matrix evaluation - else: - values = xp.empty((eta1.shape[0], eta2.shape[1], eta3.shape[2]), dtype=float) - # `eta1` is a sparse meshgrid. - if max(eta1.shape) == eta1.size: - eva_3d.evaluate_sparse( - self.T[0], - self.T[1], - self.t[2], - self.p[0], - self.p[1], - self.p[2] - 1, - self.indN[0], - self.indN[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - eta1.shape[0], - eta2.shape[1], - eta3.shape[2], - values, - 13, - ) - # `eta1` is a dense meshgrid. Process each point as default. - else: - eva_3d.evaluate_matrix( - self.T[0], - self.T[1], - self.t[2], - self.p[0], - self.p[1], - self.p[2] - 1, - self.indN[0], - self.indN[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - values, - 13, - ) - - return values - - else: - return eva_3d.evaluate_n_n_d( - self.T[0], - self.T[1], - self.t[2], - self.p[0], - self.p[1], - self.p[2] - 1, - self.indN[0], - self.indN[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - ) - - # ================================================= - def evaluate_NDD(self, eta1, eta2, eta3, coeff): - """ - Evaluates the spline space (NDD) with coefficients 'coeff' at the point eta = (eta1, eta2, eta3). - - Parameters - ---------- - eta1 : double or xp.ndarray - 1st component of logical evaluation point - - eta2 : double or xp.ndarray - 2nd component of logical evaluation point - - eta3 : double or xp.ndarray - 3rd component of logical evaluation point - - coeff : array_like - FEM coefficients - - Returns - ------- - value : double - evaluated FEM field at the point eta = (eta1, eta2, eta3) - """ - - if coeff.ndim == 1: - coeff = self.extract_2(coeff)[0] - - if isinstance(eta1, xp.ndarray): - # tensor product evaluation - if eta1.ndim == 1: - values = xp.empty((eta1.size, eta2.size, eta3.size), dtype=float) - eva_3d.evaluate_tensor_product( - self.T[0], - self.t[1], - self.t[2], - self.p[0], - self.p[1] - 1, - self.p[2] - 1, - self.indN[0], - self.indD[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - values, - 21, - ) - - # matrix evaluation - else: - values = xp.empty((eta1.shape[0], eta2.shape[1], eta3.shape[2]), dtype=float) - # `eta1` is a sparse meshgrid. - if max(eta1.shape) == eta1.size: - eva_3d.evaluate_sparse( - self.T[0], - self.t[1], - self.t[2], - self.p[0], - self.p[1] - 1, - self.p[2] - 1, - self.indN[0], - self.indD[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - eta1.shape[0], - eta2.shape[1], - eta3.shape[2], - values, - 21, - ) - # `eta1` is a dense meshgrid. Process each point as default. - else: - eva_3d.evaluate_matrix( - self.T[0], - self.t[1], - self.t[2], - self.p[0], - self.p[1] - 1, - self.p[2] - 1, - self.indN[0], - self.indD[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - values, - 21, - ) - - return values - - else: - return eva_3d.evaluate_n_d_d( - self.T[0], - self.t[1], - self.t[2], - self.p[0], - self.p[1] - 1, - self.p[2] - 1, - self.indN[0], - self.indD[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - ) - - # ================================================= - def evaluate_DND(self, eta1, eta2, eta3, coeff): - """ - Evaluates the spline space (DND) with coefficients 'coeff' at the point eta = (eta1, eta2, eta3). - - Parameters - ---------- - eta1 : double or xp.ndarray - 1st component of logical evaluation point - - eta2 : double or xp.ndarray - 2nd component of logical evaluation point - - eta3 : double or xp.ndarray - 3rd component of logical evaluation point - - coeff : array_like - FEM coefficients - - Returns - ------- - value : double - evaluated FEM field at the point eta = (eta1, eta2, eta3) - """ - - if coeff.ndim == 1: - coeff = self.extract_2(coeff)[1] - - if isinstance(eta1, xp.ndarray): - # tensor product evaluation - if eta1.ndim == 1: - values = xp.empty((eta1.size, eta2.size, eta3.size), dtype=float) - eva_3d.evaluate_tensor_product( - self.t[0], - self.T[1], - self.t[2], - self.p[0] - 1, - self.p[1], - self.p[2] - 1, - self.indD[0], - self.indN[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - values, - 22, - ) - - # matrix evaluation - else: - values = xp.empty((eta1.shape[0], eta2.shape[1], eta3.shape[2]), dtype=float) - # `eta1` is a sparse meshgrid. - if max(eta1.shape) == eta1.size: - eva_3d.evaluate_sparse( - self.t[0], - self.T[1], - self.t[2], - self.p[0] - 1, - self.p[1], - self.p[2] - 1, - self.indD[0], - self.indN[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - eta1.shape[0], - eta2.shape[1], - eta3.shape[2], - values, - 22, - ) - # `eta1` is a dense meshgrid. Process each point as default. - else: - eva_3d.evaluate_matrix( - self.t[0], - self.T[1], - self.t[2], - self.p[0] - 1, - self.p[1], - self.p[2] - 1, - self.indD[0], - self.indN[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - values, - 22, - ) - - return values - - else: - return eva_3d.evaluate_d_n_d( - self.t[0], - self.T[1], - self.t[2], - self.p[0] - 1, - self.p[1], - self.p[2] - 1, - self.indD[0], - self.indN[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - ) - - # ================================================= - def evaluate_DDN(self, eta1, eta2, eta3, coeff): - """ - Evaluates the spline space (DDN) with coefficients 'coeff' at the point eta = (eta1, eta2, eta3). - - Parameters - ---------- - eta1 : double or xp.ndarray - 1st component of logical evaluation point - - eta2 : double or xp.ndarray - 2nd component of logical evaluation point - - eta3 : double or xp.ndarray - 3rd component of logical evaluation point - - coeff : array_like - FEM coefficients - - Returns - ------- - value : double - evaluated FEM field at the point eta = (eta1, eta2, eta3) - """ - - if coeff.ndim == 1: - coeff = self.extract_2(coeff)[2] - - if isinstance(eta1, xp.ndarray): - # tensor product evaluation - if eta1.ndim == 1: - values = xp.empty((eta1.size, eta2.size, eta3.size), dtype=float) - eva_3d.evaluate_tensor_product( - self.t[0], - self.t[1], - self.T[2], - self.p[0] - 1, - self.p[1] - 1, - self.p[2], - self.indD[0], - self.indD[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - values, - 23, - ) - - # matrix evaluation - else: - values = xp.empty((eta1.shape[0], eta2.shape[1], eta3.shape[2]), dtype=float) - # `eta1` is a sparse meshgrid. - if max(eta1.shape) == eta1.size: - eva_3d.evaluate_sparse( - self.t[0], - self.t[1], - self.T[2], - self.p[0] - 1, - self.p[1] - 1, - self.p[2], - self.indD[0], - self.indD[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - eta1.shape[0], - eta2.shape[1], - eta3.shape[2], - values, - 23, - ) - # `eta1` is a dense meshgrid. Process each point as default. - else: - eva_3d.evaluate_matrix( - self.t[0], - self.t[1], - self.T[2], - self.p[0] - 1, - self.p[1] - 1, - self.p[2], - self.indD[0], - self.indD[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - values, - 23, - ) - - return values - - else: - return eva_3d.evaluate_d_d_n( - self.t[0], - self.t[1], - self.T[2], - self.p[0] - 1, - self.p[1] - 1, - self.p[2], - self.indD[0], - self.indD[1], - self.indN[2], - coeff, - eta1, - eta2, - eta3, - ) - - # ================================================= - def evaluate_DDD(self, eta1, eta2, eta3, coeff): - """ - Evaluates the spline space (DDD) with coefficients 'coeff' at the point eta = (eta1, eta2, eta3). - - Parameters - ---------- - eta1 : double or xp.ndarray - 1st component of logical evaluation point - - eta2 : double or xp.ndarray - 2nd component of logical evaluation point - - eta3 : double or xp.ndarray - 3rd component of logical evaluation point - - coeff : array_like - FEM coefficients - - Returns - ------- - value : double - evaluated FEM field at the point eta = (eta1, eta2, eta3) - """ - - if coeff.ndim == 1: - coeff = self.extract_3(coeff) - - if isinstance(eta1, xp.ndarray): - # tensor product evaluation - if eta1.ndim == 1: - values = xp.empty((eta1.size, eta2.size, eta3.size), dtype=float) - eva_3d.evaluate_tensor_product( - self.t[0], - self.t[1], - self.t[2], - self.p[0] - 1, - self.p[1] - 1, - self.p[2] - 1, - self.indD[0], - self.indD[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - values, - 3, - ) - - # matrix evaluation - else: - values = xp.empty((eta1.shape[0], eta2.shape[1], eta3.shape[2]), dtype=float) - # `eta1` is a sparse meshgrid. - if max(eta1.shape) == eta1.size: - eva_3d.evaluate_sparse( - self.t[0], - self.t[1], - self.t[2], - self.p[0] - 1, - self.p[1] - 1, - self.p[2] - 1, - self.indD[0], - self.indD[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - eta1.shape[0], - eta2.shape[1], - eta3.shape[2], - values, - 3, - ) - # `eta1` is a dense meshgrid. Process each point as default. - else: - eva_3d.evaluate_matrix( - self.t[0], - self.t[1], - self.t[2], - self.p[0] - 1, - self.p[1] - 1, - self.p[2] - 1, - self.indD[0], - self.indD[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - values, - 3, - ) - - return values - - else: - return eva_3d.evaluate_d_d_d( - self.t[0], - self.t[1], - self.t[2], - self.p[0] - 1, - self.p[1] - 1, - self.p[2] - 1, - self.indD[0], - self.indD[1], - self.indD[2], - coeff, - eta1, - eta2, - eta3, - ) diff --git a/src/struphy/eigenvalue_solvers/tests/__init__.py b/src/struphy/eigenvalue_solvers/tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/struphy/feec/tests/test_basis_ops.py b/src/struphy/feec/tests/test_basis_ops.py index 7ba56aefa..d2c2a013c 100644 --- a/src/struphy/feec/tests/test_basis_ops.py +++ b/src/struphy/feec/tests/test_basis_ops.py @@ -19,8 +19,7 @@ def test_some_basis_ops(Nel, p, spl_kind, mapping): from psydac.linalg.block import BlockVector from psydac.linalg.stencil import StencilVector - from struphy.eigenvalue_solvers.legacy.mhd_operators_MF import projectors_dot_x - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.basis_projection_ops import BasisProjectionOperators from struphy.feec.psydac_derham import Derham from struphy.fields_background.equils import HomogenSlab @@ -112,12 +111,6 @@ def test_some_basis_ops(Nel, p, spl_kind, mapping): # Psydac MHD operators OPS_PSY = BasisProjectionOperators(DERHAM_PSY, domain, eq_mhd=EQ_MHD) - # Struphy matrix-free MHD operators - print(f"Rank {mpi_rank} | Init STRUPHY `projectors_dot_x`...") - elapsed = time() - OPS_STR = projectors_dot_x(SPACES, EQ_MHD) - print(f"Rank {mpi_rank} | Init `projectors_dot_x` done ({time() - elapsed:.4f}s).") - # Test vectors x0 = xp.reshape(xp.arange(V0.nbasis), [space.nbasis for space in V0.spaces]) @@ -215,21 +208,9 @@ def test_some_basis_ops(Nel, p, spl_kind, mapping): print("\nK3 (V3 --> V3, Identity operator in this case):") res_PSY = OPS_PSY.K3.dot(x3_st) - res_STR = OPS_STR.K1_dot(x3.flatten()) - res_STR = SPACES.extract_3(res_STR) - - print(f"Rank {mpi_rank} | Asserting MHD operator K3.") - assert_ops(mpi_rank, res_PSY, res_STR, verbose=True) - print(f"Rank {mpi_rank} | Assertion passed.") K3T = OPS_PSY.K3.transpose() res_PSY = K3T.dot(x3_st) - res_STR = OPS_STR.transpose_K1_dot(x3.flatten()) - res_STR = SPACES.extract_3(res_STR) - - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator K3T.") - assert_ops(mpi_rank, res_PSY, res_STR, verbose=True) - print(f"Rank {mpi_rank} | Assertion passed.") MPI_COMM.Barrier() @@ -238,21 +219,9 @@ def test_some_basis_ops(Nel, p, spl_kind, mapping): print("\nK0 (V0 --> V0, Identity operator in this case):") res_PSY = OPS_PSY.K0.dot(x0_st) - res_STR = OPS_STR.K10_dot(x0.flatten()) - res_STR = SPACES.extract_0(res_STR) - - print(f"Rank {mpi_rank} | Asserting MHD operator K0.") - assert_ops(mpi_rank, res_PSY, res_STR, verbose=True) - print(f"Rank {mpi_rank} | Assertion passed.") K10T = OPS_PSY.K0.transpose() res_PSY = K10T.dot(x0_st) - res_STR = OPS_STR.transpose_K10_dot(x0.flatten()) - res_STR = SPACES.extract_0(res_STR) - - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator K10T.") - assert_ops(mpi_rank, res_PSY, res_STR, verbose=True) - print(f"Rank {mpi_rank} | Assertion passed.") MPI_COMM.Barrier() @@ -261,198 +230,50 @@ def test_some_basis_ops(Nel, p, spl_kind, mapping): print("\nQ1 (V1 --> V2):") res_PSY = OPS_PSY.Q1.dot(x1_st) - res_STR = OPS_STR.Q1_dot(xp.concatenate((x1[0].flatten(), x1[1].flatten(), x1[2].flatten()))) - res_STR_0, res_STR_1, res_STR_2 = SPACES.extract_2(res_STR) - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting MHD operator Q1, first component.") - assert_ops(mpi_rank, res_PSY[0], res_STR_0) - print(f"Rank {mpi_rank} | Assertion passed.") - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting MHD operator Q1, second component.") - assert_ops(mpi_rank, res_PSY[1], res_STR_1) - print(f"Rank {mpi_rank} | Assertion passed.") MPI_COMM.Barrier() - print(f"Rank {mpi_rank} | Asserting MHD operator Q1, third component.") - assert_ops(mpi_rank, res_PSY[2], res_STR_2) - print(f"Rank {mpi_rank} | Assertion passed.") - Q1T = OPS_PSY.Q1.transpose() res_PSY = Q1T.dot(x2_st) - res_STR = OPS_STR.transpose_Q1_dot(xp.concatenate((x2[0].flatten(), x2[1].flatten(), x2[2].flatten()))) - res_STR_0, res_STR_1, res_STR_2 = SPACES.extract_1(res_STR) - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator Q1T, first component.") - assert_ops(mpi_rank, res_PSY[0], res_STR_0) - print(f"Rank {mpi_rank} | Assertion passed.") MPI_COMM.Barrier() - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator Q1T, second component.") - assert_ops(mpi_rank, res_PSY[1], res_STR_1) - print(f"Rank {mpi_rank} | Assertion passed.") - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator Q1T, third component.") - assert_ops(mpi_rank, res_PSY[2], res_STR_2) - print(f"Rank {mpi_rank} | Assertion passed.") - # operator W1 (V1 --> V1) if mpi_rank == 0: print("\nW1 (V1 --> V1, Identity operator in this case):") res_PSY = OPS_PSY.W1.dot(x1_st) - res_STR = OPS_STR.W1_dot(xp.concatenate((x1[0].flatten(), x1[1].flatten(), x1[2].flatten()))) - res_STR_0, res_STR_1, res_STR_2 = SPACES.extract_1(res_STR) - - MPI_COMM.barrier() - - print(f"Rank {mpi_rank} | Asserting MHD operator W1, first component.") - assert_ops(mpi_rank, res_PSY[0], res_STR_0) - print(f"Rank {mpi_rank} | Assertion passed.") MPI_COMM.Barrier() - print(f"Rank {mpi_rank} | Asserting MHD operator W1, second component.") - assert_ops(mpi_rank, res_PSY[1], res_STR_1) - print(f"Rank {mpi_rank} | Assertion passed.") - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting MHD operator W1, third component.") - assert_ops(mpi_rank, res_PSY[2], res_STR_2) - print(f"Rank {mpi_rank} | Assertion passed.") - W1T = OPS_PSY.W1.transpose() res_PSY = W1T.dot(x1_st) - res_STR = OPS_STR.transpose_W1_dot(xp.concatenate((x1[0].flatten(), x1[1].flatten(), x1[2].flatten()))) - res_STR_0, res_STR_1, res_STR_2 = SPACES.extract_1(res_STR) MPI_COMM.barrier() - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator W1T, first component.") - assert_ops(mpi_rank, res_PSY[0], res_STR_0) - print(f"Rank {mpi_rank} | Assertion passed.") - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator W1T, second component.") - assert_ops(mpi_rank, res_PSY[1], res_STR_1) - print(f"Rank {mpi_rank} | Assertion passed.") - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator W1T, third component.") - assert_ops(mpi_rank, res_PSY[2], res_STR_2) - print(f"Rank {mpi_rank} | Assertion passed.") - # operator Q2 (V2 --> V2) if mpi_rank == 0: print("\nQ2 (V2 --> V2, Identity operator in this case):") res_PSY = OPS_PSY.Q2.dot(x2_st) - res_STR = OPS_STR.Q2_dot(xp.concatenate((x2[0].flatten(), x2[1].flatten(), x2[2].flatten()))) - res_STR_0, res_STR_1, res_STR_2 = SPACES.extract_2(res_STR) - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting MHD operator Q2, first component.") - assert_ops(mpi_rank, res_PSY[0], res_STR_0) - print(f"Rank {mpi_rank} | Assertion passed.") - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting MHD operator Q2, second component.") - assert_ops(mpi_rank, res_PSY[1], res_STR_1) - print(f"Rank {mpi_rank} | Assertion passed.") MPI_COMM.Barrier() - print(f"Rank {mpi_rank} | Asserting MHD operator Q2, third component.") - assert_ops(mpi_rank, res_PSY[2], res_STR_2) - print(f"Rank {mpi_rank} | Assertion passed.") - Q2T = OPS_PSY.Q2.transpose() res_PSY = Q2T.dot(x2_st) - res_STR = OPS_STR.transpose_Q2_dot(xp.concatenate((x2[0].flatten(), x2[1].flatten(), x2[2].flatten()))) - res_STR_0, res_STR_1, res_STR_2 = SPACES.extract_2(res_STR) - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator Q2T, first component.") - assert_ops(mpi_rank, res_PSY[0], res_STR_0) - print(f"Rank {mpi_rank} | Assertion passed.") MPI_COMM.Barrier() - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator Q2T, second component.") - assert_ops(mpi_rank, res_PSY[1], res_STR_1) - print(f"Rank {mpi_rank} | Assertion passed.") - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator Q2T, third component.") - assert_ops(mpi_rank, res_PSY[2], res_STR_2) - print(f"Rank {mpi_rank} | Assertion passed.") - # operator X1 (V1 --> V0 x V0 x V0) if mpi_rank == 0: print("\nX1 (V1 --> V0 x V0 x V0):") res_PSY = OPS_PSY.X1.dot(x1_st) - res_STR = OPS_STR.X1_dot(xp.concatenate((x1[0].flatten(), x1[1].flatten(), x1[2].flatten()))) - res_STR_0 = SPACES.extract_0(res_STR[0]) - res_STR_1 = SPACES.extract_0(res_STR[1]) - res_STR_2 = SPACES.extract_0(res_STR[2]) MPI_COMM.Barrier() - print(f"Rank {mpi_rank} | Asserting MHD operator X1, first component.") - assert_ops(mpi_rank, res_PSY[0], res_STR_0) - print(f"Rank {mpi_rank} | Assertion passed.") - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting MHD operator X1, second component.") - assert_ops(mpi_rank, res_PSY[1], res_STR_1) - print(f"Rank {mpi_rank} | Assertion passed.") - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting MHD operator X1, third component.") - assert_ops(mpi_rank, res_PSY[2], res_STR_2) - print(f"Rank {mpi_rank} | Assertion passed.") - X1T = OPS_PSY.X1.transpose() res_PSY = X1T.dot(x0vec_st) - res_STR = OPS_STR.transpose_X1_dot([x0.flatten(), x0.flatten(), x0.flatten()]) - res_STR_0, res_STR_1, res_STR_2 = SPACES.extract_1(res_STR) - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator X1T, first component.") - assert_ops(mpi_rank, res_PSY[0], res_STR_0) - print(f"Rank {mpi_rank} | Assertion passed.") - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator X1T, second component.") - assert_ops(mpi_rank, res_PSY[1], res_STR_1) - print(f"Rank {mpi_rank} | Assertion passed.") - - MPI_COMM.Barrier() - - print(f"Rank {mpi_rank} | Asserting TRANSPOSE MHD operator X1T, third component.") - assert_ops(mpi_rank, res_PSY[2], res_STR_2) - print(f"Rank {mpi_rank} | Assertion passed.") @pytest.mark.parametrize("Nel", [[6, 9, 7]]) @@ -466,9 +287,7 @@ def test_some_basis_ops(Nel, p, spl_kind, mapping): def test_basis_ops_polar(Nel, p, spl_kind, dirichlet_bc, mapping, show_plots=False): import cunumpy as xp from psydac.ddm.mpi import mpi as MPI - - from struphy.eigenvalue_solvers.mhd_operators import MHDOperators - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.basis_projection_ops import BasisProjectionOperators from struphy.feec.psydac_derham import Derham from struphy.feec.utilities import compare_arrays, create_equal_random_arrays diff --git a/src/struphy/feec/tests/test_derham.py b/src/struphy/feec/tests/test_derham.py index 1e857b5a2..46d6e559b 100644 --- a/src/struphy/feec/tests/test_derham.py +++ b/src/struphy/feec/tests/test_derham.py @@ -12,7 +12,7 @@ def test_psydac_derham(Nel, p, spl_kind): from psydac.linalg.block import BlockVector from psydac.linalg.stencil import StencilVector - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.psydac_derham import Derham from struphy.feec.utilities import compare_arrays diff --git a/src/struphy/feec/tests/test_mass_matrices.py b/src/struphy/feec/tests/test_mass_matrices.py index e1d629c2e..fe20ec39e 100644 --- a/src/struphy/feec/tests/test_mass_matrices.py +++ b/src/struphy/feec/tests/test_mass_matrices.py @@ -14,9 +14,7 @@ def test_mass(Nel, p, spl_kind, dirichlet_bc, mapping, show_plots=False): import cunumpy as xp from psydac.ddm.mpi import mpi as MPI - - from struphy.eigenvalue_solvers.mhd_operators import MHDOperators - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.mass import WeightedMassOperators, WeightedMassOperatorsOldForTesting from struphy.feec.psydac_derham import Derham from struphy.feec.utilities import RotationMatrix, compare_arrays, create_equal_random_arrays @@ -394,9 +392,7 @@ def test_mass_polar(Nel, p, spl_kind, dirichlet_bc, mapping, show_plots=False): import cunumpy as xp from psydac.ddm.mpi import mpi as MPI - - from struphy.eigenvalue_solvers.mhd_operators import MHDOperators - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.mass import WeightedMassOperators from struphy.feec.psydac_derham import Derham from struphy.feec.utilities import create_equal_random_arrays diff --git a/src/struphy/pic/tests/test_accumulation.py b/src/struphy/pic/tests/test_accumulation.py index ed3a41ff4..a97102d45 100644 --- a/src/struphy/pic/tests/test_accumulation.py +++ b/src/struphy/pic/tests/test_accumulation.py @@ -3,49 +3,6 @@ from struphy.utils.pyccel import Pyccelkernel -@pytest.mark.parametrize("Nel", [[8, 9, 10]]) -@pytest.mark.parametrize("p", [[2, 3, 4]]) -@pytest.mark.parametrize( - "spl_kind", - [[False, False, True], [False, True, False], [True, False, True], [True, True, False]], -) -@pytest.mark.parametrize( - "mapping", - [ - [ - "Cuboid", - { - "l1": 1.0, - "r1": 2.0, - "l2": 10.0, - "r2": 20.0, - "l3": 100.0, - "r3": 200.0, - }, - ], - ], -) -def test_accumulation(Nel, p, spl_kind, mapping, Np=40, verbose=False): - """ - A test to compare the old accumulation routine of step1 and step3 of cc_lin_mhd_6d with the old way (files stored in - ../test_pic_legacy_files) and the new way using the Accumulator object (ghost_region_sender, particle_to_mat_kernels). - - The two accumulation matrices are computed with the same random magnetic field produced by - feec.utilities.create_equal_random_arrays and compared against each other at the bottom using - feec.utilities.compare_arrays(). - - The times for both legacy and the new way are printed if verbose == True. This comparison only makes sense if the - ..test_pic_legacy_files/ are also all compiled. - """ - from psydac.ddm.mpi import mpi as MPI - - rank = MPI.COMM_WORLD.Get_rank() - - pc_lin_mhd_6d_step_ph_full(Nel, p, spl_kind, mapping, Np, verbose) - if verbose and rank == 0: - print("\nTest for Step ph passed\n") - - def pc_lin_mhd_6d_step_ph_full(Nel, p, spl_kind, mapping, Np, verbose=False): from time import time @@ -53,7 +10,7 @@ def pc_lin_mhd_6d_step_ph_full(Nel, p, spl_kind, mapping, Np, verbose=False): from psydac.ddm.mpi import MockComm from psydac.ddm.mpi import mpi as MPI - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.mass import WeightedMassOperators from struphy.feec.psydac_derham import Derham from struphy.feec.utilities import compare_arrays @@ -61,7 +18,6 @@ def pc_lin_mhd_6d_step_ph_full(Nel, p, spl_kind, mapping, Np, verbose=False): from struphy.pic.accumulation import accum_kernels from struphy.pic.accumulation.particles_to_grid import Accumulator from struphy.pic.particles import Particles6D - from struphy.pic.tests.test_pic_legacy_files.accumulation_kernels_3d import kernel_step_ph_full from struphy.pic.utilities import BoundaryParameters, LoadingParameters, WeightsParameters if isinstance(MPI.COMM_WORLD, MockComm): @@ -181,59 +137,6 @@ def pc_lin_mhd_6d_step_ph_full(Nel, p, spl_kind, mapping, Np, verbose=False): basis_u = 1 - start_time = time() - kernel_step_ph_full( - particles_leg, - SPACES.T[0], - SPACES.T[1], - SPACES.T[2], - xp.array(SPACES.p), - xp.array(Nel), - xp.array(SPACES.NbaseN), - xp.array(SPACES.NbaseD), - particles_leg.shape[0], - domain.kind_map, - domain.params_numpy, - domain.T[0], - domain.T[1], - domain.T[2], - xp.array(domain.p), - xp.array( - domain.Nel, - ), - xp.array(domain.NbaseN), - domain.cx, - domain.cy, - domain.cz, - mat[0][0], - mat[0][1], - mat[0][2], - mat[1][1], - mat[1][2], - mat[2][2], - vec[0], - vec[1], - vec[2], - basis_u, - ) - - end_time = time() - tot_time = xp.round(end_time - start_time, 3) - - mat[0][0] /= Np - mat[0][1] /= Np - mat[0][2] /= Np - mat[1][1] /= Np - mat[1][2] /= Np - mat[2][2] /= Np - - vec[0] /= Np - vec[1] /= Np - vec[2] /= Np - - if rank == 0 and verbose: - print(f"Step ph Legacy took {tot_time} seconds.") - # ========================= # ======== New Part ======= # ========================= @@ -258,434 +161,22 @@ def pc_lin_mhd_6d_step_ph_full(Nel, p, spl_kind, mapping, Np, verbose=False): if rank == 0 and verbose: print(f"Step ph New took {tot_time} seconds.") - # ========================= - # ======== Compare ======== - # ========================= - - atol = 1e-10 - - # mat_temp11 = [[mat[0][0][:,:,:,:,:,:,0,0], mat[0][1][:,:,:,:,:,:,0,0], mat[0][2][:,:,:,:,:,:,0,0]], - # [ mat[0][1][:,:,:,:,:,:,0,0].transpose(), mat[1][1][:,:,:,:,:,:,0,0], mat[1][2][:,:,:,:,:,:,0,0]], - # [ mat[0][2][:,:,:,:,:,:,0,0].transpose(), mat[1][2][:,:,:,:,:,:,0,0].transpose(), mat[2][2][:,:,:,:,:,:,0,0]]] - # mat_temp12 = [[mat[0][0][:,:,:,:,:,:,0,1], mat[0][1][:,:,:,:,:,:,0,1], mat[0][2][:,:,:,:,:,:,0,1]], - # [ mat[0][1][:,:,:,:,:,:,0,1].transpose(), mat[1][1][:,:,:,:,:,:,0,1], mat[1][2][:,:,:,:,:,:,0,1]], - # [ mat[0][2][:,:,:,:,:,:,0,1].transpose(), mat[1][2][:,:,:,:,:,:,0,1].transpose(), mat[2][2][:,:,:,:,:,:,0,1]]] - # mat_temp13 = [[mat[0][0][:,:,:,:,:,:,0,2], mat[0][1][:,:,:,:,:,:,0,2], mat[0][2][:,:,:,:,:,:,0,2]], - # [ mat[0][1][:,:,:,:,:,:,0,2].transpose(), mat[1][1][:,:,:,:,:,:,0,2], mat[1][2][:,:,:,:,:,:,0,2]], - # [ mat[0][2][:,:,:,:,:,:,0,2].transpose(), mat[1][2][:,:,:,:,:,:,0,2].transpose(), mat[2][2][:,:,:,:,:,:,0,2]]] - # mat_temp22 = [[mat[0][0][:,:,:,:,:,:,1,1], mat[0][1][:,:,:,:,:,:,1,1], mat[0][2][:,:,:,:,:,:,1,1]], - # [ mat[0][1][:,:,:,:,:,:,1,1].transpose(), mat[1][1][:,:,:,:,:,:,1,1], mat[1][2][:,:,:,:,:,:,1,1]], - # [ mat[0][2][:,:,:,:,:,:,1,1].transpose(), mat[1][2][:,:,:,:,:,:,1,1].transpose(), mat[2][2][:,:,:,:,:,:,1,1]]] - # mat_temp23 = [[mat[0][0][:,:,:,:,:,:,1,2], mat[0][1][:,:,:,:,:,:,1,2], mat[0][2][:,:,:,:,:,:,1,2]], - # [ mat[0][1][:,:,:,:,:,:,1,2].transpose(), mat[1][1][:,:,:,:,:,:,1,2], mat[1][2][:,:,:,:,:,:,1,2]], - # [ mat[0][2][:,:,:,:,:,:,1,2].transpose(), mat[1][2][:,:,:,:,:,:,1,2].transpose(), mat[2][2][:,:,:,:,:,:,1,2]]] - # mat_temp33 = [[mat[0][0][:,:,:,:,:,:,2,2], mat[0][1][:,:,:,:,:,:,2,2], mat[0][2][:,:,:,:,:,:,2,2]], - # [ mat[0][1][:,:,:,:,:,:,2,2].transpose(), mat[1][1][:,:,:,:,:,:,2,2], mat[1][2][:,:,:,:,:,:,2,2]], - # [ mat[0][2][:,:,:,:,:,:,2,2].transpose(), mat[1][2][:,:,:,:,:,:,2,2].transpose(), mat[2][2][:,:,:,:,:,:,2,2]]] - vec_temp1 = [vec[0][:, :, :, 0], vec[1][:, :, :, 0], vec[2][:, :, :, 0]] - vec_temp2 = [vec[0][:, :, :, 1], vec[1][:, :, :, 1], vec[2][:, :, :, 1]] - vec_temp3 = [vec[0][:, :, :, 2], vec[1][:, :, :, 2], vec[2][:, :, :, 2]] - - compare_arrays( - ACC.operators[0].matrix.blocks[0][0], - mat[0][0][:, :, :, :, :, :, 0, 0], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat11_11 passed test") - compare_arrays( - ACC.operators[0].matrix.blocks[0][1], - mat[0][1][:, :, :, :, :, :, 0, 0], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat12_11 passed test") - compare_arrays( - ACC.operators[0].matrix.blocks[0][2], - mat[0][2][:, :, :, :, :, :, 0, 0], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat13_11 passed test") - compare_arrays( - ACC.operators[0].matrix.blocks[1][1], - mat[1][1][:, :, :, :, :, :, 0, 0], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat22_11 passed test") - compare_arrays( - ACC.operators[0].matrix.blocks[1][2], - mat[1][2][:, :, :, :, :, :, 0, 0], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat23_11 passed test") - compare_arrays( - ACC.operators[0].matrix.blocks[2][2], - mat[2][2][:, :, :, :, :, :, 0, 0], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat33_11 passed test") - - compare_arrays( - ACC.operators[1].matrix.blocks[0][0], - mat[0][0][:, :, :, :, :, :, 0, 1], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat11_12 passed test") - compare_arrays( - ACC.operators[1].matrix.blocks[0][1], - mat[0][1][:, :, :, :, :, :, 0, 1], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat12_12 passed test") - compare_arrays( - ACC.operators[1].matrix.blocks[0][2], - mat[0][2][:, :, :, :, :, :, 0, 1], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat13_12 passed test") - compare_arrays( - ACC.operators[1].matrix.blocks[1][1], - mat[1][1][:, :, :, :, :, :, 0, 1], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat22_12 passed test") - compare_arrays( - ACC.operators[1].matrix.blocks[1][2], - mat[1][2][:, :, :, :, :, :, 0, 1], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat23_12 passed test") - compare_arrays( - ACC.operators[1].matrix.blocks[2][2], - mat[2][2][:, :, :, :, :, :, 0, 1], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat33_12 passed test") - - compare_arrays( - ACC.operators[2].matrix.blocks[0][0], - mat[0][0][:, :, :, :, :, :, 0, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat11_13 passed test") - compare_arrays( - ACC.operators[2].matrix.blocks[0][1], - mat[0][1][:, :, :, :, :, :, 0, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat12_13 passed test") - compare_arrays( - ACC.operators[2].matrix.blocks[0][2], - mat[0][2][:, :, :, :, :, :, 0, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat13_13 passed test") - compare_arrays( - ACC.operators[2].matrix.blocks[1][1], - mat[1][1][:, :, :, :, :, :, 0, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat22_13 passed test") - compare_arrays( - ACC.operators[2].matrix.blocks[1][2], - mat[1][2][:, :, :, :, :, :, 0, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat23_13 passed test") - compare_arrays( - ACC.operators[2].matrix.blocks[2][2], - mat[2][2][:, :, :, :, :, :, 0, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat33_13 passed test") - - compare_arrays( - ACC.operators[3].matrix.blocks[0][0], - mat[0][0][:, :, :, :, :, :, 1, 1], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat11_22 passed test") - compare_arrays( - ACC.operators[3].matrix.blocks[0][1], - mat[0][1][:, :, :, :, :, :, 1, 1], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat12_22 passed test") - compare_arrays( - ACC.operators[3].matrix.blocks[0][2], - mat[0][2][:, :, :, :, :, :, 1, 1], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat13_22 passed test") - compare_arrays( - ACC.operators[3].matrix.blocks[1][1], - mat[1][1][:, :, :, :, :, :, 1, 1], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat22_22 passed test") - compare_arrays( - ACC.operators[3].matrix.blocks[1][2], - mat[1][2][:, :, :, :, :, :, 1, 1], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat23_22 passed test") - compare_arrays( - ACC.operators[3].matrix.blocks[2][2], - mat[2][2][:, :, :, :, :, :, 1, 1], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat33_22 passed test") - - compare_arrays( - ACC.operators[4].matrix.blocks[0][0], - mat[0][0][:, :, :, :, :, :, 1, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat11_23 passed test") - compare_arrays( - ACC.operators[4].matrix.blocks[0][1], - mat[0][1][:, :, :, :, :, :, 1, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat12_23 passed test") - compare_arrays( - ACC.operators[4].matrix.blocks[0][2], - mat[0][2][:, :, :, :, :, :, 1, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat13_23 passed test") - compare_arrays( - ACC.operators[4].matrix.blocks[1][1], - mat[1][1][:, :, :, :, :, :, 1, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat22_23 passed test") - compare_arrays( - ACC.operators[4].matrix.blocks[1][2], - mat[1][2][:, :, :, :, :, :, 1, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat23_23 passed test") - compare_arrays( - ACC.operators[4].matrix.blocks[2][2], - mat[2][2][:, :, :, :, :, :, 1, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat33_23 passed test") - - compare_arrays( - ACC.operators[5].matrix.blocks[0][0], - mat[0][0][:, :, :, :, :, :, 2, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat11_33 passed test") - compare_arrays( - ACC.operators[5].matrix.blocks[0][1], - mat[0][1][:, :, :, :, :, :, 2, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat12_33 passed test") - compare_arrays( - ACC.operators[5].matrix.blocks[0][2], - mat[0][2][:, :, :, :, :, :, 2, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat13_33 passed test") - compare_arrays( - ACC.operators[5].matrix.blocks[1][1], - mat[1][1][:, :, :, :, :, :, 2, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat22_33 passed test") - compare_arrays( - ACC.operators[5].matrix.blocks[1][2], - mat[1][2][:, :, :, :, :, :, 2, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat23_33 passed test") - compare_arrays( - ACC.operators[5].matrix.blocks[2][2], - mat[2][2][:, :, :, :, :, :, 2, 2], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("mat33_33 passed test") - - compare_arrays( - ACC.vectors[0].blocks[0], - vec[0][:, :, :, 0], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("vec1_1 passed test") - compare_arrays( - ACC.vectors[0].blocks[1], - vec[1][:, :, :, 0], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("vec2_1 passed test") - compare_arrays( - ACC.vectors[0].blocks[2], - vec[2][:, :, :, 0], - rank, - atol=atol, - verbose=verbose, - ) - if verbose: - print("vec3_1 passed test") - # compare_arrays(ACC.operators[0].matrix, mat_temp11, rank, atol=atol, verbose=verbose) - # if verbose: - # print('full block matrix_11 passed test') - # compare_arrays(ACC.operators[1].matrix, mat_temp12, rank, atol=atol, verbose=verbose) - # if verbose: - # print('full block matrix_12 passed test') - # compare_arrays(ACC.operators[2].matrix, mat_temp13, rank, atol=atol, verbose=verbose) - # if verbose: - # print('full block matrix_13 passed test') - # compare_arrays(ACC.operators[3].matrix, mat_temp22, rank, atol=atol, verbose=verbose) - # if verbose: - # print('full block matrix_22 passed test') - # compare_arrays(ACC.operators[4].matrix, mat_temp23, rank, atol=atol, verbose=verbose) - # if verbose: - # print('full block matrix_23 passed test') - # compare_arrays(ACC.operators[5].matrix, mat_temp33, rank, atol=atol, verbose=verbose) - # if verbose: - # print('full block matrix_33 passed test') - compare_arrays(ACC.vectors[0], vec_temp1, rank, atol=atol, verbose=verbose) - if verbose: - print("full block vector_1 passed test") - compare_arrays(ACC.vectors[1], vec_temp2, rank, atol=atol, verbose=verbose) - if verbose: - print("full block vector_2 passed test") - compare_arrays(ACC.vectors[2], vec_temp3, rank, atol=atol, verbose=verbose) - if verbose: - print("full block vector_3 passed test") - if __name__ == "__main__": - test_accumulation( - [8, 9, 10], - [2, 3, 4], - [False, False, True], - [ - "Cuboid", - { - "l1": 1.0, - "r1": 2.0, - "l2": 10.0, - "r2": 20.0, - "l3": 100.0, - "r3": 200.0, - }, - ], - ) + # test_accumulation( + # [8, 9, 10], + # [2, 3, 4], + # [False, False, True], + # [ + # "Cuboid", + # { + # "l1": 1.0, + # "r1": 2.0, + # "l2": 10.0, + # "r2": 20.0, + # "l3": 100.0, + # "r3": 200.0, + # }, + # ], + # ) + pass diff --git a/src/struphy/pic/tests/test_pic_legacy_files/__init__.py b/src/struphy/pic/tests/test_pic_legacy_files/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/struphy/pic/tests/test_pic_legacy_files/accumulation.py b/src/struphy/pic/tests/test_pic_legacy_files/accumulation.py deleted file mode 100644 index 6bb225571..000000000 --- a/src/struphy/pic/tests/test_pic_legacy_files/accumulation.py +++ /dev/null @@ -1,544 +0,0 @@ -# coding: utf-8 -# -# Copyright 2020 Florian Holderied - -""" -Modules to create sparse matrices from 6D sub-matrices in particle accumulation steps -""" - -import time - -import cunumpy as xp -import scipy.sparse as spa -from psydac.ddm.mpi import mpi as MPI - -import struphy.pic.tests.test_pic_legacy_files.accumulation_kernels_3d as pic_ker_3d - -# import struphy.pic.tests.test_pic_legacy_files.accumulation_kernels_2d as pic_ker_2d - -# from struphy.pic.tests.test_pic_legacy_files.control_variate import TermsControlVariate - - -class Accumulator: - """ - Class for computing charge and current densities from particles. - - Parameters - --------- - tensor_space_FEM : tensor_spline_space - tensor product B-spline space - - domain : domain object - domain object from hylife.geometry.domain_3d defining the mapping - - basis_u : int - bulk velocity representation (0 : vector-field, 1 : 1-form , 2 : 2-form) - - mpi_comm : MPI.COMM_WORLD - MPI communicator - - control : boolean - whether a full-f (False) of delta-f approach is used - - cv_ep : control variate object - the distribution function that serves as a control variate (only necessary in case of use_control = True) - """ - - # =============================================================== - def __init__(self, tensor_space_FEM, domain, basis_u, mpi_comm, use_control, cv_ep=None): - self.space = tensor_space_FEM - self.domain = domain - self.basis_u = basis_u - self.mpi_rank = mpi_comm.Get_rank() - self.use_control = use_control - - # intialize delta-f correction terms - if self.use_control and self.mpi_rank == 0: - self.cont = TermsControlVariate(self.space, self.domain, self.basis_u, cv_ep) - - # reserve memory for implicit particle-coupling sub-steps - self.blocks_loc = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] - self.blocks_glo = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] - - self.vecs_loc = [0, 0, 0] - self.vecs_glo = [0, 0, 0] - - for a in range(3): - if self.basis_u == 0: - Ni = self.space.Nbase_0form - else: - Ni = getattr(self.space, "Nbase_" + str(self.basis_u) + "form")[a] - - self.vecs_loc[a] = xp.empty((Ni[0], Ni[1], Ni[2]), dtype=float) - self.vecs_glo[a] = xp.empty((Ni[0], Ni[1], Ni[2]), dtype=float) - - for b in range(3): - if self.space.dim == 2: - self.blocks_loc[a][b] = xp.empty( - (Ni[0], Ni[1], Ni[2], 2 * self.space.p[0] + 1, 2 * self.space.p[1] + 1, self.space.NbaseN[2]), - dtype=float, - ) - self.blocks_glo[a][b] = xp.empty( - (Ni[0], Ni[1], Ni[2], 2 * self.space.p[0] + 1, 2 * self.space.p[1] + 1, self.space.NbaseN[2]), - dtype=float, - ) - - else: - self.blocks_loc[a][b] = xp.empty( - ( - Ni[0], - Ni[1], - Ni[2], - 2 * self.space.p[0] + 1, - 2 * self.space.p[1] + 1, - 2 * self.space.p[2] + 1, - ), - dtype=float, - ) - self.blocks_glo[a][b] = xp.empty( - ( - Ni[0], - Ni[1], - Ni[2], - 2 * self.space.p[0] + 1, - 2 * self.space.p[1] + 1, - 2 * self.space.p[2] + 1, - ), - dtype=float, - ) - - # =============================================================== - def to_sparse_step1(self): - """Converts the 6d arrays stored in self.blocks to a sparse block matrix using row-major ordering - - Returns - ------- - M : sparse matrix in csr-format - anti-symmetric, sparse block matrix [[0, M12, M13], [-M12.T, 0, M23], [-M13.T, -M23.T, 0]] - """ - - # blocks of global matrix - M = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] - - for a in range(2): - for b in range(a + 1, 3): - if self.basis_u == 0: - Ni = self.space.Nbase_0form - Nj = self.space.Nbase_0form - - elif self.basis_u == 1: - Ni = self.space.Nbase_1form[a] - Nj = self.space.Nbase_1form[b] - - elif self.basis_u == 2: - Ni = self.space.Nbase_2form[a] - Nj = self.space.Nbase_2form[b] - - indices = xp.indices(self.blocks_glo[a][b].shape) - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - shift = [xp.arange(Ni) - p for Ni, p in zip(Ni[:2], self.space.p[:2])] - - if self.space.dim == 2: - shift += [xp.zeros(self.space.NbaseN[2], dtype=int)] - else: - shift += [xp.arange(Ni[2]) - self.space.p[2]] - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M[a][b] = spa.csr_matrix( - (self.blocks_glo[a][b].flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M[a][b].eliminate_zeros() - - # final block matrix - M = spa.bmat( - [[None, M[0][1], M[0][2]], [-M[0][1].T, None, M[1][2]], [-M[0][2].T, -M[1][2].T, None]], - format="csr", - ) - - # apply extraction operator - if self.basis_u == 0: - M = self.space.Ev_0.dot(M.dot(self.space.Ev_0.T)).tocsr() - - elif self.basis_u == 1: - M = self.space.E1_0.dot(M.dot(self.space.E1_0.T)).tocsr() - - elif self.basis_u == 2: - M = self.space.E2_0.dot(M.dot(self.space.E2_0.T)).tocsr() - - return M - - # =============================================================== - def to_sparse_step3(self): - """Converts the 6d arrays stored in self.blocks to a sparse block matrix using row-major ordering - - Returns - ------- - M : sparse matrix in csr-format - symmetric, sparse block matrix [[M11, M12, M13], [M12.T, M22, M23], [M13.T, M23.T, M33]] - """ - - # blocks of global matrix - M = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] - - for a in range(3): - for b in range(a, 3): - if self.basis_u == 0: - Ni = self.space.Nbase_0form - Nj = self.space.Nbase_0form - - elif self.basis_u == 1: - Ni = self.space.Nbase_1form[a] - Nj = self.space.Nbase_1form[b] - - elif self.basis_u == 2: - Ni = self.space.Nbase_2form[a] - Nj = self.space.Nbase_2form[b] - - indices = xp.indices(self.blocks_glo[a][b].shape) - - row = (Ni[1] * Ni[2] * indices[0] + Ni[2] * indices[1] + indices[2]).flatten() - - shift = [xp.arange(Ni) - p for Ni, p in zip(Ni[:2], self.space.p[:2])] - - if self.space.dim == 2: - shift += [xp.zeros(self.space.NbaseN[2], dtype=int)] - else: - shift += [xp.arange(Ni[2]) - self.space.p[2]] - - col1 = (indices[3] + shift[0][:, None, None, None, None, None]) % Nj[0] - col2 = (indices[4] + shift[1][None, :, None, None, None, None]) % Nj[1] - col3 = (indices[5] + shift[2][None, None, :, None, None, None]) % Nj[2] - - col = Nj[1] * Nj[2] * col1 + Nj[2] * col2 + col3 - - M[a][b] = spa.csr_matrix( - (self.blocks_glo[a][b].flatten(), (row, col.flatten())), - shape=(Ni[0] * Ni[1] * Ni[2], Nj[0] * Nj[1] * Nj[2]), - ) - M[a][b].eliminate_zeros() - - # final block matrix - M = spa.bmat( - [[M[0][0], M[0][1], M[0][2]], [M[0][1].T, M[1][1], M[1][2]], [M[0][2].T, M[1][2].T, M[2][2]]], - format="csr", - ) - - # apply extraction operator - if self.basis_u == 0: - M = self.space.Ev_0.dot(M.dot(self.space.Ev_0.T)).tocsr() - - elif self.basis_u == 1: - M = self.space.E1_0.dot(M.dot(self.space.E1_0.T)).tocsr() - - elif self.basis_u == 2: - M = self.space.E2_0.dot(M.dot(self.space.E2_0.T)).tocsr() - - return M - - # =============================================================== - def accumulate_step1(self, particles_loc, Np, b2_eq, b2, mpi_comm): - """TODO""" - - b2_1, b2_2, b2_3 = self.space.extract_2(b2) - - if self.space.dim == 2: - pic_ker_2d.kernel_step1( - particles_loc, - self.space.T[0], - self.space.T[1], - self.space.p, - self.space.Nel, - self.space.NbaseN, - self.space.NbaseD, - particles_loc.shape[0], - b2_eq[0], - b2_eq[1], - b2_eq[2], - b2_1, - b2_2, - b2_3, - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - self.blocks_loc[0][1], - self.blocks_loc[0][2], - self.blocks_loc[1][2], - self.basis_u, - self.space.n_tor, - ) - - else: - pic_ker_3d.kernel_step1( - particles_loc, - self.space.T[0], - self.space.T[1], - self.space.T[2], - self.space.p, - self.space.Nel, - self.space.NbaseN, - self.space.NbaseD, - particles_loc.shape[0], - b2_1, - b2_2, - b2_3, - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - self.blocks_loc[0][1], - self.blocks_loc[0][2], - self.blocks_loc[1][2], - self.basis_u, - ) - - mpi_comm.Allreduce(self.blocks_loc[0][1], self.blocks_glo[0][1], op=MPI.SUM) - mpi_comm.Allreduce(self.blocks_loc[0][2], self.blocks_glo[0][2], op=MPI.SUM) - mpi_comm.Allreduce(self.blocks_loc[1][2], self.blocks_glo[1][2], op=MPI.SUM) - - self.blocks_glo[0][1] /= Np - self.blocks_glo[0][2] /= Np - self.blocks_glo[1][2] /= Np - - # =============================================================== - def accumulate_step3(self, particles_loc, Np, b2_eq, b2, mpi_comm): - """TODO""" - - b2_1, b2_2, b2_3 = self.space.extract_2(b2) - - if self.space.dim == 2: - pic_ker_2d.kernel_step3( - particles_loc, - self.space.T[0], - self.space.T[1], - self.space.p, - self.space.Nel, - self.space.NbaseN, - self.space.NbaseD, - particles_loc.shape[0], - b2_eq[0], - b2_eq[1], - b2_eq[2], - b2_1, - b2_2, - b2_3, - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - self.blocks_loc[0][0], - self.blocks_loc[0][1], - self.blocks_loc[0][2], - self.blocks_loc[1][1], - self.blocks_loc[1][2], - self.blocks_loc[2][2], - self.vecs_loc[0], - self.vecs_loc[1], - self.vecs_loc[2], - self.basis_u, - self.space.n_tor, - ) - - else: - pic_ker_3d.kernel_step3( - particles_loc, - self.space.T[0], - self.space.T[1], - self.space.T[2], - self.space.p, - self.space.Nel, - self.space.NbaseN, - self.space.NbaseD, - particles_loc.shape[0], - b2_1, - b2_2, - b2_3, - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - self.blocks_loc[0][0], - self.blocks_loc[0][1], - self.blocks_loc[0][2], - self.blocks_loc[1][1], - self.blocks_loc[1][2], - self.blocks_loc[2][2], - self.vecs_loc[0], - self.vecs_loc[1], - self.vecs_loc[2], - self.basis_u, - ) - - mpi_comm.Allreduce(self.blocks_loc[0][0], self.blocks_glo[0][0], op=MPI.SUM) - mpi_comm.Allreduce(self.blocks_loc[0][1], self.blocks_glo[0][1], op=MPI.SUM) - mpi_comm.Allreduce(self.blocks_loc[0][2], self.blocks_glo[0][2], op=MPI.SUM) - mpi_comm.Allreduce(self.blocks_loc[1][1], self.blocks_glo[1][1], op=MPI.SUM) - mpi_comm.Allreduce(self.blocks_loc[1][2], self.blocks_glo[1][2], op=MPI.SUM) - mpi_comm.Allreduce(self.blocks_loc[2][2], self.blocks_glo[2][2], op=MPI.SUM) - - mpi_comm.Allreduce(self.vecs_loc[0], self.vecs_glo[0], op=MPI.SUM) - mpi_comm.Allreduce(self.vecs_loc[1], self.vecs_glo[1], op=MPI.SUM) - mpi_comm.Allreduce(self.vecs_loc[2], self.vecs_glo[2], op=MPI.SUM) - - self.blocks_glo[0][0] /= Np - self.blocks_glo[0][1] /= Np - self.blocks_glo[0][2] /= Np - self.blocks_glo[1][1] /= Np - self.blocks_glo[1][2] /= Np - self.blocks_glo[2][2] /= Np - - self.vecs_glo[0] /= Np - self.vecs_glo[1] /= Np - self.vecs_glo[2] /= Np - - # =============================================================== - def accumulate_step_ph_full(self, particles_loc, Np, mpi_comm): - """TODO""" - - if self.space.dim == 2: - raise NotImplementedError("2d not implemented") - - else: - pic_ker_3d.kernel_step_ph_full( - particles_loc, - self.space.T[0], - self.space.T[1], - self.space.T[2], - self.space.p, - self.space.Nel, - self.space.NbaseN, - self.space.NbaseD, - particles_loc.shape[0], - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - self.blocks_loc[0][0], - self.blocks_loc[0][1], - self.blocks_loc[0][2], - self.blocks_loc[1][1], - self.blocks_loc[1][2], - self.blocks_loc[2][2], - self.vecs_loc[0], - self.vecs_loc[1], - self.vecs_loc[2], - self.basis_u, - ) - - mpi_comm.Allreduce(self.blocks_loc[0][0], self.blocks_glo[0][0], op=MPI.SUM) - mpi_comm.Allreduce(self.blocks_loc[0][1], self.blocks_glo[0][1], op=MPI.SUM) - mpi_comm.Allreduce(self.blocks_loc[0][2], self.blocks_glo[0][2], op=MPI.SUM) - mpi_comm.Allreduce(self.blocks_loc[1][1], self.blocks_glo[1][1], op=MPI.SUM) - mpi_comm.Allreduce(self.blocks_loc[1][2], self.blocks_glo[1][2], op=MPI.SUM) - mpi_comm.Allreduce(self.blocks_loc[2][2], self.blocks_glo[2][2], op=MPI.SUM) - - mpi_comm.Allreduce(self.vecs_loc[0], self.vecs_glo[0], op=MPI.SUM) - mpi_comm.Allreduce(self.vecs_loc[1], self.vecs_glo[1], op=MPI.SUM) - mpi_comm.Allreduce(self.vecs_loc[2], self.vecs_glo[2], op=MPI.SUM) - - self.blocks_glo[0][0] /= Np - self.blocks_glo[0][1] /= Np - self.blocks_glo[0][2] /= Np - self.blocks_glo[1][1] /= Np - self.blocks_glo[1][2] /= Np - self.blocks_glo[2][2] /= Np - - self.vecs_glo[0] /= Np - self.vecs_glo[1] /= Np - self.vecs_glo[2] /= Np - - # =============================================================== - def assemble_step1(self, b2_eq, b2): - """TODO""" - - # delta-f correction - if self.use_control: - b2_1, b2_2, b2_3 = self.space.extract_2(b2) - - if self.space.dim == 2: - self.cont.correct_step1(b2_eq[0], b2_eq[1], b2_eq[2]) - else: - self.cont.correct_step1(b2_eq[0] + b2_1, b2_eq[1] + b2_2, b2_eq[2] + b2_3) - - self.blocks_glo[0][1] += self.cont.M12 - self.blocks_glo[0][2] += self.cont.M13 - self.blocks_glo[1][2] += self.cont.M23 - - # build global sparse matrix - return self.to_sparse_step1() - - # =============================================================== - def assemble_step3(self, b2_eq, b2): - """TODO""" - - # delta-f correction - if self.use_control: - b2_1, b2_2, b2_3 = self.space.extract_2(b2) - - if self.space.dim == 2: - self.cont.correct_step3(b2_1, b2_2, b2_3) - else: - self.cont.correct_step3(b2_eq[0] + b2_1, b2_eq[1] + b2_2, b2_eq[2] + b2_3) - - self.vecs_glo[0] += self.cont.F1 - self.vecs_glo[1] += self.cont.F2 - self.vecs_glo[2] += self.cont.F3 - - # build global sparse matrix and global vector - if self.basis_u == 0: - return self.to_sparse_step3(), self.space.Ev_0.dot( - xp.concatenate((self.vecs[0].flatten(), self.vecs[1].flatten(), self.vecs[2].flatten())), - ) - - elif self.basis_u == 1: - return self.to_sparse_step3(), self.space.E1_0.dot( - xp.concatenate((self.vecs[0].flatten(), self.vecs[1].flatten(), self.vecs[2].flatten())), - ) - - elif self.basis_u == 2: - return self.to_sparse_step3(), self.space.E2_0.dot( - xp.concatenate((self.vecs[0].flatten(), self.vecs[1].flatten(), self.vecs[2].flatten())), - ) diff --git a/src/struphy/pic/tests/test_pic_legacy_files/accumulation_kernels_3d.py b/src/struphy/pic/tests/test_pic_legacy_files/accumulation_kernels_3d.py deleted file mode 100644 index 349cca379..000000000 --- a/src/struphy/pic/tests/test_pic_legacy_files/accumulation_kernels_3d.py +++ /dev/null @@ -1,1492 +0,0 @@ -# import module for matrix-matrix and matrix-vector multiplications -# import modules for B-spline evaluation -import struphy.bsplines.bsplines_kernels as bsp -import struphy.linear_algebra.linalg_kernels as linalg - -# import module for mapping evaluation -import struphy.pic.tests.test_pic_legacy_files.mappings_3d_fast as mapping_fast -import struphy.pic.tests.test_pic_legacy_files.spline_evaluation_3d as eva3 - - -# ============================================================================== -def kernel_step1( - particles: "float[:,:]", - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - p: "int[:]", - nel: "int[:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - np: "int", - b2_1: "float[:,:,:]", - b2_2: "float[:,:,:]", - b2_3: "float[:,:,:]", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", - mat12: "float[:,:,:,:,:,:]", - mat13: "float[:,:,:,:,:,:]", - mat23: "float[:,:,:,:,:,:]", - basis_u: "int", -): - from numpy import empty, zeros - - # reset arrays - mat12[:, :, :, :, :, :] = 0.0 - mat13[:, :, :, :, :, :] = 0.0 - mat23[:, :, :, :, :, :] = 0.0 - - # ============== for magnetic field evaluation ============ - # spline degrees - pn1 = p[0] - pn2 = p[1] - pn3 = p[2] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - pd3 = pn3 - 1 - - # non-vanishing N-splines at particle position - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - # non-vanishing D-splines at particle position - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - # magnetic field at particle position - b = empty(3, dtype=float) - b_prod = zeros((3, 3), dtype=float) - # ========================================================== - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = empty((3, 3), dtype=float) - dfinv = empty((3, 3), dtype=float) - ginv = empty((3, 3), dtype=float) - fx = empty(3, dtype=float) - - temp_mat1 = empty((3, 3), dtype=float) - temp_mat2 = empty((3, 3), dtype=float) - # ========================================================== - - # -- removed omp: #$ omp parallel private (ip, eta1, eta2, eta3, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, det_df, dfinv, ginv, span1, span2, span3, bn1, bn2, bn3, bd1, bd2, bd3, b, ie1, ie2, ie3, temp_mat1, temp_mat2, w_over_det2, temp12, temp13, temp23, il1, il2, il3, jl1, jl2, jl3, i1, i2, i3, bi1, bi2, bi3, bj1, bj2, bj3) firstprivate(b_prod) - # -- removed omp: #$ omp for reduction ( + : mat12, mat13, mat23) - for ip in range(np): - # only do something if particle is inside the logical domain (s < 1) - if particles[ip, 0] > 1.0 or particles[ip, 0] < 0.0: - continue - - eta1 = particles[ip, 0] - eta2 = particles[ip, 1] - eta3 = particles[ip, 2] - - # ========= mapping evaluation ============= - span1f = int(eta1 * nelf[0]) + pf1 - span2f = int(eta2 * nelf[1]) + pf2 - span3f = int(eta3 * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate inverse metric tensor - mapping_fast.g_inv_all(dfinv, ginv) - # ========================================== - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - span3 = int(eta3 * nel[2]) + pn3 - - # N-splines and D-splines at particle positions - bsp.b_d_splines_slim(t1, int(pn1), eta1, int(span1), bn1, bd1) - bsp.b_d_splines_slim(t2, int(pn2), eta2, int(span2), bn2, bd2) - bsp.b_d_splines_slim(t3, int(pn3), eta3, int(span3), bn3, bd3) - - b[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - b2_1, - ) - b[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - b2_2, - ) - b[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - b2_3, - ) - - b_prod[0, 1] = -b[2] - b_prod[0, 2] = b[1] - - b_prod[1, 0] = b[2] - b_prod[1, 2] = -b[0] - - b_prod[2, 0] = -b[1] - b_prod[2, 1] = b[0] - # ========================================== - - # ========= charge accumulation ============ - # element indices - ie1 = span1 - pn1 - ie2 = span2 - pn2 - ie3 = span3 - pn3 - - # bulk velocity is a 0-form - if basis_u == 0: - # particle weight and magnetic field rotation - temp12 = -particles[ip, 6] * b_prod[0, 1] - temp13 = -particles[ip, 6] * b_prod[0, 2] - temp23 = -particles[ip, 6] * b_prod[1, 2] - - for il1 in range(pn1 + 1): - i1 = (ie1 + il1) % nbase_n[0] - bi1 = bn1[il1] - for il2 in range(pn2 + 1): - i2 = (ie2 + il2) % nbase_n[1] - bi2 = bi1 * bn2[il2] - for il3 in range(pn3 + 1): - i3 = (ie3 + il3) % nbase_n[2] - bi3 = bi2 * bn3[il3] - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - - mat12[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 * temp12 - mat13[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 * temp13 - mat23[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 * temp23 - - # bulk velocity is a 1-form - elif basis_u == 1: - # particle weight and magnetic field rotation - linalg.matrix_matrix(ginv, b_prod, temp_mat1) - linalg.matrix_matrix(temp_mat1, ginv, temp_mat2) - - temp12 = -particles[ip, 6] * temp_mat2[0, 1] - temp13 = -particles[ip, 6] * temp_mat2[0, 2] - temp23 = -particles[ip, 6] * temp_mat2[1, 2] - - # add contribution to 12 component (DNN NDN) and 13 component (DNN NND) - for il1 in range(pd1 + 1): - i1 = (ie1 + il1) % nbase_d[0] - bi1 = bd1[il1] - for il2 in range(pn2 + 1): - i2 = (ie2 + il2) % nbase_n[1] - bi2 = bi1 * bn2[il2] - for il3 in range(pn3 + 1): - i3 = (ie3 + il3) % nbase_n[2] - bi3 = bi2 * bn3[il3] - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] - - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] * temp12 - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - - mat12[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] * temp13 - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - - mat13[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - # add contribution to 23 component (NDN NND) - for il1 in range(pn1 + 1): - i1 = (ie1 + il1) % nbase_n[0] - bi1 = bn1[il1] * temp23 - for il2 in range(pd2 + 1): - i2 = (ie2 + il2) % nbase_d[1] - bi2 = bi1 * bd2[il2] - for il3 in range(pn3 + 1): - i3 = (ie3 + il3) % nbase_n[2] - bi3 = bi2 * bn3[il3] - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - - mat23[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - # bulk velocity is a 2-form - elif basis_u == 2: - # particle weight and magnetic field rotation - w_over_det2 = particles[ip, 6] / det_df**2 - - temp12 = -w_over_det2 * b_prod[0, 1] - temp13 = -w_over_det2 * b_prod[0, 2] - temp23 = -w_over_det2 * b_prod[1, 2] - - # add contribution to 12 component (NDD DND) and 13 component (NDD DDN) - for il1 in range(pn1 + 1): - i1 = (ie1 + il1) % nbase_n[0] - bi1 = bn1[il1] - for il2 in range(pd2 + 1): - i2 = (ie2 + il2) % nbase_d[1] - bi2 = bi1 * bd2[il2] - for il3 in range(pd3 + 1): - i3 = (ie3 + il3) % nbase_d[2] - bi3 = bi2 * bd3[il3] - - for jl1 in range(pd1 + 1): - bj1 = bi3 * bd1[jl1] - - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] * temp12 - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - - mat12[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] * temp13 - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - - mat13[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - # add contribution to 23 component (DND DDN) - for il1 in range(pd1 + 1): - i1 = (ie1 + il1) % nbase_d[0] - bi1 = bd1[il1] * temp23 - for il2 in range(pn2 + 1): - i2 = (ie2 + il2) % nbase_n[1] - bi2 = bi1 * bn2[il2] - for il3 in range(pd3 + 1): - i3 = (ie3 + il3) % nbase_d[2] - bi3 = bi2 * bd3[il3] - for jl1 in range(pd1 + 1): - bj1 = bi3 * bd1[jl1] - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - - mat23[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================== -def kernel_step3( - particles: "float[:,:]", - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - p: "int[:]", - nel: "int[:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - np: "int", - b2_1: "float[:,:,:]", - b2_2: "float[:,:,:]", - b2_3: "float[:,:,:]", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", - mat11: "float[:,:,:,:,:,:]", - mat12: "float[:,:,:,:,:,:]", - mat13: "float[:,:,:,:,:,:]", - mat22: "float[:,:,:,:,:,:]", - mat23: "float[:,:,:,:,:,:]", - mat33: "float[:,:,:,:,:,:]", - vec1: "float[:,:,:]", - vec2: "float[:,:,:]", - vec3: "float[:,:,:]", - basis_u: "int", -): - from numpy import empty, zeros - - # reset arrays - mat11[:, :, :, :, :, :] = 0.0 - mat12[:, :, :, :, :, :] = 0.0 - mat13[:, :, :, :, :, :] = 0.0 - mat22[:, :, :, :, :, :] = 0.0 - mat23[:, :, :, :, :, :] = 0.0 - mat33[:, :, :, :, :, :] = 0.0 - - vec1[:, :, :] = 0.0 - vec2[:, :, :] = 0.0 - vec3[:, :, :] = 0.0 - - # ============== for magnetic field evaluation ============ - # spline degrees - pn1 = p[0] - pn2 = p[1] - pn3 = p[2] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - pd3 = pn3 - 1 - - # p + 1 non-vanishing basis functions up tp degree p - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - # non-vanishing D-splines - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - # magnetic field at particle position - b = empty(3, dtype=float) - b_prod = zeros((3, 3), dtype=float) - b_prod_t = zeros((3, 3), dtype=float) - # ========================================================== - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = empty((3, 3), dtype=float) - dfinv = empty((3, 3), dtype=float) - ginv = empty((3, 3), dtype=float) - fx = empty(3, dtype=float) - - temp_mat1 = empty((3, 3), dtype=float) - temp_mat2 = empty((3, 3), dtype=float) - - temp_mat_vec = empty((3, 3), dtype=float) - - temp_vec = empty(3, dtype=float) - - # particle velocity - v = empty(3, dtype=float) - # ========================================================== - - # -- removed omp: #$ omp parallel private (ip, eta1, eta2, eta3, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, det_df, dfinv, ginv, span1, span2, span3, l1, l2, l3, r1, r2, r3, b1, b2, b3, d1, d2, d3, bn1, bn2, bn3, bd1, bd2, bd3, b, b_prod_t, ie1, ie2, ie3, v, temp_mat_vec, temp_mat1, temp_mat2, temp_vec, w_over_det1, w_over_det2, temp11, temp12, temp13, temp22, temp23, temp33, temp1, temp2, temp3, il1, il2, il3, jl1, jl2, jl3, i1, i2, i3, bi1, bi2, bi3, bj1, bj2, bj3) firstprivate(b_prod) - # -- removed omp: #$ omp for reduction ( + : mat11, mat12, mat13, mat22, mat23, mat33, vec1, vec2, vec3) - for ip in range(np): - # only do something if particle is inside the logical domain (s < 1) - if particles[ip, 0] > 1.0 or particles[ip, 0] < 0.0: - continue - - eta1 = particles[ip, 0] - eta2 = particles[ip, 1] - eta3 = particles[ip, 2] - - # ========= mapping evaluation ============= - span1f = int(eta1 * nelf[0]) + pf1 - span2f = int(eta2 * nelf[1]) + pf2 - span3f = int(eta3 * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate inverse metric tensor - mapping_fast.g_inv_all(dfinv, ginv) - # ========================================== - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - span3 = int(eta3 * nel[2]) + pn3 - - # N-splines and D-splines at particle positions - bsp.b_d_splines_slim(t1, int(pn1), eta1, int(span1), bn1, bd1) - bsp.b_d_splines_slim(t2, int(pn2), eta2, int(span2), bn2, bd2) - bsp.b_d_splines_slim(t3, int(pn3), eta3, int(span3), bn3, bd3) - - b[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - b2_1, - ) - b[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - b2_2, - ) - b[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - b2_3, - ) - - b_prod[0, 1] = -b[2] - b_prod[0, 2] = b[1] - - b_prod[1, 0] = b[2] - b_prod[1, 2] = -b[0] - - b_prod[2, 0] = -b[1] - b_prod[2, 1] = b[0] - - linalg.transpose(b_prod, b_prod_t) - # ========================================== - - # ========= current accumulation =========== - # element indices - ie1 = span1 - pn1 - ie2 = span2 - pn2 - ie3 = span3 - pn3 - - # particle velocity - v[:] = particles[ip, 3:6] - - if basis_u == 0: - # perform matrix-matrix multiplications - linalg.matrix_matrix(b_prod, dfinv, temp_mat_vec) - linalg.matrix_matrix(b_prod, ginv, temp_mat1) - linalg.matrix_matrix(temp_mat1, b_prod_t, temp_mat2) - - linalg.matrix_vector(temp_mat_vec, v, temp_vec) - - temp11 = particles[ip, 6] * temp_mat2[0, 0] - temp12 = particles[ip, 6] * temp_mat2[0, 1] - temp13 = particles[ip, 6] * temp_mat2[0, 2] - temp22 = particles[ip, 6] * temp_mat2[1, 1] - temp23 = particles[ip, 6] * temp_mat2[1, 2] - temp33 = particles[ip, 6] * temp_mat2[2, 2] - - temp1 = particles[ip, 6] * temp_vec[0] - temp2 = particles[ip, 6] * temp_vec[1] - temp3 = particles[ip, 6] * temp_vec[2] - - for il1 in range(pn1 + 1): - i1 = (ie1 + il1) % nbase_n[0] - bi1 = bn1[il1] - for il2 in range(pn2 + 1): - i2 = (ie2 + il2) % nbase_n[1] - bi2 = bi1 * bn2[il2] - for il3 in range(pn3 + 1): - i3 = (ie3 + il3) % nbase_n[2] - bi3 = bi2 * bn3[il3] - - vec1[i1, i2, i3] += bi3 * temp1 - vec2[i1, i2, i3] += bi3 * temp2 - vec3[i1, i2, i3] += bi3 * temp3 - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - - mat11[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 * temp11 - mat12[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 * temp12 - mat13[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 * temp13 - mat22[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 * temp22 - mat23[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 * temp23 - mat33[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 * temp33 - - elif basis_u == 1: - # perform matrix-matrix multiplications - linalg.matrix_matrix(ginv, b_prod, temp_mat1) - linalg.matrix_matrix(temp_mat1, dfinv, temp_mat_vec) - linalg.matrix_vector(temp_mat_vec, v, temp_vec) - - linalg.matrix_matrix(temp_mat1, ginv, temp_mat2) - linalg.transpose(b_prod, b_prod_t) - linalg.matrix_matrix(temp_mat2, b_prod_t, temp_mat1) - linalg.matrix_matrix(temp_mat1, ginv, temp_mat2) - - temp11 = particles[ip, 6] * temp_mat2[0, 0] - temp12 = particles[ip, 6] * temp_mat2[0, 1] - temp13 = particles[ip, 6] * temp_mat2[0, 2] - temp22 = particles[ip, 6] * temp_mat2[1, 1] - temp23 = particles[ip, 6] * temp_mat2[1, 2] - temp33 = particles[ip, 6] * temp_mat2[2, 2] - - temp1 = particles[ip, 6] * temp_vec[0] - temp2 = particles[ip, 6] * temp_vec[1] - temp3 = particles[ip, 6] * temp_vec[2] - - # add contribution to 11 component (DNN DNN), 12 component (DNN NDN) and 13 component (DNN NND) - for il1 in range(pd1 + 1): - i1 = (ie1 + il1) % nbase_d[0] - bi1 = bd1[il1] - for il2 in range(pn2 + 1): - i2 = (ie2 + il2) % nbase_n[1] - bi2 = bi1 * bn2[il2] - for il3 in range(pn3 + 1): - i3 = (ie3 + il3) % nbase_n[2] - bi3 = bi2 * bn3[il3] - - vec1[i1, i2, i3] += bi3 * temp1 - - for jl1 in range(pd1 + 1): - bj1 = bi3 * bd1[jl1] * temp11 - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - - mat11[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] * temp12 - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - - mat12[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] * temp13 - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - - mat13[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - # add contribution to 22 component (NDN NDN) and 23 component (NDN NND) - for il1 in range(pn1 + 1): - i1 = (ie1 + il1) % nbase_n[0] - bi1 = bn1[il1] - for il2 in range(pd2 + 1): - i2 = (ie2 + il2) % nbase_d[1] - bi2 = bi1 * bd2[il2] - for il3 in range(pn3 + 1): - i3 = (ie3 + il3) % nbase_n[2] - bi3 = bi2 * bn3[il3] - - vec2[i1, i2, i3] += bi3 * temp2 - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] - - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] * temp22 - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - - mat22[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] * temp23 - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - - mat23[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - # add contribution to 33 component (NND NND) - for il1 in range(pn1 + 1): - i1 = (ie1 + il1) % nbase_n[0] - bi1 = bn1[il1] - for il2 in range(pn2 + 1): - i2 = (ie2 + il2) % nbase_n[1] - bi2 = bi1 * bn2[il2] - for il3 in range(pd3 + 1): - i3 = (ie3 + il3) % nbase_d[2] - bi3 = bi2 * bd3[il3] - - vec3[i1, i2, i3] += bi3 * temp3 - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] * temp33 - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - - mat33[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - elif basis_u == 2: - # perform matrix-matrix multiplications - linalg.matrix_matrix(b_prod, dfinv, temp_mat_vec) - linalg.matrix_matrix(b_prod, ginv, temp_mat1) - linalg.matrix_matrix(temp_mat1, b_prod_t, temp_mat2) - - linalg.matrix_vector(temp_mat_vec, v, temp_vec) - - w_over_det1 = particles[ip, 6] / det_df - w_over_det2 = particles[ip, 6] / det_df**2 - - temp11 = w_over_det2 * temp_mat2[0, 0] - temp12 = w_over_det2 * temp_mat2[0, 1] - temp13 = w_over_det2 * temp_mat2[0, 2] - temp22 = w_over_det2 * temp_mat2[1, 1] - temp23 = w_over_det2 * temp_mat2[1, 2] - temp33 = w_over_det2 * temp_mat2[2, 2] - - temp1 = w_over_det1 * temp_vec[0] - temp2 = w_over_det1 * temp_vec[1] - temp3 = w_over_det1 * temp_vec[2] - - # add contribution to 11 component (NDD NDD), 12 component (NDD DND) and 13 component (NDD DDN) - for il1 in range(pn1 + 1): - i1 = (ie1 + il1) % nbase_n[0] - bi1 = bn1[il1] - for il2 in range(pd2 + 1): - i2 = (ie2 + il2) % nbase_d[1] - bi2 = bi1 * bd2[il2] - for il3 in range(pd3 + 1): - i3 = (ie3 + il3) % nbase_d[2] - bi3 = bi2 * bd3[il3] - - vec1[i1, i2, i3] += bi3 * temp1 - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] * temp11 - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - - mat11[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - for jl1 in range(pd1 + 1): - bj1 = bi3 * bd1[jl1] * temp12 - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - - mat12[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - for jl1 in range(pd1 + 1): - bj1 = bi3 * bd1[jl1] * temp13 - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - - mat13[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - # add contribution to 22 component (DND DND) and 23 component (DND DDN) - for il1 in range(pd1 + 1): - i1 = (ie1 + il1) % nbase_d[0] - bi1 = bd1[il1] - for il2 in range(pn2 + 1): - i2 = (ie2 + il2) % nbase_n[1] - bi2 = bi1 * bn2[il2] - for il3 in range(pd3 + 1): - i3 = (ie3 + il3) % nbase_d[2] - bi3 = bi2 * bd3[il3] - - vec2[i1, i2, i3] += bi3 * temp2 - - for jl1 in range(pd1 + 1): - bj1 = bi3 * bd1[jl1] - - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] * temp22 - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - - mat22[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] * temp23 - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - - mat23[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - # add contribution to 33 component (DDN DDN) - for il1 in range(pd1 + 1): - i1 = (ie1 + il1) % nbase_d[0] - bi1 = bd1[il1] - for il2 in range(pd2 + 1): - i2 = (ie2 + il2) % nbase_d[1] - bi2 = bi1 * bd2[il2] - for il3 in range(pn3 + 1): - i3 = (ie3 + il3) % nbase_n[2] - bi3 = bi2 * bn3[il3] - - vec3[i1, i2, i3] += bi3 * temp3 - - for jl1 in range(pd1 + 1): - bj1 = bi3 * bd1[jl1] * temp33 - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - - mat33[i1, i2, i3, pn1 + jl1 - il1, pn2 + jl2 - il2, pn3 + jl3 - il3] += bj3 - - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ============================================================================== -def kernel_step_ph_full( - particles: "float[:,:]", - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - p: "int[:]", - nel: "int[:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - np: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", - mat11: "float[:,:,:,:,:,:,:,:]", - mat12: "float[:,:,:,:,:,:,:,:]", - mat13: "float[:,:,:,:,:,:,:,:]", - mat22: "float[:,:,:,:,:,:,:,:]", - mat23: "float[:,:,:,:,:,:,:,:]", - mat33: "float[:,:,:,:,:,:,:,:]", - vec1: "float[:,:,:,:]", - vec2: "float[:,:,:,:]", - vec3: "float[:,:,:,:]", - basis_u: "int", -): - from numpy import empty, zeros - - # reset arrays - mat11[:, :, :, :, :, :, :, :] = 0.0 - mat12[:, :, :, :, :, :, :, :] = 0.0 - mat13[:, :, :, :, :, :, :, :] = 0.0 - mat22[:, :, :, :, :, :, :, :] = 0.0 - mat23[:, :, :, :, :, :, :, :] = 0.0 - mat33[:, :, :, :, :, :, :, :] = 0.0 - - vec1[:, :, :, :] = 0.0 - vec2[:, :, :, :] = 0.0 - vec3[:, :, :, :] = 0.0 - - # ============== for magnetic field evaluation ============ - # spline degrees - pn1 = p[0] - pn2 = p[1] - pn3 = p[2] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - pd3 = pn3 - 1 - - # # p + 1 non-vanishing basis functions up tp degree p - # b1 = empty((pn1 + 1, pn1 + 1), dtype=float) - # b2 = empty((pn2 + 1, pn2 + 1), dtype=float) - # b3 = empty((pn3 + 1, pn3 + 1), dtype=float) - - # # left and right values for spline evaluation - # l1 = empty( pn1, dtype=float) - # l2 = empty( pn2, dtype=float) - # l3 = empty( pn3, dtype=float) - - # r1 = empty( pn1, dtype=float) - # r2 = empty( pn2, dtype=float) - # r3 = empty( pn3, dtype=float) - - # # scaling arrays for M-splines - # d1 = empty( pn1, dtype=float) - # d2 = empty( pn2, dtype=float) - # d3 = empty( pn3, dtype=float) - - # non-vanishing N-splines - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - # non-vanishing D-splines - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - # ========================================================== - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = empty((3, 3), dtype=float) - dfinv = empty((3, 3), dtype=float) - dfinv_t = empty((3, 3), dtype=float) - ginv = empty((3, 3), dtype=float) - fx = empty(3, dtype=float) - temp_mat = empty((3, 3), dtype=float) - temp_vec = empty(3, dtype=float) - - # particle velocity - v = empty(3, dtype=float) - - # ========================================================== - - # -- removed omp: #$ omp parallel private(ip, vp, vq, eta1, eta2, eta3, v, span1, span2, span3, l1, l2, l3, r1, r2, r3, b1, b2, b3, d1, d2, d3, bn1, bn2, bn3, bd1, bd2, bd3, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, dfinv, dfinv_t, ginv, ie1, ie2, ie3, temp_mat, temp_vec, temp11, temp12, temp13, temp22, temp23, temp33, temp1, temp2, temp3, il1, il2, il3, jl1, jl2, jl3, i1, i2, i3, bi1, bi2, bi3, bj1, bj2, bj3) - # -- removed omp: #$ omp for reduction ( + : mat11, mat12, mat13, mat22, mat23, mat33, vec1, vec2, vec3) - for ip in range(np): - # only do something if particle is inside the logical domain (s < 1) - if particles[ip, 0] > 1.0 or particles[ip, 0] < 0.0: - continue - - eta1 = particles[ip, 0] - eta2 = particles[ip, 1] - eta3 = particles[ip, 2] - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - span3 = int(eta3 * nel[2]) + pn3 - - # bsp.basis_funs_all(t1, pn1, eta1, span1, l1, r1, b1, d1) - # bsp.basis_funs_all(t2, pn2, eta2, span2, l2, r2, b2, d2) - # bsp.basis_funs_all(t3, pn3, eta3, span3, l3, r3, b3, d3) - # N-splines and D-splines at particle positions - bsp.b_d_splines_slim(t1, int(pn1), eta1, int(span1), bn1, bd1) - bsp.b_d_splines_slim(t2, int(pn2), eta2, int(span2), bn2, bd2) - bsp.b_d_splines_slim(t3, int(pn3), eta3, int(span3), bn3, bd3) - - # # N-splines and D-splines at particle positions - # bn1[:] = b1[pn1, :] - # bn2[:] = b2[pn2, :] - # bn3[:] = b3[pn3, :] - - # bd1[:] = b1[pd1, :pn1] * d1[:] - # bd2[:] = b2[pd2, :pn2] * d2[:] - # bd3[:] = b3[pd3, :pn3] * d3[:] - # ========================================== - - # ========= mapping evaluation ============= - span1f = int(eta1 * nelf[0]) + pf1 - span2f = int(eta2 * nelf[1]) + pf2 - span3f = int(eta3 * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate inverse metric tensor - mapping_fast.g_inv_all(dfinv, ginv) - # ========================================== - - # ========= accumulation =========== - # element indices - ie1 = span1 - pn1 - ie2 = span2 - pn2 - ie3 = span3 - pn3 - - # particle velocity - v[:] = particles[ip, 3:6] - - # perform DF^-T * V - linalg.matrix_vector(dfinv, v, temp_vec) - - # perform V^T G^-1 V - linalg.transpose(dfinv, dfinv_t) - linalg.matrix_matrix(dfinv, dfinv_t, temp_mat) - - temp11 = particles[ip, 8] * temp_mat[0, 0] - temp12 = particles[ip, 8] * temp_mat[0, 1] - temp13 = particles[ip, 8] * temp_mat[0, 2] - temp22 = particles[ip, 8] * temp_mat[1, 1] - temp23 = particles[ip, 8] * temp_mat[1, 2] - temp33 = particles[ip, 8] * temp_mat[2, 2] - - temp1 = particles[ip, 8] * temp_vec[0] - temp2 = particles[ip, 8] * temp_vec[1] - temp3 = particles[ip, 8] * temp_vec[2] - - if basis_u == 1: - # add contribution to 11 component (DNN DNN), 12 component (DNN NDN) and 13 component (DNN NND) - for il1 in range(pd1 + 1): - i1 = (ie1 + il1) % nbase_d[0] - bi1 = bd1[il1] - for il2 in range(pn2 + 1): - i2 = (ie2 + il2) % nbase_n[1] - bi2 = bi1 * bn2[il2] - for il3 in range(pn3 + 1): - i3 = (ie3 + il3) % nbase_n[2] - bi3 = bi2 * bn3[il3] - for vp in range(3): - vec1[i1, i2, i3, vp] += bi3 * temp1 * v[vp] - - for jl1 in range(pd1 + 1): - bj1 = bi3 * bd1[jl1] * temp11 - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - for vp in range(3): - for vq in range(3): - mat11[ - i1, - i2, - i3, - pn1 + jl1 - il1, - pn2 + jl2 - il2, - pn3 + jl3 - il3, - vp, - vq, - ] += bj3 * v[vp] * v[vq] - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] * temp12 - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - for vp in range(3): - for vq in range(3): - mat12[ - i1, - i2, - i3, - pn1 + jl1 - il1, - pn2 + jl2 - il2, - pn3 + jl3 - il3, - vp, - vq, - ] += bj3 * v[vp] * v[vq] - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] * temp13 - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - for vp in range(3): - for vq in range(3): - mat13[ - i1, - i2, - i3, - pn1 + jl1 - il1, - pn2 + jl2 - il2, - pn3 + jl3 - il3, - vp, - vq, - ] += bj3 * v[vp] * v[vq] - - # add contribution to 22 component (NDN NDN) and 23 component (NDN NND) - for il1 in range(pn1 + 1): - i1 = (ie1 + il1) % nbase_n[0] - bi1 = bn1[il1] - for il2 in range(pd2 + 1): - i2 = (ie2 + il2) % nbase_d[1] - bi2 = bi1 * bd2[il2] - for il3 in range(pn3 + 1): - i3 = (ie3 + il3) % nbase_n[2] - bi3 = bi2 * bn3[il3] - for vp in range(3): - vec2[i1, i2, i3, vp] += bi3 * temp2 * v[vp] - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] * temp22 - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - for vp in range(3): - for vq in range(3): - mat22[ - i1, - i2, - i3, - pn1 + jl1 - il1, - pn2 + jl2 - il2, - pn3 + jl3 - il3, - vp, - vq, - ] += bj3 * v[vp] * v[vq] - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] * temp23 - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - for vp in range(3): - for vq in range(3): - mat23[ - i1, - i2, - i3, - pn1 + jl1 - il1, - pn2 + jl2 - il2, - pn3 + jl3 - il3, - vp, - vq, - ] += bj3 * v[vp] * v[vq] - - # add contribution to 33 component (NND NND) - for il1 in range(pn1 + 1): - i1 = (ie1 + il1) % nbase_n[0] - bi1 = bn1[il1] - for il2 in range(pn2 + 1): - i2 = (ie2 + il2) % nbase_n[1] - bi2 = bi1 * bn2[il2] - for il3 in range(pd3 + 1): - i3 = (ie3 + il3) % nbase_d[2] - bi3 = bi2 * bd3[il3] - for vp in range(3): - vec3[i1, i2, i3, vp] += bi3 * temp3 * v[vp] - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] * temp33 - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - for vp in range(3): - for vq in range(3): - mat33[ - i1, - i2, - i3, - pn1 + jl1 - il1, - pn2 + jl2 - il2, - pn3 + jl3 - il3, - vp, - vq, - ] += bj3 * v[vp] * v[vq] - - elif basis_u == 2: - # add contribution to 11 component (NDD NDD), 12 component (NDD DND) and 13 component (NDD DDN) - for il1 in range(pn1 + 1): - i1 = (ie1 + il1) % nbase_n[0] - bi1 = bn1[il1] - for il2 in range(pd2 + 1): - i2 = (ie2 + il2) % nbase_d[1] - bi2 = bi1 * bd2[il2] - for il3 in range(pd3 + 1): - i3 = (ie3 + il3) % nbase_d[2] - bi3 = bi2 * bd3[il3] - for vp in range(3): - vec1[i1, i2, i3, vp] += bi3 * temp1 * v[vp] - - for jl1 in range(pn1 + 1): - bj1 = bi3 * bn1[jl1] * temp11 - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - for vp in range(3): - for vq in range(3): - mat11[ - i1, - i2, - i3, - pn1 + jl1 - il1, - pn2 + jl2 - il2, - pn3 + jl3 - il3, - vp, - vq, - ] += bj3 * v[vp] * v[vq] - - for jl1 in range(pd1 + 1): - bj1 = bi3 * bd1[jl1] * temp12 - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - for vp in range(3): - for vq in range(3): - mat12[ - i1, - i2, - i3, - pn1 + jl1 - il1, - pn2 + jl2 - il2, - pn3 + jl3 - il3, - vp, - vq, - ] += bj3 * v[vp] * v[vq] - - for jl1 in range(pd1 + 1): - bj1 = bi3 * bd1[jl1] * temp13 - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - for vp in range(3): - for vq in range(3): - mat13[ - i1, - i2, - i3, - pn1 + jl1 - il1, - pn2 + jl2 - il2, - pn3 + jl3 - il3, - vp, - vq, - ] += bj3 * v[vp] * v[vq] - - # add contribution to 22 component (DND DND) and 23 component (DND DDN) - for il1 in range(pd1 + 1): - i1 = (ie1 + il1) % nbase_d[0] - bi1 = bd1[il1] - for il2 in range(pn2 + 1): - i2 = (ie2 + il2) % nbase_n[1] - bi2 = bi1 * bn2[il2] - for il3 in range(pd3 + 1): - i3 = (ie3 + il3) % nbase_d[2] - bi3 = bi2 * bd3[il3] - for vp in range(3): - vec2[i1, i2, i3, vp] += bi3 * temp2 * v[vp] - - for jl1 in range(pd1 + 1): - bj1 = bi3 * bd1[jl1] - for jl2 in range(pn2 + 1): - bj2 = bj1 * bn2[jl2] * temp22 - for jl3 in range(pd3 + 1): - bj3 = bj2 * bd3[jl3] - for vp in range(3): - for vq in range(3): - mat22[ - i1, - i2, - i3, - pn1 + jl1 - il1, - pn2 + jl2 - il2, - pn3 + jl3 - il3, - vp, - vq, - ] += bj3 * v[vp] * v[vq] - - for jl1 in range(pd1 + 1): - bj1 = bi3 * bd1[jl1] - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] * temp23 - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - for vp in range(3): - for vq in range(3): - mat23[ - i1, - i2, - i3, - pn1 + jl1 - il1, - pn2 + jl2 - il2, - pn3 + jl3 - il3, - vp, - vq, - ] += bj3 * v[vp] * v[vq] - - # add contribution to 33 component (DDN DDN) - for il1 in range(pd1 + 1): - i1 = (ie1 + il1) % nbase_d[0] - bi1 = bd1[il1] - for il2 in range(pd2 + 1): - i2 = (ie2 + il2) % nbase_d[1] - bi2 = bi1 * bd2[il2] - for il3 in range(pn3 + 1): - i3 = (ie3 + il3) % nbase_n[2] - bi3 = bi2 * bn3[il3] - for vp in range(3): - vec3[i1, i2, i3, vp] += bi3 * temp3 * v[vp] - - for jl1 in range(pd1 + 1): - bj1 = bi3 * bd1[jl1] * temp33 - for jl2 in range(pd2 + 1): - bj2 = bj1 * bd2[jl2] - for jl3 in range(pn3 + 1): - bj3 = bj2 * bn3[jl3] - for vp in range(3): - for vq in range(3): - mat33[ - i1, - i2, - i3, - pn1 + jl1 - il1, - pn2 + jl2 - il2, - pn3 + jl3 - il3, - vp, - vq, - ] += bj3 * v[vp] * v[vq] - - # -- removed omp: #$ omp end parallel - - ierr = 0 diff --git a/src/struphy/pic/tests/test_pic_legacy_files/mappings_3d.py b/src/struphy/pic/tests/test_pic_legacy_files/mappings_3d.py deleted file mode 100644 index 2e54d34dd..000000000 --- a/src/struphy/pic/tests/test_pic_legacy_files/mappings_3d.py +++ /dev/null @@ -1,823 +0,0 @@ -# coding: utf-8 - - -"""Module containing accelerated (pyccelized) functions for evaluation of metric coefficients corresponding to 3d mappings x_i = F(eta_1, eta_2, eta_3): - -- f : mapping, f_i -- df : Jacobian matrix, df_i/deta_j -- det_df : Jacobian determinant, det(df) -- df_inv : inverse Jacobian matrix, (df_i/deta_j)^(-1) -- g : metric tensor, df^T * df -- g_inv : inverse metric tensor, df^(-1) * df^(-T) - -The following mappings are implemented: - -- kind_map = 0 : 3d spline mapping with control points cx, cy, cz -- kind_map = 1 : 2d spline mapping with control points cx, cy: F_pol = (eta_1, eta_2) --> (R, y), straight in 3rd direction -- kind_map = 2 : 2d spline mapping with control points cx, cy: F_pol = (eta_1, eta_2) --> (R, y), curvature in 3rd direction - -- kind_map = 10 : cuboid, params_map = [l1, r1, l2, r2, l3, r3]. -- kind_map = 11 : orthogonal, params_map = [Lx, Ly, alpha, Lz]. -- kind_map = 12 : colella, params_map = [Lx, Ly, alpha, Lz]. -- kind_map = 20 : hollow cylinder, params_map = [a1, a2, R0]. -- kind_map = 22 : hollow torus, params_map = [a1, a2, R0]. -- kind_map = 30 : shafranov shift, params_map = [x0, y0, z0, rx, ry, Lz, delta]. -- kind_map = 31 : shafranov sqrt, params_map = [x0, y0, z0, rx, ry, Lz, delta]. -- kind_map = 32 : shafranov D-shaped, params_map = [x0, y0, z0, R0, Lz, delta_x, delta_y, delta_gs, epsilon_gs, kappa_gs]. -""" - -from numpy import arcsin, arctan2, cos, empty, pi, shape, sin, sqrt - -import struphy.pic.tests.test_pic_legacy_files.spline_evaluation_2d as eva_2d -import struphy.pic.tests.test_pic_legacy_files.spline_evaluation_3d as eva_3d - - -# ======================================================================= -def f( - eta1: "float", - eta2: "float", - eta3: "float", - component: "int", - kind_map: "int", - params_map: "float[:]", - tn1: "float[:]", - tn2: "float[:]", - tn3: "float[:]", - pn: "int[:]", - nbase_n: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -) -> "float": - """Point-wise evaluation of Cartesian coordinate x_i = f_i(eta1, eta2, eta3), i=1,2,3. - - Parameters: - ----------- - eta1, eta2, eta3: float logical coordinates in [0, 1] - component: int Cartesian coordinate (1: x, 2: y, 3: z) - kind_map: int kind of mapping (see module docstring) - params_map: float[:] parameters for the mapping - tn1, tn2, tn3: float[:] knot vectors for mapping - pn: int[:] spline degrees for mapping - nbase_n: int[:] dimensions of univariate spline spaces for mapping - cx, cy, cz: float[:, :, :] control points of (f_1, f_2, f_3) - - Returns: - -------- - value: float - Cartesian coordinate x_i = f_i(eta1, eta2, eta3) - """ - - value = 0.0 - - # =========== 3d spline ======================== - if kind_map == 0: - if component == 1: - value = eva_3d.evaluate_n_n_n( - tn1, - tn2, - tn3, - pn[0], - pn[1], - pn[2], - nbase_n[0], - nbase_n[1], - nbase_n[2], - cx, - eta1, - eta2, - eta3, - ) - - elif component == 2: - value = eva_3d.evaluate_n_n_n( - tn1, - tn2, - tn3, - pn[0], - pn[1], - pn[2], - nbase_n[0], - nbase_n[1], - nbase_n[2], - cy, - eta1, - eta2, - eta3, - ) - - elif component == 3: - value = eva_3d.evaluate_n_n_n( - tn1, - tn2, - tn3, - pn[0], - pn[1], - pn[2], - nbase_n[0], - nbase_n[1], - nbase_n[2], - cz, - eta1, - eta2, - eta3, - ) - - # ==== 2d spline (straight in 3rd direction) === - elif kind_map == 1: - Lz = params_map[0] - - if component == 1: - value = eva_2d.evaluate_n_n(tn1, tn2, pn[0], pn[1], nbase_n[0], nbase_n[1], cx[:, :, 0], eta1, eta2) - - if eta1 == 0.0 and cx[0, 0, 0] == cx[0, 1, 0]: - value = cx[0, 0, 0] - - elif component == 2: - value = eva_2d.evaluate_n_n(tn1, tn2, pn[0], pn[1], nbase_n[0], nbase_n[1], cy[:, :, 0], eta1, eta2) - - if eta1 == 0.0 and cy[0, 0, 0] == cy[0, 1, 0]: - value = cy[0, 0, 0] - - elif component == 3: - value = Lz * eta3 - - # ==== 2d spline (curvature in 3rd direction) === - elif kind_map == 2: - if component == 1: - value = eva_2d.evaluate_n_n(tn1, tn2, pn[0], pn[1], nbase_n[0], nbase_n[1], cx[:, :, 0], eta1, eta2) * cos( - 2 * pi * eta3, - ) - - if eta1 == 0.0 and cx[0, 0, 0] == cx[0, 1, 0]: - value = cx[0, 0, 0] * cos(2 * pi * eta3) - - elif component == 2: - value = eva_2d.evaluate_n_n(tn1, tn2, pn[0], pn[1], nbase_n[0], nbase_n[1], cy[:, :, 0], eta1, eta2) - - if eta1 == 0.0 and cy[0, 0, 0] == cy[0, 1, 0]: - value = cy[0, 0, 0] - - elif component == 3: - value = eva_2d.evaluate_n_n(tn1, tn2, pn[0], pn[1], nbase_n[0], nbase_n[1], cx[:, :, 0], eta1, eta2) * sin( - 2 * pi * eta3, - ) - - if eta1 == 0.0 and cx[0, 0, 0] == cx[0, 1, 0]: - value = cx[0, 0, 0] * sin(2 * pi * eta3) - - # ============== cuboid ========================= - elif kind_map == 10: - b1 = params_map[0] - e1 = params_map[1] - b2 = params_map[2] - e2 = params_map[3] - b3 = params_map[4] - e3 = params_map[5] - - # value = begin + (end - begin) * eta - if component == 1: - value = b1 + (e1 - b1) * eta1 - elif component == 2: - value = b2 + (e2 - b2) * eta2 - elif component == 3: - value = b3 + (e3 - b3) * eta3 - - # ========= hollow cylinder ===================== - elif kind_map == 20: - a1 = params_map[0] - a2 = params_map[1] - lz = params_map[2] - - da = a2 - a1 - - if component == 1: - value = (a1 + eta1 * da) * cos(2 * pi * eta2) - elif component == 2: - value = (a1 + eta1 * da) * sin(2 * pi * eta2) - elif component == 3: - value = lz * eta3 - - # ============ colella ========================== - elif kind_map == 12: - Lx = params_map[0] - Ly = params_map[1] - alpha = params_map[2] - Lz = params_map[3] - - if component == 1: - value = Lx * (eta1 + alpha * sin(2 * pi * eta1) * sin(2 * pi * eta2)) - elif component == 2: - value = Ly * (eta2 + alpha * sin(2 * pi * eta1) * sin(2 * pi * eta2)) - elif component == 3: - value = Lz * eta3 - - # =========== orthogonal ======================== - elif kind_map == 11: - Lx = params_map[0] - Ly = params_map[1] - alpha = params_map[2] - Lz = params_map[3] - - if component == 1: - value = Lx * (eta1 + alpha * sin(2 * pi * eta1)) - elif component == 2: - value = Ly * (eta2 + alpha * sin(2 * pi * eta2)) - elif component == 3: - value = Lz * eta3 - - # ========= hollow torus ======================== - elif kind_map == 22: - a1 = params_map[0] - a2 = params_map[1] - r0 = params_map[2] - - da = a2 - a1 - - if component == 1: - value = ((a1 + eta1 * da) * cos(2 * pi * eta2) + r0) * cos(2 * pi * eta3) - elif component == 2: - value = (a1 + eta1 * da) * sin(2 * pi * eta2) - elif component == 3: - value = ((a1 + eta1 * da) * cos(2 * pi * eta2) + r0) * sin(2 * pi * eta3) - - # ========= shafranov shift ===================== - elif kind_map == 30: - rx = params_map[0] - ry = params_map[1] - Lz = params_map[2] - de = params_map[3] # Domain: [0,0.1] - - if component == 1: - value = (eta1 * rx) * cos(2 * pi * eta2) + (1 - eta1**2) * rx * de - elif component == 2: - value = (eta1 * ry) * sin(2 * pi * eta2) - elif component == 3: - value = eta3 * Lz - - # ========= shafranov sqrt ===================== - elif kind_map == 31: - rx = params_map[0] - ry = params_map[1] - Lz = params_map[2] - de = params_map[3] # Domain: [0,0.1] - - if component == 1: - value = (eta1 * rx) * cos(2 * pi * eta2) + (1 - sqrt(eta1)) * rx * de - elif component == 2: - value = (eta1 * ry) * sin(2 * pi * eta2) - elif component == 3: - value = eta3 * Lz - - # ========= shafranov D-shaped ===================== - elif kind_map == 32: - r0 = params_map[0] - Lz = params_map[1] - dx = params_map[2] # Grad-Shafranov shift along x-axis. - dy = params_map[3] # Grad-Shafranov shift along y-axis. - dg = params_map[4] # Delta = sin(alpha): Triangularity, shift of high point. - eg = params_map[5] # Epsilon: Inverse aspect ratio a/r0. - kg = params_map[6] # Kappa: Ellipticity (elongation). - - if component == 1: - value = r0 * ( - 1 + (1 - eta1**2) * dx + eg * eta1 * cos(2 * pi * eta2 + arcsin(dg) * eta1 * sin(2 * pi * eta2)) - ) - elif component == 2: - value = r0 * ((1 - eta1**2) * dy + eg * kg * eta1 * sin(2 * pi * eta2)) - elif component == 3: - value = eta3 * Lz - - return value - - -# ======================================================================= -def df( - eta1: "float", - eta2: "float", - eta3: "float", - component: "int", - kind_map: "int", - params_map: "float[:]", - tn1: "float[:]", - tn2: "float[:]", - tn3: "float[:]", - pn: "int[:]", - nbase_n: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -) -> "float": - """Point-wise evaluation of ij-th component of the Jacobian matrix df_ij = df_i/deta_j (i,j=1,2,3). - - Parameters: - ----------- - eta1, eta2, eta3: float logical coordinates in [0, 1] - component: int 11 : (df1/deta1), 12 : (df1/deta2), 13 : (df1/deta3) - 21 : (df2/deta1), 22 : (df2/deta2), 23 : (df2/deta3) - 31 : (df3/deta1), 32 : (df3/deta2), 33 : (df3/deta3) - kind_map: int kind of mapping (see module docstring) - params_map: float[:] parameters for the mapping - tn1, tn2, tn3: float[:] knot vectors for mapping - pn: int[:] spline degrees for mapping - nbase_n: int[:] dimensions of univariate spline spaces for mapping - cx, cy, cz: float[:, :, :] control points of (f_1, f_2, f_3) - - Returns: - -------- - value: float - point value df_ij(eta1, eta2, eta3) - """ - - value = 0.0 - - # =========== 3d spline ======================== - if kind_map == 0: - if component == 11: - value = eva_3d.evaluate_diffn_n_n( - tn1, - tn2, - tn3, - pn[0], - pn[1], - pn[2], - nbase_n[0], - nbase_n[1], - nbase_n[2], - cx, - eta1, - eta2, - eta3, - ) - elif component == 12: - value = eva_3d.evaluate_n_diffn_n( - tn1, - tn2, - tn3, - pn[0], - pn[1], - pn[2], - nbase_n[0], - nbase_n[1], - nbase_n[2], - cx, - eta1, - eta2, - eta3, - ) - elif component == 13: - value = eva_3d.evaluate_n_n_diffn( - tn1, - tn2, - tn3, - pn[0], - pn[1], - pn[2], - nbase_n[0], - nbase_n[1], - nbase_n[2], - cx, - eta1, - eta2, - eta3, - ) - elif component == 21: - value = eva_3d.evaluate_diffn_n_n( - tn1, - tn2, - tn3, - pn[0], - pn[1], - pn[2], - nbase_n[0], - nbase_n[1], - nbase_n[2], - cy, - eta1, - eta2, - eta3, - ) - elif component == 22: - value = eva_3d.evaluate_n_diffn_n( - tn1, - tn2, - tn3, - pn[0], - pn[1], - pn[2], - nbase_n[0], - nbase_n[1], - nbase_n[2], - cy, - eta1, - eta2, - eta3, - ) - elif component == 23: - value = eva_3d.evaluate_n_n_diffn( - tn1, - tn2, - tn3, - pn[0], - pn[1], - pn[2], - nbase_n[0], - nbase_n[1], - nbase_n[2], - cy, - eta1, - eta2, - eta3, - ) - elif component == 31: - value = eva_3d.evaluate_diffn_n_n( - tn1, - tn2, - tn3, - pn[0], - pn[1], - pn[2], - nbase_n[0], - nbase_n[1], - nbase_n[2], - cz, - eta1, - eta2, - eta3, - ) - elif component == 32: - value = eva_3d.evaluate_n_diffn_n( - tn1, - tn2, - tn3, - pn[0], - pn[1], - pn[2], - nbase_n[0], - nbase_n[1], - nbase_n[2], - cz, - eta1, - eta2, - eta3, - ) - elif component == 33: - value = eva_3d.evaluate_n_n_diffn( - tn1, - tn2, - tn3, - pn[0], - pn[1], - pn[2], - nbase_n[0], - nbase_n[1], - nbase_n[2], - cz, - eta1, - eta2, - eta3, - ) - - # ==== 2d spline (straight in 3rd direction) === - elif kind_map == 1: - Lz = 2 * pi * cx[0, 0, 0] - - if component == 11: - value = eva_2d.evaluate_diffn_n(tn1, tn2, pn[0], pn[1], nbase_n[0], nbase_n[1], cx[:, :, 0], eta1, eta2) - elif component == 12: - value = eva_2d.evaluate_n_diffn(tn1, tn2, pn[0], pn[1], nbase_n[0], nbase_n[1], cx[:, :, 0], eta1, eta2) - - if eta1 == 0.0 and cx[0, 0, 0] == cx[0, 1, 0]: - value = 0.0 - - elif component == 13: - value = 0.0 - elif component == 21: - value = eva_2d.evaluate_diffn_n(tn1, tn2, pn[0], pn[1], nbase_n[0], nbase_n[1], cy[:, :, 0], eta1, eta2) - elif component == 22: - value = eva_2d.evaluate_n_diffn(tn1, tn2, pn[0], pn[1], nbase_n[0], nbase_n[1], cy[:, :, 0], eta1, eta2) - - if eta1 == 0.0 and cy[0, 0, 0] == cy[0, 1, 0]: - value = 0.0 - - elif component == 23: - value = 0.0 - elif component == 31: - value = 0.0 - elif component == 32: - value = 0.0 - elif component == 33: - value = Lz - - # ==== 2d spline (curvature in 3rd direction) === - elif kind_map == 2: - if component == 11: - value = eva_2d.evaluate_diffn_n( - tn1, - tn2, - pn[0], - pn[1], - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - eta1, - eta2, - ) * cos(2 * pi * eta3) - elif component == 12: - value = eva_2d.evaluate_n_diffn( - tn1, - tn2, - pn[0], - pn[1], - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - eta1, - eta2, - ) * cos(2 * pi * eta3) - - if eta1 == 0.0 and cx[0, 0, 0] == cx[0, 1, 0]: - value = 0.0 - - elif component == 13: - value = ( - eva_2d.evaluate_n_n(tn1, tn2, pn[0], pn[1], nbase_n[0], nbase_n[1], cx[:, :, 0], eta1, eta2) - * sin(2 * pi * eta3) - * (-2 * pi) - ) - elif component == 21: - value = eva_2d.evaluate_diffn_n(tn1, tn2, pn[0], pn[1], nbase_n[0], nbase_n[1], cy[:, :, 0], eta1, eta2) - elif component == 22: - value = eva_2d.evaluate_n_diffn(tn1, tn2, pn[0], pn[1], nbase_n[0], nbase_n[1], cy[:, :, 0], eta1, eta2) - - if eta1 == 0.0 and cy[0, 0, 0] == cy[0, 1, 0]: - value = 0.0 - - elif component == 23: - value = 0.0 - elif component == 31: - value = eva_2d.evaluate_diffn_n( - tn1, - tn2, - pn[0], - pn[1], - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - eta1, - eta2, - ) * sin(2 * pi * eta3) - elif component == 32: - value = eva_2d.evaluate_n_diffn( - tn1, - tn2, - pn[0], - pn[1], - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - eta1, - eta2, - ) * sin(2 * pi * eta3) - - if eta1 == 0.0 and cx[0, 0, 0] == cx[0, 1, 0]: - value = 0.0 - - elif component == 33: - value = ( - eva_2d.evaluate_n_n(tn1, tn2, pn[0], pn[1], nbase_n[0], nbase_n[1], cx[:, :, 0], eta1, eta2) - * cos(2 * pi * eta3) - * 2 - * pi - ) - - # ============== cuboid =================== - elif kind_map == 10: - b1 = params_map[0] - e1 = params_map[1] - b2 = params_map[2] - e2 = params_map[3] - b3 = params_map[4] - e3 = params_map[5] - - if component == 11: - value = e1 - b1 - elif component == 12: - value = 0.0 - elif component == 13: - value = 0.0 - elif component == 21: - value = 0.0 - elif component == 22: - value = e2 - b2 - elif component == 23: - value = 0.0 - elif component == 31: - value = 0.0 - elif component == 32: - value = 0.0 - elif component == 33: - value = e3 - b3 - - # ======== hollow cylinder ================= - elif kind_map == 20: - a1 = params_map[0] - a2 = params_map[1] - lz = params_map[2] - - da = a2 - a1 - - if component == 11: - value = da * cos(2 * pi * eta2) - elif component == 12: - value = -2 * pi * (a1 + eta1 * da) * sin(2 * pi * eta2) - elif component == 13: - value = 0.0 - elif component == 21: - value = da * sin(2 * pi * eta2) - elif component == 22: - value = 2 * pi * (a1 + eta1 * da) * cos(2 * pi * eta2) - elif component == 23: - value = 0.0 - elif component == 31: - value = 0.0 - elif component == 32: - value = 0.0 - elif component == 33: - value = lz - - # ============ colella ================= - elif kind_map == 12: - Lx = params_map[0] - Ly = params_map[1] - alpha = params_map[2] - Lz = params_map[3] - - if component == 11: - value = Lx * (1 + alpha * cos(2 * pi * eta1) * sin(2 * pi * eta2) * 2 * pi) - elif component == 12: - value = Lx * alpha * sin(2 * pi * eta1) * cos(2 * pi * eta2) * 2 * pi - elif component == 13: - value = 0.0 - elif component == 21: - value = Ly * alpha * cos(2 * pi * eta1) * sin(2 * pi * eta2) * 2 * pi - elif component == 22: - value = Ly * (1 + alpha * sin(2 * pi * eta1) * cos(2 * pi * eta2) * 2 * pi) - elif component == 23: - value = 0.0 - elif component == 31: - value = 0.0 - elif component == 32: - value = 0.0 - elif component == 33: - value = Lz - - # =========== orthogonal ================ - elif kind_map == 11: - Lx = params_map[0] - Ly = params_map[1] - alpha = params_map[2] - Lz = params_map[3] - - if component == 11: - value = Lx * (1 + alpha * cos(2 * pi * eta1) * 2 * pi) - elif component == 12: - value = 0.0 - elif component == 13: - value = 0.0 - elif component == 21: - value = 0.0 - elif component == 22: - value = Ly * (1 + alpha * cos(2 * pi * eta2) * 2 * pi) - elif component == 23: - value = 0.0 - elif component == 31: - value = 0.0 - elif component == 32: - value = 0.0 - elif component == 33: - value = Lz - - # ========= hollow torus ================== - elif kind_map == 22: - a1 = params_map[0] - a2 = params_map[1] - r0 = params_map[2] - - da = a2 - a1 - - if component == 11: - value = da * cos(2 * pi * eta2) * cos(2 * pi * eta3) - elif component == 12: - value = -2 * pi * (a1 + eta1 * da) * sin(2 * pi * eta2) * cos(2 * pi * eta3) - elif component == 13: - value = -2 * pi * ((a1 + eta1 * da) * cos(2 * pi * eta2) + r0) * sin(2 * pi * eta3) - elif component == 21: - value = da * sin(2 * pi * eta2) - elif component == 22: - value = (a1 + eta1 * da) * cos(2 * pi * eta2) * 2 * pi - elif component == 23: - value = 0.0 - elif component == 31: - value = da * cos(2 * pi * eta2) * sin(2 * pi * eta3) - elif component == 32: - value = -2 * pi * (a1 + eta1 * da) * sin(2 * pi * eta2) * sin(2 * pi * eta3) - elif component == 33: - value = ((a1 + eta1 * da) * cos(2 * pi * eta2) + r0) * cos(2 * pi * eta3) * 2 * pi - - # ========= shafranov shift ===================== - elif kind_map == 30: - rx = params_map[0] - ry = params_map[1] - Lz = params_map[2] - de = params_map[3] # Domain: [0,0.1] - - if component == 11: - value = rx * cos(2 * pi * eta2) - 2 * eta1 * rx * de - elif component == 12: - value = -2 * pi * (eta1 * rx) * sin(2 * pi * eta2) - elif component == 13: - value = 0.0 - elif component == 21: - value = ry * sin(2 * pi * eta2) - elif component == 22: - value = 2 * pi * (eta1 * ry) * cos(2 * pi * eta2) - elif component == 23: - value = 0.0 - elif component == 31: - value = 0.0 - elif component == 32: - value = 0.0 - elif component == 33: - value = Lz - - # ========= shafranov sqrt ===================== - elif kind_map == 31: - rx = params_map[0] - ry = params_map[1] - Lz = params_map[2] - de = params_map[3] # Domain: [0,0.1] - - if component == 11: - value = rx * cos(2 * pi * eta2) - 0.5 / sqrt(eta1) * rx * de - elif component == 12: - value = -2 * pi * (eta1 * rx) * sin(2 * pi * eta2) - elif component == 13: - value = 0.0 - elif component == 21: - value = ry * sin(2 * pi * eta2) - elif component == 22: - value = 2 * pi * (eta1 * ry) * cos(2 * pi * eta2) - elif component == 23: - value = 0.0 - elif component == 31: - value = 0.0 - elif component == 32: - value = 0.0 - elif component == 33: - value = Lz - - # ========= shafranov D-shaped ===================== - elif kind_map == 32: - r0 = params_map[0] - Lz = params_map[1] - dx = params_map[2] # Grad-Shafranov shift along x-axis. - dy = params_map[3] # Grad-Shafranov shift along y-axis. - dg = params_map[4] # Delta = sin(alpha): Triangularity, shift of high point. - eg = params_map[5] # Epsilon: Inverse aspect ratio a/R0. - kg = params_map[6] # Kappa: Ellipticity (elongation). - - if component == 11: - value = r0 * ( - -2 * dx * eta1 - - eg - * eta1 - * sin(2 * pi * eta2) - * arcsin(dg) - * sin(eta1 * sin(2 * pi * eta2) * arcsin(dg) + 2 * pi * eta2) - + eg * cos(eta1 * sin(2 * pi * eta2) * arcsin(dg) + 2 * pi * eta2) - ) - elif component == 12: - value = ( - -r0 - * eg - * eta1 - * (2 * pi * eta1 * cos(2 * pi * eta2) * arcsin(dg) + 2 * pi) - * sin(eta1 * sin(2 * pi * eta2) * arcsin(dg) + 2 * pi * eta2) - ) - elif component == 13: - value = 0.0 - elif component == 21: - value = r0 * (-2 * dy * eta1 + eg * kg * sin(2 * pi * eta2)) - elif component == 22: - value = 2 * pi * r0 * eg * eta1 * kg * cos(2 * pi * eta2) - elif component == 23: - value = 0.0 - elif component == 31: - value = 0.0 - elif component == 32: - value = 0.0 - elif component == 33: - value = Lz - - return value diff --git a/src/struphy/pic/tests/test_pic_legacy_files/mappings_3d_fast.py b/src/struphy/pic/tests/test_pic_legacy_files/mappings_3d_fast.py deleted file mode 100644 index f87380685..000000000 --- a/src/struphy/pic/tests/test_pic_legacy_files/mappings_3d_fast.py +++ /dev/null @@ -1,736 +0,0 @@ -# coding: utf-8 - - -""" -Efficient modules for point-wise evaluation of a 3d analytical (kind_map >= 10) or discrete (kind_map < 10) B-spline mapping. -Especially suited for PIC routines since it avoids computing the Jacobian matrix multiple times. -""" - -from numpy import cos, empty, pi, sin - -import struphy.bsplines.bsplines_kernels as bsp -import struphy.pic.tests.test_pic_legacy_files.mappings_3d as mapping -from struphy.pic.tests.test_pic_legacy_files.spline_evaluation_2d import evaluation_kernel_2d -from struphy.pic.tests.test_pic_legacy_files.spline_evaluation_3d import evaluation_kernel_3d - - -# ========================================================================== -def df_all( - kind_map: "int", - params_map: "float[:]", - tn1: "float[:]", - tn2: "float[:]", - tn3: "float[:]", - pn: "int[:]", - nbase_n: "int[:]", - span_n1: "int", - span_n2: "int", - span_n3: "int", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", - l1: "float[:]", - l2: "float[:]", - l3: "float[:]", - r1: "float[:]", - r2: "float[:]", - r3: "float[:]", - b1: "float[:,:]", - b2: "float[:,:]", - b3: "float[:,:]", - d1: "float[:]", - d2: "float[:]", - d3: "float[:]", - der1: "float[:]", - der2: "float[:]", - der3: "float[:]", - eta1: "float", - eta2: "float", - eta3: "float", - mat_out: "float[:,:]", - vec_out: "float[:]", - mat_or_vec: "int", -): - """ - TODO: write documentation, implement faster eval_kernels (with list of global indices, not modulo-operation) - """ - # 3d discrete mapping - if kind_map == 0: - # evaluate non-vanishing basis functions and its derivatives - bsp.basis_funs_and_der(tn1, pn[0], eta1, span_n1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(tn2, pn[1], eta2, span_n2, l2, r2, b2, d2, der2) - bsp.basis_funs_and_der(tn3, pn[2], eta3, span_n3, l3, r3, b3, d3, der3) - - # evaluate Jacobian matrix - if mat_or_vec == 0 or mat_or_vec == 2: - # sum-up non-vanishing contributions (line 1: df_11, df_12 and df_13) - mat_out[0, 0] = evaluation_kernel_3d( - pn[0], - pn[1], - pn[2], - der1, - b2[pn[1]], - b3[pn[2]], - span_n1, - span_n2, - span_n3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - cx, - ) - mat_out[0, 1] = evaluation_kernel_3d( - pn[0], - pn[1], - pn[2], - b1[pn[0]], - der2, - b3[pn[2]], - span_n1, - span_n2, - span_n3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - cx, - ) - mat_out[0, 2] = evaluation_kernel_3d( - pn[0], - pn[1], - pn[2], - b1[pn[0]], - b2[pn[1]], - der3, - span_n1, - span_n2, - span_n3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - cx, - ) - - # sum-up non-vanishing contributions (line 2: df_21, df_22 and df_23) - mat_out[1, 0] = evaluation_kernel_3d( - pn[0], - pn[1], - pn[2], - der1, - b2[pn[1]], - b3[pn[2]], - span_n1, - span_n2, - span_n3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - cy, - ) - mat_out[1, 1] = evaluation_kernel_3d( - pn[0], - pn[1], - pn[2], - b1[pn[0]], - der2, - b3[pn[2]], - span_n1, - span_n2, - span_n3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - cy, - ) - mat_out[1, 2] = evaluation_kernel_3d( - pn[0], - pn[1], - pn[2], - b1[pn[0]], - b2[pn[1]], - der3, - span_n1, - span_n2, - span_n3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - cy, - ) - - # sum-up non-vanishing contributions (line 3: df_31, df_32 and df_33) - mat_out[2, 0] = evaluation_kernel_3d( - pn[0], - pn[1], - pn[2], - der1, - b2[pn[1]], - b3[pn[2]], - span_n1, - span_n2, - span_n3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - cz, - ) - mat_out[2, 1] = evaluation_kernel_3d( - pn[0], - pn[1], - pn[2], - b1[pn[0]], - der2, - b3[pn[2]], - span_n1, - span_n2, - span_n3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - cz, - ) - mat_out[2, 2] = evaluation_kernel_3d( - pn[0], - pn[1], - pn[2], - b1[pn[0]], - b2[pn[1]], - der3, - span_n1, - span_n2, - span_n3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - cz, - ) - - # evaluate mapping - if mat_or_vec == 1 or mat_or_vec == 2: - vec_out[0] = evaluation_kernel_3d( - pn[0], - pn[1], - pn[2], - b1[pn[0]], - b2[pn[1]], - b3[pn[2]], - span_n1, - span_n2, - span_n3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - cx, - ) - vec_out[1] = evaluation_kernel_3d( - pn[0], - pn[1], - pn[2], - b1[pn[0]], - b2[pn[1]], - b3[pn[2]], - span_n1, - span_n2, - span_n3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - cy, - ) - vec_out[2] = evaluation_kernel_3d( - pn[0], - pn[1], - pn[2], - b1[pn[0]], - b2[pn[1]], - b3[pn[2]], - span_n1, - span_n2, - span_n3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - cz, - ) - - # discrete cylinder - elif kind_map == 1: - lz = 2 * pi * cx[0, 0, 0] - - # evaluate non-vanishing basis functions and its derivatives - bsp.basis_funs_and_der(tn1, pn[0], eta1, span_n1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(tn2, pn[1], eta2, span_n2, l2, r2, b2, d2, der2) - - # evaluate Jacobian matrix - if mat_or_vec == 0 or mat_or_vec == 2: - # sum-up non-vanishing contributions (line 1: df_11, df_12 and df_13) - mat_out[0, 0] = evaluation_kernel_2d( - pn[0], - pn[1], - der1, - b2[pn[1]], - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - ) - mat_out[0, 1] = evaluation_kernel_2d( - pn[0], - pn[1], - b1[pn[0]], - der2, - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - ) - mat_out[0, 2] = 0.0 - - # sum-up non-vanishing contributions (line 2: df_21, df_22 and df_23) - mat_out[1, 0] = evaluation_kernel_2d( - pn[0], - pn[1], - der1, - b2[pn[1]], - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cy[:, :, 0], - ) - mat_out[1, 1] = evaluation_kernel_2d( - pn[0], - pn[1], - b1[pn[0]], - der2, - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cy[:, :, 0], - ) - mat_out[1, 2] = 0.0 - - # sum-up non-vanishing contributions (line 3: df_31, df_32 and df_33) - mat_out[2, 0] = 0.0 - mat_out[2, 1] = 0.0 - mat_out[2, 2] = lz - - # evaluate mapping - if mat_or_vec == 1 or mat_or_vec == 2: - vec_out[0] = evaluation_kernel_2d( - pn[0], - pn[1], - b1[pn[0]], - b2[pn[1]], - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - ) - vec_out[1] = evaluation_kernel_2d( - pn[0], - pn[1], - b1[pn[0]], - b2[pn[1]], - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cy[:, :, 0], - ) - vec_out[2] = lz * eta3 - - # discrete torus - elif kind_map == 2: - # evaluate non-vanishing basis functions and its derivatives - bsp.basis_funs_and_der(tn1, pn[0], eta1, span_n1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(tn2, pn[1], eta2, span_n2, l2, r2, b2, d2, der2) - - # evaluate Jacobian matrix - if mat_or_vec == 0 or mat_or_vec == 2: - # sum-up non-vanishing contributions (line 1: df_11, df_12 and df_13) - mat_out[0, 0] = evaluation_kernel_2d( - pn[0], - pn[1], - der1, - b2[pn[1]], - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - ) * cos(2 * pi * eta3) - mat_out[0, 1] = evaluation_kernel_2d( - pn[0], - pn[1], - b1[pn[0]], - der2, - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - ) * cos(2 * pi * eta3) - mat_out[0, 2] = ( - evaluation_kernel_2d( - pn[0], - pn[1], - b1[pn[0]], - b2[pn[1]], - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - ) - * sin(2 * pi * eta3) - * (-2 * pi) - ) - - # sum-up non-vanishing contributions (line 2: df_21, df_22 and df_23) - mat_out[1, 0] = evaluation_kernel_2d( - pn[0], - pn[1], - der1, - b2[pn[1]], - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cy[:, :, 0], - ) - mat_out[1, 1] = evaluation_kernel_2d( - pn[0], - pn[1], - b1[pn[0]], - der2, - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cy[:, :, 0], - ) - mat_out[1, 2] = 0.0 - - # sum-up non-vanishing contributions (line 3: df_31, df_32 and df_33) - mat_out[2, 0] = evaluation_kernel_2d( - pn[0], - pn[1], - der1, - b2[pn[1]], - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - ) * sin(2 * pi * eta3) - mat_out[2, 1] = evaluation_kernel_2d( - pn[0], - pn[1], - b1[pn[0]], - der2, - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - ) * sin(2 * pi * eta3) - mat_out[2, 2] = ( - evaluation_kernel_2d( - pn[0], - pn[1], - b1[pn[0]], - b2[pn[1]], - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - ) - * cos(2 * pi * eta3) - * 2 - * pi - ) - - # evaluate mapping - if mat_or_vec == 1 or mat_or_vec == 2: - vec_out[0] = evaluation_kernel_2d( - pn[0], - pn[1], - b1[pn[0]], - b2[pn[1]], - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - ) * cos(2 * pi * eta3) - vec_out[1] = evaluation_kernel_2d( - pn[0], - pn[1], - b1[pn[0]], - b2[pn[1]], - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cy[:, :, 0], - ) - vec_out[2] = evaluation_kernel_2d( - pn[0], - pn[1], - b1[pn[0]], - b2[pn[1]], - span_n1, - span_n2, - nbase_n[0], - nbase_n[1], - cx[:, :, 0], - ) * sin(2 * pi * eta3) - - # analytical mapping - else: - # evaluate Jacobian matrix - if mat_or_vec == 0 or mat_or_vec == 2: - mat_out[0, 0] = mapping.df( - eta1, - eta2, - eta3, - 11, - kind_map, - params_map, - tn1, - tn2, - tn3, - pn, - nbase_n, - cx, - cy, - cz, - ) - mat_out[0, 1] = mapping.df( - eta1, - eta2, - eta3, - 12, - kind_map, - params_map, - tn1, - tn2, - tn3, - pn, - nbase_n, - cx, - cy, - cz, - ) - mat_out[0, 2] = mapping.df( - eta1, - eta2, - eta3, - 13, - kind_map, - params_map, - tn1, - tn2, - tn3, - pn, - nbase_n, - cx, - cy, - cz, - ) - - mat_out[1, 0] = mapping.df( - eta1, - eta2, - eta3, - 21, - kind_map, - params_map, - tn1, - tn2, - tn3, - pn, - nbase_n, - cx, - cy, - cz, - ) - mat_out[1, 1] = mapping.df( - eta1, - eta2, - eta3, - 22, - kind_map, - params_map, - tn1, - tn2, - tn3, - pn, - nbase_n, - cx, - cy, - cz, - ) - mat_out[1, 2] = mapping.df( - eta1, - eta2, - eta3, - 23, - kind_map, - params_map, - tn1, - tn2, - tn3, - pn, - nbase_n, - cx, - cy, - cz, - ) - - mat_out[2, 0] = mapping.df( - eta1, - eta2, - eta3, - 31, - kind_map, - params_map, - tn1, - tn2, - tn3, - pn, - nbase_n, - cx, - cy, - cz, - ) - mat_out[2, 1] = mapping.df( - eta1, - eta2, - eta3, - 32, - kind_map, - params_map, - tn1, - tn2, - tn3, - pn, - nbase_n, - cx, - cy, - cz, - ) - mat_out[2, 2] = mapping.df( - eta1, - eta2, - eta3, - 33, - kind_map, - params_map, - tn1, - tn2, - tn3, - pn, - nbase_n, - cx, - cy, - cz, - ) - - # evaluate mapping - if mat_or_vec == 1 or mat_or_vec == 2: - vec_out[0] = mapping.f(eta1, eta2, eta3, 1, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - vec_out[1] = mapping.f(eta1, eta2, eta3, 2, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - vec_out[2] = mapping.f(eta1, eta2, eta3, 3, kind_map, params_map, tn1, tn2, tn3, pn, nbase_n, cx, cy, cz) - - -# =========================================================================== -def df_inv_all(mat_in: "float[:,:]", mat_out: "float[:,:]"): - """ - Inverts the Jacobain matrix (mat_in) and writes it to mat_out - - Parameters: - ----------- - mat_in : array - Jacobian matrix - - mat_out : array - emtpy array where the inverse Jacobian matrix will be written - """ - - # inverse Jacobian determinant computed from Jacobian matrix (mat_in) - over_det_df = 1.0 / ( - mat_in[0, 0] * (mat_in[1, 1] * mat_in[2, 2] - mat_in[2, 1] * mat_in[1, 2]) - + mat_in[1, 0] * (mat_in[2, 1] * mat_in[0, 2] - mat_in[0, 1] * mat_in[2, 2]) - + mat_in[2, 0] * (mat_in[0, 1] * mat_in[1, 2] - mat_in[1, 1] * mat_in[0, 2]) - ) - - # inverse Jacobian matrix computed from Jacobian matrix (mat_in) - mat_out[0, 0] = (mat_in[1, 1] * mat_in[2, 2] - mat_in[2, 1] * mat_in[1, 2]) * over_det_df - mat_out[0, 1] = (mat_in[2, 1] * mat_in[0, 2] - mat_in[0, 1] * mat_in[2, 2]) * over_det_df - mat_out[0, 2] = (mat_in[0, 1] * mat_in[1, 2] - mat_in[1, 1] * mat_in[0, 2]) * over_det_df - - mat_out[1, 0] = (mat_in[1, 2] * mat_in[2, 0] - mat_in[2, 2] * mat_in[1, 0]) * over_det_df - mat_out[1, 1] = (mat_in[2, 2] * mat_in[0, 0] - mat_in[0, 2] * mat_in[2, 0]) * over_det_df - mat_out[1, 2] = (mat_in[0, 2] * mat_in[1, 0] - mat_in[1, 2] * mat_in[0, 0]) * over_det_df - - mat_out[2, 0] = (mat_in[1, 0] * mat_in[2, 1] - mat_in[2, 0] * mat_in[1, 1]) * over_det_df - mat_out[2, 1] = (mat_in[2, 0] * mat_in[0, 1] - mat_in[0, 0] * mat_in[2, 1]) * over_det_df - mat_out[2, 2] = (mat_in[0, 0] * mat_in[1, 1] - mat_in[1, 0] * mat_in[0, 1]) * over_det_df - - -# =========================================================================== -def g_all(mat_in: "float[:,:]", mat_out: "float[:,:]"): - """ - Compute the metric tensor (mat_out) from Jacobian matrix (mat_in) - - Parameters: - ----------- - mat_in : array - Jacobian matrix - - mat_out : array - array where metric tensor will be written to - """ - mat_out[0, 0] = mat_in[0, 0] * mat_in[0, 0] + mat_in[1, 0] * mat_in[1, 0] + mat_in[2, 0] * mat_in[2, 0] - mat_out[0, 1] = mat_in[0, 0] * mat_in[0, 1] + mat_in[1, 0] * mat_in[1, 1] + mat_in[2, 0] * mat_in[2, 1] - mat_out[0, 2] = mat_in[0, 0] * mat_in[0, 2] + mat_in[1, 2] * mat_in[1, 2] + mat_in[2, 0] * mat_in[2, 2] - - mat_out[1, 0] = mat_out[0, 1] - mat_out[1, 1] = mat_in[0, 1] * mat_in[0, 1] + mat_in[1, 1] * mat_in[1, 1] + mat_in[2, 1] * mat_in[2, 1] - mat_out[1, 2] = mat_in[0, 1] * mat_in[0, 2] + mat_in[1, 0] * mat_in[1, 2] + mat_in[2, 0] * mat_in[2, 2] - - mat_out[2, 0] = mat_out[0, 2] - mat_out[2, 1] = mat_out[1, 2] - mat_out[2, 2] = mat_in[0, 2] * mat_in[0, 2] + mat_in[1, 2] * mat_in[1, 2] + mat_in[2, 2] * mat_in[2, 2] - - -# =========================================================================== -def g_inv_all(mat_in: "float[:,:]", mat_out: "float[:,:]"): - """ - Compute the inverse metric tensor (mat_out) from inverse Jacobian matrix (mat_in) - - Parameters: - ----------- - mat_in : array - inverse Jacobian matrix - - mat_out : array - array where inverse metric tensor will be written to - """ - mat_out[0, 0] = mat_in[0, 0] * mat_in[0, 0] + mat_in[0, 1] * mat_in[0, 1] + mat_in[0, 2] * mat_in[0, 2] - mat_out[0, 1] = mat_in[0, 0] * mat_in[1, 0] + mat_in[0, 1] * mat_in[1, 1] + mat_in[0, 2] * mat_in[1, 2] - mat_out[0, 2] = mat_in[0, 0] * mat_in[2, 0] + mat_in[0, 1] * mat_in[2, 1] + mat_in[0, 2] * mat_in[2, 2] - - mat_out[1, 0] = mat_out[0, 1] - mat_out[1, 1] = mat_in[1, 0] * mat_in[1, 0] + mat_in[1, 1] * mat_in[1, 1] + mat_in[1, 2] * mat_in[1, 2] - mat_out[1, 2] = mat_in[1, 0] * mat_in[2, 0] + mat_in[1, 1] * mat_in[2, 1] + mat_in[1, 2] * mat_in[2, 2] - - mat_out[2, 0] = mat_out[0, 2] - mat_out[2, 1] = mat_out[1, 2] - mat_out[2, 2] = mat_in[2, 0] * mat_in[2, 0] + mat_in[2, 1] * mat_in[2, 1] + mat_in[2, 2] * mat_in[2, 2] diff --git a/src/struphy/pic/tests/test_pic_legacy_files/pusher.py b/src/struphy/pic/tests/test_pic_legacy_files/pusher.py deleted file mode 100644 index 518e19ee0..000000000 --- a/src/struphy/pic/tests/test_pic_legacy_files/pusher.py +++ /dev/null @@ -1,442 +0,0 @@ -import cunumpy as xp - -import struphy.pic.tests.test_pic_legacy_files.pusher_pos as push_pos -import struphy.pic.tests.test_pic_legacy_files.pusher_vel_2d as push_vel_2d -import struphy.pic.tests.test_pic_legacy_files.pusher_vel_3d as push_vel_3d - - -class Pusher: - """ - TODO - """ - - def __init__(self, domain, fem_space, b0_eq, b2_eq, basis_u, bc_pos): - # mapped domain - self.domain = domain - - # set pseudo-cartesian mapping parameters in case of polar domains - if self.domain.pole: - # IGA straight - if self.domain.kind_map == 1: - self.map_pseudo, self.R0_pseudo = 20, self.domain.cx[0, 0, 0] - - # IGA toroidal - if self.domain.kind_map == 2: - self.map_pseudo, self.R0_pseudo = 22, self.domain.cx[0, 0, 0] - - # analytical hollow cylinder - if self.domain.kind_map == 20: - self.map_pseudo, self.R0_pseudo = 20, self.domain.params_numpy[2] - - # analytical hollow torus - if self.domain.kind_map == 22: - self.map_pseudo, self.R0_pseudo = 22, self.domain.params_numpy[2] - - # FEM space for perturbed fields - self.fem_space = fem_space - - # equilibrium magnetic FE coefficients - assert b0_eq.shape[:2] == (self.fem_space.NbaseN[0], self.fem_space.NbaseN[1]) - - self.b0_eq = b0_eq - - assert b2_eq[0].shape[:2] == (self.fem_space.NbaseN[0], self.fem_space.NbaseD[1]) - assert b2_eq[1].shape[:2] == (self.fem_space.NbaseD[0], self.fem_space.NbaseN[1]) - assert b2_eq[2].shape[:2] == (self.fem_space.NbaseD[0], self.fem_space.NbaseD[1]) - - self.b2_eq = b2_eq - - # basis of perturbed velocity field - assert basis_u == 0 or basis_u == 1 or basis_u == 2 - - self.basis_u = basis_u - - # boundary condition in s-direction (0 : periodic, 1 : absorbing) - self.bc_pos = bc_pos - - # ====================================================== - def push_step3(self, particles, dt, b2, up, mu_0, power): - """ - TODO - """ - - # extract flattened magnetic FE coefficients - b2 = self.fem_space.extract_2(b2) - - # extract flattened velocity FE coefficients - if self.basis_u == 0: - up = self.fem_space.extract_v(up) - elif self.basis_u == 1: - up = self.fem_space.extract_1(up) - elif self.basis_u == 2: - up = self.fem_space.extract_2(up) - - # push particles - if self.fem_space.dim == 2: - push_vel_2d.pusher_step3( - particles, - dt, - self.fem_space.T[0], - self.fem_space.T[1], - self.fem_space.p, - self.fem_space.Nel, - self.fem_space.NbaseN, - self.fem_space.NbaseD, - particles.shape[1], - self.b2_eq[0], - self.b2_eq[1], - self.b2_eq[2], - b2[0], - b2[1], - b2[2], - self.b0_eq, - up[0], - up[1], - up[2], - self.basis_u, - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - mu_0, - power, - self.fem_space.n_tor, - ) - - else: - push_vel_3d.pusher_step3( - particles, - dt, - self.fem_space.T[0], - self.fem_space.T[1], - self.fem_space.T[2], - self.fem_space.p, - self.fem_space.Nel, - self.fem_space.NbaseN, - self.fem_space.NbaseD, - particles.shape[1], - self.b2_eq[0] + b2[0], - self.b2_eq[1] + b2[1], - self.b2_eq[2] + b2[2], - self.b0_eq, - up[0], - up[1], - up[2], - self.basis_u, - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - mu_0, - power, - ) - - # ====================================================== - def push_step4(self, particles, dt): - """ - TODO - """ - - # modified pusher in pseudo cartesian coordinates (for polar domain) - if self.domain.pole: - push_pos.pusher_step4_pcart( - particles, - dt, - particles.shape[1], - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - self.map_pseudo, - self.R0_pseudo, - ) - - # standard pusher in logical coordinates (for domains without a pole) - else: - push_pos.pusher_step4( - particles, - dt, - particles.shape[1], - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - self.bc_pos, - ) - - # ====================================================== - def push_step5(self, particles, dt, b2): - """ - TODO - """ - - # extract flattened magnetic FE coefficients - b2 = self.fem_space.extract_2(b2) - - # push particles - if self.fem_space.dim == 2: - push_vel_2d.pusher_step5( - particles, - dt, - self.fem_space.T[0], - self.fem_space.T[1], - self.fem_space.p, - self.fem_space.Nel, - self.fem_space.NbaseN, - self.fem_space.NbaseD, - particles.shape[1], - self.b2_eq[0], - self.b2_eq[1], - self.b2_eq[2], - b2[0], - b2[1], - b2[2], - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - self.fem_space.n_tor, - ) - - else: - push_vel_3d.pusher_step5( - particles, - dt, - self.fem_space.T[0], - self.fem_space.T[1], - self.fem_space.T[2], - self.fem_space.p, - self.fem_space.Nel, - self.fem_space.NbaseN, - self.fem_space.NbaseD, - particles.shape[1], - self.b2_eq[0] + b2[0], - self.b2_eq[1] + b2[1], - self.b2_eq[2] + b2[2], - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - ) - - # ====================================================== - def push_eta_pc_full(self, particles, dt, up): - """ - TODO - """ - - # extract flattened flow field FE coefficients - if self.basis_u == 1: - up = self.fem_space.extract_1(up) - elif self.basis_u == 2: - up = self.fem_space.extract_2(up) - else: - up = self.fem_space.extract_v(up) - - # push particles - push_pos.pusher_rk4_pc_full( - particles, - dt, - self.fem_space.T[0], - self.fem_space.T[1], - self.fem_space.T[2], - self.fem_space.p, - self.fem_space.Nel, - self.fem_space.NbaseN, - self.fem_space.NbaseD, - particles.shape[1], - up[0], - up[1], - up[2], - self.basis_u, - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - self.bc_pos, - ) - - # ====================================================== - def push_eta_pc_perp(self, particles, dt, up): - """ - TODO - """ - - # extract flattened magnetic FE coefficients - if self.basis_u == 1: - up = self.fem_space.extract_1(up) - elif self.basus_u == 2: - up = self.fem_space.extract_2(up) - else: - up[0] = self.fem_space.extract_0(up[0]) - up[1] = self.fem_space.extract_0(up[1]) - up[2] = self.fem_space.extract_0(up[2]) - - # push particles - push_pos.pusher_rk4_pc_perp( - particles, - dt, - self.fem_space.T[0], - self.fem_space.T[1], - self.fem_space.T[2], - self.fem_space.p, - self.fem_space.Nel, - self.fem_space.NbaseN, - self.fem_space.NbaseD, - particles.shape[1], - up[0], - up[1], - up[2], - self.basis_u, - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - self.bc_pos, - ) - - # ====================================================== - def push_vel_pc_full(self, particles, dt, GXu_1, GXu_2, GXu_3): - """ - TODO - """ - - # extract flattened magnetic FE coefficients - GXu_1_1, GXu_1_2, GXu_1_3 = self.fem_space.extract_1(GXu_1) - GXu_2_1, GXu_2_2, GXu_2_3 = self.fem_space.extract_1(GXu_2) - GXu_3_1, GXu_3_2, GXu_3_3 = self.fem_space.extract_1(GXu_3) - - # push particles - push_vel_3d.pusher_v_pressure_full( - particles, - dt, - self.fem_space.T[0], - self.fem_space.T[1], - self.fem_space.T[2], - self.fem_space.p, - self.fem_space.Nel, - self.fem_space.NbaseN, - self.fem_space.NbaseD, - particles.shape[1], - GXu_1_1, - GXu_1_2, - GXu_1_3, - GXu_2_1, - GXu_2_2, - GXu_2_3, - GXu_3_1, - GXu_3_2, - GXu_3_3, - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - ) - - # ====================================================== - def push_vel_pc_perp(self, particles, dt, GXu_1, GXu_2, GXu_3): - """ - TODO - """ - - # extract flattened magnetic FE coefficients - GXu_1_1, GXu_1_2, GXu_1_3 = self.fem_space.extract_1(GXu_1) - GXu_2_1, GXu_2_2, GXu_2_3 = self.fem_space.extract_1(GXu_2) - GXu_3_1, GXu_3_2, GXu_3_3 = self.fem_space.extract_1(GXu_3) - - # push particles - push_vel_3d.pusher_v_pressure_perp( - particles, - dt, - self.fem_space.T[0], - self.fem_space.T[1], - self.fem_space.T[2], - self.fem_space.p, - self.fem_space.Nel, - self.fem_space.NbaseN, - self.fem_space.NbaseD, - particles.shape[1], - GXu_1_1, - GXu_1_2, - GXu_1_3, - GXu_2_1, - GXu_2_2, - GXu_2_3, - GXu_3_1, - GXu_3_2, - GXu_3_3, - self.domain.kind_map, - self.domain.params_numpy, - self.domain.T[0], - self.domain.T[1], - self.domain.T[2], - self.domain.p, - self.domain.Nel, - self.domain.NbaseN, - self.domain.cx, - self.domain.cy, - self.domain.cz, - ) diff --git a/src/struphy/pic/tests/test_pic_legacy_files/pusher_pos.py b/src/struphy/pic/tests/test_pic_legacy_files/pusher_pos.py deleted file mode 100644 index ee4c30c40..000000000 --- a/src/struphy/pic/tests/test_pic_legacy_files/pusher_pos.py +++ /dev/null @@ -1,3463 +0,0 @@ -# import pyccel decorators - - -# import modules for B-spline evaluation -import struphy.bsplines.bsplines_kernels as bsp - -# import module for matrix-matrix and matrix-vector multiplications -import struphy.linear_algebra.linalg_kernels as linalg - -# import modules for mapping evaluation -import struphy.pic.tests.test_pic_legacy_files.mappings_3d as mapping -import struphy.pic.tests.test_pic_legacy_files.mappings_3d_fast as mapping_fast -import struphy.pic.tests.test_pic_legacy_files.spline_evaluation_3d as eva3 - - -# ========================================================================================================== -def pusher_step4( - particles: "float[:,:]", - dt: "float", - np: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", - bc: "int", -): - from numpy import arctan2, cos, empty, pi, sin, sqrt - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = empty((3, 3), dtype=float) - dfinv = empty((3, 3), dtype=float) - fx = empty(3, dtype=float) - # ======================================================== - - # ======= particle position and velocity ================= - e = empty(3, dtype=float) - v = empty(3, dtype=float) - - e_new = empty(3, dtype=float) - # ======================================================== - - # ===== intermediate stps in 4th order Runge-Kutta ======= - k1 = empty(3, dtype=float) - k2 = empty(3, dtype=float) - k3 = empty(3, dtype=float) - k4 = empty(3, dtype=float) - # ======================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ip, e, v, e_new, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, dfinv, k1, k2, k3, k4) - for ip in range(np): - # only do something if particle is inside the logical domain (0 < s < 1) - if particles[0, ip] < 0.0 or particles[0, ip] > 1.0: - continue - - # current position and velocity - e[:] = particles[0:3, ip] - v[:] = particles[3:6, ip] - - # ----------- step 1 in Runge-Kutta method ----------------------- - e_new[0] = e[0] - e_new[1] = e[1] - e_new[2] = e[2] - - span1f = int(e_new[0] * nelf[0]) + pf1 - span2f = int(e_new[1] * nelf[1]) + pf2 - span3f = int(e_new[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - e_new[0], - e_new[1], - e_new[2], - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # pull-back of velocity - linalg.matrix_vector(dfinv, v, k1) - # ------------------------------------------------------------------ - - # ----------------- step 2 in Runge-Kutta method ------------------- - e_new[0] = e[0] + dt * k1[0] / 2 - - # check boundary condition in eta_1 direction - - # periodic - if bc == 0: - e_new[0] = e_new[0] % 1.0 - - # lost - elif bc == 1: - if e_new[0] > 1.0: - particles[6, ip] = 0.0 - particles[0, ip] = 1.5 - continue - - elif e_new[0] < 0.0: - particles[6, ip] = 0.0 - particles[0, ip] = -0.5 - continue - - e_new[1] = (e[1] + dt * k1[1] / 2) % 1.0 - e_new[2] = (e[2] + dt * k1[2] / 2) % 1.0 - - span1f = int(e_new[0] * nelf[0]) + pf1 - span2f = int(e_new[1] * nelf[1]) + pf2 - span3f = int(e_new[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - e_new[0], - e_new[1], - e_new[2], - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # pull-back of velocity - linalg.matrix_vector(dfinv, v, k2) - # ------------------------------------------------------------------ - - # ------------------ step 3 in Runge-Kutta method ------------------ - e_new[0] = e[0] + dt * k2[0] / 2 - - # check boundary condition in eta_1 direction - - # periodic - if bc == 0: - e_new[0] = e_new[0] % 1.0 - - # lost - elif bc == 1: - if e_new[0] > 1.0: - particles[6, ip] = 0.0 - particles[0, ip] = 1.5 - continue - - elif e_new[0] < 0.0: - particles[6, ip] = 0.0 - particles[0, ip] = -0.5 - continue - - e_new[1] = (e[1] + dt * k2[1] / 2) % 1.0 - e_new[2] = (e[2] + dt * k2[2] / 2) % 1.0 - - span1f = int(e_new[0] * nelf[0]) + pf1 - span2f = int(e_new[1] * nelf[1]) + pf2 - span3f = int(e_new[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - e_new[0], - e_new[1], - e_new[2], - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # pull-back of velocity - linalg.matrix_vector(dfinv, v, k3) - # ------------------------------------------------------------------ - - # ------------------ step 4 in Runge-Kutta method ------------------ - e_new[0] = e[0] + dt * k3[0] - - # check boundary condition in eta_1 direction - - # periodic - if bc == 0: - e_new[0] = e_new[0] % 1.0 - - # lost - elif bc == 1: - if e_new[0] > 1.0: - particles[6, ip] = 0.0 - particles[0, ip] = 1.5 - continue - - elif e_new[0] < 0.0: - particles[6, ip] = 0.0 - particles[0, ip] = -0.5 - continue - - e_new[1] = (e[1] + dt * k3[1]) % 1.0 - e_new[2] = (e[2] + dt * k3[2]) % 1.0 - - span1f = int(e_new[0] * nelf[0]) + pf1 - span2f = int(e_new[1] * nelf[1]) + pf2 - span3f = int(e_new[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - e_new[0], - e_new[1], - e_new[2], - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # pull-back of velocity - linalg.matrix_vector(dfinv, v, k4) - # ------------------------------------------------------------------ - - # ---------------- update logical coordinates --------------------- - e_new[0] = e[0] + dt * (k1[0] + 2 * k2[0] + 2 * k3[0] + k4[0]) / 6 - - # check boundary condition in eta_1 direction - - # periodic - if bc == 0: - e_new[0] = e_new[0] % 1.0 - - # lost - elif bc == 1: - if e_new[0] > 1.0: - particles[6, ip] = 0.0 - particles[0, ip] = 1.5 - continue - - elif e_new[0] < 0.0: - particles[6, ip] = 0.0 - particles[0, ip] = -0.5 - continue - - e_new[1] = (e[1] + dt * (k1[1] + 2 * k2[1] + 2 * k3[1] + k4[1]) / 6) % 1 - e_new[2] = (e[2] + dt * (k1[2] + 2 * k2[2] + 2 * k3[2] + k4[2]) / 6) % 1 - - particles[0, ip] = e_new[0] - particles[1, ip] = e_new[1] - particles[2, ip] = e_new[2] - # ------------------------------------------------------------------ - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ======================================================================================================== -def reflect( - df, -): - from numpy import empty, sqrt - - vg = empty(3, dtype=float) - - basis = empty((3, 3), dtype=float) - basis_inv = empty((3, 3), dtype=float) - - # calculate normalized basis vectors - norm1 = sqrt(df_inv[0, 0] ** 2 + df_inv[0, 1] ** 2 + df_inv[0, 2] ** 2) - - norm2 = sqrt(df[0, 1] ** 2 + df[1, 1] ** 2 + df[2, 1] ** 2) - norm3 = sqrt(df[0, 2] ** 2 + df[1, 2] ** 2 + df[2, 2] ** 2) - - basis[:, 0] = df_inv[0, :] / norm1 - - basis[:, 1] = df[:, 1] / norm2 - basis[:, 2] = df[:, 2] / norm3 - - linalg.matrix_inv(basis, basis_inv) - - linalg.matrix_vector(basis_inv, v, vg) - - vg[0] = -vg[0] - - linalg.matrix_vector(basis, vg, v) - - -# ========================================================================================================== -def pusher_step4_pcart( - particles: "float[:,:]", - dt: "float", - np: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", - map_pseudo: "int", - r0_pseudo: "float", -): - from numpy import empty, zeros - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = empty((3, 3), dtype=float) - dfinv = empty((3, 3), dtype=float) - - df_old = empty((3, 3), dtype=float) - dfinv_old = empty((3, 3), dtype=float) - - fx = empty(3, dtype=float) - - # needed mapping quantities for pseudo-cartesian coordinates - df_pseudo = empty((3, 3), dtype=float) - - df_pseudo_old = empty((3, 3), dtype=float) - fx_pseudo = empty(3, dtype=float) - - params_pseudo = empty(3, dtype=float) - - params_pseudo[0] = 0.0 - params_pseudo[1] = 1.0 - params_pseudo[2] = r0_pseudo - # ======================================================== - - # ======= particle position and velocity ================= - eta = empty(3, dtype=float) - v = empty(3, dtype=float) - v_temp = empty(3, dtype=float) - # ======================================================== - - # ===== intermediate stps in 4th order Runge-Kutta ======= - k1 = empty(3, dtype=float) - k2 = empty(3, dtype=float) - k3 = empty(3, dtype=float) - k4 = empty(3, dtype=float) - # ======================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ip, eta, v, fx_pseudo, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df_old, fx, dfinv_old, df_pseudo_old, df, dfinv, df_pseudo, v_temp, k1, k2, k3, k4) - for ip in range(np): - # only do something if particle is inside the logical domain (s < 1) - if particles[0, ip] > 1.0: - continue - - # old logical coordinates and velocities - eta[:] = particles[0:3, ip] - v[:] = particles[3:6, ip] - - # compute old pseudo-cartesian coordinates - fx_pseudo[0] = mapping.f( - eta[0], - eta[1], - eta[2], - 1, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - fx_pseudo[1] = mapping.f( - eta[0], - eta[1], - eta[2], - 2, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - fx_pseudo[2] = mapping.f( - eta[0], - eta[1], - eta[2], - 3, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - # evaluate old Jacobian matrix of mapping F - span1f = int(eta[0] * nelf[0]) + pf1 - span2f = int(eta[1] * nelf[1]) + pf2 - span3f = int(eta[2] * nelf[2]) + pf3 - - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta[0], - eta[1], - eta[2], - df_old, - fx, - 0, - ) - - # evaluate old inverse Jacobian matrix of mapping F - mapping_fast.df_inv_all(df_old, dfinv_old) - - # evaluate old Jacobian matrix of mapping F_pseudo - df_pseudo_old[0, 0] = mapping.df( - eta[0], - eta[1], - eta[2], - 11, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo_old[0, 1] = mapping.df( - eta[0], - eta[1], - eta[2], - 12, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo_old[0, 2] = mapping.df( - eta[0], - eta[1], - eta[2], - 13, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - df_pseudo_old[1, 0] = mapping.df( - eta[0], - eta[1], - eta[2], - 21, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo_old[1, 1] = mapping.df( - eta[0], - eta[1], - eta[2], - 22, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo_old[1, 2] = mapping.df( - eta[0], - eta[1], - eta[2], - 23, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - df_pseudo_old[2, 0] = mapping.df( - eta[0], - eta[1], - eta[2], - 31, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo_old[2, 1] = mapping.df( - eta[0], - eta[1], - eta[2], - 32, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo_old[2, 2] = mapping.df( - eta[0], - eta[1], - eta[2], - 33, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - while True: - # ----------- step 1 in Runge-Kutta method ----------------------- - # compute df_pseudo*df_inv*v - linalg.matrix_vector(dfinv_old, v, v_temp) - linalg.matrix_vector(df_pseudo_old, v_temp, k1) - # ------------------------------------------------------------------ - - # ----------------- step 2 in Runge-Kutta method ------------------- - # eta[0] = mapping.f_inv(fx_pseudo[0] + dt*k1[0]/2, fx_pseudo[1] + dt*k1[1]/2, fx_pseudo[2] + dt*k1[2]/2, 1, map_pseudo, params_pseudo) - # eta[1] = mapping.f_inv(fx_pseudo[0] + dt*k1[0]/2, fx_pseudo[1] + dt*k1[1]/2, fx_pseudo[2] + dt*k1[2]/2, 2, map_pseudo, params_pseudo) - # eta[2] = mapping.f_inv(fx_pseudo[0] + dt*k1[0]/2, fx_pseudo[1] + dt*k1[1]/2, fx_pseudo[2] + dt*k1[2]/2, 3, map_pseudo, params_pseudo) - - eta[0] = 0.5 - eta[1] = 0.5 - eta[2] = 0.5 - - # check if particle has left the domain at s = 1: if yes, stop iteration and set weight to zero - if eta[0] > 1.0: - particles[6, ip] = 0.0 - particles[0, ip] = 1.5 - - break - - # evaluate Jacobian matrix of mapping F - span1f = int(eta[0] * nelf[0]) + pf1 - span2f = int(eta[1] * nelf[1]) + pf2 - span3f = int(eta[2] * nelf[2]) + pf3 - - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta[0], - eta[1], - eta[2], - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix of mapping F - mapping_fast.df_inv_all(df, dfinv) - - # evaluate Jacobian matrix of mapping F_pseudo - df_pseudo[0, 0] = mapping.df( - eta[0], - eta[1], - eta[2], - 11, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[0, 1] = mapping.df( - eta[0], - eta[1], - eta[2], - 12, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[0, 2] = mapping.df( - eta[0], - eta[1], - eta[2], - 13, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - df_pseudo[1, 0] = mapping.df( - eta[0], - eta[1], - eta[2], - 21, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[1, 1] = mapping.df( - eta[0], - eta[1], - eta[2], - 22, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[1, 2] = mapping.df( - eta[0], - eta[1], - eta[2], - 23, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - df_pseudo[2, 0] = mapping.df( - eta[0], - eta[1], - eta[2], - 31, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[2, 1] = mapping.df( - eta[0], - eta[1], - eta[2], - 32, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[2, 2] = mapping.df( - eta[0], - eta[1], - eta[2], - 33, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - # compute df_pseudo*df_inv*v - linalg.matrix_vector(dfinv, v, v_temp) - linalg.matrix_vector(df_pseudo, v_temp, k2) - # ------------------------------------------------------------------ - - # ------------------ step 3 in Runge-Kutta method ------------------ - # eta[0] = mapping.f_inv(fx_pseudo[0] + dt*k2[0]/2, fx_pseudo[1] + dt*k2[1]/2, fx_pseudo[2] + dt*k2[2]/2, 1, map_pseudo, params_pseudo) - # eta[1] = mapping.f_inv(fx_pseudo[0] + dt*k2[0]/2, fx_pseudo[1] + dt*k2[1]/2, fx_pseudo[2] + dt*k2[2]/2, 2, map_pseudo, params_pseudo) - # eta[2] = mapping.f_inv(fx_pseudo[0] + dt*k2[0]/2, fx_pseudo[1] + dt*k2[1]/2, fx_pseudo[2] + dt*k2[2]/2, 3, map_pseudo, params_pseudo) - - eta[0] = 0.5 - eta[1] = 0.5 - eta[2] = 0.5 - - # check if particle has left the domain at s = 1: if yes, stop iteration and set weight to zero - if eta[0] > 1.0: - particles[6, ip] = 0.0 - particles[0, ip] = 1.5 - - break - - # evaluate Jacobian matrix of mapping F - span1f = int(eta[0] * nelf[0]) + pf1 - span2f = int(eta[1] * nelf[1]) + pf2 - span3f = int(eta[2] * nelf[2]) + pf3 - - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta[0], - eta[1], - eta[2], - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix of mapping F - mapping_fast.df_inv_all(df, dfinv) - - # evaluate Jacobian matrix of mapping F_pseudo - df_pseudo[0, 0] = mapping.df( - eta[0], - eta[1], - eta[2], - 11, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[0, 1] = mapping.df( - eta[0], - eta[1], - eta[2], - 12, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[0, 2] = mapping.df( - eta[0], - eta[1], - eta[2], - 13, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - df_pseudo[1, 0] = mapping.df( - eta[0], - eta[1], - eta[2], - 21, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[1, 1] = mapping.df( - eta[0], - eta[1], - eta[2], - 22, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[1, 2] = mapping.df( - eta[0], - eta[1], - eta[2], - 23, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - df_pseudo[2, 0] = mapping.df( - eta[0], - eta[1], - eta[2], - 31, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[2, 1] = mapping.df( - eta[0], - eta[1], - eta[2], - 32, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[2, 2] = mapping.df( - eta[0], - eta[1], - eta[2], - 33, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - # compute df_pseudo*df_inv*v - linalg.matrix_vector(dfinv, v, v_temp) - linalg.matrix_vector(df_pseudo, v_temp, k3) - # ------------------------------------------------------------------ - - # ------------------ step 4 in Runge-Kutta method ------------------ - # eta[0] = mapping.f_inv(fx_pseudo[0] + dt*k3[0], fx_pseudo[1] + dt*k3[1], fx_pseudo[2] + dt*k3[2], 1, map_pseudo, params_pseudo) - # eta[1] = mapping.f_inv(fx_pseudo[0] + dt*k3[0], fx_pseudo[1] + dt*k3[1], fx_pseudo[2] + dt*k3[2], 2, map_pseudo, params_pseudo) - # eta[2] = mapping.f_inv(fx_pseudo[0] + dt*k3[0], fx_pseudo[1] + dt*k3[1], fx_pseudo[2] + dt*k3[2], 3, map_pseudo, params_pseudo) - - eta[0] = 0.5 - eta[1] = 0.5 - eta[2] = 0.5 - - # check if particle has left the domain at s = 1: if yes, stop iteration and set weight to zero - if eta[0] > 1.0: - particles[6, ip] = 0.0 - particles[0, ip] = 1.5 - - break - - # evaluate Jacobian matrix of mapping F - span1f = int(eta[0] * nelf[0]) + pf1 - span2f = int(eta[1] * nelf[1]) + pf2 - span3f = int(eta[2] * nelf[2]) + pf3 - - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta[0], - eta[1], - eta[2], - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix of mapping F - mapping_fast.df_inv_all(df, dfinv) - - # evaluate Jacobian matrix of mapping F_pseudo - df_pseudo[0, 0] = mapping.df( - eta[0], - eta[1], - eta[2], - 11, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[0, 1] = mapping.df( - eta[0], - eta[1], - eta[2], - 12, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[0, 2] = mapping.df( - eta[0], - eta[1], - eta[2], - 13, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - df_pseudo[1, 0] = mapping.df( - eta[0], - eta[1], - eta[2], - 21, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[1, 1] = mapping.df( - eta[0], - eta[1], - eta[2], - 22, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[1, 2] = mapping.df( - eta[0], - eta[1], - eta[2], - 23, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - df_pseudo[2, 0] = mapping.df( - eta[0], - eta[1], - eta[2], - 31, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[2, 1] = mapping.df( - eta[0], - eta[1], - eta[2], - 32, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - df_pseudo[2, 2] = mapping.df( - eta[0], - eta[1], - eta[2], - 33, - map_pseudo, - params_pseudo, - tf1, - tf2, - tf3, - pf, - nbasef, - cx, - cy, - cz, - ) - - # compute df_pseudo*df_inv*v - linalg.matrix_vector(dfinv, v, v_temp) - linalg.matrix_vector(df_pseudo, v_temp, k4) - # ------------------------------------------------------------------ - - # ---------------- update pseudo-cartesian coordinates ------------ - fx_pseudo[0] = fx_pseudo[0] + dt * (k1[0] + 2 * k2[0] + 2 * k3[0] + k4[0]) / 6.0 - fx_pseudo[1] = fx_pseudo[1] + dt * (k1[1] + 2 * k2[1] + 2 * k3[1] + k4[1]) / 6.0 - fx_pseudo[2] = fx_pseudo[2] + dt * (k1[2] + 2 * k2[2] + 2 * k3[2] + k4[2]) / 6.0 - # ------------------------------------------------------------------ - - # compute logical coordinates - # eta[0] = mapping.f_inv(fx_pseudo[0], fx_pseudo[1], fx_pseudo[2], 1, map_pseudo, params_pseudo) - # eta[1] = mapping.f_inv(fx_pseudo[0], fx_pseudo[1], fx_pseudo[2], 2, map_pseudo, params_pseudo) - # eta[2] = mapping.f_inv(fx_pseudo[0], fx_pseudo[1], fx_pseudo[2], 3, map_pseudo, params_pseudo) - - eta[0] = 0.5 - eta[1] = 0.5 - eta[2] = 0.5 - - # check if particle has left the domain at s = 1: if yes, stop iteration and set weight to zero - if eta[0] > 1.0: - particles[6, ip] = 0.0 - particles[0, ip] = 1.5 - - break - - particles[0, ip] = eta[0] - particles[1, ip] = eta[1] - particles[2, ip] = eta[2] - - # set particle velocity (will only change if particle was reflected) - particles[3, ip] = v[0] - particles[4, ip] = v[1] - particles[5, ip] = v[2] - - break - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================================== -def pusher_step4_cart( - particles: "float[:,:]", - dt: "float", - np: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", - tol: "float", -): - from numpy import empty - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = empty((3, 3), dtype=float) - dfinv = empty((3, 3), dtype=float) - - x_old = empty(3, dtype=float) - x_new = empty(3, dtype=float) - - temp = empty(3, dtype=float) - # ======================================================== - - # ======= particle position and velocity ================= - e = empty(3, dtype=float) - v = empty(3, dtype=float) - # ======================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ip, e, v, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, x_old, x_new, dfinv, temp) - for ip in range(np): - e[:] = particles[0:3, ip] - v[:] = particles[3:6, ip] - - span1f = int(e[0] * nelf[0]) + pf1 - span2f = int(e[1] * nelf[1]) + pf2 - span3f = int(e[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix and current Cartesian coordinates - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - e[0], - e[1], - e[2], - df, - x_old, - 2, - ) - - # update cartesian coordinates exactly - x_new[0] = x_old[0] + dt * v[0] - x_new[1] = x_old[1] + dt * v[1] - x_new[2] = x_old[2] + dt * v[2] - - # calculate new logical coordinates by solving inverse mapping with Newton-method - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - while True: - x_old[:] = x_old - x_new - linalg.matrix_vector(dfinv, x_old, temp) - - e[0] = e[0] - temp[0] - e[1] = (e[1] - temp[1]) % 1.0 - e[2] = (e[2] - temp[2]) % 1.0 - - span1f = int(e[0] * nelf[0]) + pf1 - span2f = int(e[1] * nelf[1]) + pf2 - span3f = int(e[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix and mapping - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - e[0], - e[1], - e[2], - df, - x_old, - 2, - ) - - if abs(x_old[0] - x_new[0]) < tol and abs(x_old[1] - x_new[1]) < tol and abs(x_old[2] - x_new[2]) < tol: - particles[0:3, ip] = e - break - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================================== -def pusher_rk4_pc_full( - particles, - dt, - t1, - t2, - t3, - p, - nel, - nbase_n, - nbase_d, - np, - u1, - u2, - u3, - basis_u, - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nelf, - nbasef, - cx, - cy, - cz, - bc, -): - from numpy import empty - - # ============== for velocity evaluation ============ - # spline degrees - pn1 = p[0] - pn2 = p[1] - pn3 = p[2] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - pd3 = pn3 - 1 - - # p + 1 non-vanishing basis functions up tp degree p - b1 = empty((pn1 + 1, pn1 + 1), dtype=float) - b2 = empty((pn2 + 1, pn2 + 1), dtype=float) - b3 = empty((pn3 + 1, pn3 + 1), dtype=float) - - # left and right values for spline evaluation - l1 = empty(pn1, dtype=float) - l2 = empty(pn2, dtype=float) - l3 = empty(pn3, dtype=float) - - r1 = empty(pn1, dtype=float) - r2 = empty(pn2, dtype=float) - r3 = empty(pn3, dtype=float) - - # scaling arrays for M-splines - d1 = empty(pn1, dtype=float) - d2 = empty(pn2, dtype=float) - d3 = empty(pn3, dtype=float) - - # p + 1 non-vanishing derivatives - der1 = empty(pn1 + 1, dtype=float) - der2 = empty(pn2 + 1, dtype=float) - der3 = empty(pn3 + 1, dtype=float) - - # non-vanishing N-splines at particle position - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - # non-vanishing D-splines at particle position - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - # # velocity field at particle position - u = empty(3, dtype=float) - # ========================================================== - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = empty((3, 3), dtype=float) - dfinv = empty((3, 3), dtype=float) - dfinv_t = empty((3, 3), dtype=float) - Ginv = empty((3, 3), dtype=float) - fx = empty(3, dtype=float) - # ======================================================== - - # ======= particle position and velocity ================= - e = empty(3, dtype=float) - v = empty(3, dtype=float) - - e_new = empty(3, dtype=float) - # ======================================================== - - # ===== intermediate stps in 4th order Runge-Kutta ======= - k1 = empty(3, dtype=float) - k2 = empty(3, dtype=float) - k3 = empty(3, dtype=float) - k4 = empty(3, dtype=float) - k1_u = empty(3, dtype=float) - k2_u = empty(3, dtype=float) - k3_u = empty(3, dtype=float) - k4_u = empty(3, dtype=float) - k1_v = empty(3, dtype=float) - k2_v = empty(3, dtype=float) - k3_v = empty(3, dtype=float) - k4_v = empty(3, dtype=float) - # ======================================================== - - for ip in range(np): - # only do something if particle is inside the logical domain (0 < s < 1) - if particles[0, ip] < 0.0 or particles[0, ip] > 1.0: - particles[0:3, ip] = -1.0 - continue - - # current position and velocity - e[:] = particles[0:3, ip] - v[:] = particles[3:6, ip] - - # ----------- step 1 in Runge-Kutta method ----------------------- - e_new[0] = e[0] - e_new[1] = e[1] - e_new[2] = e[2] - # ========= mapping evaluation ============= - span1f = int(e_new[0] * nelf[0]) + pf1 - span2f = int(e_new[1] * nelf[1]) + pf2 - span3f = int(e_new[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - e_new[0], - e_new[1], - e_new[2], - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - # evaluate transposed inverse Jacobian matrix - linalg.transpose(dfinv, dfinv_t) - - # evaluate Ginv matrix - linalg.matrix_matrix(dfinv, dfinv_t, Ginv) - # ============================================ - - # pull-back of velocity - linalg.matrix_vector(dfinv, v, k1_v) - - # ========== field evaluation ============== - span1 = int(e_new[0] * nel[0]) + pn1 - span2 = int(e_new[1] * nel[1]) + pn2 - span3 = int(e_new[2] * nel[2]) + pn3 - - # evaluation of basis functions and derivatives - bsp.basis_funs_and_der(t1, pn1, e_new[0], span1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(t2, pn2, e_new[1], span2, l2, r2, b2, d2, der2) - bsp.basis_funs_and_der(t3, pn3, e_new[2], span3, l3, r3, b3, d3, der3) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - bn3[:] = b3[pn3, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - bd3[:] = b3[pd3, :pn3] * d3[:] - - # velocity field - if basis_u == 1: - u[0] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - nbase_d[0], - nbase_n[1], - nbase_n[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - nbase_n[0], - nbase_d[1], - nbase_n[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - nbase_n[0], - nbase_n[1], - nbase_d[2], - u3, - ) - - linalg.matrix_vector(Ginv, u, k1_u) - - elif basis_u == 2: - u[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - u3, - ) - - k1_u[:] = u / det_df - - k1[:] = k1_v + k1_u - # ------------------------------------------------------------------ - - # ----------------- step 2 in Runge-Kutta method ------------------- - e_new[0] = e[0] + dt * k1[0] / 2 - e_new[1] = e[1] + dt * k1[1] / 2 - e_new[2] = e[2] + dt * k1[2] / 2 - - if e_new[0] < 0.0 or e_new[0] > 1.0 or e_new[1] < 0.0 or e_new[1] > 1.0 or e_new[2] < 0.0 or e_new[2] > 1.0: - particles[0:3, ip] = -1.0 - continue - - # ========= mapping evaluation ============= - span1f = int(e_new[0] * nelf[0]) + pf1 - span2f = int(e_new[1] * nelf[1]) + pf2 - span3f = int(e_new[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - e_new[0], - e_new[1], - e_new[2], - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - # evaluate transposed inverse Jacobian matrix - linalg.transpose(dfinv, dfinv_t) - - # evaluate Ginv matrix - linalg.matrix_matrix(dfinv, dfinv_t, Ginv) - # ============================================ - - # pull-back of velocity - linalg.matrix_vector(dfinv, v, k2_v) - - # ========== field evaluation ============== - span1 = int(e_new[0] * nel[0]) + pn1 - span2 = int(e_new[1] * nel[1]) + pn2 - span3 = int(e_new[2] * nel[2]) + pn3 - - # evaluation of basis functions and derivatives - bsp.basis_funs_and_der(t1, pn1, e_new[0], span1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(t2, pn2, e_new[1], span2, l2, r2, b2, d2, der2) - bsp.basis_funs_and_der(t3, pn3, e_new[2], span3, l3, r3, b3, d3, der3) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - bn3[:] = b3[pn3, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - bd3[:] = b3[pd3, :pn3] * d3[:] - - # velocity field - if basis_u == 1: - u[0] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - nbase_d[0], - nbase_n[1], - nbase_n[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - nbase_n[0], - nbase_d[1], - nbase_n[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - nbase_n[0], - nbase_n[1], - nbase_d[2], - u3, - ) - - linalg.matrix_vector(Ginv, u, k2_u) - - elif basis_u == 2: - u[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - u3, - ) - - k2_u[:] = u / det_df - - k2[:] = k2_v + k2_u - # ------------------------------------------------------------------ - - # ------------------ step 3 in Runge-Kutta method ------------------ - e_new[0] = e[0] + dt * k2[0] / 2 - e_new[1] = e[1] + dt * k2[1] / 2 - e_new[2] = e[2] + dt * k2[2] / 2 - - if e_new[0] < 0.0 or e_new[0] > 1.0 or e_new[1] < 0.0 or e_new[1] > 1.0 or e_new[2] < 0.0 or e_new[2] > 1.0: - particles[0:3, ip] = -1.0 - continue - - # ========= mapping evaluation ============= - span1f = int(e_new[0] * nelf[0]) + pf1 - span2f = int(e_new[1] * nelf[1]) + pf2 - span3f = int(e_new[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - e_new[0], - e_new[1], - e_new[2], - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - # evaluate transposed inverse Jacobian matrix - linalg.transpose(dfinv, dfinv_t) - - # evaluate Ginv matrix - linalg.matrix_matrix(dfinv, dfinv_t, Ginv) - # ============================================ - - # pull-back of velocity - linalg.matrix_vector(dfinv, v, k3_v) - - # ========== field evaluation ============== - span1 = int(e_new[0] * nel[0]) + pn1 - span2 = int(e_new[1] * nel[1]) + pn2 - span3 = int(e_new[2] * nel[2]) + pn3 - - # evaluation of basis functions and derivatives - bsp.basis_funs_and_der(t1, pn1, e_new[0], span1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(t2, pn2, e_new[1], span2, l2, r2, b2, d2, der2) - bsp.basis_funs_and_der(t3, pn3, e_new[2], span3, l3, r3, b3, d3, der3) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - bn3[:] = b3[pn3, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - bd3[:] = b3[pd3, :pn3] * d3[:] - - # velocity field - if basis_u == 1: - u[0] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - nbase_d[0], - nbase_n[1], - nbase_n[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - nbase_n[0], - nbase_d[1], - nbase_n[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - nbase_n[0], - nbase_n[1], - nbase_d[2], - u3, - ) - - linalg.matrix_vector(Ginv, u, k3_u) - - elif basis_u == 2: - u[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - u3, - ) - - k3_u[:] = u / det_df - - k3[:] = k3_v + k3_u - # ------------------------------------------------------------------ - - # ------------------ step 4 in Runge-Kutta method ------------------ - e_new[0] = e[0] + dt * k3[0] - e_new[1] = e[1] + dt * k3[1] - e_new[2] = e[2] + dt * k3[2] - - if e_new[0] < 0.0 or e_new[0] > 1.0 or e_new[1] < 0.0 or e_new[1] > 1.0 or e_new[2] < 0.0 or e_new[2] > 1.0: - particles[0:3, ip] = -1.0 - continue - - # ========= mapping evaluation ============= - span1f = int(e_new[0] * nelf[0]) + pf1 - span2f = int(e_new[1] * nelf[1]) + pf2 - span3f = int(e_new[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - e_new[0], - e_new[1], - e_new[2], - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - # evaluate transposed inverse Jacobian matrix - linalg.transpose(dfinv, dfinv_t) - - # evaluate Ginv matrix - linalg.matrix_matrix(dfinv, dfinv_t, Ginv) - # ============================================ - - # ========== field evaluation ============== - span1 = int(e_new[0] * nel[0]) + pn1 - span2 = int(e_new[1] * nel[1]) + pn2 - span3 = int(e_new[2] * nel[2]) + pn3 - - # evaluation of basis functions and derivatives - bsp.basis_funs_and_der(t1, pn1, e_new[0], span1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(t2, pn2, e_new[1], span2, l2, r2, b2, d2, der2) - bsp.basis_funs_and_der(t3, pn3, e_new[2], span3, l3, r3, b3, d3, der3) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - bn3[:] = b3[pn3, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - bd3[:] = b3[pd3, :pn3] * d3[:] - - # velocity field - if basis_u == 1: - u[0] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - nbase_d[0], - nbase_n[1], - nbase_n[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - nbase_n[0], - nbase_d[1], - nbase_n[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - nbase_n[0], - nbase_n[1], - nbase_d[2], - u3, - ) - - linalg.matrix_vector(Ginv, u, k4_u) - - elif basis_u == 2: - u[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - u3, - ) - - k4_u[:] = u / det_df - - # pull-back of velocity - linalg.matrix_vector(dfinv, v, k4_v) - - k4[:] = k4_v[:] + k4_u[:] - # ------------------------------------------------------------------ - - # ---------------- update logical coordinates --------------------- - e_new[0] = e[0] + dt * (k1[0] + 2 * k2[0] + 2 * k3[0] + k4[0]) / 6 - e_new[1] = e[1] + dt * (k1[1] + 2 * k2[1] + 2 * k3[1] + k4[1]) / 6 - e_new[2] = e[2] + dt * (k1[2] + 2 * k2[2] + 2 * k3[2] + k4[2]) / 6 - - if e_new[0] < 0.0 or e_new[0] > 1.0 or e_new[1] < 0.0 or e_new[1] > 1.0 or e_new[2] < 0.0 or e_new[2] > 1.0: - particles[0:3, ip] = -1.0 - continue - - particles[0, ip] = e_new[0] - particles[1, ip] = e_new[1] - particles[2, ip] = e_new[2] - # ------------------------------------------------------------------ - - ierr = 0 - - -# ========================================================================================================== -def pusher_rk4_pc_perp( - particles: "float[:,:]", - dt: "float", - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - p: "int[:]", - nel: "int[:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - np: "int", - u1: "float[:,:,:]", - u2: "float[:,:,:]", - u3: "float[:,:,:]", - basis_u: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty - - # ============== for velocity evaluation ============ - # spline degrees - pn1 = p[0] - pn2 = p[1] - pn3 = p[2] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - pd3 = pn3 - 1 - - # p + 1 non-vanishing basis functions up tp degree p - b1 = empty((pn1 + 1, pn1 + 1), dtype=float) - b2 = empty((pn2 + 1, pn2 + 1), dtype=float) - b3 = empty((pn3 + 1, pn3 + 1), dtype=float) - - # left and right values for spline evaluation - l1 = empty(pn1, dtype=float) - l2 = empty(pn2, dtype=float) - l3 = empty(pn3, dtype=float) - - r1 = empty(pn1, dtype=float) - r2 = empty(pn2, dtype=float) - r3 = empty(pn3, dtype=float) - - # scaling arrays for M-splines - d1 = empty(pn1, dtype=float) - d2 = empty(pn2, dtype=float) - d3 = empty(pn3, dtype=float) - - # p + 1 non-vanishing derivatives - der1 = empty(pn1 + 1, dtype=float) - der2 = empty(pn2 + 1, dtype=float) - der3 = empty(pn3 + 1, dtype=float) - - # non-vanishing N-splines at particle position - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - # non-vanishing D-splines at particle position - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - # # velocity field at particle position - u = empty(3, dtype=float) - # ========================================================== - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = empty((3, 3), dtype=float) - dfinv = empty((3, 3), dtype=float) - dfinv_t = empty((3, 3), dtype=float) - Ginv = empty((3, 3), dtype=float) - fx = empty(3, dtype=float) - # ======================================================== - - # ======= particle position and velocity ================= - eta = empty(3, dtype=float) - v = empty(3, dtype=float) - # ======================================================== - - # ===== intermediate stps in 4th order Runge-Kutta ======= - k1 = empty(3, dtype=float) - k2 = empty(3, dtype=float) - k3 = empty(3, dtype=float) - k4 = empty(3, dtype=float) - k1_u = empty(3, dtype=float) - k2_u = empty(3, dtype=float) - k3_u = empty(3, dtype=float) - k4_u = empty(3, dtype=float) - k1_v = empty(3, dtype=float) - k2_v = empty(3, dtype=float) - k3_v = empty(3, dtype=float) - k4_v = empty(3, dtype=float) - # ======================================================== - - for ip in range(np): - eta[:] = particles[0:3, ip] - v[:] = particles[3:6, ip] - - # ----------- step 1 in Runge-Kutta method ----------------------- - # ========= mapping evaluation ============= - eta1 = eta[0] - eta2 = eta[1] - eta3 = eta[2] - - span1f = int(eta[0] * nelf[0]) + pf1 - span2f = int(eta[1] * nelf[1]) + pf2 - span3f = int(eta[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - # evaluate transposed inverse Jacobian matrix - linalg.transpose(dfinv, dfinv_t) - - # evaluate Ginv matrix - linalg.matrix_matrix(dfinv, dfinv_t, Ginv) ########### - # ============================================ - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - span3 = int(eta3 * nel[2]) + pn3 - - # evaluation of basis functions and derivatives - bsp.basis_funs_and_der(t1, pn1, eta1, span1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(t2, pn2, eta2, span2, l2, r2, b2, d2, der2) - bsp.basis_funs_and_der(t3, pn3, eta3, span3, l3, r3, b3, d3, der3) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - bn3[:] = b3[pn3, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - bd3[:] = b3[pd3, :pn3] * d3[:] - - # velocity field - if basis_u == 1: - u[0] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - nbase_d[0], - nbase_n[1], - nbase_n[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - nbase_n[0], - nbase_d[1], - nbase_n[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - nbase_n[0], - nbase_n[1], - nbase_d[2], - u3, - ) - - linalg.matrix_vector(Ginv, u, k1_u) - - elif basis_u == 2: - u[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - u3, - ) - - k1_u[:] = u / det_df - - k1_u[0] = 0.0 - - # pull-back of velocity - linalg.matrix_vector(dfinv, v, k1_v) - - k1[:] = k1_v[:] + k1_u[:] - - # ------------------------------------------------------------------ - - # ----------------- step 2 in Runge-Kutta method ------------------- - eta1 = (eta[0] + dt * k1[0] / 2) % 1.0 - eta2 = (eta[1] + dt * k1[1] / 2) % 1.0 - eta3 = (eta[2] + dt * k1[2] / 2) % 1.0 - - # ========= mapping evaluation ============= - span1f = int(eta[0] * nelf[0]) + pf1 - span2f = int(eta[1] * nelf[1]) + pf2 - span3f = int(eta[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - # evaluate transposed inverse Jacobian matrix - linalg.transpose(dfinv, dfinv_t) - - # evaluate Ginv matrix - linalg.matrix_matrix(dfinv, dfinv_t, Ginv) - # ============================================ - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - span3 = int(eta3 * nel[2]) + pn3 - - # evaluation of basis functions and derivatives - bsp.basis_funs_and_der(t1, pn1, eta1, span1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(t2, pn2, eta2, span2, l2, r2, b2, d2, der2) - bsp.basis_funs_and_der(t3, pn3, eta3, span3, l3, r3, b3, d3, der3) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - bn3[:] = b3[pn3, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - bd3[:] = b3[pd3, :pn3] * d3[:] - - # velocity field - if basis_u == 1: - u[0] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - nbase_d[0], - nbase_n[1], - nbase_n[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - nbase_n[0], - nbase_d[1], - nbase_n[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - nbase_n[0], - nbase_n[1], - nbase_d[2], - u3, - ) - - linalg.matrix_vector(Ginv, u, k2_u) - - elif basis_u == 2: - u[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - u3, - ) - - k2_u[:] = u / det_df - - k2_u[0] = 0.0 - - # pull-back of velocity - linalg.matrix_vector(dfinv, v, k2_v) - - k2[:] = k2_v[:] + k2_u[:] - # ------------------------------------------------------------------ - - # ------------------ step 3 in Runge-Kutta method ------------------ - eta1 = (eta[0] + dt * k2[0] / 2) % 1.0 - eta2 = (eta[1] + dt * k2[1] / 2) % 1.0 - eta3 = (eta[2] + dt * k2[2] / 2) % 1.0 - - # ========= mapping evaluation ============= - span1f = int(eta[0] * nelf[0]) + pf1 - span2f = int(eta[1] * nelf[1]) + pf2 - span3f = int(eta[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - # evaluate transposed inverse Jacobian matrix - linalg.transpose(dfinv, dfinv_t) - - # evaluate Ginv matrix - linalg.matrix_matrix(dfinv, dfinv_t, Ginv) - # ============================================ - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - span3 = int(eta3 * nel[2]) + pn3 - - # evaluation of basis functions and derivatives - bsp.basis_funs_and_der(t1, pn1, eta1, span1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(t2, pn2, eta2, span2, l2, r2, b2, d2, der2) - bsp.basis_funs_and_der(t3, pn3, eta3, span3, l3, r3, b3, d3, der3) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - bn3[:] = b3[pn3, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - bd3[:] = b3[pd3, :pn3] * d3[:] - - # velocity field - if basis_u == 1: - u[0] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - nbase_d[0], - nbase_n[1], - nbase_n[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - nbase_n[0], - nbase_d[1], - nbase_n[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - nbase_n[0], - nbase_n[1], - nbase_d[2], - u3, - ) - - linalg.matrix_vector(Ginv, u, k3_u) - - elif basis_u == 2: - u[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - u3, - ) - - k3_u[:] = u / det_df - - k3_u[0] = 0.0 - - # pull-back of velocity - linalg.matrix_vector(dfinv, v, k3_v) - - k3[:] = k3_v[:] + k3_u[:] - # ------------------------------------------------------------------ - - # ------------------ step 4 in Runge-Kutta method ------------------ - eta1 = (eta[0] + dt * k3[0]) % 1.0 - eta2 = (eta[1] + dt * k3[1]) % 1.0 - eta3 = (eta[2] + dt * k3[2]) % 1.0 - - # ========= mapping evaluation ============= - span1f = int(eta[0] * nelf[0]) + pf1 - span2f = int(eta[1] * nelf[1]) + pf2 - span3f = int(eta[2] * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - # evaluate transposed inverse Jacobian matrix - linalg.transpose(dfinv, dfinv_t) - - # evaluate Ginv matrix - linalg.matrix_matrix(dfinv, dfinv_t, Ginv) - # ============================================ - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - span3 = int(eta3 * nel[2]) + pn3 - - # evaluation of basis functions and derivatives - bsp.basis_funs_and_der(t1, pn1, eta1, span1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(t2, pn2, eta2, span2, l2, r2, b2, d2, der2) - bsp.basis_funs_and_der(t3, pn3, eta3, span3, l3, r3, b3, d3, der3) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - bn3[:] = b3[pn3, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - bd3[:] = b3[pd3, :pn3] * d3[:] - - # velocity field - if basis_u == 1: - u[0] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - nbase_d[0], - nbase_n[1], - nbase_n[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - nbase_n[0], - nbase_d[1], - nbase_n[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - nbase_n[0], - nbase_n[1], - nbase_d[2], - u3, - ) - - linalg.matrix_vector(Ginv, u, k4_u) - - elif basis_u == 2: - u[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - u3, - ) - - k4_u[:] = u / det_df - - k4_u[0] = 0.0 - - # pull-back of velocity - linalg.matrix_vector(dfinv, v, k4_v) - - k4[:] = k4_v[:] + k4_u[:] - # ------------------------------------------------------------------ - - # ---------------- update logical coordinates --------------------- - particles[0, ip] = (eta[0] + dt * (k1[0] + 2 * k2[0] + 2 * k3[0] + k4[0]) / 6) % 1.0 - particles[1, ip] = (eta[1] + dt * (k1[1] + 2 * k2[1] + 2 * k3[1] + k4[1]) / 6) % 1.0 - particles[2, ip] = (eta[2] + dt * (k1[2] + 2 * k2[2] + 2 * k3[2] + k4[2]) / 6) % 1.0 - - # ------------------------------------------------------------------ - - ierr = 0 diff --git a/src/struphy/pic/tests/test_pic_legacy_files/pusher_vel_2d.py b/src/struphy/pic/tests/test_pic_legacy_files/pusher_vel_2d.py deleted file mode 100644 index 0fcc29751..000000000 --- a/src/struphy/pic/tests/test_pic_legacy_files/pusher_vel_2d.py +++ /dev/null @@ -1,791 +0,0 @@ -# import pyccel decorators - - -# import modules for B-spline evaluation -import struphy.bsplines.bsplines_kernels as bsp - -# import module for matrix-matrix and matrix-vector multiplications -import struphy.linear_algebra.linalg_kernels as linalg - -# import modules for mapping evaluation -import struphy.pic.tests.test_pic_legacy_files.mappings_3d_fast as mapping_fast -import struphy.pic.tests.test_pic_legacy_files.spline_evaluation_2d as eva2 - - -# ========================================================================================================== -def pusher_step3( - particles: "float[:,:]", - dt: "float", - t1: "float[:]", - t2: "float[:]", - p: "int[:]", - nel: "int[:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - np: "int", - b_eq_1: "float[:,:,:]", - b_eq_2: "float[:,:,:]", - b_eq_3: "float[:,:,:]", - b_p_1: "float[:,:,:]", - b_p_2: "float[:,:,:]", - b_p_3: "float[:,:,:]", - b_norm: "float[:,:,:]", - u1: "float[:,:,:]", - u2: "float[:,:,:]", - u3: "float[:,:,:]", - basis_u: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", - mu: "float[:]", - power: "float[:]", - n_tor: "int", -): - from numpy import cos, empty, pi, sin, zeros - - # ============== for magnetic field evaluation ============ - # spline degrees - pn1 = p[0] - pn2 = p[1] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - - # p + 1 non-vanishing basis functions up tp degree p - b1 = empty((pn1 + 1, pn1 + 1), dtype=float) - b2 = empty((pn2 + 1, pn2 + 1), dtype=float) - - # left and right values for spline evaluation - l1 = empty(pn1, dtype=float) - l2 = empty(pn2, dtype=float) - - r1 = empty(pn1, dtype=float) - r2 = empty(pn2, dtype=float) - - # scaling arrays for M-splines - d1 = empty(pn1, dtype=float) - d2 = empty(pn2, dtype=float) - - # p + 1 non-vanishing derivatives - der1 = empty(pn1 + 1, dtype=float) - der2 = empty(pn2 + 1, dtype=float) - - # non-vanishing N-splines at particle position - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - - # non-vanishing D-splines at particle position - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - - # cos/sin at particle position - cs = empty(2, dtype=float) - - # magnetic field, velocity field and electric field at particle position - u = empty(3, dtype=float) - b = empty(3, dtype=float) - b_grad = empty(3, dtype=float) - - u_cart = empty(3, dtype=float) - b_cart = empty(3, dtype=float) - b_grad_cart = empty(3, dtype=float) - - e_cart = empty(3, dtype=float) - # ========================================================== - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = empty((3, 3), dtype=float) - dfinv = empty((3, 3), dtype=float) - dfinv_t = empty((3, 3), dtype=float) - # ========================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ip, eta1, eta2, eta3, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, det_df, dfinv, dfinv_t, span1, span2, l1, l2, r1, r2, b1, b2, d1, d2, der1, der2, bn1, bn2, bd1, bd2, cs, u, u_cart, b, b_cart, b_grad, b_grad_cart, e_cart) - for ip in range(np): - # only do something if particle is inside the logical domain (0 < s < 1) - if particles[0, ip] < 0.0 or particles[0, ip] > 1.0: - continue - - eta1 = particles[0, ip] - eta2 = particles[1, ip] - eta3 = particles[2, ip] - - # ========= mapping evaluation ============= - span1f = int(eta1 * nelf[0]) + pf1 - span2f = int(eta2 * nelf[1]) + pf2 - span3f = int(eta3 * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate transposed inverse Jacobian matrix - linalg.transpose(dfinv, dfinv_t) - # ========================================== - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - - # evaluation of basis functions and derivatives - bsp.basis_funs_and_der(t1, pn1, eta1, span1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(t2, pn2, eta2, span2, l2, r2, b2, d2, der2) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - - # cos/sin at particle position - cs[0] = cos(2 * pi * n_tor * eta3) - cs[1] = sin(2 * pi * n_tor * eta3) - - # velocity field (0-form, push-forward with df) - if basis_u == 0: - u[:] = 0.0 - - for i in range(nbase_n[2]): - u[0] += ( - eva2.evaluation_kernel_2d(pn1, pn2, bn1, bn2, span1, span2, nbase_n[0], nbase_n[1], u1[:, :, i]) - * cs[i] - ) - u[1] += ( - eva2.evaluation_kernel_2d(pn1, pn2, bn1, bn2, span1, span2, nbase_n[0], nbase_n[1], u2[:, :, i]) - * cs[i] - ) - u[2] += ( - eva2.evaluation_kernel_2d(pn1, pn2, bn1, bn2, span1, span2, nbase_n[0], nbase_n[1], u3[:, :, i]) - * cs[i] - ) - - linalg.matrix_vector(df, u, u_cart) - - # velocity field (1-form, push forward with df^(-T)) - elif basis_u == 1: - u[:] = 0.0 - - for i in range(nbase_n[2]): - u[0] += ( - eva2.evaluation_kernel_2d( - pd1, - pn2, - bd1, - bn2, - span1 - 1, - span2 - 0, - nbase_d[0], - nbase_n[1], - u1[:, :, i], - ) - * cs[i] - ) - u[1] += ( - eva2.evaluation_kernel_2d( - pn1, - pd2, - bn1, - bd2, - span1 - 0, - span2 - 1, - nbase_n[0], - nbase_d[1], - u2[:, :, i], - ) - * cs[i] - ) - u[2] += ( - eva2.evaluation_kernel_2d( - pn1, - pn2, - bn1, - bn2, - span1 - 0, - span2 - 0, - nbase_n[0], - nbase_n[1], - u3[:, :, i], - ) - * cs[i] - ) - - linalg.matrix_vector(dfinv_t, u, u_cart) - - # velocity field (2-form, push forward with df/|det df|) - elif basis_u == 2: - u[:] = 0.0 - - for i in range(nbase_n[2]): - u[0] += ( - eva2.evaluation_kernel_2d( - pn1, - pd2, - bn1, - bd2, - span1 - 0, - span2 - 1, - nbase_n[0], - nbase_d[1], - u1[:, :, i], - ) - * cs[i] - ) - u[1] += ( - eva2.evaluation_kernel_2d( - pd1, - pn2, - bd1, - bn2, - span1 - 1, - span2 - 0, - nbase_d[0], - nbase_n[1], - u2[:, :, i], - ) - * cs[i] - ) - u[2] += ( - eva2.evaluation_kernel_2d( - pd1, - pd2, - bd1, - bd2, - span1 - 1, - span2 - 1, - nbase_d[0], - nbase_d[1], - u3[:, :, i], - ) - * cs[i] - ) - - linalg.matrix_vector(df, u, u_cart) - - u_cart[0] = u_cart[0] / det_df - u_cart[1] = u_cart[1] / det_df - u_cart[2] = u_cart[2] / det_df - - # equilibrium magnetic field (2-form) - b[0] = eva2.evaluation_kernel_2d( - pn1, - pd2, - bn1, - bd2, - span1 - 0, - span2 - 1, - nbase_n[0], - nbase_d[1], - b_eq_1[:, :, 0], - ) - b[1] = eva2.evaluation_kernel_2d( - pd1, - pn2, - bd1, - bn2, - span1 - 1, - span2 - 0, - nbase_d[0], - nbase_n[1], - b_eq_2[:, :, 0], - ) - b[2] = eva2.evaluation_kernel_2d( - pd1, - pd2, - bd1, - bd2, - span1 - 1, - span2 - 1, - nbase_d[0], - nbase_d[1], - b_eq_3[:, :, 0], - ) - - # perturbed magnetic field (2-form) - for i in range(nbase_n[2]): - b[0] += ( - eva2.evaluation_kernel_2d( - pn1, - pd2, - bn1, - bd2, - span1 - 0, - span2 - 1, - nbase_n[0], - nbase_d[1], - b_p_1[:, :, i], - ) - * cs[i] - ) - b[1] += ( - eva2.evaluation_kernel_2d( - pd1, - pn2, - bd1, - bn2, - span1 - 1, - span2 - 0, - nbase_d[0], - nbase_n[1], - b_p_2[:, :, i], - ) - * cs[i] - ) - b[2] += ( - eva2.evaluation_kernel_2d( - pd1, - pd2, - bd1, - bd2, - span1 - 1, - span2 - 1, - nbase_d[0], - nbase_d[1], - b_p_3[:, :, i], - ) - * cs[i] - ) - - # push-forward to physical domain - linalg.matrix_vector(df, b, b_cart) - - b_cart[0] = b_cart[0] / det_df - b_cart[1] = b_cart[1] / det_df - b_cart[2] = b_cart[2] / det_df - - # gradient of absolute value of magnetic field (1-form) - b_grad[0] = eva2.evaluation_kernel_2d( - pn1, - pn2, - der1, - bn2, - span1, - span2, - nbase_n[0], - nbase_n[1], - b_norm[:, :, 0], - ) - b_grad[1] = eva2.evaluation_kernel_2d( - pn1, - pn2, - bn1, - der2, - span1, - span2, - nbase_n[0], - nbase_n[1], - b_norm[:, :, 0], - ) - b_grad[2] = 0.0 - - # push-forward to physical domain - linalg.matrix_vector(dfinv_t, b_grad, b_grad_cart) - - # electric field B x U - linalg.cross(b_cart, u_cart, e_cart) - - # additional artificial electric field if Pauli particles are used - e_cart[:] = e_cart - mu[ip] * b_grad_cart - - # power transfer (v.E) - power[ip] = particles[3, ip] * e_cart[0] + particles[4, ip] * e_cart[1] + particles[5, ip] * e_cart[2] - # ========================================== - - # ======== particle pushing ================ - particles[3, ip] += dt * e_cart[0] - particles[4, ip] += dt * e_cart[1] - particles[5, ip] += dt * e_cart[2] - # ========================================== - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================================== -def pusher_step5( - particles: "float[:,:]", - dt: "float", - t1: "float[:]", - t2: "float[:]", - p: "int[:]", - nel: "int[:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - np: "int", - b_eq_1: "float[:,:,:]", - b_eq_2: "float[:,:,:]", - b_eq_3: "float[:,:,:]", - b_p_1: "float[:,:,:]", - b_p_2: "float[:,:,:]", - b_p_3: "float[:,:,:]", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", - n_tor: "int", -): - from numpy import cos, empty, pi, sin, sqrt, zeros - - # ============== for magnetic field evaluation ============ - # spline degrees - pn1 = p[0] - pn2 = p[1] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - - # p + 1 non-vanishing basis functions up tp degree p - b1 = empty((pn1 + 1, pn1 + 1), dtype=float) - b2 = empty((pn2 + 1, pn2 + 1), dtype=float) - - # left and right values for spline evaluation - l1 = empty(pn1, dtype=float) - l2 = empty(pn2, dtype=float) - - r1 = empty(pn1, dtype=float) - r2 = empty(pn2, dtype=float) - - # scaling arrays for M-splines - d1 = empty(pn1, dtype=float) - d2 = empty(pn2, dtype=float) - - # non-vanishing N-splines at particle position - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - - # non-vanishing D-splines at particle position - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - - # cos/sin at particle position - cs = empty(2, dtype=float) - - # magnetic field at particle position (2-form, cartesian, normalized cartesian) - b = empty(3, dtype=float) - b_cart = empty(3, dtype=float) - b0 = empty(3, dtype=float) - - # particle velocity (cartesian, perpendicular, v x b0, b0 x vperp) - v = empty(3, dtype=float) - vperp = empty(3, dtype=float) - vxb0 = empty(3, dtype=float) - b0xvperp = empty(3, dtype=float) - # ========================================================== - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = empty((3, 3), dtype=float) - # ========================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ip, eta1, eta2, eta3, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, det_df, span1, span2, l1, l2, r1, r2, b1, b2, d1, d2, bn1, bn2, bd1, bd2, cs, b, b_cart, b_norm, b0, v, vpar, vxb0, vperp, b0xvperp) - for ip in range(np): - # only do something if particle is inside the logical domain (0 < s < 1) - if particles[0, ip] < 0.0 or particles[0, ip] > 1.0: - continue - - eta1 = particles[0, ip] - eta2 = particles[1, ip] - eta3 = particles[2, ip] - - # ========= mapping evaluation ============= - span1f = int(eta1 * nelf[0]) + pf1 - span2f = int(eta2 * nelf[1]) + pf2 - span3f = int(eta3 * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - # ========================================== - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - - # evaluation of basis functions - bsp.basis_funs_all(t1, pn1, eta1, span1, l1, r1, b1, d1) - bsp.basis_funs_all(t2, pn2, eta2, span2, l2, r2, b2, d2) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - - # cos/sin at particle position - cs[0] = cos(2 * pi * n_tor * eta3) - cs[1] = sin(2 * pi * n_tor * eta3) - - # equilibrium magnetic field (2-form) - b[0] = eva2.evaluation_kernel_2d( - pn1, - pd2, - bn1, - bd2, - span1 - 0, - span2 - 1, - nbase_n[0], - nbase_d[1], - b_eq_1[:, :, 0], - ) - b[1] = eva2.evaluation_kernel_2d( - pd1, - pn2, - bd1, - bn2, - span1 - 1, - span2 - 0, - nbase_d[0], - nbase_n[1], - b_eq_2[:, :, 0], - ) - b[2] = eva2.evaluation_kernel_2d( - pd1, - pd2, - bd1, - bd2, - span1 - 1, - span2 - 1, - nbase_d[0], - nbase_d[1], - b_eq_3[:, :, 0], - ) - - # perturbed magnetic field (2-form) - for i in range(nbase_n[2]): - b[0] += ( - eva2.evaluation_kernel_2d( - pn1, - pd2, - bn1, - bd2, - span1 - 0, - span2 - 1, - nbase_n[0], - nbase_d[1], - b_p_1[:, :, i], - ) - * cs[i] - ) - b[1] += ( - eva2.evaluation_kernel_2d( - pd1, - pn2, - bd1, - bn2, - span1 - 1, - span2 - 0, - nbase_d[0], - nbase_n[1], - b_p_2[:, :, i], - ) - * cs[i] - ) - b[2] += ( - eva2.evaluation_kernel_2d( - pd1, - pd2, - bd1, - bd2, - span1 - 1, - span2 - 1, - nbase_d[0], - nbase_d[1], - b_p_3[:, :, i], - ) - * cs[i] - ) - - # push-forward to physical domain - linalg.matrix_vector(df, b, b_cart) - - b_cart[0] = b_cart[0] / det_df - b_cart[1] = b_cart[1] / det_df - b_cart[2] = b_cart[2] / det_df - - # absolute value of magnetic field - b_norm = sqrt(b_cart[0] ** 2 + b_cart[1] ** 2 + b_cart[2] ** 2) - - # normalized magnetic field direction - b0[0] = b_cart[0] / b_norm - b0[1] = b_cart[1] / b_norm - b0[2] = b_cart[2] / b_norm - # ========================================== - - # ======== particle pushing ================ - # particle velocity - v[:] = particles[3:6, ip] - - # parallel velocity v . b0 - vpar = v[0] * b0[0] + v[1] * b0[1] + v[2] * b0[2] - - # perpendicular velocity b0 x (v x b0) - linalg.cross(v, b0, vxb0) - linalg.cross(b0, vxb0, vperp) - - # analytical rotation - linalg.cross(b0, vperp, b0xvperp) - - particles[3:6, ip] = vpar * b0 + cos(b_norm * dt) * vperp - sin(b_norm * dt) * b0xvperp - # ========================================== - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 diff --git a/src/struphy/pic/tests/test_pic_legacy_files/pusher_vel_3d.py b/src/struphy/pic/tests/test_pic_legacy_files/pusher_vel_3d.py deleted file mode 100644 index cd3884209..000000000 --- a/src/struphy/pic/tests/test_pic_legacy_files/pusher_vel_3d.py +++ /dev/null @@ -1,1622 +0,0 @@ -# import pyccel decorators - - -# import modules for B-spline evaluation -import struphy.bsplines.bsplines_kernels as bsp - -# import module for matrix-matrix and matrix-vector multiplications -import struphy.linear_algebra.linalg_kernels as linalg - -# import modules for mapping evaluation -import struphy.pic.tests.test_pic_legacy_files.mappings_3d_fast as mapping_fast -import struphy.pic.tests.test_pic_legacy_files.spline_evaluation_3d as eva3 - - -# ========================================================================================================== -def pusher_step3( - particles: "float[:,:]", - dt: "float", - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - p: "int[:]", - nel: "int[:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - np: "int", - b2_1: "float[:,:,:]", - b2_2: "float[:,:,:]", - b2_3: "float[:,:,:]", - b0: "float[:,:,:]", - u1: "float[:,:,:]", - u2: "float[:,:,:]", - u3: "float[:,:,:]", - basis_u: "int", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", - mu: "float[:]", - power: "float[:]", -): - from numpy import cos, empty, pi, sin, zeros - - # ============== for magnetic field evaluation ============ - # spline degrees - pn1 = p[0] - pn2 = p[1] - pn3 = p[2] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - pd3 = pn3 - 1 - - # p + 1 non-vanishing basis functions up tp degree p - b1 = empty((pn1 + 1, pn1 + 1), dtype=float) - b2 = empty((pn2 + 1, pn2 + 1), dtype=float) - b3 = empty((pn3 + 1, pn3 + 1), dtype=float) - - # left and right values for spline evaluation - l1 = empty(pn1, dtype=float) - l2 = empty(pn2, dtype=float) - l3 = empty(pn3, dtype=float) - - r1 = empty(pn1, dtype=float) - r2 = empty(pn2, dtype=float) - r3 = empty(pn3, dtype=float) - - # scaling arrays for M-splines - d1 = empty(pn1, dtype=float) - d2 = empty(pn2, dtype=float) - d3 = empty(pn3, dtype=float) - - # p + 1 non-vanishing derivatives - der1 = empty(pn1 + 1, dtype=float) - der2 = empty(pn2 + 1, dtype=float) - der3 = empty(pn3 + 1, dtype=float) - - # non-vanishing N-splines at particle position - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - # non-vanishing D-splines at particle position - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - # magnetic field, velocity field and electric field at particle position - u = empty(3, dtype=float) - b = empty(3, dtype=float) - b_grad = empty(3, dtype=float) - - u_cart = empty(3, dtype=float) - b_cart = empty(3, dtype=float) - b_grad_cart = empty(3, dtype=float) - - e_cart = empty(3, dtype=float) - # ========================================================== - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = empty((3, 3), dtype=float) - dfinv = empty((3, 3), dtype=float) - dfinv_t = empty((3, 3), dtype=float) - # ========================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ip, eta1, eta2, eta3, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, det_df, dfinv, dfinv_t, span1, span2, span3, l1, l2, l3, r1, r2, r3, b1, b2, b3, d1, d2, d3, der1, der2, der3, bn1, bn2, bn3, bd1, bd2, bd3, u, u_cart, b, b_cart, b_grad, b_grad_cart, e_cart) - for ip in range(np): - # only do something if particle is inside the logical domain (0 < s < 1) - if particles[0, ip] < 0.0 or particles[0, ip] > 1.0: - continue - - eta1 = particles[0, ip] - eta2 = particles[1, ip] - eta3 = particles[2, ip] - - # ========= mapping evaluation ============= - span1f = int(eta1 * nelf[0]) + pf1 - span2f = int(eta2 * nelf[1]) + pf2 - span3f = int(eta3 * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate transposed inverse Jacobian matrix - linalg.transpose(dfinv, dfinv_t) - # ========================================== - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - span3 = int(eta3 * nel[2]) + pn3 - - # evaluation of basis functions and derivatives - bsp.basis_funs_and_der(t1, pn1, eta1, span1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(t2, pn2, eta2, span2, l2, r2, b2, d2, der2) - bsp.basis_funs_and_der(t3, pn3, eta3, span3, l3, r3, b3, d3, der3) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - bn3[:] = b3[pn3, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - bd3[:] = b3[pd3, :pn3] * d3[:] - - # velocity field (0-form, push-forward with df) - if basis_u == 0: - u[0] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pn3, - bn1, - bn2, - bn3, - span1, - span2, - span3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pn3, - bn1, - bn2, - bn3, - span1, - span2, - span3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pn3, - bn1, - bn2, - bn3, - span1, - span2, - span3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - u3, - ) - - linalg.matrix_vector(df, u, u_cart) - - # velocity field (1-form, push forward with df^(-T)) - elif basis_u == 1: - u[0] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - nbase_d[0], - nbase_n[1], - nbase_n[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - nbase_n[0], - nbase_d[1], - nbase_n[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - nbase_n[0], - nbase_n[1], - nbase_d[2], - u3, - ) - - linalg.matrix_vector(dfinv_t, u, u_cart) - - # velocity field (2-form, push forward with df/|det df|) - elif basis_u == 2: - u[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - u1, - ) - u[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - u2, - ) - u[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - u3, - ) - - linalg.matrix_vector(df, u, u_cart) - - u_cart[0] = u_cart[0] / det_df - u_cart[1] = u_cart[1] / det_df - u_cart[2] = u_cart[2] / det_df - - # magnetic field (2-form) - b[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - b2_1, - ) - b[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - b2_2, - ) - b[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - b2_3, - ) - - # push-forward to physical domain - linalg.matrix_vector(df, b, b_cart) - - b_cart[0] = b_cart[0] / det_df - b_cart[1] = b_cart[1] / det_df - b_cart[2] = b_cart[2] / det_df - - # gradient of absolute value of magnetic field (1-form) - b_grad[0] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pn3, - der1, - bn2, - bn3, - span1, - span2, - span3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - b0, - ) - b_grad[1] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pn3, - bn1, - der2, - bn3, - span1, - span2, - span3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - b0, - ) - b_grad[2] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pn3, - bn1, - bn2, - der3, - span1, - span2, - span3, - nbase_n[0], - nbase_n[1], - nbase_n[2], - b0, - ) - - # push-forward to physical domain - linalg.matrix_vector(dfinv_t, b_grad, b_grad_cart) - - # electric field B x U - linalg.cross(b_cart, u_cart, e_cart) - - # additional artificial electric field if Pauli particles are used - e_cart[:] = e_cart - mu[ip] * b_grad_cart - - # power transfer (v.E) - power[ip] = particles[3, ip] * e_cart[0] + particles[4, ip] * e_cart[1] + particles[5, ip] * e_cart[2] - # ========================================== - - # ======== particle pushing ================ - particles[3, ip] += dt * e_cart[0] - particles[4, ip] += dt * e_cart[1] - particles[5, ip] += dt * e_cart[2] - # ========================================== - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================================== -def pusher_step5_old( - particles: "float[:,:]", - dt: "float", - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - p: "int[:]", - nel: "int[:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - np: "int", - b2_1: "float[:,:,:]", - b2_2: "float[:,:,:]", - b2_3: "float[:,:,:]", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import cos, empty, pi, sin, zeros - - # ============== for magnetic field evaluation ============ - # spline degrees - pn1 = p[0] - pn2 = p[1] - pn3 = p[2] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - pd3 = pn3 - 1 - - # p + 1 non-vanishing basis functions up tp degree p - b1 = empty((pn1 + 1, pn1 + 1), dtype=float) - b2 = empty((pn2 + 1, pn2 + 1), dtype=float) - b3 = empty((pn3 + 1, pn3 + 1), dtype=float) - - # left and right values for spline evaluation - l1 = empty(pn1, dtype=float) - l2 = empty(pn2, dtype=float) - l3 = empty(pn3, dtype=float) - - r1 = empty(pn1, dtype=float) - r2 = empty(pn2, dtype=float) - r3 = empty(pn3, dtype=float) - - # scaling arrays for M-splines - d1 = empty(pn1, dtype=float) - d2 = empty(pn2, dtype=float) - d3 = empty(pn3, dtype=float) - - # non-vanishing N-splines at particle position - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - # non-vanishing D-splines at particle position - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - # magnetic field at particle position and velocity - b = empty(3, dtype=float) - b_prod = zeros((3, 3), dtype=float) - v = empty(3, dtype=float) - # ========================================================== - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = empty((3, 3), dtype=float) - dfinv = empty((3, 3), dtype=float) - dfinv_t = empty((3, 3), dtype=float) - # ========================================================== - - # ============== for solving linear 3 x 3 system =========== - temp_mat1 = empty((3, 3), dtype=float) - temp_mat2 = empty((3, 3), dtype=float) - - rhs = empty(3, dtype=float) - lhs = empty((3, 3), dtype=float) - lhs1 = empty((3, 3), dtype=float) - lhs2 = empty((3, 3), dtype=float) - lhs3 = empty((3, 3), dtype=float) - - identity = zeros((3, 3), dtype=float) - - identity[0, 0] = 1.0 - identity[1, 1] = 1.0 - identity[2, 2] = 1.0 - # =========================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ip, eta1, eta2, eta3, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, det_df, dfinv, dfinv_t, span1, span2, span3, l1, l2, l3, r1, r2, r3, b1, b2, b3, d1, d2, d3, bn1, bn2, bn3, bd1, bd2, bd3, b, v, temp_mat1, temp_mat2, rhs, lhs, det_lhs, lhs1, lhs2, lhs3, det_lhs1, det_lhs2, det_lhs3) firstprivate(b_prod) - for ip in range(np): - # only do something if particle is inside the logical domain (0 < s < 1) - if particles[0, ip] < 0.0 or particles[0, ip] > 1.0: - continue - - eta1 = particles[0, ip] - eta2 = particles[1, ip] - eta3 = particles[2, ip] - - # ========= mapping evaluation ============= - span1f = int(eta1 * nelf[0]) + pf1 - span2f = int(eta2 * nelf[1]) + pf2 - span3f = int(eta3 * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate transposed inverse Jacobian matrix - linalg.transpose(dfinv, dfinv_t) - # ========================================== - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - span3 = int(eta3 * nel[2]) + pn3 - - # evaluation of basis functions - bsp.basis_funs_all(t1, pn1, eta1, span1, l1, r1, b1, d1) - bsp.basis_funs_all(t2, pn2, eta2, span2, l2, r2, b2, d2) - bsp.basis_funs_all(t3, pn3, eta3, span3, l3, r3, b3, d3) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - bn3[:] = b3[pn3, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - bd3[:] = b3[pd3, :pn3] * d3[:] - - # magnetic field (2-form) - b[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - b2_1, - ) - b[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - b2_2, - ) - b[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - b2_3, - ) - - b_prod[0, 1] = -b[2] - b_prod[0, 2] = b[1] - - b_prod[1, 0] = b[2] - b_prod[1, 2] = -b[0] - - b_prod[2, 0] = -b[1] - b_prod[2, 1] = b[0] - # ========================================== - - # ======== particle pushing ================ - v[:] = particles[3:6, ip] - - # perform matrix-matrix and matrix-vector multiplications - linalg.matrix_matrix(b_prod, dfinv, temp_mat1) - linalg.matrix_matrix(dfinv_t, temp_mat1, temp_mat2) - - # explicit part of update rule - linalg.matrix_vector(identity - dt / 2 * temp_mat2, v, rhs) - - # implicit part of update rule - lhs = identity + dt / 2 * temp_mat2 - - # solve 3 x 3 system with Cramer's rule - det_lhs = linalg.det(lhs) - - lhs1[:, 0] = rhs - lhs1[:, 1] = lhs[:, 1] - lhs1[:, 2] = lhs[:, 2] - - lhs2[:, 0] = lhs[:, 0] - lhs2[:, 1] = rhs - lhs2[:, 2] = lhs[:, 2] - - lhs3[:, 0] = lhs[:, 0] - lhs3[:, 1] = lhs[:, 1] - lhs3[:, 2] = rhs - - det_lhs1 = linalg.det(lhs1) - det_lhs2 = linalg.det(lhs2) - det_lhs3 = linalg.det(lhs3) - - # update particle velocities - particles[3, ip] = det_lhs1 / det_lhs - particles[4, ip] = det_lhs2 / det_lhs - particles[5, ip] = det_lhs3 / det_lhs - # ========================================== - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - -# ========================================================================================================== -def pusher_step5( - particles: "float[:,:]", - dt: "float", - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - p: "int[:]", - nel: "int[:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - np: "int", - b2_1: "float[:,:,:]", - b2_2: "float[:,:,:]", - b2_3: "float[:,:,:]", - kind_map: "int", - params_map: "float[:]", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "int[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "float[:,:,:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import cos, empty, pi, sin, sqrt, zeros - - # ============== for magnetic field evaluation ============ - # spline degrees - pn1 = p[0] - pn2 = p[1] - pn3 = p[2] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - pd3 = pn3 - 1 - - # p + 1 non-vanishing basis functions up tp degree p - b1 = empty((pn1 + 1, pn1 + 1), dtype=float) - b2 = empty((pn2 + 1, pn2 + 1), dtype=float) - b3 = empty((pn3 + 1, pn3 + 1), dtype=float) - - # left and right values for spline evaluation - l1 = empty(pn1, dtype=float) - l2 = empty(pn2, dtype=float) - l3 = empty(pn3, dtype=float) - - r1 = empty(pn1, dtype=float) - r2 = empty(pn2, dtype=float) - r3 = empty(pn3, dtype=float) - - # scaling arrays for M-splines - d1 = empty(pn1, dtype=float) - d2 = empty(pn2, dtype=float) - d3 = empty(pn3, dtype=float) - - # non-vanishing N-splines at particle position - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - # non-vanishing D-splines at particle position - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - # magnetic field at particle position (2-form, cartesian, normalized cartesian) - b = empty(3, dtype=float) - b_cart = empty(3, dtype=float) - b0 = empty(3, dtype=float) - - # particle velocity (cartesian, perpendicular, v x b0, b0 x vperp) - v = empty(3, dtype=float) - vperp = empty(3, dtype=float) - vxb0 = empty(3, dtype=float) - b0xvperp = empty(3, dtype=float) - # ========================================================== - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - df = empty((3, 3), dtype=float) - fx = empty(3, dtype=float) - # ========================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ip, eta1, eta2, eta3, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, det_df, span1, span2, span3, l1, l2, l3, r1, r2, r3, b1, b2, b3, d1, d2, d3, bn1, bn2, bn3, bd1, bd2, bd3, b, b_cart, b_norm, b0, v, vpar, vxb0, vperp, b0xvperp) - for ip in range(np): - # only do something if particle is inside the logical domain (0 < s < 1) - if particles[0, ip] < 0.0 or particles[0, ip] > 1.0: - continue - - eta1 = particles[0, ip] - eta2 = particles[1, ip] - eta3 = particles[2, ip] - - # ========= mapping evaluation ============= - span1f = int(eta1 * nelf[0]) + pf1 - span2f = int(eta2 * nelf[1]) + pf2 - span3f = int(eta3 * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate Jacobian determinant - det_df = abs(linalg.det(df)) - # ========================================== - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - span3 = int(eta3 * nel[2]) + pn3 - - # evaluation of basis functions - bsp.basis_funs_all(t1, pn1, eta1, span1, l1, r1, b1, d1) - bsp.basis_funs_all(t2, pn2, eta2, span2, l2, r2, b2, d2) - bsp.basis_funs_all(t3, pn3, eta3, span3, l3, r3, b3, d3) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - bn3[:] = b3[pn3, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - bd3[:] = b3[pd3, :pn3] * d3[:] - - # magnetic field (2-form) - b[0] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span1, - span2 - 1, - span3 - 1, - nbase_n[0], - nbase_d[1], - nbase_d[2], - b2_1, - ) - b[1] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span1 - 1, - span2, - span3 - 1, - nbase_d[0], - nbase_n[1], - nbase_d[2], - b2_2, - ) - b[2] = eva3.evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span1 - 1, - span2 - 1, - span3, - nbase_d[0], - nbase_d[1], - nbase_n[2], - b2_3, - ) - - # push-forward to physical domain - linalg.matrix_vector(df, b, b_cart) - - b_cart[0] = b_cart[0] / det_df - b_cart[1] = b_cart[1] / det_df - b_cart[2] = b_cart[2] / det_df - - # absolute value of magnetic field - b_norm = sqrt(b_cart[0] ** 2 + b_cart[1] ** 2 + b_cart[2] ** 2) - - # normalized magnetic field direction - b0[0] = b_cart[0] / b_norm - b0[1] = b_cart[1] / b_norm - b0[2] = b_cart[2] / b_norm - # ========================================== - - # ======== particle pushing ================ - # particle velocity - v[:] = particles[3:6, ip] - - # parallel velocity v . b0 - vpar = v[0] * b0[0] + v[1] * b0[1] + v[2] * b0[2] - - # perpendicular velocity b0 x (v x b0) - linalg.cross(v, b0, vxb0) - linalg.cross(b0, vxb0, vperp) - - # analytical rotation - linalg.cross(b0, vperp, b0xvperp) - - particles[3:6, ip] = vpar * b0 + cos(b_norm * dt) * vperp - sin(b_norm * dt) * b0xvperp - # ========================================== - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 - - # ========================================================================================================== - - -def pusher_v_pressure_full( - particles: "float[:,:]", - dt: "float", - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - p: "int[:]", - nel: "int[:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - np: "int", - u11: "float[:,:,:]", - u12: "float[:,:,:]", - u13: "float[:,:,:]", - u21: "float[:,:,:]", - u22: "float[:,:,:]", - u23: "float[:,:,:]", - u31: "float[:,:,:]", - u32: "float[:,:,:]", - u33: "float[:,:,:]", - kind_map: "int", - params_map: "int", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "float[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "int[:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, zeros - - # ============== for magnetic field evaluation ============ - # spline degrees - pn1 = p[0] - pn2 = p[1] - pn3 = p[2] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - pd3 = pn3 - 1 - - # p + 1 non-vanishing basis functions up tp degree p - b1 = empty((pn1 + 1, pn1 + 1), dtype=float) - b2 = empty((pn2 + 1, pn2 + 1), dtype=float) - b3 = empty((pn3 + 1, pn3 + 1), dtype=float) - - # left and right values for spline evaluation - l1 = empty(pn1, dtype=float) - l2 = empty(pn2, dtype=float) - l3 = empty(pn3, dtype=float) - - r1 = empty(pn1, dtype=float) - r2 = empty(pn2, dtype=float) - r3 = empty(pn3, dtype=float) - - # scaling arrays for M-splines - d1 = empty(pn1, dtype=float) - d2 = empty(pn2, dtype=float) - d3 = empty(pn3, dtype=float) - - # p + 1 non-vanishing derivatives - der1 = empty(pn1 + 1, dtype=float) - der2 = empty(pn2 + 1, dtype=float) - der3 = empty(pn3 + 1, dtype=float) - - # non-vanishing N-splines at particle position - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - # non-vanishing D-splines at particle position - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - # # velocity field at particle position - u = empty(3, dtype=float) - u_cart = empty(3, dtype=float) - - # particle velocity - v = empty(3, dtype=float) - # ========================================================== - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = empty((3, 3), dtype=float) - dfinv = empty((3, 3), dtype=float) - dfinv_t = empty((3, 3), dtype=float) - # ========================================================== - - for ip in range(np): - # only do something if particle is inside the logical domain (0 < s < 1) - if particles[0, ip] < 0.0 or particles[0, ip] > 1.0: - continue - - eta1 = particles[0, ip] - eta2 = particles[1, ip] - eta3 = particles[2, ip] - - v[:] = particles[3:6, ip] - - # ========= mapping evaluation ============= - span1f = int(eta1 * nelf[0]) + pf1 - span2f = int(eta2 * nelf[1]) + pf2 - span3f = int(eta3 * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate transposed inverse Jacobian matrix - linalg.transpose(dfinv, dfinv_t) - # ========================================== - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - span3 = int(eta3 * nel[2]) + pn3 - - # evaluation of basis functions and derivatives - bsp.basis_funs_and_der(t1, pn1, eta1, span1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(t2, pn2, eta2, span2, l2, r2, b2, d2, der2) - bsp.basis_funs_and_der(t3, pn3, eta3, span3, l3, r3, b3, d3, der3) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - bn3[:] = b3[pn3, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - bd3[:] = b3[pd3, :pn3] * d3[:] - - # Evaluate G.dot(X_dot(u) at the particle positions - u[0] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - nbase_d[0], - nbase_n[1], - nbase_n[2], - u11 * v[0] + u21 * v[1] + u31 * v[2], - ) - u[1] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - nbase_n[0], - nbase_d[1], - nbase_n[2], - u12 * v[0] + u22 * v[1] + u32 * v[2], - ) - u[2] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - nbase_n[0], - nbase_n[1], - nbase_d[2], - u13 * v[0] + u23 * v[1] + u33 * v[2], - ) - - linalg.matrix_vector(dfinv_t, u, u_cart) - # ========================================== - - # ======== particle pushing ================ - particles[3, ip] -= dt * u_cart[0] / 2 - particles[4, ip] -= dt * u_cart[1] / 2 - particles[5, ip] -= dt * u_cart[2] / 2 - # ========================================== - - ierr = 0 - - -# ========================================================================================================== -def pusher_v_pressure_perp( - particles: "float[:,:]", - dt: "float", - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - p: "int[:]", - nel: "int[:]", - nbase_n: "int[:]", - nbase_d: "int[:]", - np: "int", - u11: "float[:,:,:]", - u12: "float[:,:,:]", - u13: "float[:,:,:]", - u21: "float[:,:,:]", - u22: "float[:,:,:]", - u23: "float[:,:,:]", - u31: "float[:,:,:]", - u32: "float[:,:,:]", - u33: "float[:,:,:]", - kind_map: "int", - params_map: "int", - tf1: "float[:]", - tf2: "float[:]", - tf3: "float[:]", - pf: "float[:]", - nelf: "int[:]", - nbasef: "int[:]", - cx: "int[:]", - cy: "float[:,:,:]", - cz: "float[:,:,:]", -): - from numpy import empty, zeros - - # ============== for magnetic field evaluation ============ - # spline degrees - pn1 = p[0] - pn2 = p[1] - pn3 = p[2] - - pd1 = pn1 - 1 - pd2 = pn2 - 1 - pd3 = pn3 - 1 - - # p + 1 non-vanishing basis functions up tp degree p - b1 = empty((pn1 + 1, pn1 + 1), dtype=float) - b2 = empty((pn2 + 1, pn2 + 1), dtype=float) - b3 = empty((pn3 + 1, pn3 + 1), dtype=float) - - # left and right values for spline evaluation - l1 = empty(pn1, dtype=float) - l2 = empty(pn2, dtype=float) - l3 = empty(pn3, dtype=float) - - r1 = empty(pn1, dtype=float) - r2 = empty(pn2, dtype=float) - r3 = empty(pn3, dtype=float) - - # scaling arrays for M-splines - d1 = empty(pn1, dtype=float) - d2 = empty(pn2, dtype=float) - d3 = empty(pn3, dtype=float) - - # p + 1 non-vanishing derivatives - der1 = empty(pn1 + 1, dtype=float) - der2 = empty(pn2 + 1, dtype=float) - der3 = empty(pn3 + 1, dtype=float) - - # non-vanishing N-splines at particle position - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - # non-vanishing D-splines at particle position - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - # # velocity field at particle position - u = empty(3, dtype=float) - u_cart = empty(3, dtype=float) - - # particle velocity - v = empty(3, dtype=float) - # ========================================================== - - # ================ for mapping evaluation ================== - # spline degrees - pf1 = pf[0] - pf2 = pf[1] - pf3 = pf[2] - - # pf + 1 non-vanishing basis functions up tp degree pf - b1f = empty((pf1 + 1, pf1 + 1), dtype=float) - b2f = empty((pf2 + 1, pf2 + 1), dtype=float) - b3f = empty((pf3 + 1, pf3 + 1), dtype=float) - - # left and right values for spline evaluation - l1f = empty(pf1, dtype=float) - l2f = empty(pf2, dtype=float) - l3f = empty(pf3, dtype=float) - - r1f = empty(pf1, dtype=float) - r2f = empty(pf2, dtype=float) - r3f = empty(pf3, dtype=float) - - # scaling arrays for M-splines - d1f = empty(pf1, dtype=float) - d2f = empty(pf2, dtype=float) - d3f = empty(pf3, dtype=float) - - # pf + 1 derivatives - der1f = empty(pf1 + 1, dtype=float) - der2f = empty(pf2 + 1, dtype=float) - der3f = empty(pf3 + 1, dtype=float) - - # needed mapping quantities - fx = empty(3, dtype=float) - df = empty((3, 3), dtype=float) - dfinv = empty((3, 3), dtype=float) - dfinv_t = empty((3, 3), dtype=float) - # ========================================================== - - # -- removed omp: #$ omp parallel - # -- removed omp: #$ omp do private (ip, eta1, eta2, eta3, v, span1f, span2f, span3f, l1f, l2f, l3f, r1f, r2f, r3f, b1f, b2f, b3f, d1f, d2f, d3f, der1f, der2f, der3f, df, fx, dfinv, dfinv_t, span1, span2, span3, l1, l2, l3, r1, r2, r3, b1, b2, b3, d1, d2, d3, der1, der2, der3, bn1, bn2, bn3, bd1, bd2, bd3, u, u_cart) - for ip in range(np): - eta1 = particles[0, ip] - eta2 = particles[1, ip] - eta3 = particles[2, ip] - - v[:] = particles[3:6, ip] - - # ========= mapping evaluation ============= - span1f = int(eta1 * nelf[0]) + pf1 - span2f = int(eta2 * nelf[1]) + pf2 - span3f = int(eta3 * nelf[2]) + pf3 - - # evaluate Jacobian matrix - mapping_fast.df_all( - kind_map, - params_map, - tf1, - tf2, - tf3, - pf, - nbasef, - span1f, - span2f, - span3f, - cx, - cy, - cz, - l1f, - l2f, - l3f, - r1f, - r2f, - r3f, - b1f, - b2f, - b3f, - d1f, - d2f, - d3f, - der1f, - der2f, - der3f, - eta1, - eta2, - eta3, - df, - fx, - 0, - ) - - # evaluate inverse Jacobian matrix - mapping_fast.df_inv_all(df, dfinv) - - # evaluate transposed inverse Jacobian matrix - linalg.transpose(dfinv, dfinv_t) - # ========================================== - - # ========== field evaluation ============== - span1 = int(eta1 * nel[0]) + pn1 - span2 = int(eta2 * nel[1]) + pn2 - span3 = int(eta3 * nel[2]) + pn3 - - # evaluation of basis functions and derivatives - bsp.basis_funs_and_der(t1, pn1, eta1, span1, l1, r1, b1, d1, der1) - bsp.basis_funs_and_der(t2, pn2, eta2, span2, l2, r2, b2, d2, der2) - bsp.basis_funs_and_der(t3, pn3, eta3, span3, l3, r3, b3, d3, der3) - - # N-splines and D-splines at particle positions - bn1[:] = b1[pn1, :] - bn2[:] = b2[pn2, :] - bn3[:] = b3[pn3, :] - - bd1[:] = b1[pd1, :pn1] * d1[:] - bd2[:] = b2[pd2, :pn2] * d2[:] - bd3[:] = b3[pd3, :pn3] * d3[:] - - # Evaluate G.dot(X_dot(u) at the particle positions - u[0] = eva3.evaluation_kernel_3d( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span1 - 1, - span2, - span3, - nbase_d[0], - nbase_n[1], - nbase_n[2], - u21 * v[1] + u31 * v[2], - ) - u[1] = eva3.evaluation_kernel_3d( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span1, - span2 - 1, - span3, - nbase_n[0], - nbase_d[1], - nbase_n[2], - u22 * v[1] + u32 * v[2], - ) - u[2] = eva3.evaluation_kernel_3d( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span1, - span2, - span3 - 1, - nbase_n[0], - nbase_n[1], - nbase_d[2], - u23 * v[1] + u33 * v[2], - ) - - linalg.matrix_vector(dfinv_t, u, u_cart) - # ========================================== - - # ======== particle pushing ================ - particles[3, ip] -= dt * u_cart[0] / 2 - particles[4, ip] -= dt * u_cart[1] / 2 - particles[5, ip] -= dt * u_cart[2] / 2 - # ========================================== - - # -- removed omp: #$ omp end do - # -- removed omp: #$ omp end parallel - - ierr = 0 diff --git a/src/struphy/pic/tests/test_pic_legacy_files/spline_evaluation_2d.py b/src/struphy/pic/tests/test_pic_legacy_files/spline_evaluation_2d.py deleted file mode 100644 index fdd4485b5..000000000 --- a/src/struphy/pic/tests/test_pic_legacy_files/spline_evaluation_2d.py +++ /dev/null @@ -1,470 +0,0 @@ -# coding: utf-8 - - -""" -Acccelerated functions for point-wise evaluation of tensor product B-splines. - -S(eta1, eta2) = sum_ij c_ij * B_i(eta1) * B_j(eta2) with c_ij in R. - -Possible combinations for tensor product (BB): -(NN) -(dN/deta N) -(N dN/deta) -(DN) -(ND) -(DD) -""" - -from numpy import empty - -import struphy.bsplines.bsplines_kernels as bsp - - -# ============================================================================= -def evaluation_kernel_2d( - p1: "int", - p2: "int", - basis1: "float[:]", - basis2: "float[:]", - span1: "int", - span2: "int", - nbase1: "int", - nbase2: "int", - coeff: "float[:,:]", -): - """Summing non-zero contributions. - - Parameters: - ----------- - p1, p2: int spline degrees - basis1, basis2: double[:] pn+1 values of non-zero basis splines at one point eta_n from 'basis_funs' (n=1,2) - span1, span2: int knot span indices from 'find_span' - nbase1, nbase2: int dimensions of spline spaces - coeff: double[:, :] spline coefficients c_ij - - Returns: - -------- - value: float - Value of B-spline at point (eta1, eta2). - """ - - value = 0.0 - - for il1 in range(p1 + 1): - i1 = (span1 - il1) % nbase1 - for il2 in range(p2 + 1): - i2 = (span2 - il2) % nbase2 - - value += coeff[i1, i2] * basis1[p1 - il1] * basis2[p2 - il2] - - return value - - -# ============================================================================= -def evaluate_n_n( - tn1: "float[:]", - tn2: "float[:]", - pn1: "int", - pn2: "int", - nbase_n1: "int", - nbase_n2: "int", - coeff: "float[:,:]", - eta1: "float", - eta2: "float", -): - """Point-wise evaluation of (NN)-tensor-product spline. - - Parameters: - ----------- - tn1, tn2: double[:] knot vectors - pn1, pn2: int spline degrees - nbase_n1, nbase_n2: int dimensions of univariate spline spaces - coeff: double[:, :] spline coefficients c_ij - eta1, eta2: double point of evaluation - - Returns: - -------- - value: float - Value of (NN)-tensor-product spline at point (eta1, eta2). - """ - - # find knot span indices - span_n1 = bsp.find_span(tn1, pn1, eta1) - span_n2 = bsp.find_span(tn2, pn2, eta2) - - # evaluate non-vanishing basis functions - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - - bl1 = empty(pn1, dtype=float) - bl2 = empty(pn2, dtype=float) - - br1 = empty(pn1, dtype=float) - br2 = empty(pn2, dtype=float) - - bsp.basis_funs(tn1, pn1, eta1, span_n1, bl1, br1, bn1) - bsp.basis_funs(tn2, pn2, eta2, span_n2, bl2, br2, bn2) - - # sum up non-vanishing contributions - value = evaluation_kernel_2d(pn1, pn2, bn1, bn2, span_n1, span_n2, nbase_n1, nbase_n2, coeff) - - return value - - -# ============================================================================= -def evaluate_diffn_n( - tn1: "float[:]", - tn2: "float[:]", - pn1: "int", - pn2: "int", - nbase_n1: "int", - nbase_n2: "int", - coeff: "float[:,:]", - eta1: "float", - eta2: "float", -): - """Point-wise evaluation of (dN/deta N)-tensor-product spline. - - Parameters: - ----------- - tn1, tn2: double[:] knot vectors - pn1, pn2: int spline degrees - nbase_n1, nbase_n2: int dimensions of spline spaces - coeff: double[:, :] spline coefficients c_ij - eta1, eta2: double point of evaluation - - Returns: - -------- - value: float - Value of (dN/deta N)-tensor-product spline at point (eta1, eta2). - """ - - # find knot span indices - span_n1 = bsp.find_span(tn1, pn1, eta1) - span_n2 = bsp.find_span(tn2, pn2, eta2) - - # evaluate non-vanishing basis functions - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - - bl1 = empty(pn1, dtype=float) - bl2 = empty(pn2, dtype=float) - - br1 = empty(pn1, dtype=float) - br2 = empty(pn2, dtype=float) - - bsp.basis_funs_1st_der(tn1, pn1, eta1, span_n1, bl1, br1, bn1) - bsp.basis_funs(tn2, pn2, eta2, span_n2, bl2, br2, bn2) - - # sum up non-vanishing contributions - value = evaluation_kernel_2d(pn1, pn2, bn1, bn2, span_n1, span_n2, nbase_n1, nbase_n2, coeff) - - return value - - -# ============================================================================= -def evaluate_n_diffn( - tn1: "float[:]", - tn2: "float[:]", - pn1: "int", - pn2: "int", - nbase_n1: "int", - nbase_n2: "int", - coeff: "float[:,:]", - eta1: "float", - eta2: "float", -): - """Point-wise evaluation of (N dN/deta)-tensor-product spline. - - Parameters: - ----------- - tn1, tn2: double[:] knot vectors - pn1, pn2: int spline degrees - nbase_n1, nbase_n2: int dimensions of spline spaces - coeff: double[:, :] spline coefficients c_ij - eta1, eta2: double point of evaluation - - Returns: - -------- - value: float - Value of (N dN/deta)-tensor-product spline at point (eta1, eta2). - """ - - # find knot span indices - span_n1 = bsp.find_span(tn1, pn1, eta1) - span_n2 = bsp.find_span(tn2, pn2, eta2) - - # evaluate non-vanishing basis functions - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - - bl1 = empty(pn1, dtype=float) - bl2 = empty(pn2, dtype=float) - - br1 = empty(pn1, dtype=float) - br2 = empty(pn2, dtype=float) - - bsp.basis_funs(tn1, pn1, eta1, span_n1, bl1, br1, bn1) - bsp.basis_funs_1st_der(tn2, pn2, eta2, span_n2, bl2, br2, bn2) - - # sum up non-vanishing contributions - value = evaluation_kernel_2d(pn1, pn2, bn1, bn2, span_n1, span_n2, nbase_n1, nbase_n2, coeff) - - return value - - -# ============================================================================= -def evaluate_d_n( - td1: "float[:]", - tn2: "float[:]", - pd1: "int", - pn2: "int", - nbase_d1: "int", - nbase_n2: "int", - coeff: "float[:,:]", - eta1: "float", - eta2: "float", -): - """Point-wise evaluation of (DN)-tensor-product spline. - - Parameters: - ----------- - td1, tn2: double[:] knot vectors - pd1, pn2: int spline degrees - nbase_d1, nbase_n2: int dimensions of spline spaces - coeff: double[:, :] spline coefficients c_ij - eta1, eta2: double point of evaluation - - Returns: - -------- - value: float - Value of (DN)-tensor-product spline at point (eta1, eta2). - """ - - # find knot span indices - span_d1 = bsp.find_span(td1, pd1, eta1) - span_n2 = bsp.find_span(tn2, pn2, eta2) - - # evaluate non-vanishing basis functions - bd1 = empty(pd1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - - bl1 = empty(pd1, dtype=float) - bl2 = empty(pn2, dtype=float) - - br1 = empty(pd1, dtype=float) - br2 = empty(pn2, dtype=float) - - bsp.basis_funs(td1, pd1, eta1, span_d1, bl1, br1, bd1) - bsp.basis_funs(tn2, pn2, eta2, span_n2, bl2, br2, bn2) - - bsp.scaling(td1, pd1, span_d1, bd1) - - # sum up non-vanishing contributions - value = evaluation_kernel_2d(pd1, pn2, bd1, bn2, span_d1, span_n2, nbase_d1, nbase_n2, coeff) - - return value - - -# ============================================================================= -def evaluate_n_d( - tn1: "float[:]", - td2: "float[:]", - pn1: "int", - pd2: "int", - nbase_n1: "int", - nbase_d2: "int", - coeff: "float[:,:]", - eta1: "float", - eta2: "float", -): - """Point-wise evaluation of (ND)-tensor-product spline. - - Parameters: - ----------- - tn1, td2: double[:] knot vectors - pn1, pd2: int spline degrees - nbase_n1, nbase_d2: int dimensions of spline spaces - coeff: double[:, :] spline coefficients c_ij - eta1, eta2: double point of evaluation - - Returns: - -------- - value: float - Value of (ND)-tensor-product spline at point (eta1, eta2). - """ - - # find knot span indices - span_n1 = bsp.find_span(tn1, pn1, eta1) - span_d2 = bsp.find_span(td2, pd2, eta2) - - # evaluate non-vanishing basis functions - bn1 = empty(pn1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - - bl1 = empty(pn1, dtype=float) - bl2 = empty(pd2, dtype=float) - - br1 = empty(pn1, dtype=float) - br2 = empty(pd2, dtype=float) - - bsp.basis_funs(tn1, pn1, eta1, span_n1, bl1, br1, bn1) - bsp.basis_funs(td2, pd2, eta2, span_d2, bl2, br2, bd2) - - bsp.scaling(td2, pd2, span_d2, bd2) - - # sum up non-vanishing contributions - value = evaluation_kernel_2d(pn1, pd2, bn1, bd2, span_n1, span_d2, nbase_n1, nbase_d2, coeff) - - return value - - -# ============================================================================= -def evaluate_d_d( - td1: "float[:]", - td2: "float[:]", - pd1: "int", - pd2: "int", - nbase_d1: "int", - nbase_d2: "int", - coeff: "float[:,:]", - eta1: "float", - eta2: "float", -): - """Point-wise evaluation of (DD)-tensor-product spline. - - Parameters: - ----------- - td1, td2: double[:] knot vectors - pd1, pd2: int spline degrees - nbase_d1, nbase_d2: int dimensions of spline spaces - coeff: double[:, :] spline coefficients c_ij - eta1, eta2: double point of evaluation - - Returns: - -------- - value: float - Value of (DD)-tensor-product spline at point (eta1, eta2). - """ - - # find knot span indices - span_d1 = bsp.find_span(td1, pd1, eta1) - span_d2 = bsp.find_span(td2, pd2, eta2) - - # evaluate non-vanishing basis functions - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - - bl1 = empty(pd1, dtype=float) - bl2 = empty(pd2, dtype=float) - - br1 = empty(pd1, dtype=float) - br2 = empty(pd2, dtype=float) - - bsp.basis_funs(td1, pd1, eta1, span_d1, bl1, br1, bd1) - bsp.basis_funs(td2, pd2, eta2, span_d2, bl2, br2, bd2) - - bsp.scaling(td1, pd1, span_d1, bd1) - bsp.scaling(td2, pd2, span_d2, bd2) - - # sum up non-vanishing contributions - value = evaluation_kernel_2d(pd1, pd2, bd1, bd2, span_d1, span_d2, nbase_d1, nbase_d2, coeff) - - return value - - -# ============================================================================= -def evaluate_tensor_product( - t1: "float[:]", - t2: "float[:]", - p1: "int", - p2: "int", - nbase_1: "int", - nbase_2: "int", - coeff: "float[:,:]", - eta1: "float[:]", - eta2: "float[:]", - values: "float[:,:]", - kind: "int", -): - """Tensor product evaluation (meshgrid) of tensor product splines (2d). - - Parameters: - ----------- - t1, t2: double[:] knot vectors - p1, p2: int spline degrees - nbase_1, nbase_2: int dimensions of univariate spline spaces - coeff: double[:, :] spline coefficients c_ij - eta1, eta2: double[:] 1d arrays of points of evaluation in respective direction - kind: int which tensor product spline, 0: (NN), 11: (DN), 12: (ND), 2: (DD) - - Returns: - -------- - values: double[:, :] values of spline at points from xp.meshgrid(eta1, eta2, indexing='ij'). - """ - - for i1 in range(len(eta1)): - for i2 in range(len(eta2)): - # V0 - space - if kind == 0: - values[i1, i2] = evaluate_n_n(t1, t2, p1, p2, nbase_1, nbase_2, coeff, eta1[i1], eta2[i2]) - - # V1 - space - elif kind == 11: - values[i1, i2] = evaluate_d_n(t1, t2, p1, p2, nbase_1, nbase_2, coeff, eta1[i1], eta2[i2]) - elif kind == 12: - values[i1, i2] = evaluate_n_d(t1, t2, p1, p2, nbase_1, nbase_2, coeff, eta1[i1], eta2[i2]) - - # V2 - space - elif kind == 2: - values[i1, i2] = evaluate_d_d(t1, t2, p1, p2, nbase_1, nbase_2, coeff, eta1[i1], eta2[i2]) - - -# ============================================================================= -def evaluate_matrix( - t1: "float[:]", - t2: "float[:]", - p1: "int", - p2: "int", - nbase_1: "int", - nbase_2: "int", - coeff: "float[:,:]", - eta1: "float[:,:]", - eta2: "float[:,:]", - n1: "int", - n2: "int", - values: "float[:,:]", - kind: "int", -): - """Matrix evaluation of tensor product splines (2d). - - Parameters: - ----------- - t1, t2: double[:] knot vectors - p1, p2: int spline degrees - nbase_1, nbase_2: int dimensions of univariate spline spaces - coeff: double[:, :] spline coefficients c_ij - eta1, eta2: double[:, :] points of evaluation - n1, n2: int eta1.shape = (n1, n2) - kind: int which tensor product spline, 0: (NN), 11: (DN), 12: (ND), 2: (DD) - - Returns: - -------- - values: double[:, :] values of spline at points (eta1, eta2). - """ - - for i1 in range(n1): - for i2 in range(n2): - # V0 - space - if kind == 0: - values[i1, i2] = evaluate_n_n(t1, t2, p1, p2, nbase_1, nbase_2, coeff, eta1[i1, i2], eta2[i1, i2]) - - # V1 - space - elif kind == 11: - values[i1, i2] = evaluate_d_n(t1, t2, p1, p2, nbase_1, nbase_2, coeff, eta1[i1, i2], eta2[i1, i2]) - elif kind == 12: - values[i1, i2] = evaluate_n_d(t1, t2, p1, p2, nbase_1, nbase_2, coeff, eta1[i1, i2], eta2[i1, i2]) - - # V3 - space - elif kind == 2: - values[i1, i2] = evaluate_d_d(t1, t2, p1, p2, nbase_1, nbase_2, coeff, eta1[i1, i2], eta2[i1, i2]) diff --git a/src/struphy/pic/tests/test_pic_legacy_files/spline_evaluation_3d.py b/src/struphy/pic/tests/test_pic_legacy_files/spline_evaluation_3d.py deleted file mode 100644 index 7923b3966..000000000 --- a/src/struphy/pic/tests/test_pic_legacy_files/spline_evaluation_3d.py +++ /dev/null @@ -1,1443 +0,0 @@ -# coding: utf-8 - - -""" -Acccelerated functions for point-wise evaluation of tensor product B-splines. - -S(eta1, eta2, eta3) = sum_ijk c_ijk * B_i(eta1) * B_j(eta2) * B_k(eta3) with c_ijk in R. - -Possible combinations for tensor product (BBB): -(NNN) -(dN/deta NN) -(N dN/deta N) -(NN dN/deta) -(DNN) -(NDN) -(NND) -(NDD) -(DND) -(DDN) -(DDD) -""" - -from numpy import empty - -import struphy.bsplines.bsplines_kernels as bsp - - -# ============================================================================= -def evaluation_kernel_3d( - p1: "int", - p2: "int", - p3: "int", - basis1: "float[:]", - basis2: "float[:]", - basis3: "float[:]", - span1: "int", - span2: "int", - span3: "int", - nbase1: "int", - nbase2: "int", - nbase3: "int", - coeff: "float[:,:,:]", -): - """Summing non-zero contributions. - - Parameters: - ----------- - p1, p2, p3: int spline degrees - basis1, basis2, basis3: double[:] pn+1 values of non-zero basis splines at one point eta_n from 'basis_funs' (n=1,2,3) - span1, span2, span3: int knot span indices from 'find_span' - nbase1, nbase2, nbase3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - - Returns: - -------- - value: float - Value of B-spline at point (eta1, eta2, eta3). - """ - - value = 0.0 - - for il1 in range(p1 + 1): - i1 = (span1 - il1) % nbase1 - for il2 in range(p2 + 1): - i2 = (span2 - il2) % nbase2 - for il3 in range(p3 + 1): - i3 = (span3 - il3) % nbase3 - - value += coeff[i1, i2, i3] * basis1[p1 - il1] * basis2[p2 - il2] * basis3[p3 - il3] - - return value - - -# ============================================================================= -def evaluate_n_n_n( - tn1: "float[:]", - tn2: "float[:]", - tn3: "float[:]", - pn1: "int", - pn2: "int", - pn3: "int", - nbase_n1: "int", - nbase_n2: "int", - nbase_n3: "int", - coeff: "float[:,:,:]", - eta1: "float", - eta2: "float", - eta3: "float", -): - """Point-wise evaluation of (NNN)-tensor-product spline. - - Parameters: - ----------- - tn1, tn2, tn3: double[:] knot vectors - pn1, pn2, pn3: int spline degrees - nbase_n1, nbase_n2, nbase_n3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double point of evaluation - - Returns: - -------- - value: float - Value of (NNN)-tensor-product spline at point (eta1, eta2, eta3). - """ - - # find knot span indices - span_n1 = bsp.find_span(tn1, pn1, eta1) - span_n2 = bsp.find_span(tn2, pn2, eta2) - span_n3 = bsp.find_span(tn3, pn3, eta3) - - # evaluate non-vanishing basis functions - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - bl1 = empty(pn1, dtype=float) - bl2 = empty(pn2, dtype=float) - bl3 = empty(pn3, dtype=float) - - br1 = empty(pn1, dtype=float) - br2 = empty(pn2, dtype=float) - br3 = empty(pn3, dtype=float) - - bsp.basis_funs(tn1, pn1, eta1, span_n1, bl1, br1, bn1) - bsp.basis_funs(tn2, pn2, eta2, span_n2, bl2, br2, bn2) - bsp.basis_funs(tn3, pn3, eta3, span_n3, bl3, br3, bn3) - - # sum up non-vanishing contributions - value = evaluation_kernel_3d( - pn1, - pn2, - pn3, - bn1, - bn2, - bn3, - span_n1, - span_n2, - span_n3, - nbase_n1, - nbase_n2, - nbase_n3, - coeff, - ) - - return value - - -# ============================================================================= -def evaluate_diffn_n_n( - tn1: "float[:]", - tn2: "float[:]", - tn3: "float[:]", - pn1: "int", - pn2: "int", - pn3: "int", - nbase_n1: "int", - nbase_n2: "int", - nbase_n3: "int", - coeff: "float[:,:,:]", - eta1: "float", - eta2: "float", - eta3: "float", -): - """Point-wise evaluation of (dN/deta NN)-tensor-product spline. - - Parameters: - ----------- - tn1, tn2, tn3: double[:] knot vectors - pn1, pn2, pn3: int spline degrees - nbase_n1, nbase_n2, nbase_n3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double point of evaluation - - Returns: - -------- - value: float - Value of (dN/deta NN)-tensor-product spline at point (eta1, eta2, eta3). - """ - - # find knot span indices - span_n1 = bsp.find_span(tn1, pn1, eta1) - span_n2 = bsp.find_span(tn2, pn2, eta2) - span_n3 = bsp.find_span(tn3, pn3, eta3) - - # evaluate non-vanishing basis functions - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - bl1 = empty(pn1, dtype=float) - bl2 = empty(pn2, dtype=float) - bl3 = empty(pn3, dtype=float) - - br1 = empty(pn1, dtype=float) - br2 = empty(pn2, dtype=float) - br3 = empty(pn3, dtype=float) - - bsp.basis_funs_1st_der(tn1, pn1, eta1, span_n1, bl1, br1, bn1) - bsp.basis_funs(tn2, pn2, eta2, span_n2, bl2, br2, bn2) - bsp.basis_funs(tn3, pn3, eta3, span_n3, bl3, br3, bn3) - - # sum up non-vanishing contributions - value = evaluation_kernel_3d( - pn1, - pn2, - pn3, - bn1, - bn2, - bn3, - span_n1, - span_n2, - span_n3, - nbase_n1, - nbase_n2, - nbase_n3, - coeff, - ) - - return value - - -# ============================================================================= -def evaluate_n_diffn_n( - tn1: "float[:]", - tn2: "float[:]", - tn3: "float[:]", - pn1: "int", - pn2: "int", - pn3: "int", - nbase_n1: "int", - nbase_n2: "int", - nbase_n3: "int", - coeff: "float[:,:,:]", - eta1: "float", - eta2: "float", - eta3: "float", -): - """Point-wise evaluation of (N dN/deta N)-tensor-product spline. - - Parameters: - ----------- - tn1, tn2, tn3: double[:] knot vectors - pn1, pn2, pn3: int spline degrees - nbase_n1, nbase_n2, nbase_n3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double point of evaluation - - Returns: - -------- - value: float - Value of (N dN/deta N)-tensor-product spline at point (eta1, eta2, eta3). - """ - - # find knot span indices - span_n1 = bsp.find_span(tn1, pn1, eta1) - span_n2 = bsp.find_span(tn2, pn2, eta2) - span_n3 = bsp.find_span(tn3, pn3, eta3) - - # evaluate non-vanishing basis functions - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - bl1 = empty(pn1, dtype=float) - bl2 = empty(pn2, dtype=float) - bl3 = empty(pn3, dtype=float) - - br1 = empty(pn1, dtype=float) - br2 = empty(pn2, dtype=float) - br3 = empty(pn3, dtype=float) - - bsp.basis_funs(tn1, pn1, eta1, span_n1, bl1, br1, bn1) - bsp.basis_funs_1st_der(tn2, pn2, eta2, span_n2, bl2, br2, bn2) - bsp.basis_funs(tn3, pn3, eta3, span_n3, bl3, br3, bn3) - - # sum up non-vanishing contributions - value = evaluation_kernel_3d( - pn1, - pn2, - pn3, - bn1, - bn2, - bn3, - span_n1, - span_n2, - span_n3, - nbase_n1, - nbase_n2, - nbase_n3, - coeff, - ) - - return value - - -# ============================================================================= -def evaluate_n_n_diffn( - tn1: "float[:]", - tn2: "float[:]", - tn3: "float[:]", - pn1: "int", - pn2: "int", - pn3: "int", - nbase_n1: "int", - nbase_n2: "int", - nbase_n3: "int", - coeff: "float[:,:,:]", - eta1: "float", - eta2: "float", - eta3: "float", -): - """Point-wise evaluation of (NN dN/deta)-tensor-product spline. - - Parameters: - ----------- - tn1, tn2, tn3: double[:] knot vectors - pn1, pn2, pn3: int spline degrees - nbase_n1, nbase_n2, nbase_n3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double point of evaluation - - Returns: - -------- - value: float - Value of (NN dN/deta)-tensor-product spline at point (eta1, eta2, eta3). - """ - - # find knot span indices - span_n1 = bsp.find_span(tn1, pn1, eta1) - span_n2 = bsp.find_span(tn2, pn2, eta2) - span_n3 = bsp.find_span(tn3, pn3, eta3) - - # evaluate non-vanishing basis functions - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - bl1 = empty(pn1, dtype=float) - bl2 = empty(pn2, dtype=float) - bl3 = empty(pn3, dtype=float) - - br1 = empty(pn1, dtype=float) - br2 = empty(pn2, dtype=float) - br3 = empty(pn3, dtype=float) - - bsp.basis_funs(tn1, pn1, eta1, span_n1, bl1, br1, bn1) - bsp.basis_funs(tn2, pn2, eta2, span_n2, bl2, br2, bn2) - bsp.basis_funs_1st_der(tn3, pn3, eta3, span_n3, bl3, br3, bn3) - - # sum up non-vanishing contributions - value = evaluation_kernel_3d( - pn1, - pn2, - pn3, - bn1, - bn2, - bn3, - span_n1, - span_n2, - span_n3, - nbase_n1, - nbase_n2, - nbase_n3, - coeff, - ) - - return value - - -# ============================================================================= -def evaluate_d_n_n( - td1: "float[:]", - tn2: "float[:]", - tn3: "float[:]", - pd1: "int", - pn2: "int", - pn3: "int", - nbase_d1: "int", - nbase_n2: "int", - nbase_n3: "int", - coeff: "float[:,:,:]", - eta1: "float", - eta2: "float", - eta3: "float", -): - """Point-wise evaluation of (DNN)-tensor-product spline. - - Parameters: - ----------- - td1, tn2, tn3: double[:] knot vectors - pd1, pn2, pn3: int spline degrees - nbase_d1, nbase_n2, nbase_n3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double point of evaluation - - Returns: - -------- - value: float - Value of (DNN)-tensor-product spline at point (eta1, eta2, eta3). - """ - - # find knot span indices - span_d1 = bsp.find_span(td1, pd1, eta1) - span_n2 = bsp.find_span(tn2, pn2, eta2) - span_n3 = bsp.find_span(tn3, pn3, eta3) - - # evaluate non-vanishing basis functions - bd1 = empty(pd1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - bl1 = empty(pd1, dtype=float) - bl2 = empty(pn2, dtype=float) - bl3 = empty(pn3, dtype=float) - - br1 = empty(pd1, dtype=float) - br2 = empty(pn2, dtype=float) - br3 = empty(pn3, dtype=float) - - bsp.basis_funs(td1, pd1, eta1, span_d1, bl1, br1, bd1) - bsp.basis_funs(tn2, pn2, eta2, span_n2, bl2, br2, bn2) - bsp.basis_funs(tn3, pn3, eta3, span_n3, bl3, br3, bn3) - - bsp.scaling(td1, pd1, span_d1, bd1) - - # sum up non-vanishing contributions - value = evaluation_kernel_3d( - pd1, - pn2, - pn3, - bd1, - bn2, - bn3, - span_d1, - span_n2, - span_n3, - nbase_d1, - nbase_n2, - nbase_n3, - coeff, - ) - - return value - - -# ============================================================================= -def evaluate_n_d_n( - tn1: "float[:]", - td2: "float[:]", - tn3: "float[:]", - pn1: "int", - pd2: "int", - pn3: "int", - nbase_n1: "int", - nbase_d2: "int", - nbase_n3: "int", - coeff: "float[:,:,:]", - eta1: "float", - eta2: "float", - eta3: "float", -): - """Point-wise evaluation of (NDN)-tensor-product spline. - - Parameters: - ----------- - tn1, td2, tn3: double[:] knot vectors - pn1, pd2, pn3: int spline degrees - nbase_n1, nbase_d2, nbase_n3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double point of evaluation - - Returns: - -------- - value: float - Value of (NDN)-tensor-product spline at point (eta1, eta2, eta3). - """ - - # find knot span indices - span_n1 = bsp.find_span(tn1, pn1, eta1) - span_d2 = bsp.find_span(td2, pd2, eta2) - span_n3 = bsp.find_span(tn3, pn3, eta3) - - # evaluate non-vanishing basis functions - bn1 = empty(pn1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - bl1 = empty(pn1, dtype=float) - bl2 = empty(pd2, dtype=float) - bl3 = empty(pn3, dtype=float) - - br1 = empty(pn1, dtype=float) - br2 = empty(pd2, dtype=float) - br3 = empty(pn3, dtype=float) - - bsp.basis_funs(tn1, pn1, eta1, span_n1, bl1, br1, bn1) - bsp.basis_funs(td2, pd2, eta2, span_d2, bl2, br2, bd2) - bsp.basis_funs(tn3, pn3, eta3, span_n3, bl3, br3, bn3) - - bsp.scaling(td2, pd2, span_d2, bd2) - - # sum up non-vanishing contributions - value = evaluation_kernel_3d( - pn1, - pd2, - pn3, - bn1, - bd2, - bn3, - span_n1, - span_d2, - span_n3, - nbase_n1, - nbase_d2, - nbase_n3, - coeff, - ) - - return value - - -# ============================================================================= -def evaluate_n_n_d( - tn1: "float[:]", - tn2: "float[:]", - td3: "float[:]", - pn1: "int", - pn2: "int", - pd3: "int", - nbase_n1: "int", - nbase_n2: "int", - nbase_d3: "int", - coeff: "float[:,:,:]", - eta1: "float", - eta2: "float", - eta3: "float", -): - """Point-wise evaluation of (NND)-tensor-product spline. - - Parameters: - ----------- - tn1, tn2, td3: double[:] knot vectors - pn1, pn2, pd3: int spline degrees - nbase_n1, nbase_n2, nbase_d3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double point of evaluation - - Returns: - -------- - value: float - Value of (NND)-tensor-product spline at point (eta1, eta2, eta3). - """ - - # find knot span indices - span_n1 = bsp.find_span(tn1, pn1, eta1) - span_n2 = bsp.find_span(tn2, pn2, eta2) - span_d3 = bsp.find_span(td3, pd3, eta3) - - # evaluate non-vanishing basis functions - bn1 = empty(pn1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - bl1 = empty(pn1, dtype=float) - bl2 = empty(pn2, dtype=float) - bl3 = empty(pd3, dtype=float) - - br1 = empty(pn1, dtype=float) - br2 = empty(pn2, dtype=float) - br3 = empty(pd3, dtype=float) - - bsp.basis_funs(tn1, pn1, eta1, span_n1, bl1, br1, bn1) - bsp.basis_funs(tn2, pn2, eta2, span_n2, bl2, br2, bn2) - bsp.basis_funs(td3, pd3, eta3, span_d3, bl3, br3, bd3) - - bsp.scaling(td3, pd3, span_d3, bd3) - - # sum up non-vanishing contributions - value = evaluation_kernel_3d( - pn1, - pn2, - pd3, - bn1, - bn2, - bd3, - span_n1, - span_n2, - span_d3, - nbase_n1, - nbase_n2, - nbase_d3, - coeff, - ) - - return value - - -# ============================================================================= -def evaluate_n_d_d( - tn1: "float[:]", - td2: "float[:]", - td3: "float[:]", - pn1: "int", - pd2: "int", - pd3: "int", - nbase_n1: "int", - nbase_d2: "int", - nbase_d3: "int", - coeff: "float[:,:,:]", - eta1: "float", - eta2: "float", - eta3: "float", -): - """Point-wise evaluation of (NDD)-tensor-product spline. - - Parameters: - ----------- - tn1, td2, td3: double[:] knot vectors - pn1, pd2, pd3: int spline degrees - nbase_n1, nbase_d2, nbase_d3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double point of evaluation - - Returns: - -------- - value: float - Value of (NDD)-tensor-product spline at point (eta1, eta2, eta3). - """ - - # find knot span indices - span_n1 = bsp.find_span(tn1, pn1, eta1) - span_d2 = bsp.find_span(td2, pd2, eta2) - span_d3 = bsp.find_span(td3, pd3, eta3) - - # evaluate non-vanishing basis functions - bn1 = empty(pn1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - bl1 = empty(pn1, dtype=float) - bl2 = empty(pd2, dtype=float) - bl3 = empty(pd3, dtype=float) - - br1 = empty(pn1, dtype=float) - br2 = empty(pd2, dtype=float) - br3 = empty(pd3, dtype=float) - - bsp.basis_funs(tn1, pn1, eta1, span_n1, bl1, br1, bn1) - bsp.basis_funs(td2, pd2, eta2, span_d2, bl2, br2, bd2) - bsp.basis_funs(td3, pd3, eta3, span_d3, bl3, br3, bd3) - - bsp.scaling(td2, pd2, span_d2, bd2) - bsp.scaling(td3, pd3, span_d3, bd3) - - # sum up non-vanishing contributions - value = evaluation_kernel_3d( - pn1, - pd2, - pd3, - bn1, - bd2, - bd3, - span_n1, - span_d2, - span_d3, - nbase_n1, - nbase_d2, - nbase_d3, - coeff, - ) - - return value - - -# ============================================================================= -def evaluate_d_n_d( - td1: "float[:]", - tn2: "float[:]", - td3: "float[:]", - pd1: "int", - pn2: "int", - pd3: "int", - nbase_d1: "int", - nbase_n2: "int", - nbase_d3: "int", - coeff: "float[:,:,:]", - eta1: "float", - eta2: "float", - eta3: "float", -): - """Point-wise evaluation of (DND)-tensor-product spline. - - Parameters: - ----------- - td1, tn2, td3: double[:] knot vectors - pd1, pn2, pd3: int spline degrees - nbase_d1, nbase_n2, nbase_d3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double point of evaluation - - Returns: - -------- - value: float - Value of (DND)-tensor-product spline at point (eta1, eta2, eta3). - """ - - # find knot span indices - span_d1 = bsp.find_span(td1, pd1, eta1) - span_n2 = bsp.find_span(tn2, pn2, eta2) - span_d3 = bsp.find_span(td3, pd3, eta3) - - # evaluate non-vanishing basis functions - bd1 = empty(pd1 + 1, dtype=float) - bn2 = empty(pn2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - bl1 = empty(pd1, dtype=float) - bl2 = empty(pn2, dtype=float) - bl3 = empty(pd3, dtype=float) - - br1 = empty(pd1, dtype=float) - br2 = empty(pn2, dtype=float) - br3 = empty(pd3, dtype=float) - - bsp.basis_funs(td1, pd1, eta1, span_d1, bl1, br1, bd1) - bsp.basis_funs(tn2, pn2, eta2, span_n2, bl2, br2, bn2) - bsp.basis_funs(td3, pd3, eta3, span_d3, bl3, br3, bd3) - - bsp.scaling(td1, pd1, span_d1, bd1) - bsp.scaling(td3, pd3, span_d3, bd3) - - # sum up non-vanishing contributions - value = evaluation_kernel_3d( - pd1, - pn2, - pd3, - bd1, - bn2, - bd3, - span_d1, - span_n2, - span_d3, - nbase_d1, - nbase_n2, - nbase_d3, - coeff, - ) - - return value - - -# ============================================================================= -def evaluate_d_d_n( - td1: "float[:]", - td2: "float[:]", - tn3: "float[:]", - pd1: "int", - pd2: "int", - pn3: "int", - nbase_d1: "int", - nbase_d2: "int", - nbase_n3: "int", - coeff: "float[:,:,:]", - eta1: "float", - eta2: "float", - eta3: "float", -): - """Point-wise evaluation of (DDN)-tensor-product spline. - - Parameters: - ----------- - td1, td2, tn3: double[:] knot vectors - pd1, pd2, pn3: int spline degrees - nbase_d1, nbase_d2, nbase_n3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double point of evaluation - - Returns: - -------- - value: float - Value of (DDN)-tensor-product spline at point (eta1, eta2, eta3). - """ - - # find knot span indices - span_d1 = bsp.find_span(td1, pd1, eta1) - span_d2 = bsp.find_span(td2, pd2, eta2) - span_n3 = bsp.find_span(tn3, pn3, eta3) - - # evaluate non-vanishing basis functions - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bn3 = empty(pn3 + 1, dtype=float) - - bl1 = empty(pd1, dtype=float) - bl2 = empty(pd2, dtype=float) - bl3 = empty(pn3, dtype=float) - - br1 = empty(pd1, dtype=float) - br2 = empty(pd2, dtype=float) - br3 = empty(pn3, dtype=float) - - bsp.basis_funs(td1, pd1, eta1, span_d1, bl1, br1, bd1) - bsp.basis_funs(td2, pd2, eta2, span_d2, bl2, br2, bd2) - bsp.basis_funs(tn3, pn3, eta3, span_n3, bl3, br3, bn3) - - bsp.scaling(td1, pd1, span_d1, bd1) - bsp.scaling(td2, pd2, span_d2, bd2) - - # sum up non-vanishing contributions - value = evaluation_kernel_3d( - pd1, - pd2, - pn3, - bd1, - bd2, - bn3, - span_d1, - span_d2, - span_n3, - nbase_d1, - nbase_d2, - nbase_n3, - coeff, - ) - - return value - - -# ============================================================================= -def evaluate_d_d_d( - td1: "float[:]", - td2: "float[:]", - td3: "float[:]", - pd1: "int", - pd2: "int", - pd3: "int", - nbase_d1: "int", - nbase_d2: "int", - nbase_d3: "int", - coeff: "float[:,:,:]", - eta1: "float", - eta2: "float", - eta3: "float", -): - """Point-wise evaluation of (DDD)-tensor-product spline. - - Parameters: - ----------- - td1, td2, td3: double[:] knot vectors - pd1, pd2, pd3: int spline degrees - nbase_d1, nbase_d2, nbase_d3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double point of evaluation - - Returns: - -------- - value: float - Value of (DDD)-tensor-product spline at point (eta1, eta2, eta3). - """ - - # find knot span indices - span_d1 = bsp.find_span(td1, pd1, eta1) - span_d2 = bsp.find_span(td2, pd2, eta2) - span_d3 = bsp.find_span(td3, pd3, eta3) - - # evaluate non-vanishing basis functions - bd1 = empty(pd1 + 1, dtype=float) - bd2 = empty(pd2 + 1, dtype=float) - bd3 = empty(pd3 + 1, dtype=float) - - bl1 = empty(pd1, dtype=float) - bl2 = empty(pd2, dtype=float) - bl3 = empty(pd3, dtype=float) - - br1 = empty(pd1, dtype=float) - br2 = empty(pd2, dtype=float) - br3 = empty(pd3, dtype=float) - - bsp.basis_funs(td1, pd1, eta1, span_d1, bl1, br1, bd1) - bsp.basis_funs(td2, pd2, eta2, span_d2, bl2, br2, bd2) - bsp.basis_funs(td3, pd3, eta3, span_d3, bl3, br3, bd3) - - bsp.scaling(td1, pd1, span_d1, bd1) - bsp.scaling(td2, pd2, span_d2, bd2) - bsp.scaling(td3, pd3, span_d3, bd3) - - # sum up non-vanishing contributions - value = evaluation_kernel_3d( - pd1, - pd2, - pd3, - bd1, - bd2, - bd3, - span_d1, - span_d2, - span_d3, - nbase_d1, - nbase_d2, - nbase_d3, - coeff, - ) - - return value - - -# ============================================================================= -def evaluate_tensor_product( - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - p1: "int", - p2: "int", - p3: "int", - nbase_1: "int", - nbase_2: "int", - nbase_3: "int", - coeff: "float[:,:,:]", - eta1: "float[:]", - eta2: "float[:]", - eta3: "float[:]", - values: "float[:,:,:]", - kind: "int", -): - """Tensor product evaluation (meshgrid) of tensor product splines (3d). - - Parameters: - ----------- - t1, t2, t3: double[:] knot vectors - p1, p2, p3: int spline degrees - nbase_1, nbase_2, nbase_3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double[:] 1d arrays of points of evaluation in respective direction - kind: int which tensor product spline, - 0: (NNN), 11: (DNN), 12: (NDN), 13: (NND), - 21: (NDD), 22: (DND), 23: (DDN), 3: (DDD) - - Returns: - -------- - values: double[:, :, :] values of spline at points from - xp.meshgrid(eta1, eta2, eta3, indexing='ij'). - """ - - for i1 in range(len(eta1)): - for i2 in range(len(eta2)): - for i3 in range(len(eta3)): - # V0 - space - if kind == 0: - values[i1, i2, i3] = evaluate_n_n_n( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1], - eta2[i2], - eta3[i3], - ) - - # V1 - space - elif kind == 11: - values[i1, i2, i3] = evaluate_d_n_n( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1], - eta2[i2], - eta3[i3], - ) - elif kind == 12: - values[i1, i2, i3] = evaluate_n_d_n( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1], - eta2[i2], - eta3[i3], - ) - elif kind == 13: - values[i1, i2, i3] = evaluate_n_n_d( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1], - eta2[i2], - eta3[i3], - ) - - # V2 - space - elif kind == 21: - values[i1, i2, i3] = evaluate_n_d_d( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1], - eta2[i2], - eta3[i3], - ) - elif kind == 22: - values[i1, i2, i3] = evaluate_d_n_d( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1], - eta2[i2], - eta3[i3], - ) - elif kind == 23: - values[i1, i2, i3] = evaluate_d_d_n( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1], - eta2[i2], - eta3[i3], - ) - - # V3 - space - elif kind == 3: - values[i1, i2, i3] = evaluate_d_d_d( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1], - eta2[i2], - eta3[i3], - ) - - -# ============================================================================= -def evaluate_matrix( - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - p1: "int", - p2: "int", - p3: "int", - nbase_1: "int", - nbase_2: "int", - nbase_3: "int", - coeff: "float[:,:,:]", - eta1: "float[:,:,:]", - eta2: "float[:,:,:]", - eta3: "float[:,:,:]", - n1: "int", - n2: "int", - n3: "int", - values: "float[:,:,:]", - kind: "int", -): - """Matrix evaluation of tensor product splines (3d). - - Parameters: - ----------- - t1, t2, t3: double[:] knot vectors - p1, p2, p3: int spline degrees - nbase_1, nbase_2, nbase_3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double[:, :, :] points of evaluation - n1, n2, n3: int eta1.shape = (n1, n2, n3) - kind: int which tensor product spline, - 0: (NNN), 11: (DNN), 12: (NDN), 13: (NND), - 21: (NDD), 22: (DND), 23: (DDN), 3: (DDD) - - Returns: - -------- - values: double[:, :, :] values of spline at points (eta1, eta2, eta3). - """ - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - # V0 - space - if kind == 0: - values[i1, i2, i3] = evaluate_n_n_n( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, i2, i3], - eta2[i1, i2, i3], - eta3[i1, i2, i3], - ) - - # V1 - space - elif kind == 11: - values[i1, i2, i3] = evaluate_d_n_n( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, i2, i3], - eta2[i1, i2, i3], - eta3[i1, i2, i3], - ) - elif kind == 12: - values[i1, i2, i3] = evaluate_n_d_n( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, i2, i3], - eta2[i1, i2, i3], - eta3[i1, i2, i3], - ) - elif kind == 13: - values[i1, i2, i3] = evaluate_n_n_d( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, i2, i3], - eta2[i1, i2, i3], - eta3[i1, i2, i3], - ) - - # V2 - space - elif kind == 21: - values[i1, i2, i3] = evaluate_n_d_d( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, i2, i3], - eta2[i1, i2, i3], - eta3[i1, i2, i3], - ) - elif kind == 22: - values[i1, i2, i3] = evaluate_d_n_d( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, i2, i3], - eta2[i1, i2, i3], - eta3[i1, i2, i3], - ) - elif kind == 23: - values[i1, i2, i3] = evaluate_d_d_n( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, i2, i3], - eta2[i1, i2, i3], - eta3[i1, i2, i3], - ) - - # V3 - space - elif kind == 3: - values[i1, i2, i3] = evaluate_d_d_d( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, i2, i3], - eta2[i1, i2, i3], - eta3[i1, i2, i3], - ) - - -# ============================================================================= -def evaluate_sparse( - t1: "float[:]", - t2: "float[:]", - t3: "float[:]", - p1: "int", - p2: "int", - p3: "int", - nbase_1: "int", - nbase_2: "int", - nbase_3: "int", - coeff: "float[:,:,:]", - eta1: "float[:,:,:]", - eta2: "float[:,:,:]", - eta3: "float[:,:,:]", - n1: "int", - n2: "int", - n3: "int", - values: "float[:,:,:]", - kind: "int", -): - """Evaluation of tensor product splines (3d) at point sets obtained from sparse meshgrid. - - Sparse meshgrid output has shape (n1, 1, 1), (1, n2, 1) and (1, 1, n3) - - Parameters: - ----------- - t1, t2, t3: double[:] knot vectors - p1, p2, p3: int spline degrees - nbase_1, nbase_2, nbase_3: int dimensions of univariate spline spaces - coeff: double[:, :, :] spline coefficients c_ijk - eta1, eta2, eta3: double[:, :, :] points of evaluation - n1, n2, n3: int n1 = eta1.shape[0], n2 = eta2.shape[1], n3 = eta3.shape[2] - kind: int which tensor product spline, - 0: (NNN), 11: (DNN), 12: (NDN), 13: (NND), - 21: (NDD), 22: (DND), 23: (DDN), 3: (DDD) - - Returns: - -------- - values: double[:, :, :] values of spline at points (eta1, eta2, eta3). - """ - - for i1 in range(n1): - for i2 in range(n2): - for i3 in range(n3): - # V0 - space - if kind == 0: - values[i1, i2, i3] = evaluate_n_n_n( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, 0, 0], - eta2[0, i2, 0], - eta3[0, 0, i3], - ) - - # V1 - space - elif kind == 11: - values[i1, i2, i3] = evaluate_d_n_n( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, 0, 0], - eta2[0, i2, 0], - eta3[0, 0, i3], - ) - elif kind == 12: - values[i1, i2, i3] = evaluate_n_d_n( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, 0, 0], - eta2[0, i2, 0], - eta3[0, 0, i3], - ) - elif kind == 13: - values[i1, i2, i3] = evaluate_n_n_d( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, 0, 0], - eta2[0, i2, 0], - eta3[0, 0, i3], - ) - - # V2 - space - elif kind == 21: - values[i1, i2, i3] = evaluate_n_d_d( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, 0, 0], - eta2[0, i2, 0], - eta3[0, 0, i3], - ) - elif kind == 22: - values[i1, i2, i3] = evaluate_d_n_d( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, 0, 0], - eta2[0, i2, 0], - eta3[0, 0, i3], - ) - elif kind == 23: - values[i1, i2, i3] = evaluate_d_d_n( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, 0, 0], - eta2[0, i2, 0], - eta3[0, 0, i3], - ) - - # V3 - space - elif kind == 3: - values[i1, i2, i3] = evaluate_d_d_d( - t1, - t2, - t3, - p1, - p2, - p3, - nbase_1, - nbase_2, - nbase_3, - coeff, - eta1[i1, 0, 0], - eta2[0, i2, 0], - eta3[0, 0, i3], - ) diff --git a/src/struphy/pic/tests/test_pushers.py b/src/struphy/pic/tests/test_pushers.py index 321ab9aba..b06190c2b 100644 --- a/src/struphy/pic/tests/test_pushers.py +++ b/src/struphy/pic/tests/test_pushers.py @@ -27,14 +27,13 @@ def test_push_vxb_analytic(Nel, p, spl_kind, mapping, show_plots=False): import cunumpy as xp from psydac.ddm.mpi import mpi as MPI - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.psydac_derham import Derham from struphy.feec.utilities import create_equal_random_arrays from struphy.geometry import domains from struphy.pic.particles import Particles6D from struphy.pic.pushing import pusher_kernels from struphy.pic.pushing.pusher import Pusher as Pusher_psy - from struphy.pic.tests.test_pic_legacy_files.pusher import Pusher as Pusher_str from struphy.pic.utilities import BoundaryParameters, LoadingParameters, WeightsParameters comm = MPI.COMM_WORLD @@ -45,7 +44,7 @@ def test_push_vxb_analytic(Nel, p, spl_kind, mapping, show_plots=False): domain_class = getattr(domains, mapping[0]) domain = domain_class(**mapping[1]) - # discrete Derham sequence (psydac and legacy struphy) + # discrete Derham sequence (psydac) derham = Derham(Nel, p, spl_kind, comm=comm) domain_array = derham.domain_array @@ -79,39 +78,18 @@ def test_push_vxb_analytic(Nel, p, spl_kind, mapping, show_plots=False): if show_plots: particles.show_physical() - # make copy of markers (legacy struphy uses transposed markers!) - markers_str = particles.markers.copy().T - - # create random FEM coefficients for magnetic field - b0_eq_str, b0_eq_psy = create_equal_random_arrays( - derham.Vh_fem["0"], - seed=1234, - flattened=True, - ) - b2_eq_str, b2_eq_psy = create_equal_random_arrays( + _, b2_eq_psy = create_equal_random_arrays( derham.Vh_fem["2"], seed=2345, flattened=True, ) - b2_str, b2_psy = create_equal_random_arrays( + _, b2_psy = create_equal_random_arrays( derham.Vh_fem["2"], seed=3456, flattened=True, ) - # create legacy struphy pusher and psydac based pusher - pusher_str = Pusher_str( - domain, - space, - space.extract_0( - b0_eq_str, - ), - space.extract_2(b2_eq_str), - basis_u=2, - bc_pos=0, - ) - pusher_psy = Pusher_psy( particles, Pyccelkernel(pusher_kernels.push_vxb_analytic), @@ -125,19 +103,11 @@ def test_push_vxb_analytic(Nel, p, spl_kind, mapping, show_plots=False): alpha_in_kernel=1.0, ) - # compare if markers are the same BEFORE push - assert xp.allclose(particles.markers, markers_str.T) - # push markers dt = 0.1 - pusher_str.push_step5(markers_str, dt, b2_str) - pusher_psy(dt) - # compare if markers are the same AFTER push - assert xp.allclose(particles.markers[:, :6], markers_str.T[:, :6]) - @pytest.mark.parametrize("Nel", [[8, 9, 5], [7, 8, 9]]) @pytest.mark.parametrize("p", [[2, 3, 1], [1, 2, 3]]) @@ -163,14 +133,13 @@ def test_push_bxu_Hdiv(Nel, p, spl_kind, mapping, show_plots=False): import cunumpy as xp from psydac.ddm.mpi import mpi as MPI - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.psydac_derham import Derham from struphy.feec.utilities import create_equal_random_arrays from struphy.geometry import domains from struphy.pic.particles import Particles6D from struphy.pic.pushing import pusher_kernels from struphy.pic.pushing.pusher import Pusher as Pusher_psy - from struphy.pic.tests.test_pic_legacy_files.pusher import Pusher as Pusher_str from struphy.pic.utilities import BoundaryParameters, LoadingParameters, WeightsParameters comm = MPI.COMM_WORLD @@ -181,7 +150,7 @@ def test_push_bxu_Hdiv(Nel, p, spl_kind, mapping, show_plots=False): domain_class = getattr(domains, mapping[0]) domain = domain_class(**mapping[1]) - # discrete Derham sequence (psydac and legacy struphy) + # discrete Derham sequence (psydac) derham = Derham(Nel, p, spl_kind, comm=comm) domain_array = derham.domain_array @@ -215,46 +184,24 @@ def test_push_bxu_Hdiv(Nel, p, spl_kind, mapping, show_plots=False): if show_plots: particles.show_physical() - # make copy of markers (legacy struphy uses transposed markers!) - markers_str = particles.markers.copy().T - # create random FEM coefficients for magnetic field and velocity field - b0_eq_str, b0_eq_psy = create_equal_random_arrays( - derham.Vh_fem["0"], - seed=1234, - flattened=True, - ) - b2_eq_str, b2_eq_psy = create_equal_random_arrays( + _, b2_eq_psy = create_equal_random_arrays( derham.Vh_fem["2"], seed=2345, flattened=True, ) - b2_str, b2_psy = create_equal_random_arrays( + _, b2_psy = create_equal_random_arrays( derham.Vh_fem["2"], seed=3456, flattened=True, ) - u2_str, u2_psy = create_equal_random_arrays( + _, u2_psy = create_equal_random_arrays( derham.Vh_fem["2"], seed=4567, flattened=True, ) - # create legacy struphy pusher and psydac based pusher - pusher_str = Pusher_str( - domain, - space, - space.extract_0( - b0_eq_str, - ), - space.extract_2(b2_eq_str), - basis_u=2, - bc_pos=0, - ) - mu0_str = xp.zeros(markers_str.shape[1], dtype=float) - pow_str = xp.zeros(markers_str.shape[1], dtype=float) - pusher_psy = Pusher_psy( particles, Pyccelkernel(pusher_kernels.push_bxu_Hdiv), @@ -272,19 +219,11 @@ def test_push_bxu_Hdiv(Nel, p, spl_kind, mapping, show_plots=False): alpha_in_kernel=1.0, ) - # compare if markers are the same BEFORE push - assert xp.allclose(particles.markers, markers_str.T) - # push markers dt = 0.1 - pusher_str.push_step3(markers_str, dt, b2_str, u2_str, mu0_str, pow_str) - pusher_psy(dt) - # compare if markers are the same AFTER push - assert xp.allclose(particles.markers[:, :6], markers_str.T[:, :6]) - @pytest.mark.parametrize("Nel", [[8, 9, 5], [7, 8, 9]]) @pytest.mark.parametrize("p", [[2, 3, 1], [1, 2, 3]]) @@ -310,14 +249,13 @@ def test_push_bxu_Hcurl(Nel, p, spl_kind, mapping, show_plots=False): import cunumpy as xp from psydac.ddm.mpi import mpi as MPI - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.psydac_derham import Derham from struphy.feec.utilities import create_equal_random_arrays from struphy.geometry import domains from struphy.pic.particles import Particles6D from struphy.pic.pushing import pusher_kernels from struphy.pic.pushing.pusher import Pusher as Pusher_psy - from struphy.pic.tests.test_pic_legacy_files.pusher import Pusher as Pusher_str from struphy.pic.utilities import BoundaryParameters, LoadingParameters, WeightsParameters comm = MPI.COMM_WORLD @@ -328,7 +266,7 @@ def test_push_bxu_Hcurl(Nel, p, spl_kind, mapping, show_plots=False): domain_class = getattr(domains, mapping[0]) domain = domain_class(**mapping[1]) - # discrete Derham sequence (psydac and legacy struphy) + # discrete Derham sequence (psydac) derham = Derham(Nel, p, spl_kind, comm=comm) domain_array = derham.domain_array @@ -362,46 +300,24 @@ def test_push_bxu_Hcurl(Nel, p, spl_kind, mapping, show_plots=False): if show_plots: particles.show_physical() - # make copy of markers (legacy struphy uses transposed markers!) - markers_str = particles.markers.copy().T - # create random FEM coefficients for magnetic field - b0_eq_str, b0_eq_psy = create_equal_random_arrays( - derham.Vh_fem["0"], - seed=1234, - flattened=True, - ) - b2_eq_str, b2_eq_psy = create_equal_random_arrays( + _, b2_eq_psy = create_equal_random_arrays( derham.Vh_fem["2"], seed=2345, flattened=True, ) - b2_str, b2_psy = create_equal_random_arrays( + _, b2_psy = create_equal_random_arrays( derham.Vh_fem["2"], seed=3456, flattened=True, ) - u1_str, u1_psy = create_equal_random_arrays( + _, u1_psy = create_equal_random_arrays( derham.Vh_fem["1"], seed=4567, flattened=True, ) - # create legacy struphy pusher and psydac based pusher - pusher_str = Pusher_str( - domain, - space, - space.extract_0( - b0_eq_str, - ), - space.extract_2(b2_eq_str), - basis_u=1, - bc_pos=0, - ) - mu0_str = xp.zeros(markers_str.shape[1], dtype=float) - pow_str = xp.zeros(markers_str.shape[1], dtype=float) - pusher_psy = Pusher_psy( particles, Pyccelkernel(pusher_kernels.push_bxu_Hcurl), @@ -419,19 +335,11 @@ def test_push_bxu_Hcurl(Nel, p, spl_kind, mapping, show_plots=False): alpha_in_kernel=1.0, ) - # compare if markers are the same BEFORE push - assert xp.allclose(particles.markers, markers_str.T) - # push markers dt = 0.1 - pusher_str.push_step3(markers_str, dt, b2_str, u1_str, mu0_str, pow_str) - pusher_psy(dt) - # compare if markers are the same AFTER push - assert xp.allclose(particles.markers[:, :6], markers_str.T[:, :6]) - @pytest.mark.parametrize("Nel", [[8, 9, 5], [7, 8, 9]]) @pytest.mark.parametrize("p", [[2, 3, 1], [1, 2, 3]]) @@ -457,14 +365,13 @@ def test_push_bxu_H1vec(Nel, p, spl_kind, mapping, show_plots=False): import cunumpy as xp from psydac.ddm.mpi import mpi as MPI - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.psydac_derham import Derham from struphy.feec.utilities import create_equal_random_arrays from struphy.geometry import domains from struphy.pic.particles import Particles6D from struphy.pic.pushing import pusher_kernels from struphy.pic.pushing.pusher import Pusher as Pusher_psy - from struphy.pic.tests.test_pic_legacy_files.pusher import Pusher as Pusher_str from struphy.pic.utilities import BoundaryParameters, LoadingParameters, WeightsParameters comm = MPI.COMM_WORLD @@ -475,7 +382,7 @@ def test_push_bxu_H1vec(Nel, p, spl_kind, mapping, show_plots=False): domain_class = getattr(domains, mapping[0]) domain = domain_class(**mapping[1]) - # discrete Derham sequence (psydac and legacy struphy) + # discrete Derham sequence (psydac) derham = Derham(Nel, p, spl_kind, comm=comm) domain_array = derham.domain_array @@ -509,46 +416,24 @@ def test_push_bxu_H1vec(Nel, p, spl_kind, mapping, show_plots=False): if show_plots: particles.show_physical() - # make copy of markers (legacy struphy uses transposed markers!) - markers_str = particles.markers.copy().T - # create random FEM coefficients for magnetic field - b0_eq_str, b0_eq_psy = create_equal_random_arrays( - derham.Vh_fem["0"], - seed=1234, - flattened=True, - ) - b2_eq_str, b2_eq_psy = create_equal_random_arrays( + _, b2_eq_psy = create_equal_random_arrays( derham.Vh_fem["2"], seed=2345, flattened=True, ) - b2_str, b2_psy = create_equal_random_arrays( + _, b2_psy = create_equal_random_arrays( derham.Vh_fem["2"], seed=3456, flattened=True, ) - uv_str, uv_psy = create_equal_random_arrays( + _, uv_psy = create_equal_random_arrays( derham.Vh_fem["v"], seed=4567, flattened=True, ) - # create legacy struphy pusher and psydac based pusher - pusher_str = Pusher_str( - domain, - space, - space.extract_0( - b0_eq_str, - ), - space.extract_2(b2_eq_str), - basis_u=0, - bc_pos=0, - ) - mu0_str = xp.zeros(markers_str.shape[1], dtype=float) - pow_str = xp.zeros(markers_str.shape[1], dtype=float) - pusher_psy = Pusher_psy( particles, Pyccelkernel(pusher_kernels.push_bxu_H1vec), @@ -566,19 +451,11 @@ def test_push_bxu_H1vec(Nel, p, spl_kind, mapping, show_plots=False): alpha_in_kernel=1.0, ) - # compare if markers are the same BEFORE push - assert xp.allclose(particles.markers, markers_str.T) - # push markers dt = 0.1 - pusher_str.push_step3(markers_str, dt, b2_str, uv_str, mu0_str, pow_str) - pusher_psy(dt) - # compare if markers are the same AFTER push - assert xp.allclose(particles.markers[:, :6], markers_str.T[:, :6]) - @pytest.mark.parametrize("Nel", [[8, 9, 5], [7, 8, 9]]) @pytest.mark.parametrize("p", [[2, 3, 1], [1, 2, 3]]) @@ -604,14 +481,13 @@ def test_push_bxu_Hdiv_pauli(Nel, p, spl_kind, mapping, show_plots=False): import cunumpy as xp from psydac.ddm.mpi import mpi as MPI - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.psydac_derham import Derham from struphy.feec.utilities import create_equal_random_arrays from struphy.geometry import domains from struphy.pic.particles import Particles6D from struphy.pic.pushing import pusher_kernels from struphy.pic.pushing.pusher import Pusher as Pusher_psy - from struphy.pic.tests.test_pic_legacy_files.pusher import Pusher as Pusher_str from struphy.pic.utilities import BoundaryParameters, LoadingParameters, WeightsParameters comm = MPI.COMM_WORLD @@ -622,7 +498,7 @@ def test_push_bxu_Hdiv_pauli(Nel, p, spl_kind, mapping, show_plots=False): domain_class = getattr(domains, mapping[0]) domain = domain_class(**mapping[1]) - # discrete Derham sequence (psydac and legacy struphy) + # discrete Derham sequence (psydac) derham = Derham(Nel, p, spl_kind, comm=comm) domain_array = derham.domain_array @@ -656,45 +532,30 @@ def test_push_bxu_Hdiv_pauli(Nel, p, spl_kind, mapping, show_plots=False): if show_plots: particles.show_physical() - # make copy of markers (legacy struphy uses transposed markers!) - markers_str = particles.markers.copy().T - # create random FEM coefficients for magnetic field - b0_eq_str, b0_eq_psy = create_equal_random_arrays( + _, b0_eq_psy = create_equal_random_arrays( derham.Vh_fem["0"], seed=1234, flattened=True, ) - b2_eq_str, b2_eq_psy = create_equal_random_arrays( + _, b2_eq_psy = create_equal_random_arrays( derham.Vh_fem["2"], seed=2345, flattened=True, ) - b2_str, b2_psy = create_equal_random_arrays( + _, b2_psy = create_equal_random_arrays( derham.Vh_fem["2"], seed=3456, flattened=True, ) - u2_str, u2_psy = create_equal_random_arrays( + _, u2_psy = create_equal_random_arrays( derham.Vh_fem["2"], seed=4567, flattened=True, ) - # create legacy struphy pusher and psydac based pusher - pusher_str = Pusher_str( - domain, - space, - space.extract_0( - b0_eq_str, - ), - space.extract_2(b2_eq_str), - basis_u=2, - bc_pos=0, - ) - mu0_str = xp.random.rand(markers_str.shape[1]) - pow_str = xp.zeros(markers_str.shape[1], dtype=float) + mu0 = xp.zeros(particles.markers.copy().T.shape[1], dtype=float) pusher_psy = Pusher_psy( particles, @@ -709,25 +570,17 @@ def test_push_bxu_Hdiv_pauli(Nel, p, spl_kind, mapping, show_plots=False): u2_psy[1]._data, u2_psy[2]._data, b0_eq_psy._data, - mu0_str, + mu0, ), domain.args_domain, alpha_in_kernel=1.0, ) - # compare if markers are the same BEFORE push - assert xp.allclose(particles.markers, markers_str.T) - # push markers dt = 0.1 - pusher_str.push_step3(markers_str, dt, b2_str, u2_str, mu0_str, pow_str) - pusher_psy(dt) - # compare if markers are the same AFTER push - assert xp.allclose(particles.markers[:, :6], markers_str.T[:, :6]) - @pytest.mark.parametrize("Nel", [[8, 9, 5], [7, 8, 9]]) @pytest.mark.parametrize("p", [[2, 3, 1], [1, 2, 3]]) @@ -753,7 +606,7 @@ def test_push_eta_rk4(Nel, p, spl_kind, mapping, show_plots=False): import cunumpy as xp from psydac.ddm.mpi import mpi as MPI - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.psydac_derham import Derham from struphy.feec.utilities import create_equal_random_arrays from struphy.geometry import domains @@ -761,7 +614,6 @@ def test_push_eta_rk4(Nel, p, spl_kind, mapping, show_plots=False): from struphy.pic.particles import Particles6D from struphy.pic.pushing import pusher_kernels from struphy.pic.pushing.pusher import Pusher as Pusher_psy - from struphy.pic.tests.test_pic_legacy_files.pusher import Pusher as Pusher_str from struphy.pic.utilities import BoundaryParameters, LoadingParameters, WeightsParameters comm = MPI.COMM_WORLD @@ -773,7 +625,7 @@ def test_push_eta_rk4(Nel, p, spl_kind, mapping, show_plots=False): domain_class = getattr(domains, mapping[0]) domain = domain_class(**mapping[1]) - # discrete Derham sequence (psydac and legacy struphy) + # discrete Derham sequence (psydac) derham = Derham(Nel, p, spl_kind, comm=comm) domain_array = derham.domain_array @@ -807,32 +659,7 @@ def test_push_eta_rk4(Nel, p, spl_kind, mapping, show_plots=False): if show_plots: particles.show_physical() - # make copy of markers (legacy struphy uses transposed markers!) - markers_str = particles.markers.copy().T - - # create random FEM coefficients for magnetic field - b0_eq_str, b0_eq_psy = create_equal_random_arrays( - derham.Vh_fem["0"], - seed=1234, - flattened=True, - ) - b2_eq_str, b2_eq_psy = create_equal_random_arrays( - derham.Vh_fem["2"], - seed=2345, - flattened=True, - ) - # create legacy struphy pusher and psydac based pusher - pusher_str = Pusher_str( - domain, - space, - space.extract_0( - b0_eq_str, - ), - space.extract_2(b2_eq_str), - basis_u=0, - bc_pos=0, - ) butcher = ButcherTableau("rk4") # temp fix due to refactoring of ButcherTableau: @@ -848,13 +675,9 @@ def test_push_eta_rk4(Nel, p, spl_kind, mapping, show_plots=False): n_stages=butcher.n_stages, ) - # compare if markers are the same BEFORE push - assert xp.allclose(particles.markers, markers_str.T) - # push markers dt = 0.1 - pusher_str.push_step4(markers_str, dt) pusher_psy(dt) n_mks_load = xp.zeros(size, dtype=int) @@ -871,18 +694,11 @@ def test_push_eta_rk4(Nel, p, spl_kind, mapping, show_plots=False): accum_sendcounts += sendcounts[i] all_particles_psy = xp.zeros((int(accum_sendcounts) * 3,), dtype=float) - all_particles_str = xp.zeros((int(accum_sendcounts) * 3,), dtype=float) comm.Barrier() comm.Allgatherv(xp.array(particles.markers[:, :3]), [all_particles_psy, sendcounts, displacements, MPI.DOUBLE]) - comm.Allgatherv(xp.array(markers_str.T[:, :3]), [all_particles_str, sendcounts, displacements, MPI.DOUBLE]) comm.Barrier() - unique_psy = xp.unique(all_particles_psy) - unique_str = xp.unique(all_particles_str) - - assert xp.allclose(unique_psy, unique_str) - if __name__ == "__main__": test_push_vxb_analytic( diff --git a/src/struphy/polar/extraction_operators.py b/src/struphy/polar/extraction_operators.py index 1c2a461ce..5fa38f982 100644 --- a/src/struphy/polar/extraction_operators.py +++ b/src/struphy/polar/extraction_operators.py @@ -36,8 +36,6 @@ class PolarExtractionBlocksC1: def __init__(self, domain, derham): from scipy.sparse import csr_matrix as csr - from struphy.eigenvalue_solvers.derivatives import grad_1d_matrix - # get control points cx = domain.cx[:, :, 0] cy = domain.cy[:, :, 0] @@ -514,8 +512,6 @@ class PolarSplines_C0_2D: def __init__(self, n0, n1): import scipy.sparse as spa - from struphy.eigenvalue_solvers.derivatives import grad_1d_matrix - d0 = n0 - 1 d1 = n1 - 0 @@ -657,8 +653,6 @@ class PolarSplines_C1_2D: def __init__(self, cx, cy): import scipy.sparse as spa - from struphy.eigenvalue_solvers.derivatives import grad_1d_matrix - n0, n1 = cx.shape d0 = n0 - 1 @@ -947,8 +941,6 @@ class PolarSplines: def __init__(self, tensor_space, cx, cy): import scipy.sparse as spa - from struphy.eigenvalue_solvers.derivatives import grad_1d_matrix - n0, n1, n2 = tensor_space.NbaseN d0, d1, d2 = tensor_space.NbaseD diff --git a/src/struphy/polar/tests/test_legacy_polar_splines.py b/src/struphy/polar/tests/test_legacy_polar_splines.py index be2bfb654..ea726dbd6 100644 --- a/src/struphy/polar/tests/test_legacy_polar_splines.py +++ b/src/struphy/polar/tests/test_legacy_polar_splines.py @@ -11,7 +11,7 @@ def test_polar_splines_2D(plot=False): import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.geometry import domains # parameters diff --git a/src/struphy/polar/tests/test_polar.py b/src/struphy/polar/tests/test_polar.py index ac0113c4f..80b1c09c6 100644 --- a/src/struphy/polar/tests/test_polar.py +++ b/src/struphy/polar/tests/test_polar.py @@ -170,7 +170,7 @@ def test_extraction_ops_and_derivatives(Nel, p, spl_kind): import cunumpy as xp from psydac.ddm.mpi import mpi as MPI - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.psydac_derham import Derham from struphy.feec.utilities import compare_arrays, create_equal_random_arrays from struphy.geometry.domains import IGAPolarCylinder @@ -305,7 +305,7 @@ def test_projectors(Nel, p, spl_kind): import cunumpy as xp from psydac.ddm.mpi import mpi as MPI - from struphy.eigenvalue_solvers.spline_space import Spline_space_1d, Tensor_spline_space + from struphy.feec.psydac_derham import Derham from struphy.geometry.domains import IGAPolarCylinder diff --git a/src/struphy/verify_compilation.sh b/src/struphy/verify_compilation.sh deleted file mode 100755 index eb41c15ca..000000000 --- a/src/struphy/verify_compilation.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash -e - -SO_EXT=$(python3 -c "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))") - -cd .. -struphy_path=$(python3 -c "import struphy as _; print(_.__path__[0])") - -BTS=$struphy_path/eigenvalue_solvers/kernels_projectors_global_mhd - -if [[ ! -f $BTS$SO_EXT ]] ; then - echo 'File' $BTS$SO_EXT 'is not there, aborting.' - exit 1 -elif [[ -f $BTS$SO_EXT ]] ; then - echo 'Compilation successful.' -fi