From a057e0249be1dd87a09a57d299588cfcf710ef54 Mon Sep 17 00:00:00 2001 From: Didou09 Date: Thu, 15 Sep 2016 18:26:23 +0200 Subject: [PATCH] Cleaning up temporarilly for release 1.1.0 --- tofu/Eq/__init__.py | 34 - tofu/Eq/_compute.py | 114 -- tofu/Eq/_core.py | 425 ----- tofu/Eq/_plot.py | 656 ------- tofu/inv/ToFu_Inv.py | 1246 ------------- tofu/inv/ToFu_PostTreat.py | 1484 ---------------- tofu/inv/ToFu_TreatForPostTreat.py | 330 ---- tofu/inv/__init__.py | 1 - tofu/matcomp/ToFu_MatComp.py | 839 --------- tofu/matcomp/__init__.py | 1 - tofu/mesh/Profile.prof | Bin 3463 -> 0 bytes tofu/mesh/Profiling.py | 19 - tofu/mesh/__init__.py | 27 - tofu/mesh/_bsplines.py | 1585 ----------------- tofu/mesh/_bsplines_cy.pyx | 1269 ------------- tofu/mesh/_compute.py | 2452 ------------------------- tofu/mesh/_core.py | 2661 ---------------------------- tofu/mesh/_plot.py | 2314 ------------------------ tofu/mesh/setup.py | 19 - 19 files changed, 15476 deletions(-) delete mode 100644 tofu/Eq/__init__.py delete mode 100644 tofu/Eq/_compute.py delete mode 100644 tofu/Eq/_core.py delete mode 100644 tofu/Eq/_plot.py delete mode 100644 tofu/inv/ToFu_Inv.py delete mode 100644 tofu/inv/ToFu_PostTreat.py delete mode 100644 tofu/inv/ToFu_TreatForPostTreat.py delete mode 100644 tofu/inv/__init__.py delete mode 100644 tofu/matcomp/ToFu_MatComp.py delete mode 100644 tofu/matcomp/__init__.py delete mode 100644 tofu/mesh/Profile.prof delete mode 100644 tofu/mesh/Profiling.py delete mode 100644 tofu/mesh/__init__.py delete mode 100644 tofu/mesh/_bsplines.py delete mode 100644 tofu/mesh/_bsplines_cy.pyx delete mode 100644 tofu/mesh/_compute.py delete mode 100644 tofu/mesh/_core.py delete mode 100644 tofu/mesh/_plot.py delete mode 100644 tofu/mesh/setup.py diff --git a/tofu/Eq/__init__.py b/tofu/Eq/__init__.py deleted file mode 100644 index 240e4f0f4..000000000 --- a/tofu/Eq/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -#! /usr/bin/python - - -""" -Load all core packages and modules which are all machine-independent, diagnostic-independent and code-independent - - -Created on Tuesday 07 June 2016 - -@version: 0.9 -@author: didiervezinet -@author_email: didier.vezinet@gmail.com -""" - - -from ._core import * - -#del _core - -#__name__ = "" -__version__ = "0.9" -__author__ = "Didier Vezinet" -__author_email__="didier.vezinet@gmail.com" -__date__ = "$Monday 20 June 2016$" -#__copyright__ = "" -#__license__ = "" -#__url__ = "" -#__path__ = - - - - - diff --git a/tofu/Eq/_compute.py b/tofu/Eq/_compute.py deleted file mode 100644 index a5a998f9c..000000000 --- a/tofu/Eq/_compute.py +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Aug 25 10:03:58 2014 - -@author: didiervezinet -""" - -import numpy as np -import scipy.interpolate as scpinterp -import warnings - -# ToFu-specific -import tofu.helper as tfh -from tofu.geom import _GG as TFGG # For Remap_2DFromFlat() only => make local version to get rid of dependency ? - - - - - -""" -############################################################################### -############################################################################### - Eq2D -############################################################################### -""" - - -############################################ -##### Computing functions for Eq2D -############################################ - - - -def _correctRef(Ref, RefV, Nt, PtsCross, MagAx): - if Ref in ['surf','vol','rho_p','rho_t','tf']: - # Linear interpolation to 0. - for ii in range(0,Nt): - r = np.hypot(PtsCross[0,:]-MagAx[ii,0], PtsCross[1,:]-MagAx[ii,1]) - indnan = np.isnan(RefV[ii,:]) - rmin = np.nanmin(r[~indnan]) - if np.any(indnan & (r<=rmin)): - warnings.warn("Some points close to the Magnetic Axis could be extrapolated to 0 because Ref = "+Ref) - rminarg = ((r==rmin) & (~indnan)).nonzero()[0] - refmin = RefV[ii,rminarg] - RefV[ii,indnan] = refmin*r[indnan]/rmin - return RefV - - - -def _interp_Quant(Tab_t, Tab_Pts, Tab_vPts, Pts, LQuant='rho_p', indt=None, t=None, deg=3, Test=True): - if Test: - assert np.asarray(Pts).ndim==2 and 2 in np.asarray(Pts).shape and np.asarray(Pts).dtype.name=='float64', "Arg Pts must be an iterable with 2D coordinates of points !" - assert type(Tab_vPts) is list, "Arg Tab_vPts must be a list !" - assert (type(LQuant) is str and len(Tab_vPts)==1) or (type(LQuant) is list and len(LQuant)==len(Tab_vPts) and all([type(qq) is str for qq in LQuant])), "Arg LQuant must be a str or a list of str !" - assert indt is None or type(indt) is int or hasattr(indt,'__iter__'), "Arg indt must be a int (index) or an iterable of such !" - assert t is None or type(t) is float or hasattr(t,'__iter__'), "Arg t must be a float (time) or an iterable of such" - - # Pre-formatting inputs - Pts = np.asarray(Pts) - Pts = Pts if Pts.shape[0]==2 else Pts.T - ind = tfh.get_indt(Tab_t=Tab_t, indt=indt, t=t, defind='all', out=int, Test=Test) - - # Compute - NP = Pts.shape[1] - LQuant = [LQuant] if type(LQuant) is str else LQuant - LQ = dict([(ss,[]) for ss in LQuant]) - LQin = [qq[ind,:] if not qq is None else qq for qq in Tab_vPts] - for jj in range(0,len(LQin)): - if not LQin[jj] is None: - qin, X0, X1, nx0, nx1 = TFGG.Remap_2DFromFlat(np.ascontiguousarray(Tab_Pts), [qq for qq in LQin[jj]], epsx0=None, epsx1=None) - qq = np.nan*np.ones((len(ind),NP)) - for ii in range(0,len(ind)): - fq = scpinterp.RectBivariateSpline(X0, X1, qin[ii], bbox=[None, None, None, None], kx=deg, ky=deg, s=0) - qq[ii,:] = fq.ev(Pts[0,:],Pts[1,:]) - else: - qq =None - LQ[LQuant[jj]] = qq - if len(LQuant)==1: - LQ = LQ[LQuant[0]] - return LQ - - - - -def _get_rgrad(Pts, Tab_Pts, Tab_vPts, Tab_t, indt=None, t=None, Test=True): - if Test: - assert type(Pts) is np.ndarray and Pts.ndim==2 and Pts.shape[0]==2 and Pts.dtype.name=='float64', "Arg Pts must be a (2,NP) np.ndarray of floats !" - assert type(Tab_Pts) is np.ndarray and Tab_Pts.ndim==2 and Tab_Pts.shape[0]==2 and Tab_Pts.dtype.name=='float64', "Arg Tab_Pts must be a (2,N) np.ndarray of floats !" - assert type(Tab_vPts) is np.ndarray and Tab_vPts.ndim==2 and Tab_vPts.shape[1]== Tab_Pts.shape[1] and Tab_vPts.dtype.name=='float64', "Arg vPts must be a (Nt,N) np.ndarray of floats !" - assert indt is None or type(indt) is int or hasattr(indt,'__iter__'), "Arg indt must be a int (index) or an iterable of such !" - assert t is None or type(t) is float or hasattr(t,'__iter__'), "Arg t must be a float (time) or an iterable of such" - - ind = tfh.get_indt(Tab_t=Tab_t, indt=indt, t=t, defind='all', out=int, Test=Test) - rgrad = [] - vpts, X0, X1, nx0, nx1 = TFGG.Remap_2DFromFlat(np.ascontiguousarray(Tab_Pts), [qq for qq in Tab_vPts], epsx0=None, epsx1=None) - for ii in ind: - rg = scpinterp.RectBivariateSpline(X0, X1, vpts[ii], bbox=[None, None, None, None], kx=3, ky=3, s=0) - gradx = rg.ev(Pts[0,:], Pts[1,:], dx=1, dy=0) - grady = rg.ev(Pts[0,:], Pts[1,:], dx=0, dy=1) - norm = np.hypot(gradx,grady) - grad = np.array([gradx/norm, grady/norm]) - rgrad.append(grad) - if len(ind)==1: - rgrad = rgrad[0] - return rgrad - - - - - - - - - diff --git a/tofu/Eq/_core.py b/tofu/Eq/_core.py deleted file mode 100644 index 355bb3274..000000000 --- a/tofu/Eq/_core.py +++ /dev/null @@ -1,425 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Aug 25 10:03:58 2014 - -@author: didiervezinet -""" - -import numpy as np -import datetime as dtm -import warnings - -# ToFu-specific -import tofu.defaults as tfd -import tofu.pathfile as tfpf -from . import _compute as _tfEq_c -from . import _plot as _tfEq_p - - -__all__ = ['Eq2D'] - - - -""" -############################################################################### -############################################################################### - Eq 2D class (for GBF) -############################################################################### -""" - - - -class Eq2D(object): - """ Create a 2D equilibrium object, which stores all relevant data (rho, q, theta mappings) for one time point """ - - def __init__(self, Id, PtsCross, t=None, MagAx=None, Sep=None, rho_p=None, rho_t=None, surf=None, vol=None, q=None, jp=None, pf=None, tf=None, theta=None, thetastar=None, BTX=None, BRY=None, BZ=None, Ref=None, - Type='Tor', Exp=None, shot=None, Diag=None, dtime=None, dtimeIn=False, SavePath=None): - - self._Done = False - self._set_Id(Id, Type=Type, Exp=Exp, shot=shot, Diag=Diag, dtime=dtime, dtimeIn=dtimeIn, SavePath=SavePath) - - self._Tabs_vRho = ['q','jp','rho_p','rho_t','surf','vol','pf','tf'] - self._Tabs_vPts_add = ['theta','thetastar','BTX','BRY','BZ'] - self._Tabs_vPts = self._Tabs_vPts_add + self._Tabs_vRho - self._Tabs_Quants = ['MagAx','Sep'] + self._Tabs_vPts - - btx = r"$B_T$" if Type=='Tor' else r"$B_X$" - bry = r"$B_R$" if Type=='Tor' else r"$B_Y$" - self._Tabs_LTXUnits = {'q':{'LTX':r"$q$",'units':r""}, 'rho_p':{'LTX':r"$\rho_P$",'units':r""}, 'rho_t':{'LTX':r"$\rho_T$",'units':r""}, 'vol':{'LTX':r"$V$",'units':r"$m^3$"}, 'surf':{'LTX':r"$S$",'units':r"$m^2$"}, - 'pf':{'LTX':r"$\phi$",'units':r"$V.s$"}, 'tf':{'LTX':r"$\psi$",'units':r"$V.s$"}, 'jp':{'LTX':r"$j_P$",'units':r"$A$"}, - 'BTX':{'LTX':btx,'units':r"$T$"}, 'BRY':{'LTX':bry,'units':r"$T$"}, 'BZ':{'LTX':r"$B_Z$",'units':r"$T$"}, - 'theta':{'LTX':r"$\theta$",'units':r"rad."}, 'thetastar':{'LTX':r"$\theta^*$",'units':r"rad."}} - - self._preset_Tab() - self._add_Eq(PtsCross=PtsCross, t=t, MagAx=MagAx, Sep=Sep, rho_p=rho_p, rho_t=rho_t, surf=surf, vol=vol, q=q, jp=jp, theta=theta, thetastar=thetastar, pf=pf, tf=tf, BTX=BTX, BRY=BRY, BZ=BZ, Ref=Ref) - self._Done = True - - @property - def Id(self): - return self._Id - @property - def Type(self): - return self.Id.Type - @property - def shot(self): - return self.Id.shot - @property - def Diag(self): - return self.Id.Diag - - @property - def PtsCross(self): - return self._Tab['PtsCross'] - @property - def NP(self): - return self._NP - - @property - def t(self): - return self._Tab['t'] - @property - def Nt(self): - return self._Nt - - @property - def MagAx(self): - return self._Tab['MagAx'] - @property - def Sep(self): - return self._Tab['Sep'] - @property - def pf(self): - return self._get_vPtsFromvRef('pf') - @property - def tf(self): - return self._get_vPtsFromvRef('tf') - @property - def rho_p(self): - return self._get_vPtsFromvRef('rho_p') - @property - def rho_t(self): - return self._get_vPtsFromvRef('rho_t') - @property - def surf(self): - return self._get_vPtsFromvRef('surf') - @property - def vol(self): - return self._get_vPtsFromvRef('vol') - @property - def q(self): - return self._get_vPtsFromvRef('q') - @property - def jp(self): - return self._get_vPtsFromvRef('jp') - @property - def theta(self): - return self._get_vPtsFromvRef('theta') - @property - def thetastar(self): - return self._get_vPtsFromvRef('thetastar') - @property - def BTX(self): - return self._get_vPtsFromvRef('BTX') - @property - def BRY(self): - return self._get_vPtsFromvRef('BRY') - @property - def BZ(self): - return self._get_vPtsFromvRef('BZ') - @property - def Tabs_vPts(self): - return self._Tabs_vPts - @property - def Ref(self): - return self._Tab['Ref'] - @property - def NRef(self): - return self._NRef - - - - def _check_inputs(self, Id=None, PtsCross=None, t=None, MagAx=None, Sep=None, rho_p=None, rho_t=None, surf=None, vol=None, q=None, jp=None, pf=None, tf=None, theta=None, thetastar=None, BTX=None, BRY=None, BZ=None, Ref=None, - Type=None, Exp=None, shot=None, Diag=None, dtime=None, dtimeIn=False, SavePath=None): - _Eq2D_check_inputs(Id=Id, PtsCross=PtsCross, t=t, MagAx=MagAx, Sep=Sep, rho_p=rho_p, rho_t=rho_t, surf=surf, vol=vol, q=q, jp=jp, pf=pf, tf=tf, theta=theta, thetastar=thetastar, BTX=BTX, BRY=BRY, BZ=BZ, Ref=Ref, - Type=Type, Exp=Exp, shot=shot, Diag=Diag, dtime=dtime, dtimeIn=dtimeIn, SavePath=SavePath) - - def _set_Id(self, Id, Type=None, Exp=None, shot=None, Diag=None, dtime=None, dtimeIn=False, SavePath=None): - if self._Done: - Out = tfpf._get_FromItself(self.Id,{'Type':Type, 'Exp':Exp, 'shot':shot, 'Diag':Diag, 'dtime':dtime, '_dtimeIn':dtimeIn, 'SavePath':SavePath}) - Type, Exp, shot, Diag, dtime, dtimeIn, SavePath = Out['Type'], Out['Exp'], Out['shot'], Out['Diag'], Out['dtime'], Out['dtimeIn'], Out['SavePath'] - tfpf._check_NotNone({'Id':Id}) - self._check_inputs(Id=Id) - if type(Id) is str: - Exp = 'Test' if Exp is None else Exp - tfpf._check_NotNone({'Exp':Exp, 'dtimeIn':dtimeIn}) - self._check_inputs(Type=Type, Exp=Exp, shot=shot, Diag=Diag, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - Id = tfpf.ID('Eq2D', Id, Type=Type, Exp=Exp, shot=shot, Diag=Diag, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._Id = Id - - def _preset_Tab(self, SepNPmax=100): - self._Tab = {} - - def _add_Eq(self, PtsCross=None, t=None, MagAx=None, Sep=None, rho_p=None, rho_t=None, surf=None, vol=None, q=None, jp=None, theta=None, thetastar=None, pf=None, tf=None, BTX=None, BRY=None, BZ=None, Ref=None): - """ - Stores all provided quantities of the equilibrium as a dict called Tab, only one radial quantity is stored as a 2D map (vPts), the others are mapped against this one (vRef) - """ - self._check_inputs(PtsCross=PtsCross, t=t, MagAx=MagAx, Sep=Sep, rho_p=rho_p, rho_t=rho_t, surf=surf, vol=vol, q=q, jp=jp, theta=theta, thetastar=thetastar, pf=pf, tf=tf, BTX=BTX, BRY=BRY, BZ=BZ, Ref=Ref) - for ss in self._Tabs_Quants: - qq = eval(ss) - self._Tab[ss] = qq - self._Tab['Ref'] = Ref - self._Tab['PtsCross'] = PtsCross - self._Tab['t'] = t - self._Nt = self._Tab[self.Ref]['vRef'].shape[0] - self._NP = PtsCross.shape[1] - self._NRef = self._Tab[self.Ref]['vRef'].shape[1] - self._correct_Ref() - - def _correct_Ref(self): - RefV = _tfEq_c._correctRef(self.Ref, self._Tab[self.Ref]['vPts'], self.Nt, self.PtsCross, self.MagAx) - self._Tab[self.Ref]['vPts'] = RefV - - def _get_vPtsFromvRef(self, ss): - assert ss in self._Tabs_Quants, "Provided quantity is not in self._Tabs_Quants !" - if ss==self.Ref: - vPts = self._Tab[ss]['vPts'] - elif not self._Tab[ss] is None: - Extra = False - vPts = np.nan*np.ones((self.Nt,self.NP)) - for ii in range(0,self.Nt): - indsort = np.argsort(self._Tab[self.Ref]['vRef'][ii,:]) - vPts[ii,:] = np.interp(self._Tab[self.Ref]['vPts'][ii,:], self._Tab[self.Ref]['vRef'][ii,indsort], self._Tab[ss]['vRef'][ii,indsort], left=None, right=None) - if ss in ['surf','vol','rho_p','rho_t','tf']: # Extrapolate to 0 if necessary - r = np.hypot(self.PtsCross[0,:]-self.MagAx[ii,0], self.PtsCross[1,:]-self.MagAx[ii,1]) - indnan = np.isnan(vPts[ii,:]) - rmin = np.nanmin(r[~indnan]) - if np.any(indnan & (r<=rmin)): - rminarg = ((r==rmin) & (~indnan)).nonzero()[0] - refmin = vPts[ii,rminarg] - N1 = np.isnan(vPts[ii,:]).sum() - vPts[ii,indnan] = refmin*r[indnan]/rmin - Extra = True - if Extra: - warnings.warn("{0} / {1} points close to the Magnetic Axis could be extrapolated to 0 because quantity = ".format(N1-np.isnan(vPts[ii,:]).sum(),np.isnan(vPts[ii,:]).sum())+ss) - else: - vPts = None - return vPts - - def interp(self, Pts, Quant='rho_p', indt=None, t=None, deg=3, Test=True): - """ - Interpolate the chosen equilibrium quantities at the provided points (from the stored/tabulated grid) - - Inputs: - ------- - Pts iterable Iterable containing the 2D cartesian coordinates of points in a cross-section where the quantity of interest should be interpolated - Quant str / iterable Key or iterable of keys designing the quantities to be interpolated (from self.Tabs_vPts) - indt None / int Index (in time) at which the quantities should be plotted - t None / float Time at which the quantities should be plotted (used if indt not provided) - deg int Degree to be used forthe 2D spline interpolation - Test - - Outputs: - -------- - dQuant np.ndarray / dict Array of b-spline interpolated quantities at desired times (first dimension) and points (second dimension), dictionary of uch if several quantities were asked - - """ - assert (Quant in self.Tabs_vPts) or (hasattr(Quant,'__iter__') and all([ss in self.Tabs_vPts for ss in Quant])), "Arg Quant must be a valid str or iterable of such !" - Quant = [Quant] if type(Quant) is str else Quant - Tab_vPts = [eval('self.'+ss) for ss in Quant] - dQuant = _tfEq_c._interp_Quant(self.t, self.PtsCross, Tab_vPts, Pts, LQuant=Quant, indt=indt, t=t, deg=deg, Test=Test) - return dQuant - - def get_RadDir(self, Pts, indt=None, t=None, Test=True): - """ - Return an array of normalised vectors showing the direction of negative (outward) radial gradient at each input point - - Inputs: - ------- - Pts iterable Iterable containing the 2D cartesian coordinates of points in a cross-section where the quantity of interest should be interpolated - - Outputs: - -------- - rgrad - - """ - refrad = self._Tab[self.Ref]['vPts'] - rgrad = _tfEq_c._get_rgrad(Pts, self.PtsCross, refrad, self.t, indt=None, t=None, Test=Test) - return rgrad - - - def plot(self, V='inter', ax=None, Quant=['q','MagAx','Sep','pol'], plotfunc='contour', lvls=[1.,1.5,2.], indt=None, t=None, Cdict=None, RadDict=None, PolDict=None, MagAxDict=None, SepDict=None, LegDict=tfd.TorLegd, - ZRef='MagAx', NP=100, Ratio=-0.1, ylim=None, - NaNout=True, Abs=True, clab=True, cbar=False, draw=True, a4=False, Test=True): - - """ - Plot a 2D map of the chosen quantity, plus optionally the magnetic axis ('MagAx') and the separatrix ('Sep') - - Inputs: - ------- - V str Flag indicating which version of the plot is expected: - 'static': a simple 2D plot of the desired quantity - 'inter': an interactive figure, with a 2D plot, a 1D plot of a cut through the equatorial plane and time traces of the cut points, time is changed with left/right arrows - ax None / plt.Axes Axes to be used for plotting, if None a new figure / axes is created - Quant str / iterable Flag(s) indicating which 2D quantity to plot (from self._Tabs_vPts), if iterable, can contain also 'MagAx' and 'Sep', and 'rad' and 'pol' for direction arrows - plotfunc str Flag indicating which function to use for plotting in ['scatter','contour','contourf','imshow'] - lvls None / iterable Iterable of the levels to be used for plotfunc='contour' - indt None / int Index (in time) at which the quantities should be plotted - t None / float Time at which the quantities should be plotted (used if indt not provided) - Cdict None / dict Dictionary of properties used for plotting the 2D quantity (fed to the chosen plotfunc), default used from tofu.defaults if None - RadDict None / dict Dictionary of properties used for plotting the arrows of the radial direction (fed to plt.quiver()), default used from tofu.defaults if None - PolDict None / dict Dictionary of properties used for plotting the arrows of the poloidal direction (fed to plt.quiver()), default used from tofu.defaults if None - MagAxDict None / dict Dictionary of properties used for plotting the Magnetic Axis (fed to plt.plot()), default used from tofu.defaults if None - SepDict None / dict Dictionary of properties used for plotting the Separatrix (fed to plt.plot()), default used from tofu.defaults if None - LegDict None / dict Dictionary of properties for plotting the legend, legend not plotted if None - ZRef float / str The height at which the equatorial cut should be made, if 'MagAx', the cut is made at the height of the magnetic axis, averaged over the time interval - NP int Number of points to be used for computing the quantity along the equatorial cut - Ratio float Ratio to be used for adjusting the width of the equatorial cut with respect to the width spanned by self.PtsCross (typically -0.1 for a small span or 0.1 for a larger one) - ylim None / iterable If not None, a len()==2 iterable of floats to be used to set the ylim of the plot of the equatorial cut - NaNout bool Flag indicating whether all points outside of the separatrix shall be set to NaN - Abs bool Flag indicating whether the absolute value of the quantity should be plotted (e.g.: avoid negative q...) - clab bool Flag indicating whether the contours should be labelled with ther corresponding values (for plotfunc='contour' only) - cbar bool Flag indicating whether the colorbar axes should be plotted - draw bool Flag indicating whether the fig.canvas.draw() shall be called automatically - a4 bool Flag indicating whether the figure should be plotted in a4 dimensions for printing - Test bool Flag indicating whether the inputs should be tested for conformity - - Outputs: - -------- - ax plt.Axes / dict Axes used for plotting, returned as a single axes (V='static') or a dictionary of axes (V='inter') - - """ - ax = _tfEq_p.Eq2D_plot(self, Quant, V=V, ax=ax, plotfunc=plotfunc, lvls=lvls, indt=indt, t=t, clab=clab, Cdict=Cdict, RadDict=RadDict, PolDict=PolDict, MagAxDict=MagAxDict, SepDict=SepDict, LegDict=LegDict, - ZRef=ZRef, NP=NP, Ratio=Ratio, ylim=ylim, - VType=self.Id.Type, NaNout=NaNout, Abs=Abs, cbar=cbar, draw=draw, a4=a4, Test=Test) - return ax - - - def plot_vs(self, ax=None, Qy='q', Qx='rho_p', indt=None, t=None, Dict=None, xlim=None, ylim=None, Abs=True, LegDict=None, draw=True, a4=False, Test=True): - """ - Plot a quantity vs another - - Inputs: - ------- - ax None / plt.Axes Axes to be used for plotting, if None a new figure / axes is created - Qy str Flag indicating which quantity should be plotted on the y-axis - Qx str Flag indicating which quantity should be plotted on the x-axis - indt None / int Index (in time) at which the quantities should be plotted - t None / float Time at which the quantities should be plotted (used if indt not provided) - Dict dict Dictionary of properties used for plotting the line (fed to plt.plot()), default used from tofu.defaults if None - Abs bool Flag indicating whether the absolute value of the quantity should be plotted (e.g.: avoid negative q...) - LegDict None / dict Dictionary of properties for plotting the legend, legend not plotted if None - draw bool Flag indicating whether the fig.canvas.draw() shall be called automatically - a4 bool Flag indicating whether the figure should be plotted in a4 dimensions for printing - Test bool Flag indicating whether the inputs should be tested for conformity - - Outputs: - -------- - ax plt.Axes Axes used for plotting - - """ - ax = _tfEq_p.Eq2D_plot_vs(self, ax=ax, Qy=Qy, Qx=Qx, indt=indt, t=t, Dict=Dict, Abs=Abs, LegDict=LegDict, xlim=xlim, ylim=ylim, draw=draw, a4=a4, Test=Test) - return ax - - - def save(self, SaveName=None, Path=None, Mode='npz'): - """ - Save the object in folder Name, under file name SaveName, using specified mode - - Inputs: - ------ - SaveName str The name to be used to for the saved file, if None (recommended) uses Ves.Id.SaveName (default: None) - Path str Path specifying where to save the file, if None (recommended) uses Ves.Id.SavePath (default: None) - Mode str Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, may cause retro-compatibility issues with later versions) - """ - tfpf.Save_Generic(self, SaveName=SaveName, Path=Path, Mode=Mode) - - - - - - - - -def _Eq2D_check_inputs(Id=None, PtsCross=None, t=None, MagAx=None, Sep=None, rho_p=None, rho_t=None, surf=None, vol=None, q=None, jp=None, pf=None, tf=None, theta=None, thetastar=None, BTX=None, BRY=None, BZ=None, Ref=None, - Type=None, Exp=None, shot=None, Diag=None, dtime=None, dtimeIn=False, SavePath=None): - - if Id is not None: - assert type(Id) in [str,tfpf.ID], "Arg Id must be a str or a tfpf.ID object !" - - # Here all inputs must be provided simultaneously ! - vRho = ['q','jp','rho_p','rho_t','surf','vol','pf','tf'] - vPts_add = ['theta','thetastar','BTX','BRY','BZ'] - vPts = vPts_add + vPts_add - Quants = ['MagAx','Sep'] + vPts - - if PtsCross is not None: - pts = np.asarray(PtsCross) - assert np.asarray(pts).ndim==2 and 2 in np.asarray(pts).shape and max(np.asarray(pts).shape)>2 and pts.dtype.name=='float64', "Arg PtsCross must be a 2-dim np.ndarray of floats !" - NP = max(pts.shape) - - assert Ref is None or (type(Ref) is str and Ref in vRho), "Arg Ref must be a str in vRho !" - if any([eval(ss+' is not None') for ss in vRho]): - assert Ref is not None, "Arg Ref must be provided if any vRho is provided too !" - assert eval(Ref+' is not None'), "The Ref quantity must be provided if any vRho is provided too !" - Sh = eval(Ref+"['vRef'].shape") - for ss in vRho: - val = eval(ss) - if val is not None: - assert type(val) is dict and all([kk in val.keys() for kk in ['vPts','vRef']]), "Arg "+ss+" must be a dict with keys ['vPts','vRef'] !" - assert val['vRef'] is None or (type(val['vRef']) is np.ndarray and val['vRef'].ndim==2 and val['vRef'].dtype.name=='float64'), "Arg "+ss+"['vRef'] must be a 2-dim np.ndarray of floats !" - assert val['vRef'].shape==Sh, "Arg "+ss+"['vRef'] must be the same shape as Ref !" - - if Ref is not None: - assert PtsCross is not None, "PtsCross must be provided if 'Ref' is provided !" - val = eval(Ref) - assert type(val) is dict and all([dd in val.keys() for dd in ['vRef','vPts']]), Ref+" must be a dict with keys ['vPts','vRef'] !" - assert type(val['vPts']) is np.ndarray and val['vPts'].ndim==2 and val['vPts'].shape[1]==NP, "Arg "+Ref+"['vPts'] must be a np.ndarray of float with shape (Nt,NP) !" - assert type(val['vRef']) is np.ndarray and val['vRef'].ndim==2 and val['vRef'].dtype.name=='float64', "Arg "+Ref+"['vRef'] must be a 2-dim np.ndarray of floats !" - - if any([eval(ss+' is not None') for ss in vPts_add]): - assert PtsCross is not None, "PtsCross must be provided if any vPts is provided !" - for ss in vPts_add: - val = eval(ss) - if val is not None: - assert type(val) is dict and all([dd in val.keys() for dd in ['vRef','vPts']]), "Ref must be provided if 'Ref' is provided !" - assert type(val['vPts']) is np.ndarray and val['vPts'].ndim==2 and val['vPts'].shape[1]==NP, "Arg "+ss+"['vPts'] must be a np.ndarray of float with shape (Nt,NP) !" - - if MagAx is not None: - assert type(MagAx) is np.ndarray and MagAx.ndim==2 and MagAx.shape[1]==2 and MagAx.dtype.name=='float64', "MagAx must be a 2-dim (Nt,2) np.ndarray of floats !" - - if Sep is not None: - assert type(Sep) is list and all([type(sp) is np.ndarray and sp.ndim==2 and sp.shape[0]==2 and sp.dtype.name=='float64' for sp in Sep]), "sp must be a list of 2-dim (2,N) np.ndarray of floats !" - - if not t is None: - assert type(t) is np.ndarray and t.ndim==1 and t.dtype.name=='float64', "Arg t must be a 1-dim np.ndarray of floats !" - - # Inputs below can be provided separately - if not Type is None: - assert Type in ['Tor','Lin'], "Arg Type must be in ['Tor','Lin'] !" - if not Exp is None: - assert Exp in tfd.AllowedExp, "Ar Exp must be in "+str(tfd.AllowedExp)+" !" - Ints = [shot] - if any([not aa is None for aa in Ints]): - assert all([aa is None or type(aa) is int for aa in Ints]), "Args [shot] must be int !" - strs = [SavePath] - if any([not aa is None for aa in strs]): - assert all([aa is None or type(aa) is str for aa in strs]), "Args [SavePath] must all be str !" - if not dtime is None: - assert type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !" - bools = [dtimeIn] - if any([not aa is None for aa in bools]): - assert all([aa is None or type(aa) is bool for aa in bools]), " Args [dtimeIn] must all be bool !" - - - - - - - - - - - - - - diff --git a/tofu/Eq/_plot.py b/tofu/Eq/_plot.py deleted file mode 100644 index 58ae9866b..000000000 --- a/tofu/Eq/_plot.py +++ /dev/null @@ -1,656 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Aug 25 10:03:58 2014 - -@author: didiervezinet -""" - -import numpy as np -import matplotlib.pyplot as plt -from mpl_toolkits.mplot3d import Axes3D -import Polygon as plg -import scipy.sparse as scpsp -from matplotlib.path import Path -import matplotlib.patches as patches -from matplotlib.collections import PatchCollection as PcthColl -import datetime as dtm -import scipy.interpolate as scpinterp - -import types -import warnings - - -# ToFu-specific -import tofu.defaults as tfd -import tofu.helper as tfh -from tofu.geom import _GG as TFGG # For Remap_2DFromFlat() only => make local version to get rid of dependency ? - - -#from mayavi import mlab - -""" -############################################################################### -############################################################################### - Helper routines -############################################################################### -""" - - -def _get_xylim(Q, Qd, lim=None, xy='x'): - if lim is None: - if Q=='q': - sg = np.all(Qd>=0.) - lim = [0.,4.] if sg else [-4.,0.] - elif 'rho' in Q: - lim = {'left':0.,'right':1.1} if xy=='x' else {'bottom':0.,'top':1.1} - else: - lim = {'left':np.nanmin(Qd), 'right':np.nanmax(Qd)} if xy=='x' else {'bottom':np.nanmin(Qd), 'top':np.nanmax(Qd)} - if hasattr(lim,'__iter__') and not type(lim) is dict: - assert len(lim)==2 and lim[0]3 !" - assert all([ss in Obj.Tabs_vPts+['MagAx','Sep']+['rad','pol'] for ss in Quant]), "Arg Quant can only contains keys in self.Tabs_vPts + ['MagAx','Sep'] !" - assert len([ss for ss in Quant if not ss in ['MagAx','Sep']+['rad','pol']])<=1, "Arg Quant cannot contain more than one 2D mappable quantity from self.Tabs_vPts !" - assert ax is None or type(ax) is plt.Axes, "Arg ax must be a plt.Axes instance !" - assert plotfunc in ['contour','contourf','scatter','imshow'], "Arg plotfunc must be in ['contour','contouf','scatter','imshow'] !" - assert lvls is None or type(lvls) in [int,float] or hasattr(lvls,'__iter__'), "Arg lvls must be a value or an iterable of values !" - assert all([dd is None or type(dd) is dict for dd in [Cdict,MagAxDict,SepDict]]), "Args [Cdict,MagAxDict,SepDict] must be dictionaries of properties (fed to plotfunc and plot()) !" - assert indt is None or type(indt) is int, "Arg indt must be a int (index) !" - assert t is None or type(t) in [int,float,np.float64], "Arg t must be a float (time) !" - assert all([type(bb) is bool for bb in [clab,draw,a4]]), "Args [draw,a4] must be bool !" - - # Prepare selected input - Tab_t = Obj.t - PtsCross = Obj.PtsCross - ind = tfh.get_indt(Tab_t=Tab_t, indt=indt, t=t, defind=-1, out=int, Test=Test)[0] - Quant = Quant if hasattr(Quant,'__iter__') else [Quant] - lq = [ss for ss in Quant if not ss in ['MagAx','Sep']+['rad','pol']] - if not eval('Obj.'+lq[0]) is None: - QQ = eval('Obj.'+lq[0]) if len(lq)==1 else None - else: - warnings.warn("Requested quantity ("+lq[0]+") is not available !") - QQ = np.nan*np.ones((Obj.Nt,Obj.NP)) - if QQ is not None: - QName = Obj._Tabs_LTXUnits[lq[0]]['LTX'] - Qunit = Obj._Tabs_LTXUnits[lq[0]]['units'] - if 'rad' in Quant or 'pol' in Quant: - Qrad = Obj.get_RadDir(PtsCross, indt=ind, t=Tab_t, Test=Test)[0] - Qpol = np.array([-Qrad[1,:], Qrad[0,:]]) - if NaNout: - indout = ~Path(Obj.Sep[ind].T).contains_points(PtsCross.T) - Qrad[:,indout] = np.nan - Qpol[:,indout] = np.nan - AvDry = np.nanmean(np.diff(np.unique(PtsCross[0,:]))) - AvDz = np.nanmean(np.diff(np.unique(PtsCross[1,:]))) - AvD = np.hypot(AvDry, AvDz) - - - if Cdict is None and QQ is not None: - Cdict = dict(tfd.Eq2DPlotDict[plotfunc]) - if not lvls is None and plotfunc in ['contour','contourf'] and QQ is not None: - Cdict['levels'] = np.unique(lvls) if hasattr(lvls,'__iter__') else [lvls] - if RadDict is None and 'rad' in Quant: - RadDict = dict(tfd.Eq2DPlotRadDict) - if PolDict is None and 'pol' in Quant: - PolDict = dict(tfd.Eq2DPlotPolDict) - - # Plot - if ax is None: - ax, axc = tfd.Plot_Eq2D_DefAxes(VType=VType, cbar=cbar, a4=a4) - title = Obj.Id.Name + "\n"+Obj.Id.Exp+" {0:05.0f}".format(Obj.Id.shot)+" t = {0:06.3f} s".format(Tab_t[ind]) - if QQ is not None: - title = title + r" $\|$"+QName+r"$\|$" if Abs else title + " "+QName - ax.set_title(title) - if cbar: - axc.set_title(Qunit) - - if QQ is not None: - qq = np.abs(QQ[ind,:]) if Abs else np.copy(QQ[ind,:]) - if NaNout: - indout = ~Path(Obj.Sep[ind].T).contains_points(Obj.PtsCross.T) - qq[indout] = np.nan - if plotfunc=='scatter': - CS = ax.scatter(PtsCross[0,:], PtsCross[1,:], c=qq, **Cdict) - else: - Lqq, X0, X1, nx0, nx1 = TFGG.Remap_2DFromFlat(np.ascontiguousarray(PtsCross), [qq], epsx0=None, epsx1=None) - qq = Lqq[0] - if plotfunc=='imshow': - extent = (np.nanmin(X0),np.nanmax(X0),np.nanmin(X1),np.nanmax(X1)) - CS = ax.imshow(qq.T, aspect='auto', interpolation='bilinear', origin='lower', extent=extent, **Cdict) - else: - XX0 = np.tile(X0,(nx1,1)) - XX1 = np.tile(X1,(nx0,1)).T - if plotfunc=='contour': - CS = ax.contour(XX0, XX1, qq.T, **Cdict) - elif plotfunc=='contourf': - CS = ax.contourf(XX0, XX1, qq.T, **Cdict) - if clab and plotfunc=='contour': - plt.clabel(CS, Cdict['levels'], inline=1, fontsize=10, fmt='%03.0f') - if cbar: - ax.figure.colorbar(CS, cax=axc) - - if 'rad' in Quant: - ax.quiver(PtsCross[0,:], PtsCross[1,:], Qrad[0,:]*AvD, Qrad[1,:]*AvD, label='Rad.', **RadDict) - if 'pol' in Quant: - ax.quiver(PtsCross[0,:], PtsCross[1,:], Qpol[0,:]*AvD, Qpol[1,:]*AvD, label='Pol.', **PolDict) - - if 'MagAx' in Quant: - MagAxDict = tfd.Eq2DMagAxDict if MagAxDict is None else MagAxDict - ax.plot(Obj.MagAx[ind,0:1], Obj.MagAx[ind,1:2], label=r"MagAx", **MagAxDict) - if 'Sep' in Quant: - SepDict = tfd.Eq2DSepDict if SepDict is None else SepDict - ax.plot(Obj.Sep[ind][0,:], Obj.Sep[ind][1,:], label=r"Sep", **SepDict) - ax.set_aspect(aspect='equal', adjustable='datalim') - - if not LegDict is None: - ax.legend(**LegDict) - if draw: - ax.figure.canvas.draw() - return ax - - - - -def Eq2D_plot_vs(Obj, ax=None, Qy='q', Qx='rho_p', indt=None, t=None, Dict=None, Abs=True, LegDict=None, xlim=None, ylim=None, draw=True, a4=False, Test=True): - if Test: - assert Obj.Id.Cls=='Eq2D', "Arg Obj must be a tfm.Eq2D instance !" - assert all([type(qq) is str and qq in Obj._Tab.keys() for qq in [Qx,Qy]]), "Args Qx qnd Qy must be key str in Obj._Tab !" - assert ax is None or type(ax) is plt.Axes, "Arg ax must be a plt.Axes instance !" - assert Dict is None or type(Dict) is dict, "Arg Dict must be a dictionary of properties (fed to the plotting function) !" - assert indt is None or type(indt) is int or hasattr(indt,'__iter__'), "Arg indt must be a int or an iterable (index) !" - assert t is None or type(t) is float or hasattr(indt,'__iter__'), "Arg t must be a float or an iterable (time) !" - assert all([type(bb) is bool for bb in [draw,a4]]), "Args [draw,a4] must be bool !" - - # Prepare selected input - Tab_t = Obj.t - ind = tfh.get_indt(Tab_t=Tab_t, indt=indt, t=t, defind=-1, out=int, Test=Test)[0] - - if not Obj._Tab[Qx] is None: - Qxx = np.abs(Obj._Tab[Qx]['vRef'][ind,:]) if Abs else Obj._Tab[Qx]['vRef'][ind,:] - else: - warnings.warn("Requested quantity ("+Qx+") is not available !") - Qxx = np.nan*np.ones((Obj.NRef,)) - if not Obj._Tab[Qy] is None: - Qyy = np.abs(Obj._Tab[Qy]['vRef'][ind,:]) if Abs else Obj._Tab[Qy]['vRef'][ind,:] - else: - warnings.warn("Requested quantity ("+Qy+") is not available !") - Qyy = np.nan*np.ones((Obj.NRef,)) - QxName = Obj._Tabs_LTXUnits[Qx]['LTX'] - QyName = Obj._Tabs_LTXUnits[Qy]['LTX'] - Qxunit = Obj._Tabs_LTXUnits[Qx]['units'] - Qyunit = Obj._Tabs_LTXUnits[Qy]['units'] - - xlim = _get_xylim(Qx, Qxx, lim=xlim, xy='x') - ylim = _get_xylim(Qy, Qyy, lim=ylim, xy='y') - - if Dict is None: - Dict = dict(tfd.Eq2DPlotVsDict) - - # Plot - if ax is None: - labx = QxName + r" (" + Qxunit + r")" if len(Qxunit)>0 else QxName - laby = QyName + r" (" + Qyunit + r")" if len(Qyunit)>0 else QyName - ax = tfd.Plot_Eq2D_Vs_DefAxes(a4=a4) - title = Obj.Id.Name + "\n"+Obj.Id.Exp+" {0:05.0f}".format(Obj.Id.shot) - if not hasattr(ind,'__iter__'): - title = title+" t = {0:06.3f} s".format(Tab_t[ind]) - title = title + r" $\|$"+QyName+r"$\|$ vs $\|$"+QxName+r"$\|$" if Abs else title + " "+QyName+r" vs "+QxName - ax.set_title(title) - ax.set_xlabel(labx) - ax.set_ylabel(laby) - - if hasattr(ind,'__iter__'): - del Dict['color'], Dict['mec'] - col = ['k','b','r','g','c','m','y'] - for ii in range(0,len(ind)): - ax.plot(Qxx[ii,:], Qyy[ii,:], label=r"t = {0:06.3f} s".format(Tab_t[ind[ii]]), color=col[ii%len(col)], mec=col[ii%len(col)], **Dict) - else: - ax.plot(Qxx, Qyy, **Dict) - - if not xlim is None: - ax.set_xlim(**xlim) - if not ylim is None: - ax.set_ylim(**ylim) - - if not LegDict is None: - ax.legend(**LegDict) - if draw: - ax.figure.canvas.draw() - return ax - - - - - - -""" -############################################################################### -############################################################################### - Eq2D plotting - interactive -############################################################################### -""" - - - -def _Eq2D_plot_inter(Obj, Quant, plotfunc='contour', indt=None, t=None, lvls=None, clab=False, Cdict=None, RadDict=None, PolDict=None, MagAxDict=None, SepDict=None, LegDict=None, ZRef='MagAx', NP=100, Ratio=-0.1, - ylim=None, VType='Tor', NaNout=True, Abs=True, cbar=False, draw=True, a4=False, Test=True): - if Test: - assert Obj.Id.Cls=='Eq2D', "Arg Obj must be a tfm.Eq2D instance !" - if type(Quant) is str: - assert Quant in Obj.Tabs_vPts+['MagAx','Sep']+['rad','pol'], "Arg Quant must be a key in self.Tabs_vPts + ['MagAx','Sep']+['rad','pol'] !" - if hasattr(Quant,'__iter__'): - assert len(Quant)<=5, "Arg Quant cannot have len()>3 !" - assert all([ss in Obj.Tabs_vPts+['MagAx','Sep']+['rad','pol'] for ss in Quant]), "Arg Quant can only contains keys in self.Tabs_vPts + ['MagAx','Sep'] !" - assert len([ss for ss in Quant if not ss in ['MagAx','Sep']+['rad','pol']])<=1, "Arg Quant cannot contain more than one 2D mappable quantity from self.Tabs_vPts !" - assert type(ZRef) in [float,np.float64] or ZRef=='MagAx', "Arg ZRef must be float or 'MagAx' (for average position of MagAx) !" - assert plotfunc in ['contour','contourf','scatter','imshow'], "Arg plotfunc must be in ['contour','contouf','scatter','imshow'] !" - assert lvls is None or type(lvls) in [int,float] or hasattr(lvls,'__iter__'), "Arg lvls must be a value or an iterable of values !" - assert indt is None or type(indt) is int, "Arg indt must be a int (index) !" - assert t is None or type(t) in [int,float,np.float64], "Arg t must be a float (time) !" - assert all([dd is None or type(dd) is dict for dd in [Cdict,MagAxDict,SepDict]]), "Args [Cdict,MagAxDict,SepDict] must be dictionaries of properties (fed to plotfunc and plot()) !" - assert all([type(bb) is bool for bb in [clab,draw,a4]]), "Args [draw,a4] must be bool !" - - - # Prepare input - Tab_t = Obj.t - ind = tfh.get_indt(Tab_t=Tab_t, indt=indt, t=t, defind=0, out=int, Test=Test)[0] - PtsCross = Obj.PtsCross - Quant = Quant if hasattr(Quant,'__iter__') else [Quant] - lq = [ss for ss in Quant if not ss in ['MagAx','Sep']+['rad','pol']] - assert len(lq)==1 - if not eval('Obj.'+lq[0]) is None: - QQ = np.abs(eval('Obj.'+lq[0])) if Abs else eval('Obj.'+lq[0]) - else: - warnings.warn("Requested quantity ("+lq[0]+") is not available !") - QQ = np.nan*np.ones((Obj.Nt,Obj.NP)) - if NaNout: - for ii in range(0,Obj.Nt): - indout = ~Path(Obj.Sep[ii].T).contains_points(Obj.PtsCross.T) - QQ[ii,indout] = np.nan - QName = Obj._Tabs_LTXUnits[lq[0]]['LTX'] - Qunit = Obj._Tabs_LTXUnits[lq[0]]['units'] - Qrad, Qpol, AvD = None, None, None - if 'rad' in Quant or 'pol' in Quant: - Qrad = Obj.get_RadDir(PtsCross, Test=Test) - Qpol = [] - for ii in range(0,Obj.Nt): - Qpol.append(np.array([-Qrad[ii][1,:], Qrad[ii][0,:]])) - if NaNout: - indout = ~Path(Obj.Sep[ii].T).contains_points(PtsCross.T) - Qrad[ii][:,indout] = np.nan - Qpol[ii][:,indout] = np.nan - AvDry = np.nanmean(np.diff(np.unique(PtsCross[0,:]))) - AvDz = np.nanmean(np.diff(np.unique(PtsCross[1,:]))) - AvD = np.hypot(AvDry, AvDz) - - DRY = [np.nanmin(Obj.PtsCross[0,:]), np.nanmax(Obj.PtsCross[0,:])] - DRY = [DRY[0]-Ratio*np.diff(DRY), DRY[1]+Ratio*np.diff(DRY)] - ZRef = np.nanmean(Obj.MagAx[:,1]) if ZRef=='MagAx' else ZRef - Ptsrz = np.array([np.sort(np.append(np.linspace(DRY[0],DRY[1],NP),np.nanmean(Obj.MagAx[:,0]))), ZRef*np.ones((NP+1,))]) - Ptsval = Obj.interp(Ptsrz, Quant=lq[0], deg=3, Test=Test) - if not eval('Obj.'+lq[0]) is None: - Ptsval = np.abs(Ptsval) if Abs else Ptsval - else: - Ptsval = np.nan*np.ones((Obj.Nt,NP+1)) - ylim = _get_xylim(lq[0], Ptsval, lim=ylim, xy='y') - - Cdict = dict(tfd.Eq2DPlotDict[plotfunc]) if Cdict is None else Cdict - if plotfunc in ['contour','contourf']: - if lvls is None and not 'levels' in Cdict.keys(): - Cdict['levels'] = np.linspace(np.nanmin(QQ), np.nanmax(QQ), 10) - else: - Cdict['levels'] = lvls if lvls is not None else Cdict['levels'] - Cdict['levels'] = np.unique(Cdict['levels']) if hasattr(Cdict['levels'],'__iter__') else [lvls] - RadDict = dict(tfd.Eq2DPlotRadDict) if RadDict is None and 'rad' in Quant else RadDict - PolDict = dict(tfd.Eq2DPlotPolDict) if PolDict is None and 'pol' in Quant else PolDict - MagAxDict = tfd.Eq2DMagAxDict if MagAxDict is None else MagAxDict - SepDict = tfd.Eq2DSepDict if SepDict is None else SepDict - - indSepHFS, indSepLFS = [], [] - for ii in range(0,Obj.Nt): - inds = Obj.Sep[ii][0,:]>Obj.MagAx[ii,0] - indSep = np.abs(Obj.Sep[ii][1,:]-ZRef) - indSephfs = np.copy(indSep) - indSephfs[inds] = np.nan - indSep[~inds] = np.nan - indSepHFS.append(np.nanargmin(indSephfs)) - indSepLFS.append(np.nanargmin(indSep)) - - XX0, XX1, extent = None, None, None - if not plotfunc=='scatter': - QQ, X0, X1, nx0, nx1 = TFGG.Remap_2DFromFlat(np.ascontiguousarray(PtsCross), [qq for qq in QQ], epsx0=None, epsx1=None) - QQ = [qq.T for qq in QQ] # for plotting - if plotfunc=='imshow': - extent = (np.nanmin(X0),np.nanmax(X0),np.nanmin(X1),np.nanmax(X1)) - else: - XX0 = np.tile(X0,(nx1,1)) - XX1 = np.tile(X1,(nx0,1)).T - - # Plot background (and set xylim) - La = _Eq2D_plot_inter_Bckg(Obj, Ptsval, QName, Qunit, NP=NP, Abs=Abs, VType=VType, cbar=cbar, a4=a4) - DxPtsCross = PtsCross[0,:].max()-PtsCross[0,:].min() - DyPtsCross = PtsCross[1,:].max()-PtsCross[1,:].min() - xlim = {'1DTime':[Obj.t.min(), Obj.t.max()], '1DProf':[Ptsrz[0,:].min(), Ptsrz[0,:].max()], '2DProf':[PtsCross[0,:].min()-0.1*DxPtsCross, PtsCross[0,:].max()+0.1*DxPtsCross]} - ylim = {'1DProf':[ylim['bottom'],ylim['top']], '2DProf':[PtsCross[1,:].min()-0.1*DyPtsCross, PtsCross[1,:].max()+0.1*DyPtsCross]} - ylim['1DTime'] = ylim['1DProf'] - La['1DTime'][0].set_xlim(xlim['1DTime']) - La['1DTime'][0].set_ylim(ylim['1DTime']) - La['1DProf'][0].set_xlim(xlim['1DProf']) - La['1DProf'][0].set_ylim(ylim['1DProf']) - La['2DProf'][0].set_xlim(xlim['2DProf']) - La['2DProf'][0].set_ylim(ylim['2DProf']) - La['2DProf'][0].set_aspect(aspect='equal',adjustable='datalim') - can = La['2DProf'][0].figure.canvas - - can.draw() - xlim['2DProf'] = La['2DProf'][0].get_xlim() - ylim['2DProf'] = La['2DProf'][0].get_ylim() - - Bckgrd2DProf = can.copy_from_bbox(La['2DProf'][0].bbox) - BckgrdTime = can.copy_from_bbox(La['1DTime'][0].bbox) - Bckgrd1DProf = can.copy_from_bbox(La['1DProf'][0].bbox) - Bckgrd = {'2DProf':Bckgrd2DProf, '1DProf':Bckgrd1DProf, '1DTime':BckgrdTime} - - LaTxt = None - - # Implement interactivity - Keyhandler = _keyhandler(La, LaTxt, Bckgrd, can, finit=_Eq2D_plot_inter_init, fup=_Eq2D_plot_inter_up, - ind=ind, QQ=QQ, PtsCross=PtsCross, Ptsrz=Ptsrz, Ptsval=Ptsval, t=Obj.t, Quant=Quant, Qrad=Qrad, Qpol=Qpol, AvD=AvD, MagAx=Obj.MagAx, Sep=Obj.Sep, plotfunc=plotfunc, XX0=XX0, XX1=XX1, extent=extent, - indSepHFS=indSepHFS, indSepLFS=indSepLFS, Cdict=Cdict, RadDict=RadDict, PolDict=PolDict, MagAxDict=MagAxDict, SepDict=SepDict, cbar=cbar, clab=clab, xlim=xlim, ylim=ylim) - def on_press(event): - Keyhandler.onkeypress(event) - def on_clic(event): - Keyhandler.mouseclic(event) - Keyhandler.can.mpl_connect('key_press_event', on_press) - Keyhandler.can.mpl_connect('key_release_event', on_press) - Keyhandler.can.mpl_connect('button_press_event', on_clic) - - return La - - - - - -#################################################################### - -def _Eq2D_plot_inter_Bckg(Obj, Ptsval, QName, Qunit, NP=50, Abs=True, VType='Tor', cbar=True, a4=False): - - La = tfd.Plot_Eq2D_Inter_DefAxes(VType=VType, cbar=cbar, a4=a4) - title = Obj.Id.Name + "\n"+Obj.Id.Exp+" {0:05.0f}".format(Obj.Id.shot)+" t = {0:06.3f} s".format(Obj.t[0]) - title = title + r" $\|$"+QName+r"$\|$" if Abs else title + " "+QName - La['2DProf'][0].set_title(title) - if cbar: - La['Misc'][0].set_title(Qunit) - - laby = QName + r" (" + Qunit + r")" if len(Qunit)>0 else QName - La['1DProf'][0].set_ylabel(laby) - La['1DTime'][0].set_ylabel(laby) - - tplot = np.concatenate(tuple([np.append(Obj.t,np.nan) for ii in range(0,NP)])) - Ptsplot = np.concatenate(tuple([np.append(Ptsval[:,ii],np.nan) for ii in range(0,NP)])) - La['1DTime'][0].plot(tplot, Ptsplot, c=(0.8,0.8,0.8), ls='-', lw=1.) - - return La - - -def _Eq2D_plot_inter_init(La, ind, QQ, PtsCross, Ptsrz, Ptsval, t, Quant=None, Qrad=None, Qpol=None, AvD=None, MagAx=None, Sep=None, plotfunc='contour', XX0=None, XX1=None, extent=None, - indSepHFS=None, indSepLFS=None, Cdict=None, RadDict=None, PolDict=None, MagAxDict=None, SepDict=None, cbar=True, clab=True, xlim=None, ylim=None): - - # Plotting on 2DProf - if plotfunc=='scatter': - CS = La['2DProf'][0].scatter(PtsCross[0,:], PtsCross[1,:], c=QQ[ind,:], **Cdict) - else: - if plotfunc=='imshow': - CS = La['2DProf'][0].imshow(QQ[ind], aspect='auto', interpolation='bilinear', origin='lower', extent=extent, **Cdict) - else: - if plotfunc=='contour': - CS = La['2DProf'][0].contour(XX0, XX1, QQ[ind], **Cdict) - elif plotfunc=='contourf': - CS = La['2DProf'][0].contourf(XX0, XX1, QQ[ind], **Cdict) - if clab and plotfunc=='contour': - plt.clabel(CS, Cdict['levels'], inline=1, fontsize=10, fmt='%03.0f') - if cbar: - La['2DProf'][0].figure.colorbar(CS, cax=La['Misc'][0]) - - # Definign a draw method and parameters for the 2D plot - if plotfunc in ['contour','contourf']: - CS.axes = La['2DProf'][0] - CS.figure = La['2DProf'][0].figure - def draw(self,renderer): - for cc in self.collections: cc.draw(renderer) - CS.draw = types.MethodType(draw,CS,None) - - QVrad = La['2DProf'][0].quiver(PtsCross[0,:], PtsCross[1,:], Qrad[ind][0,:]*AvD, Qrad[ind][1,:]*AvD, label='Rad.', **RadDict) if 'rad' in Quant else None - QVpol = La['2DProf'][0].quiver(PtsCross[0,:], PtsCross[1,:], Qpol[ind][0,:]*AvD, Qpol[ind][1,:]*AvD, label='Pol.', **PolDict) if 'pol' in Quant else None - - Ax, = La['2DProf'][0].plot(MagAx[ind,0:1], MagAx[ind,1:2], label=r"MagAx", **MagAxDict) if 'MagAx' in Quant else None - Sp, = La['2DProf'][0].plot(Sep[ind][0,:], Sep[ind][1,:], label=r"Sep", **SepDict) if 'Sep' in Quant else None - - # Plotting on 1DProf - Cut, = La['1DProf'][0].plot(Ptsrz[0,:], Ptsval[ind,:], c='k', lw=1., ls='-') - CutAx = La['1DProf'][0].axvline(MagAx[ind,0], ls='-', lw=1, c='k') - CutSp1 = La['1DProf'][0].axvline(Sep[ind][0,indSepHFS[ind]], c='k', lw=1., ls='--') - CutSp2 = La['1DProf'][0].axvline(Sep[ind][0,indSepLFS[ind]], c='k', lw=1., ls='--') - - - # plotting on 1DTime - t1 = La['1DTime'][0].axvline(t[ind], ls='--', lw=1, c='k') - - La['2DProf'][0].set_xlim(xlim['2DProf']) - La['2DProf'][0].set_ylim(ylim['2DProf']) - La['1DProf'][0].set_xlim(xlim['1DProf']) - La['1DProf'][0].set_ylim(ylim['1DProf']) - La['1DTime'][0].set_xlim(xlim['1DTime']) - La['1DTime'][0].set_ylim(ylim['1DTime']) - - return {'CS':CS, 'QVrad':QVrad, 'QVpol':QVpol, 'Ax':Ax, 'Sp':Sp, 'Cut':[Cut], 'CutAx':[CutAx], 'CutSp1':[CutSp1], 'CutSp2':[CutSp2], 'tl':[t1]} - - - - -def _Eq2D_plot_inter_up(La, dobj, ind, QQ, PtsCross, Ptsrz, Ptsval, t, Quant=None, Qrad=None, Qpol=None, AvD=None, MagAx=None, Sep=None, plotfunc='contour', XX0=None, XX1=None, extent=None, indSepHFS=None, indSepLFS=None, - Cdict=None, RadDict=None, PolDict=None, clab=False, xlim=None, ylim=None): - - # Delete former elements - del dobj['CS'], dobj['QVrad'], dobj['QVpol'] - - # Plotting on 2DProf - if plotfunc=='scatter': - dobj['CS'] = La['2DProf'][0].scatter(PtsCross[0,:], PtsCross[1,:], c=QQ[ind,:], **Cdict) - else: - if plotfunc=='imshow': - dobj['CS'] = La['2DProf'][0].imshow(QQ[ind], aspect='auto', interpolation='bilinear', origin='lower', extent=extent, **Cdict) - else: - if plotfunc=='contour': - dobj['CS'] = La['2DProf'][0].contour(XX0, XX1, QQ[ind], **Cdict) - elif plotfunc=='contourf': - dobj['CS'] = La['2DProf'][0].contourf(XX0, XX1, QQ[ind], **Cdict) - if clab and plotfunc=='contour': - plt.clabel(dobj['CS'], Cdict['levels'], inline=1, fontsize=10, fmt='%03.0f') - - # Definign a draw method and parameters for the 2D plot - if plotfunc in ['contour','contourf']: - dobj['CS'].axes = La['2DProf'][0] - dobj['CS'].figure = La['2DProf'][0].figure - def draw(self,renderer): - for cc in self.collections: cc.draw(renderer) - dobj['CS'].draw = types.MethodType(draw,dobj['CS'],None) - - dobj['QVrad'] = La['2DProf'][0].quiver(PtsCross[0,:], PtsCross[1,:], Qrad[ind][0,:]*AvD, Qrad[ind][1,:]*AvD, label='Rad.', **RadDict) if 'rad' in Quant else None - dobj['QVpol'] = La['2DProf'][0].quiver(PtsCross[0,:], PtsCross[1,:], Qpol[ind][0,:]*AvD, Qpol[ind][1,:]*AvD, label='Pol.', **PolDict) if 'pol' in Quant else None - - if dobj['Ax'] is not None: - dobj['Ax'].set_data(MagAx[ind,0:1], MagAx[ind,1:2]) - if dobj['Sp'] is not None: - dobj['Sp'].set_data(Sep[ind][0,:], Sep[ind][1,:]) - - # Plotting on 1DProf - dobj['Cut'][-1].set_data(Ptsrz[0,:], Ptsval[ind,:]) - dobj['CutAx'][-1].set_xdata(MagAx[ind,0]) - dobj['CutSp1'][-1].set_xdata(Sep[ind][0,indSepHFS[ind]]) - dobj['CutSp2'][-1].set_xdata(Sep[ind][0,indSepLFS[ind]]) - - # plotting on 1DTime - dobj['tl'][-1].set_xdata(t[ind]) - - La['2DProf'][0].set_xlim(xlim['2DProf']) - La['2DProf'][0].set_ylim(ylim['2DProf']) - La['1DProf'][0].set_xlim(xlim['1DProf']) - La['1DProf'][0].set_ylim(ylim['1DProf']) - La['1DTime'][0].set_xlim(xlim['1DTime']) - La['1DTime'][0].set_ylim(ylim['1DTime']) - - return dobj - - - - - - - -# ------------ Interactive key handler ---------------- - -class _keyhandler(): - def __init__(self, La, LaTxt, Bckgrd, can, finit=_Eq2D_plot_inter_init, fup=_Eq2D_plot_inter_up, - ind=None, QQ=None, PtsCross=None, Ptsrz=None, Ptsval=None, t=None, Quant=None, Qrad=None, Qpol=None, AvD=None, MagAx=None, Sep=None, plotfunc=None, XX0=None, XX1=None, extent=None, - indSepHFS=None, indSepLFS=None, Cdict=None, RadDict=None, PolDict=None, MagAxDict=None, SepDict=None, cbar=True, clab=True, xlim=None, ylim=None): - self.t, self.ind = t, ind - self.La, self.LaTxt = La, LaTxt - self.Bckgrd = Bckgrd - self.can = can - self.finit, self.fup = finit, fup - - self.QQ = QQ - self.PtsCross = PtsCross - self.Ptsrz, self.Ptsval = Ptsrz, Ptsval - self.Quant = Quant - self.Qrad, self.Qpol, self.AvD = Qrad, Qpol, AvD - self.MagAx, self.Sep = MagAx, Sep - self.plotfunc = plotfunc - self.XX0, self.XX1, self.extent = XX0, XX1, extent - self.indSepHFS, self.indSepLFS = indSepHFS, indSepLFS - self.Cdict, self.RadDict, self.PolDict, self.MagAxDict, self.SepDict = Cdict, RadDict, PolDict, MagAxDict, SepDict - self.cbar, self.clab = cbar, clab - self.xlim, self.ylim = xlim, ylim - - self.initplot() - - def initplot(self): - - self.dobj = self.finit(self.La, self.ind, self.QQ, self.PtsCross, self.Ptsrz, self.Ptsval, self.t, Quant=self.Quant, Qrad=self.Qrad, Qpol=self.Qpol, AvD=self.AvD, MagAx=self.MagAx, Sep=self.Sep, - plotfunc=self.plotfunc, XX0=self.XX0, XX1=self.XX1, extent=self.extent, - indSepHFS=self.indSepHFS, indSepLFS=self.indSepLFS, Cdict=self.Cdict, RadDict=self.RadDict, PolDict=self.PolDict, MagAxDict=self.MagAxDict, SepDict=self.SepDict, cbar=self.cbar, clab=self.clab, - xlim=self.xlim, ylim=self.ylim) - self.La['2DProf'][0].draw_artist(self.dobj['CS']) - if self.dobj['QVrad'] is not None: - self.La['2DProf'][0].draw_artist(self.dobj['QVrad']) - if self.dobj['QVpol'] is not None: - self.La['2DProf'][0].draw_artist(self.dobj['QVpol']) - if self.dobj['Ax'] is not None: - self.La['2DProf'][0].draw_artist(self.dobj['Ax']) - if self.dobj['Sp'] is not None: - self.La['2DProf'][0].draw_artist(self.dobj['Sp']) - self.can.blit(self.La['2DProf'][0].bbox) - - self.La['1DTime'][0].draw_artist(self.dobj['tl'][0]) - self.can.blit(self.La['1DTime'][0].bbox) - #self.LaTxt['Time'][0].draw_artist(self.dobj['tstr'][0]) - #self.can.blit(self.LaTxt['Time'][0].bbox) - self.La['1DProf'][0].draw_artist(self.dobj['Cut'][0]) - self.La['1DProf'][0].draw_artist(self.dobj['CutAx'][0]) - self.La['1DProf'][0].draw_artist(self.dobj['CutSp1'][0]) - self.La['1DProf'][0].draw_artist(self.dobj['CutSp2'][0]) - self.can.blit(self.La['1DProf'][0].bbox) - - def update_t(self): - self.can.restore_region(self.Bckgrd['2DProf']) - self.can.restore_region(self.Bckgrd['1DProf']) - self.can.restore_region(self.Bckgrd['1DTime']) - - self.dobj = self.fup(self.La, self.dobj, self.ind, self.QQ, self.PtsCross, self.Ptsrz, self.Ptsval, self.t, Quant=self.Quant, Qrad=self.Qrad, Qpol=self.Qpol, AvD=self.AvD, MagAx=self.MagAx, Sep=self.Sep, - plotfunc=self.plotfunc, XX0=self.XX0, XX1=self.XX1, extent=self.extent, indSepHFS=self.indSepHFS, indSepLFS=self.indSepLFS, - Cdict=self.Cdict, RadDict=self.RadDict, PolDict=self.PolDict, clab=self.clab, xlim=self.xlim, ylim=self.ylim) - - self.La['2DProf'][0].draw_artist(self.dobj['CS']) - if self.dobj['QVrad'] is not None: - self.La['2DProf'][0].draw_artist(self.dobj['QVrad']) - if self.dobj['QVpol'] is not None: - self.La['2DProf'][0].draw_artist(self.dobj['QVpol']) - if self.dobj['Ax'] is not None: - self.La['2DProf'][0].draw_artist(self.dobj['Ax']) - if self.dobj['Sp'] is not None: - self.La['2DProf'][0].draw_artist(self.dobj['Sp']) - self.can.blit(self.La['2DProf'][0].bbox) - - self.La['1DTime'][0].draw_artist(self.dobj['tl'][-1]) - self.can.blit(self.La['1DTime'][0].bbox) - #self.LaTxt['Time'][0].draw_artist(self.dobj['tstr'][0]) - #self.can.blit(self.LaTxt['Time'][0].bbox) - self.La['1DProf'][0].draw_artist(self.dobj['Cut'][-1]) - self.La['1DProf'][0].draw_artist(self.dobj['CutAx'][-1]) - self.La['1DProf'][0].draw_artist(self.dobj['CutSp1'][-1]) - self.La['1DProf'][0].draw_artist(self.dobj['CutSp2'][-1]) - self.can.blit(self.La['1DProf'][0].bbox) - - def onkeypress(self,event): - if event.name is 'key_press_event' and event.key == 'left': - self.ind -= 1 - self.ind = self.ind%self.t.size - self.update_t() - elif event.name is 'key_press_event' and event.key == 'right': - self.ind += 1 - self.ind = self.ind%self.t.size - self.update_t() - - def mouseclic(self,event): - if event.button == 1 and event.inaxes in self.La['1DTime']: - self.ind = np.argmin(np.abs(self.t-event.xdata)) - self.update_t() - - - - diff --git a/tofu/inv/ToFu_Inv.py b/tofu/inv/ToFu_Inv.py deleted file mode 100644 index 68e12780e..000000000 --- a/tofu/inv/ToFu_Inv.py +++ /dev/null @@ -1,1246 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Sep 26 16:22:47 2014 - -@author: didiervezinet -""" - -import numpy as np -import scipy.sparse as scpsp -import scipy.sparse.linalg as scpsplin -import scipy.optimize as scpop -import ToFu_Mesh as TFM -import ToFu_MatComp as TFMC -import ToFu_Defaults as TFD -import ToFu_PathFile as TFPF -import ToFu_Treat as TFT -import ToFu_PostTreat as TFPT -import matplotlib.pyplot as plt -import matplotlib.animation as anim -import matplotlib.mlab as mlab -import matplotlib as mpl -from matplotlib import path -from matplotlib import _cntr as cntr -import datetime as dtm -import types - - -# Nomenclature : 'Linearity_Parameter_Version' -# -# Linearity : Function name starts with 'InvLin' if it solves linear problems, 'InvNonLin' else -# Parameter : A short name or acronym, sufficently explicit, to identify the method used to determine the regularisation parameter (e.g.: DisPrinc, GenCross, AugTikho...) -# Version : 'V' + version number of the function - -# Each function should include a short description of its philosophy + one or two relevant references - - -####### Intermediate pre-conditioning ########### - -SpFcNames = ['csr','csc','coo','bsr','dia','dok','lil'] -SpFcl = [scpsp.csr_matrix, scpsp.csc_matrix, scpsp.coo_matrix, scpsp.bsr_matrix, scpsp.dia_matrix, scpsp.dok_matrix, scpsp.lil_matrix] -SpIsl = [scpsp.isspmatrix_csr, scpsp.isspmatrix_csc, scpsp.isspmatrix_coo, scpsp.isspmatrix_bsr, scpsp.isspmatrix_dia, scpsp.isspmatrix_dok, scpsp.isspmatrix_lil] - -SpFc, SpIs = {}, {} -for ii in range(0,len(SpFcNames)): - SpFc[SpFcNames[ii]] = SpFcl[ii] - SpIs[SpFcNames[ii]] = SpIsl[ii] - - -def Default_sol(BF2, TMat, data0, sigma0=None, N=3): - def sol0_Mode0(Points): - R = np.hypot(Points[0,:],Points[1,:]) - return np.exp(-(R-1.70)**2/0.10**2 - (Points[2,:]-0.05)**2/0.15**2) - - def sol0_Mode1(Points): - R = np.hypot(Points[0,:],Points[1,:]) - Z = Points[2,:] - return np.exp(-(R-1.70)**2/0.20**2 - (Z-0.05)**2/0.30**2) - 0.50*np.exp(-(R-1.67)**2/0.10**2 - (Z-0.05)**2/0.15**2) - - def sol0_Mode2(Points): - R = np.hypot(Points[0,:],Points[1,:]) - Z = Points[2,:] - return (1.+np.tanh((R-1.35)/0.10))*(1.-np.tanh((R-1.85)/0.15)) * (1.+np.tanh((Z+0.35)/0.20))*(1.-np.tanh((Z-0.45)/0.20)) - - if not sigma0 is None: - data0bis = data0/sigma0 - TMatbis = np.diag(1./sigma0).dot(TMat) - else: - data0bis = data0[:] - TMatbis = TMat[:] - - sol, a, Chi2 = np.nan*np.ones((N,TMat.shape[1])), np.nan*np.ones((N,)), np.nan*np.ones((N,)) - for ii in range(0,N): - sol[ii,:] = BF2.get_Coefs( ff = locals()['sol0_Mode'+str(ii)] )[0] - a[ii] = ((sol[ii,:].dot(TMatbis.T)).dot(data0bis))/((sol[ii,:].dot(TMatbis.T)).dot(TMatbis.dot(sol[ii,:]))) - Chi2[ii] = (a[ii]*TMatbis.dot(sol[ii,:])-data0bis).T.dot(a[ii]*TMatbis.dot(sol[ii,:])-data0bis) - return a[np.nanargmin(Chi2)]*sol[np.nanargmin(Chi2),:] - - -############################################################################################################################################## -############################################################################################################################################## -############################################################################################################################################## -########### Main routines -############################################################################################################################################## -############################################################################################################################################## - - - - -def InvChoose(TMat, data, t, BF2, sigma=None, Dt=None, mu0=TFD.mu0, SolMethod='InvLin_AugTikho_V1', Deriv='D2N2', IntMode='Vol', Cond=None, ConvCrit=TFD.ConvCrit, Sparse=True, SpType='csr', Pos=True, KWARGS=None, timeit=True, Verb=False, VerbNb=None): - if timeit: - t1 = dtm.datetime.now() - - t = t.flatten() - if sigma is None: - sigma = 0.5*np.mean(np.mean(data))*np.ones((TMat.shape[0],)) - NdimSig = sigma.ndim - - if Dt is None: - indt = np.ones((t.size,),dtype=bool) - else: - if type(Dt) is float: - indt = np.nanargmin(np.abs(t-Dt)) - elif len(Dt)==2: - indt = (t>=Dt[0]) & (t<=Dt[1]) - t = t[indt] - data = data[indt,:] - if data.ndim==1: - data = data.reshape((1,data.size)) - if NdimSig==2: - sigma = sigma[indt,:] - #SigMean = np.mean(np.mean(sigma)) - - NMes, Nbf = TMat.shape - Nt = t.size - if SolMethod=='InvLin_AugTikho_V1' and Pos: - SolMethod = 'InvLinQuad_AugTikho_V1' - - if KWARGS is None: - if SolMethod in 'InvLin_AugTikho_V1': - KWARGS = {'a0':TFD.AugTikho_a0, 'b0':TFD.AugTikho_b0, 'a1':TFD.AugTikho_a1, 'b1':TFD.AugTikho_b1, 'd':TFD.AugTikho_d, 'ConvReg':True, 'FixedNb':True} - elif SolMethod == 'InvLin_DisPrinc_V1': - KWARGS = {'chi2Tol':TFD.chi2Tol, 'chi2Obj':TFD.chi2Obj} - elif SolMethod == 'InvLinQuad_AugTikho_V1': - KWARGS = {'a0':TFD.AugTikho_a0, 'b0':TFD.AugTikho_b0, 'a1':TFD.AugTikho_a1, 'b1':TFD.AugTikho_b1, 'd':TFD.AugTikho_d, 'ConvReg':True, 'FixedNb':True} - elif SolMethod == 'InvQuad_AugTikho_V1': - KWARGS = {'a0':TFD.AugTikho_a0, 'b0':TFD.AugTikho_b0, 'a1':TFD.AugTikho_a1, 'b1':TFD.AugTikho_b1, 'd':TFD.AugTikho_d, 'ConvReg':True, 'FixedNb':True} - - if VerbNb is None: - VerbNb = np.ceil(Nt/20.) - - # Getting initial solution - step 1/2 - if scpsp.issparse(TMat): - tmat = TMat.toarray() - else: - tmat = TMat.copy() - if NdimSig==2: - ssigm = np.mean(sigma,axis=0) - else: - ssigm = sigma.copy() - if data.ndim==1: - ddat = data.copy() - else: - ddat = np.copy(data[0,:]) - sol0 = Default_sol(BF2, tmat, ddat, sigma0=ssigm, N=3) - - # Using discrepancy principle on averaged signal - LL, mm = BF2.get_IntOp(Deriv=Deriv, Mode=IntMode) - - if mm==2: - LL = LL[0]+LL[1] - b = ddat/ssigm # DB - Tm = np.diag(1./ssigm).dot(tmat) # DB - Tb = Tm.T.dot(b) # DB - TT = Tm.T.dot(Tm) # DB - sol0, mu0 = InvLin_DisPrinc_V1_Sparse(NMes, Nbf, SpFc[SpType](Tm), SpFc[SpType](TT), SpFc[SpType](LL), Tb, b, sol0, ConvCrit=ConvCrit, mu0=mu0, chi2Tol=0.2, chi2Obj=1.2, M=None, Verb=True)[0:2] # DB - - # Launching inversions with chosen method - step 2/2 of initial solution included below - Sol, Mu, Chi2N, R, Nit, Spec = np.nan*np.ones((Nt,Nbf)), np.nan*np.ones((Nt,)), np.nan*np.ones((Nt,)), np.nan*np.ones((Nt,)), np.nan*np.ones((Nt,)), [[] for ii in range(0,Nt)] - NormL = sol0.dot(LL.dot(sol0)) - if Sparse: - func = globals()[SolMethod+'_Sparse'] - if not SpIs[SpType](TMat): - TMat = SpFc[SpType](TMat) - if not SpIs[SpType](LL): - LL = SpFc[SpType](LL) - b = ddat/ssigm - Tm = np.diag(1./ssigm).dot(tmat) - Tb = Tm.T.dot(b) - TT = SpFc[SpType](Tm.T.dot(Tm)) - sol0, mu0, chi2N0, R0, Nit0, spec0 = func(NMes, Nbf, SpFc[SpType](Tm), TT, LL, Tb, b, sol0, ConvCrit=ConvCrit, mu0=mu0, M=None, Verb=False, **KWARGS) - M = scpsplin.inv((TT+mu0*LL/sol0.dot(LL.dot(sol0))).tocsc()) - # Beware of element-wise operations vs matrix operations !!!! - assert not mm==0, "Inversion-regularisation routines require a quadratic operator !" - if NdimSig==2: - b = data/sigma - for ii in range(0,Nt): - if ii==0 or (ii+1)%VerbNb==0: - print " Running inversion for time step ", ii+1,' / ', Nt - Tm = np.diag(1./sigma[ii,:]).dot(tmat) - Tb = np.concatenate(tuple([(Tm.T.dot(b[ii,:])).reshape((1,Nbf)) for ii in range(0,Nt)]),axis=0) - TT = SpFc[SpType](Tm.T.dot(Tm)) - Sol[ii,:], Mu[ii], Chi2N[ii], R[ii], Nit[ii], Spec[ii] = func(NMes, Nbf, SpFc[SpType](Tm), TT, LL, Tb[ii,:], b[ii,:], sol0, ConvCrit=ConvCrit, mu0=mu0, NormL=NormL, M=M, Verb=Verb, **KWARGS) - sol0[:] = Sol[ii,:] - mu0 = Mu[ii] - #print ' Nit or Ntry : ', Spec[ii][0] - else: - b = data.dot(np.diag(1./sigma)) - Tm = np.diag(1./sigma).dot(tmat) - Tb = np.concatenate(tuple([(Tm.T.dot(b[ii,:])).reshape((1,Nbf)) for ii in range(0,Nt)]),axis=0) - TT = SpFc[SpType](Tm.T.dot(Tm)) - Tm = SpFc[SpType](Tm) - for ii in range(0,Nt): - if ii==0 or (ii+1)%VerbNb==0: - print " Running inversion for time step ", ii+1,' / ', Nt, KWARGS['ConvReg'], KWARGS['FixedNb'] - Sol[ii,:], Mu[ii], Chi2N[ii], R[ii], Nit[ii], Spec[ii] = func(NMes, Nbf, Tm, TT, LL, Tb[ii,:], b[ii,:], sol0, ConvCrit=ConvCrit, mu0=mu0, NormL=NormL, M=M, Verb=Verb, **KWARGS) - sol0[:] = Sol[ii,:] - mu0 = Mu[ii] - #print ' Nit or Ntry : ', Spec[ii][0] - - else: - func = globals()[SolMethod] - if scpsp.issparse(TMat): - TMat = TMat.toarray() - if scpsp.issparse(LL): - LL = LL.toarray() - - assert not mm==0, "Inversion-regularisation routines require a quadratic operator !" - if NdimSig==2: - b = data/sigma - for ii in range(0,Nt): - if ii==0 or (ii+1)%VerbNb==0: - print " Running inversion for time step ", ii+1,' / ', Nt - Tm = np.diag(1./sigma[ii,:]).dot(TMat) - Tb = np.concatenate(tuple([(Tm.T.dot(b[ii,:])).reshape((1,Nbf)) for ii in range(0,Nt)]),axis=0) - TT = Tm.T.dot(Tm) - Sol[ii,:], Mu[ii], Chi2N[ii], R[ii], Nit[ii], Spec[ii] = func(NMes, Nbf, Tm, TT, LL, Tb[ii,:], b[ii,:], sol0, ConvCrit=ConvCrit, mu0=mu0, Verb=Verb, **KWARGS) - sol0[:] = Sol[ii,:] - mu0 = Mu[ii] - #print ' Nit or Ntry : ', Spec[ii][0] - else: - b = data.dot(np.diag(1./sigma)) - Tm = np.diag(1./sigma).dot(TMat) - Tb = np.concatenate(tuple([(Tm.T.dot(b[ii,:])).reshape((1,Nbf)) for ii in range(0,Nt)]),axis=0) - TT = Tm.T.dot(Tm) - for ii in range(0,Nt): - if ii==0 or (ii+1)%VerbNb==0: - print " Running inversion for time step ", ii+1,' / ', Nt - Sol[ii,:], Mu[ii], Chi2N[ii], R[ii], Nit[ii], Spec[ii] = func(NMes, Nbf, Tm, TT, LL, Tb[ii,:], b[ii,:], sol0, ConvCrit=ConvCrit, mu0=mu0, Verb=Verb, **KWARGS) - sol0[:] = Sol[ii,:] - mu0 = Mu[ii] - #print ' Nit or Ntry : ', Spec[ii][0] - - """# ------- DB --------- - indview = 0 - f, (ax1,ax2) = plt.subplots(1,2) - ax1.axis('equal') - ax1 = BF2.plot(Coefs=Sol[indview,:], ax=ax1) - ax2.plot(data[indview,:],'k+') - ax2.plot(TMat.dot(Sol[indview,:]),'r-') - #print TMat.dot(Sol[indview,:])/data[indview,:] - plt.show() - """# -------------------- - if timeit: - t2 = dtm.datetime.now()-t1 - print t2 - else: - t2 = None - return Sol, t, data, sigma, Mu, Chi2N, R, Nit, Spec, t2 - - - -def InvRatio(TMat, data, t, BF2, indCorr, sigma=None, Dt=None, mu0=TFD.mu0, SolMethod='InvLin_AugTikho_V1', Deriv='D2N2', IntMode='Vol', Cond=None, ConvCrit=TFD.ConvCrit, Sparse=True, SpType='csr', Pos=True, KWARGS=None, timeit=True, Verb=False, VerbNb=None): - assert isinstance(indCorr,np.ndarray) and indCorr.ndim==1, "Arg indCorr must be a 1D np.ndarray !" - if indCorr.dtype in ['int','int64']: - ind = np.zeros((TMat.shape[0],),dtype=bool) - ind[indCorr] = True - indCorr = ind - - datatemp = data[:,~indCorr] - TMattemp = TMat[(~indCorr).nonzero()[0],:] - TMatCorr = TMat[indCorr.nonzero()[0],:] - if not sigma is None: - if sigma.ndim==2: - sigmatemp = sigma[:,~indCorr] - else: - sigmatemp = sigma[~indCorr] - else: - sigmatemp = None - Sol, tbis, datatemp, sigmatemp, Mu, Chi2N, R, Nit, Spec, t2 = InvChoose(TMattemp, datatemp, t, BF2, sigma=sigmatemp, Dt=Dt, mu0=mu0, SolMethod=SolMethod, Deriv=Deriv, IntMode=IntMode, Cond=Cond, ConvCrit=ConvCrit, Sparse=Sparse, SpType=SpType, Pos=Pos, KWARGS=KWARGS, timeit=timeit, Verb=Verb, VerbNb=VerbNb) - if Dt is None: - indt = np.ones((t.size,),dtype=bool) - else: - indt = (t>=Dt[0]) & (t<=Dt[1]) - dataCorr = data[:,indCorr] - Retro = np.empty((tbis.size,np.sum(indCorr))) - for ii in range(0,tbis.size): - Retro[ii,:] = TMatCorr.dot(Sol[ii,:]) - return dataCorr[indt,:], Retro, indCorr - - -def Corrdata(data, retro, sigma, Method='Poly', Deg=1, Group=True, plot=False, LNames=None, Com=''): - assert isinstance(data,np.ndarray) and isinstance(retro,np.ndarray) and data.shape==retro.shape, "Args data and retro must be np.ndarrays of same shape !" - Nt, Nm = data.shape - if Method=='Const': - Mean = np.mean(retro/data,axis=0) - if Group: - def ffcorr(x): - return np.mean(Mean)*x, Mean - else: - def ffcorr(x): - if x.ndim==2: - return np.tile(Mean,(Nt,1))*x, Mean - else: - return Mean*x, Mean - elif Method=='Poly': - if Group: - pp = np.polyfit(np.abs(data.flatten()), np.abs(retro.flatten()), Deg, rcond=None, full=False, w=None, cov=False) - def ffcorr(x): - return np.polyval(pp, x), pp - else: - PP = [np.polyfit(np.abs(data[:,ii]), np.abs(retro[:,ii]), Deg, rcond=None, full=False, w=None, cov=False) for ii in range(0,Nm)] - def ffcorr(x): - if x.ndim==2: - return np.concatenate(tuple([np.polyval(PP[ii], x[:,ii]).reshape((Nt,1)) for ii in range(0,Nm)]),axis=1), PP - else: - return np.array([np.polyval(PP[ii], x[ii]) for ii in range(0,Nm)]), PP - sigmabis, pp = ffcorr(sigma) - databis, pp = ffcorr(data) - if plot: - fW,fH,fdpi,axCol = 17,10,80,'w' - f = plt.figure(facecolor=axCol,figsize=(fW,fH),dpi=fdpi) - ax = f.add_axes([0.1,0.1,0.75,0.8],frameon=True,axisbg=axCol) - ax.set_title(r"Correction Coef. estimation for "+Com) - ax.set_xlabel(r"Measurements (a.u.)") - ax.set_ylabel(r"Retrofit (a.u.)") - if LNames is None: - LNames = range(0,Nm) - for ii in range(0,Nm): - ll = ax.plot(data[:,ii], retro[:,ii], ls='none', lw=2, marker='x', label=LNames[ii]) - if not Group: - indsort = np.argsort(data[:,ii]) - ax.plot(np.sort(data[:,ii]), (databis[:,ii])[indsort], ls='solid', lw=2, c=ll[0].get_color(), label=LNames[ii]+' fit') - if Group: - indsort = np.argsort(data.flatten()) - ax.plot(np.sort(data.flatten()), databis.flatten()[indsort], ls='solid', lw=2, c='k', label='Fit') - X = np.sort(data.flatten()) - ax.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.,prop={'size':10}) - ax.plot(X, X, lw=1, c='k', ls='dashed', label='y = x') - return databis, sigmabis, pp, ax - else: - return databis, sigmabis, pp, None - - -def InvCorrdata(TMat, data, t, BF2, indCorr, sigma=None, Dt=None, mu0=TFD.mu0, SolMethod='InvLin_AugTikho_V1', Deriv='D2N2', IntMode='Vol', Cond=None, ConvCrit=TFD.ConvCrit, Sparse=True, SpType='csr', Pos=True, KWARGS=None, timeit=True, Verb=False, VerbNb=None, Method='Poly', Deg=1, Group=True, plot=False, LNames=None, Com=''): - if sigma is None: - sigma = 0.5*np.mean(np.mean(np.abs(data)))*np.ones((TMat.shape[0],)) - dataCorr, Retro, indCorr = InvRatio(TMat, data, t, BF2, indCorr, sigma=sigma, Dt=Dt, mu0=mu0, SolMethod=SolMethod, Deriv=Deriv, IntMode=IntMode, Cond=Cond, ConvCrit=ConvCrit, Sparse=Sparse, SpType=SpType, Pos=Pos, KWARGS=KWARGS, timeit=timeit, Verb=Verb, VerbNb=VerbNb) - if sigma.ndim==2: - sigmaCorr = sigma[:,indCorr] - else: - sigmaCorr = sigma[indCorr] - databis, sigmabis, pp, ax = Corrdata(dataCorr, Retro, sigmaCorr, Method=Method, Deg=Deg, Group=Group, plot=plot, LNames=LNames, Com=Com) - if Dt is None: - indt = np.ones((t.size,),dtype=bool) - else: - indt = (t>=Dt[0]) & (t<=Dt[1]) - tin = t[indt] - datain = data[indt,:] - datain[:,indCorr] = databis - - # Implement corrected sigma, taking care it should not be too low ! - if sigma.ndim==2: - sigmain = sigma[indt,:] - indNonCorrbool = np.ones((sigma.shape[1],),dtype=bool) - indNonCorrbool[indCorr] = False - sigmaMin = np.nanmean(sigmain[:,indNonCorrbool],axis=1) - indMin = sigmabis < np.tile(sigmaMin,(sigmabis.shape[1],1)).T - sigmabis[indMin] = sigmaMin - sigmain[:,indCorr] = sigmabis - else: - sigmain = sigma - indNonCorrbool = np.ones((sigma.size,),dtype=bool) - indNonCorrbool[indCorr] = False - sigmaMin = np.nanmean(sigmain[indNonCorrbool]) - sigmabis[sigmabis0: - return TFPT.Dispatch_Compare([self]+LSol2, V=V, prop=prop, Test=Test) - - - def plot_diff(self, Ref, V='basic', prop=None, Test=True): - """ - Plot the difference between the TFI.Sol2D instance and a reference time, time interval, coefs array or Sol2D with the chosen post-treatment plot configuration - - Call: - ----- - La = Sol2D.plot_diff(Ref, V='basic', prop=None, Test=True) - - Inputs : - -------- - Ref float, list, np.ndarray or TFI.Sol2D The reference solution to be substracted from the Sol2D solution - int: interpreted as the index of the reference time step - float: interpreted as the reference time step - list: of len()=2, computes the average profile over the chosen time interval - np.ndarray: interpreted as a reference set of Coefs, must be Coefs.shape==Sol2D.Coefs.shape - TFI.Sol2D: interpreted as the reference solution, must have shape==Sol2D.Coefs.shape - V str, specifies the version of the plot configuration in ['basic','technical','profiles'] (default : 'basic') - prop dict, specifies the properties to be used for the various artists of the plot, if None sets to defaults depending on the chosen V (default : None) - Test bool, specifies wether to Test the input data for consistency (default : True) - Outputs : - La dict, a dict of plt.Axes instances on which the various plots were made, classified depending of the type of plot (i.e.: 2D constant, 2D changing, 1D changing profiles, 1D time traces, 1D constant) - """ - if Test: - assert type(Ref) in [int,float,list,np.ndarray,Sol2D], "Arg Ref must be of type in [int,float,list,np.ndarray,TFI.Sol2D] !" - if type(Ref) is int: - Ref = np.tile(self.Coefs[Ref,:],(self.t.size,1)) - elif type(Ref) is float: - Ref = np.tile(self.Coefs[np.nanargmin(np.abs(self.t-Ref)),:],(self.t.size,1)) - elif type(Ref) is list: - Ref = (self.t>=Ref[0]) & (self.t<=Ref[1]) - Ref = np.tile(np.nanmean(self.Coefs[Ref,:],axis=0),(self.t.size,1)) - elif type(Ref) is np.ndarray: - Ref = Ref - elif type(Ref) is Sol2D: - Ref = Ref.Coefs - CoefsI = self.Coefs - CoefsD = CoefsI - Ref - self._Coefs = CoefsD - if prop is None: - prop = dict(TFD.TFPT_Lprop[V]) - Max = np.nanmax(np.abs(CoefsD)) - prop['InvLvls'] = np.linspace(-Max,Max,29) - prop['Norm'] = False - prop['VMinMax'] = [-Max,Max] - prop['Invd'] = {'cmap':plt.cm.seismic,'edgecolor':None} - Out = TFPT.Dispatch_Inv_Plot(self, V=V, prop=prop, Test=Test) - self._Coefs = CoefsI - return Out - - - - def plot_fft(self, V='basic', prop=None, FreqIn=None, FreqOut=None, HarmIn=True, HarmOut=True, Test=True): - return TFPT.Dispatch_Inv_Plot(self, V=V, prop=prop, FreqIn=FreqIn, FreqOut=FreqOut, HarmIn=HarmIn, HarmOut=HarmOut, Test=Test) - - def anim(self, DVect=TFD.BF2_DVect_DefR, SubP=TFD.InvPlotSubP, SubMode=TFD.InvPlotSubMode, blit=TFD.InvAnimBlit, interval=TFD.InvAnimIntervalms, repeat=TFD.InvAnimRepeat, repeat_delay=TFD.InvAnimRepeatDelay, - InvPlotFunc=TFD.InvPlotF, InvLvls=TFD.InvLvls, Invd=TFD.Invdict, Tempd=TFD.Tempd, Retrod=TFD.Retrod, TimeScale=TFD.InvAnimTimeScale, VMinMax=[None,None], Test=True, Hybrid=False, FName=None, Com='', Norm=False): - TMat = self.GMat.MatLOS if self._LOS else self.GMat.Mat - Nit = np.array([ss[0] for ss in self._Spec]) - ani, axInv, axTMat, Laxtemp = TFPT.Inv_MakeAnim(self.BF2, self.Coefs, t=self.t, Com=Com, shot=self.shot, Ves=self.GMat.Ves, SXR=self.data, sigma=self._sigma, TMat=TMat, Chi2N=self._Chi2N, - Mu=self._Mu, R=self._R, Nit=Nit, Deriv=0, indt0=0, DVect=DVect, SubP=SubP, SubMode=SubMode, blit=blit, interval=interval, repeat=repeat, repeat_delay=repeat_delay, InvPlotFunc=InvPlotFunc, InvLvls=InvLvls, - Invd=Invd, Tempd=Tempd, Retrod=Retrod, TimeScale=TimeScale, VMinMax=VMinMax, Test=Test, Hybrid=Hybrid, FName=FName) - return ani - - def plot_fftpow(self, PtsRZ=None, V='user', Deriv=0, DVect=TFD.BF2_DVect_DefR, SubP=TFD.InvPlotSubP, SubMode=TFD.InvPlotSubMode, InvPlotFunc=TFD.InvPlotF, InvLvls=TFD.InvLvls, Invd=TFD.Invdict, - Tempd=TFD.Tempd, Retrod=TFD.Retrod, VMinMax=[None,None], Test=True, Com='', DTF=None, RatDef=100, Method='Max', Trunc=0.60, Inst=True, SpectNorm=True, cmapPow=plt.cm.gray_r, a4=False): - TMat = self.GMat.MatLOS if self._LOS else self.GMat.Mat - Nit = np.array([ss[0] for ss in self._Spec]) - axInv, axTMat, Laxtemp = TFPT.Inv_PlotFFTPow(self.BF2, self.Coefs, RZPts=PtsRZ, t=self.t, Com=Com, shot=self.shot, Ves=self.GMat.Ves, SXR=self.data, sigma=self._sigma, TMat=TMat, Deriv=Deriv, DVect=DVect, SubP=SubP, SubMode=SubMode, InvPlotFunc=InvPlotFunc, InvLvls=InvLvls, Invd=Invd, Tempd=Tempd, Retrod=Retrod, VMinMax=VMinMax, DTF=DTF, RatDef=RatDef, Method=Method, Trunc=Trunc, Inst=Inst, SpectNorm=SpectNorm, cmapPow=cmapPow, a4=a4, Test=Test) - return axInv, axTMat, Laxtemp - - def posttreat(self, pathfileext, kwdargs={}, overwrite=False, update=False): - assert type(pathfileext) is str, "Arg pathfileext must be a str !" - import os - strrev = pathfileext[-1::-1] - Path = pathfileext[:-strrev.index('/')] - Mod = pathfileext[-strrev.index('/'):-strrev.index('.')-1] - cwd = os.getcwd() - os.chdir(Path) - Path = os.getcwd() - exec "import "+Mod+" as pt" - os.chdir(cwd) - Out = pt.Init(self, kwdargs=kwdargs, overwrite=overwrite, update=update) - if not Out is None: - Out['Path'] = Path - Out['Mod'] = Mod - if not 'Name' in Out.keys(): - Out['Name'] = Mod - ind = [ii for ii in range(0,len(self._PostTreat)) if self._PostTreat[ii]['Name']==Out['Name']] - assert len(ind) in [0,1], "Several matching Sol2D.PostTreat !" - if len(ind)==1: - self._PostTreat[ind[0]] = Out - else: - self._PostTreat.append(Out) - - def posttreat_plot(self, name=None, ind=-1, **kwdargs): - if not name is None: - ind = [ii for ii in range(0,len(self.PostTreat)) if self.PostTreat[ii]['Name']==name][0] - import os - gcwd = os.getcwd() - os.chdir(self.PostTreat[ind]['Path']) - exec "import "+self.PostTreat[ind]['Mod']+" as pt" - os.chdir(gcwd) - return pt.plot(self, self.PostTreat[ind], **kwdargs) - - def save(self,SaveName=None,Path=None,Mode='npz'): - """ - Save the obj to specified path and name, with numpy of cPickle - - Call : - ------ - - obj.save( SaveName=None, Path=None, Mode='npz' ) - - Arguments: - ---------- - - Inputs : - SaveName str or None Specifies the name under which the file should be saved, if None uses obj.Id.SaveName (default: None) - Path str or None Specifies the relative path in which to save the file, if None uses obj.Id.SavePath (default: None) - Mode str Specifies the format used for saving, 'npz' uses numpy to store the data in numpy arrays while 'pck' uses cPickle to store the whole object structure (default: 'npz') - - Examples: - --------- - - >> Sol.save(Path='./') - Will save the obj called Sol in the current folder using its defaults Id.SaveName and numpy - """ - if Path is None: - Path = self.Id.SavePath - else: - assert type(Path) is str, "Arg Path must be a str !" - self._Id.SavePath = Path - if SaveName is None: - SaveName = self.Id.SaveName - else: - assert type(SaveName) is str, "Arg SaveName must be a str !" - self.Id.SaveName = SaveName - Ext = '.npz' if 'npz' in Mode else '.pck' - TFPF.save(self, Path+SaveName+Ext) - - - - - - - - - -############################################################################################################################################## -############################################################################################################################################## -############################################################################################################################################## -############## Routines -############################################################################################################################################## -############################################################################################################################################## - - - -def _Sol2D_get_InvRad(Sol, PreDt, PostDt, SubP=TFD.InvPlotSubP, SubMode=TFD.InvPlotSubMode, Test=True): - if Test: - assert type(PreDt) in [int,float,list], "Arg PreDt must be of type in [int,float,list] !" - assert type(PostDt) in [int,float,list], "Arg PostDt must be of type in [int,float,list] !" - if type(PreDt) is list: - assert len(PreDt)==2, "Arg PreDt must be a list of len()==2 !" - if type(PostDt) is list: - assert len(PostDt)==2, "Arg PostDt must be a list of len()==2 !" - - # Get coefficients - Coefs = [PreDt,PostDt] - for ii in range(0,2): - if type(Coefs[ii]) is int: - Coefs[ii] = Sol.Coefs[Coefs[ii]] - elif type(Coefs[ii]) is float: - Coefs[ii] = Sol.Coefs[np.nanargmin(np.abs(Sol.t-Coefs[ii]))] - elif type(Coefs[ii]) is list: - indt = (Sol.t>=Coefs[ii][0]) & (Sol.t<=Coefs[ii][1]) - Coefs[ii] = np.nanmean(Sol.Coefs[indt,:],axis=0) - Coefs = Coefs[0]-Coefs[1] - - # Get mesh and values - Rplot, Zplot, nR, nZ = Sol.BF2.get_XYplot(SubP=SubP, SubMode=SubMode) - Pts = np.array([Rplot.flatten(), np.zeros((nR*nZ,)), Zplot.flatten()]) - indnan = ~Sol.BF2.Mesh.isInside(np.array([Rplot.flatten(),Zplot.flatten()])) - Vals = np.nan*np.ma.ones((nR*nZ,)) - Vals[~indnan] = Sol.BF2.get_TotVal(Pts[:,~indnan], Deriv='D0', Coefs=Coefs, Test=Test) - indpeak = np.nanargmax(np.abs(Vals)) - Peak = Pts[:,indpeak] - Vals = np.reshape(Vals,(nZ,nR)) - print Peak - - # Get contours containing peak - Lcont = cntr.Cntr(Rplot, Zplot, Vals) - Lcont = Lcont.trace(0.) - print Lcont - print len(Lcont) - nseg = len(Lcont) // 2 - print nseg - segments, codes = Lcont[:nseg], Lcont[nseg:] - print segments - print codes - - inds = np.zeros((len(Lcont)),dtype=bool) - for ii in range(0,len(Lcont)): - Pth = path.Path(Lcont[ii]) - print Pth - print Pth.contains_points(Peak) - if Pth.contains_points(Peak): - inds[ii] = True - assert inds.sum()>=1, "TFI._Sol2D_get_InvRad : could not find a 0-contour containing the peak for "+Sol.Id.Name+" with specified intput !" - Lcont = [Lcont[ii] for ii in range(0,len(Lcont)) if inds[ii]] - print Lcont - - # Select innermost contour - #if inds.sum()>1: - #Area = - - - return Pts#, Area - - - - - - - - - - - - - - - - - diff --git a/tofu/inv/ToFu_PostTreat.py b/tofu/inv/ToFu_PostTreat.py deleted file mode 100644 index 623d06c65..000000000 --- a/tofu/inv/ToFu_PostTreat.py +++ /dev/null @@ -1,1484 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Fri Sep 26 16:22:47 2014 - -@author: didiervezinet -""" - -import numpy as np -import scipy.sparse as scpsp -import scipy.sparse.linalg as scpsplin -import scipy.optimize as scpop -import ToFu_Mesh as TFM -import ToFu_MatComp as TFMC -import ToFu_Defaults as TFD -import ToFu_PathFile as TFPF -import ToFu_Treat as TFT -import ToFu_Inv as TFI -import matplotlib.pyplot as plt -import matplotlib.animation as anim -import matplotlib.collections as mplcll -import matplotlib.mlab as mlab -import matplotlib as mpl -import itertools as itt -import datetime as dtm -import types -import os - - - -############################################################################################################################################## -############################################################################################################################################## -############################################################################################################################################## -########### Dispatch -############################################################################################################################################## -############################################################################################################################################## - - -def Dispatch_Inv_Plot(Sol2, V='basic', prop=None, FreqIn=None, FreqOut=None, HarmIn=True, HarmOut=True, Test=True): - """ - Plot the TFI.Sol2D instance with the chosen post-treatment plot configuration - Inputs : - Sol2 TFI.Sol2D object, for which the inversion as been carried out - V str, specifies the version of the plot configuration in ['basic','technical','profiles'] (default : 'basic') - prop dict, specifies the properties to be used for the various artists of the plot (default : None) - FreqIn list, - FreqOut list, - HarmIn bool, - HarmOut bool, - Test bool, specifies wether to Test the input data for consistency (default : True) - Outputs : - La dict, a dict of plt.Axes instances on which the various plots were made, classified depending of the type of plot (i.e.: 2D constant, 2D changing, 1D changing profiles, 1D time traces, 1D constant) - """ - - if Test: - assert V in ['basic','technical','profiles'] or type(V) is str, "Arg V must be in ['basic','technical','prof','sawtooth'] or a str with path+module+function !" - assert prop is None or type(prop) is dict, "Arg prop must be None (default) or a dict instance with necessary kwargs !" - assert type(Test) is bool, "Arg Test must be a bool !" - - if prop is None and V in ['basic','technical','profiles']: - prop = dict(TFD.TFPT_Lprop[V]) - prop['FreqIn'], prop['FreqOut'], prop['HarmIn'], prop['HarmOut'] = FreqIn, FreqOut, HarmIn, HarmOut - if any([not ss is None for ss in [FreqIn, FreqOut]]): - prop['Invd']['cmap'] = plt.cm.seismic - - freqstr = '\n' if FreqIn is None else '{0:05.2f}-{1:05.2f} kHz\n'.format(FreqIn[0]*1.e-3,FreqIn[1]*1.e-3) - prop['Com'] = prop['Com'] + '\n' + Sol2.Id.LObj['PreData']['Name'][0]+'\n'+ Sol2.GMat.Id.Name+'\n' + Sol2.Id.Name[Sol2.Id.Name.index('Deriv'):]+'\n' + freqstr - - if V=='basic': - return Inv_Plot_Basic(Sol2, Test=Test, **prop) - elif V=='technical': - return Inv_Plot_Technical(Sol2, Test=Test, **prop) - elif V=='profiles': - return Inv_Plot_Profiles(Sol2, Test=Test, **prop) - else: - indpath, indp = -V[::-1].find('/'), -V[::-1].find('.') - path, mod, func = V[:indpath], V[indpath:indp-1], V[indp:] - exec('import '+path+mod) - eval(mod+'.'+func+'(Sol2, **prop)') - - -def Dispatch_Compare(LSol2, V='basic', prop=None, FreqIn=None, FreqOut=None, HarmIn=True, HarmOut=True, Test=True): - """ - Plot a comparison of the TFI.Sol2D instance with a list of other TFI.Sol2D instances with the chosen post-treatment plot configuration - Inputs : - Sol2 TFI.Sol2D object, for which the inversion as been carried out - V str, specifies the version of the plot configuration in ['basic','technical','profiles'] (default : 'basic') - prop dict, specifies the properties to be used for the various artists of the plot (default : None) - FreqIn list, - FreqOut list, - HarmIn bool, - HarmOut bool, - Test bool, specifies wether to Test the input data for consistency (default : True) - Outputs : - La dict, a dict of plt.Axes instances on which the various plots were made, classified depending of the type of plot (i.e.: 2D constant, 2D changing, 1D changing profiles, 1D time traces, 1D constant) - """ - - if Test: - assert V in ['basic','technical','profiles'] or type(V) is str, "Arg V must be in ['basic','technical','prof','sawtooth'] or a str with path+module+function !" - assert prop is None or type(prop) is dict, "Arg prop must be None (default) or a dict instance with necessary kwargs !" - assert type(Test) is bool, "Arg Test must be a bool !" - assert type(LSol2) is list and all([isinstance(ss,TFI.Sol2D) and ss.shot==LSol2[0].shot and np.all(ss.t==LSol2[0].t) for ss in LSol2]), "Arg LSol2 must be a list of TFI.Sol2D instances with same shot and time vector !" - - if prop is None and V in ['basic','technical','profiles']: - prop = dict(TFD.TFPT_Lprop[V]) - - freqstr = '' if FreqIn is None else '{0:05.2f}-{1:05.2f} kHz\n'.format(FreqIn[0]*1.e-3,FreqIn[1]*1.e-3) - prop['LCom'] = [prop['Com'] + '\n' + ss.Id.LObj['PreData']['Name'][0]+'\n'+ ss.GMat.Id.Name+'\n' + ss.Id.Name[ss.Id.Name.index('Deriv'):]+'\n' + freqstr for ss in LSol2] - - if V=='basic': - return Inv_Compare_Basic(LSol2, Test=Test, **prop) - elif V=='technical': - return Inv_Compare_Technical(LSol2, Test=Test, **prop) - elif V=='profiles': - return Inv_Compare_Profiles(LSol2, Test=Test, **prop) - else: - indpath, indp = -V[::-1].find('/'), -V[::-1].find('.') - path, mod, func = V[:indpath], V[indpath:indp-1], V[indp:] - exec('import '+path+mod) - eval(mod+'.'+func+'(LSol2, **prop)') - - - -############################################################################################################################################## -############################################################################################################################################## -############################################################################################################################################## -########### Interactive plots -############################################################################################################################################## -############################################################################################################################################## - - -# ------------ Preliminary functions ---------------- - - -def _getmeshVals(t, BF2, SubP, SubMode, Reg, Deriv, DVect, Coefs, FreqIn=None, FreqOut=None, HarmIn=None, HarmOut=None, Nt=None, Test=True): - Rplot, Zplot, nR, nZ = BF2.get_XYplot(SubP=SubP, SubMode=SubMode) - if Reg=='Reg': - extent = (BF2.Mesh.MeshR.Cents.min(), BF2.Mesh.MeshR.Cents.max(), BF2.Mesh.MeshZ.Cents.min(), BF2.Mesh.MeshZ.Cents.max()) - Rplot,Zplot = np.mgrid[extent[0]:extent[1]:complex(nR), extent[2]:extent[3]:complex(nZ)] - Rplot,Zplot = Rplot.T,Zplot.T - Points = np.array([Rplot.flatten(), np.zeros((nR*nZ,)), Zplot.flatten()]) - indnan = ~BF2.Mesh.isInside(np.array([Rplot.flatten(),Zplot.flatten()])) - Vals = np.nan*np.ma.ones((Nt,nR*nZ)) - Vals[:,~indnan] = BF2.get_TotVal(Points[:,~indnan], Deriv=Deriv, DVect=DVect, Coefs=Coefs, Test=Test) - if not (FreqIn is None and FreqOut is None): - Vals[:,~indnan] = TFT.FourierExtract(t, Vals[:,~indnan], DF=FreqIn, DFEx=FreqOut, Harm=HarmIn, HarmEx=HarmOut, Test=Test)[0] - Vals[:,indnan] = np.ma.masked - if Reg=='Irreg': - return Rplot, Zplot, nR, nZ, Vals - elif Reg=='Reg': - return extent, nR, nZ, Vals - - -def _getProfVals(t, BF2, Ves, LPath, dl, Deriv, DVect, Coefs, FreqIn=None, FreqOut=None, HarmIn=None, HarmOut=None, Nt=None, NL=None, Test=True): - RMin, RMax, ZMin, ZMax = Ves._PRMin[0], Ves._PRMax[0], Ves._PZMin[1], Ves._PZMax[1] - DMax = max(RMax-RMin, ZMax-ZMin) - nP = np.ceil(2.*DMax/dl) - LPts, LVals, Ll = [], [], [] - for ii in range(0,NL): - llR = np.linspace(LPath[ii][0][0]-DMax*LPath[ii][1][0], LPath[ii][0][0]+DMax*LPath[ii][1][0], nP) - llZ = np.linspace(LPath[ii][0][1]-DMax*LPath[ii][1][1], LPath[ii][0][1]+DMax*LPath[ii][1][1], nP) - pts = np.array([llR,llZ]) - pts = pts[:,Ves.isInside(pts)] - indnan = ~BF2.Mesh.isInside(pts) - vals = np.nan*np.ones((Nt,pts.shape[1])) - vals[:,~indnan] = BF2.get_TotVal(pts[:,~indnan], Deriv=Deriv, DVect=DVect, Coefs=Coefs, Test=Test) - if not (FreqIn is None and FreqOut is None): - vals[:,~indnan] = TFTvFourierExtract(t, vals[:,~indnan], DF=FreqIn, DFEx=FreqOut, Harm=HarmIn, HarmEx=HarmOut, Test=Test)[0] - LPts.append(pts) - Ll.append((pts[0,:]-LPath[ii][0][0])*LPath[ii][1][0] + (pts[1,:]-LPath[ii][0][1])*LPath[ii][1][1]) - LVals.append(vals) - return LVals, LPts, Ll - - - -# Function building the mesh for plotting 2D emissivity -def _getValsPlotF(Nt, InvPlotFunc, VMinMax, t, BF2, SubP, SubMode, Deriv, DVect, Coefs, Invd, InvLvls=None, FreqIn=None, FreqOut=None, HarmIn=None, HarmOut=None, Norm=False, Test=True): - Vminmax = VMinMax[:] - if InvPlotFunc=='imshow': - extent, nR, nZ, Vals = _getmeshVals(t, BF2, SubP, SubMode, 'Reg', Deriv, DVect, Coefs, FreqIn=FreqIn, FreqOut=FreqOut, HarmIn=HarmIn, HarmOut=HarmOut, Nt=Nt, Test=Test) - interp = ['nearest','bilinear','bicubic'][BF2.Deg] - else: - Rplot, Zplot, nR, nZ, Vals = _getmeshVals(t, BF2, SubP, SubMode, 'Irreg', Deriv, DVect, Coefs, FreqIn=FreqIn, FreqOut=FreqOut, HarmIn=HarmIn, HarmOut=HarmOut, Nt=Nt, Test=Test) - if Vminmax[0] is None: - Vminmax[0] = np.min([0,Vals.min()]) - if Vminmax[1] is None: - Vminmax[1] = 0.95*Vals.max() - if Norm: - print Norm - Vals = Vals/np.tile(np.nanmax(Vals,axis=1),(Vals.shape[1],1)).T - Vminmax = [0, 1] - #Vminmax = [np.nanmin(Vals,axis=1)[0], np.nanmax(Vals,axis=1)[0]] - if InvPlotFunc=='imshow': - def plot_ImageInv(vals=None, indt=None, Vminmax=None, nR=None, nZ=None, axInv=None, Invd=None, extent=None, interp=None): - Inv = axInv.imshow(vals[indt,:].reshape((nZ,nR)), extent=extent, cmap=Invd['cmap'], origin='lower', aspect='auto', interpolation=interp, zorder=0, vmin=Vminmax[0], vmax=Vminmax[1]) - return [Inv] - InvSig = {'vals':Vals, 'Vminmax':Vminmax, 'nR':nR, 'nZ':nZ, 'axInv':None, 'Invd':Invd, 'extent':extent, 'interp':interp} - else: - def plot_ImageInv(vals=None, indt=None, Vminmax=None, nR=None, nZ=None, axInv=None, Invd=None, Rplot=None, Zplot=None, InvLvls=None): - pltfunc = axInv.contour if InvPlotFunc=='contour' else axInv.contourf - Inv = pltfunc(Rplot, Zplot, vals[indt,:].reshape((nZ,nR)), InvLvls, zorder=0, vmin=Vminmax[0], vmax=Vminmax[1], **Invd) - Inv.axes = axInv - Inv.figure = axInv.figure - def draw(self,renderer): - for cc in self.collections: cc.draw(renderer) - Inv.draw = types.MethodType(draw,Inv,None) - return [Inv] - InvSig = {'vals':Vals, 'Vminmax':Vminmax, 'nR':nR, 'nZ':nZ, 'axInv':None, 'Invd':Invd, 'Rplot':Rplot, 'Zplot':Zplot, 'InvLvls':InvLvls} - return plot_ImageInv, InvSig, Vminmax - - -# Function for plotting the SXR data profile and retrofit - -def _getSigmaProf_init(LProf=[], Sig=None, LRetrofit=None, indt=None, ax=None, sigma=None, NMes=None, SXRd=None, Retrod=None, Sigmad=None, LCol=None): - LProf = [0,0]+range(0,len(LRetrofit)) - sigma = sigma if sigma.ndim==1 else sigma[indt,:] - LProf[0] = ax.fill_between(range(1,NMes+1), Sig[indt,:]+sigma, Sig[indt,:]-sigma, **Sigmad) - LProf[1], = ax.plot(range(1,NMes+1),Sig[indt,:], **SXRd) - for ii in range(2,2+len(LRetrofit)): - LProf[ii], = ax.plot(range(1,NMes+1),LRetrofit[ii-2][indt,:], label=r"Sol2D {0:1f}".format(ii-1), c=LCol[ii-2], **Retrod) - return LProf - - -def _getSigmaProf_up(LProf=[], Sig=None, LRetrofit=None, indt=None, ax=None, sigma=None, NMes=None, SXRd=None, Retrod=None, Sigmad=None, LCol=None): - sigma = sigma if sigma.ndim==1 else sigma[indt,:] - LProf[0] = ax.fill_between(range(1,NMes+1), Sig[indt,:]+sigma, Sig[indt,:]-sigma, **Sigmad) - LProf[1].set_ydata(Sig[indt,:]) - for ii in range(2,2+len(LRetrofit)): - LProf[ii].set_ydata(LRetrofit[ii-2][indt,:]) - return LProf - - -def _getEmissProf_init(LProf=None, indt=None, NL=None, NSol=None, Lax=None, LPts=None, LVals=None, Ll=None, LCol=None, ldict=None): - LProf = [] - if NSol is None: - for ii in range(0,NL): - LProf.append(Lax[ii].plot(Ll[ii], LVals[ii][indt,:], **ldict)[0]) - else: - ldictbis = dict(ldict) - del ldictbis['c'] - for ii in range(0,NL): - for jj in range(0,NSol): - LProf.append(Lax[ii].plot(Ll[ii], LVals[jj][ii][indt,:], c=LCol[jj], **ldictbis)[0]) - return LProf - -def _getEmissProf_up(LProf=None, indt=None, NL=None, NSol=None, Lax=None, LPts=None, LVals=None, Ll=None, LCol=None, ldict=None): - if NSol is None: - for ii in range(0,NL): - LProf[ii].set_ydata(LVals[ii][indt,:]) - else: - for ii in range(0,NL): - for jj in range(0,NSol): - LProf[ii*NSol+jj].set_ydata(LVals[jj][ii][indt,:]) - return LProf - - -# ------------ Background-setting functions ---------------- - - -def _Plot_Inv_Config_Basic(Nt, NMes, t, Ves, SXR, Retrofit, Com=None, Tempd=TFD.Tempd, Vminmax=None, cmap=None, Test=True, a4=False): - if Test: - assert isinstance(t,np.ndarray) and t.ndim==1 and t.size==Nt, "Arg t must be a 1D np.ndarray with t.size==Nt" - assert Com is None or type(Com) is str, "Arg Com must be None or a str !" - assert SXR is None or (isinstance(SXR,np.ndarray) and SXR.ndim==2 and SXR.shape[0]==Nt), "Arg SXR must be None or a 2D np.ndarray with SXR.shape[0]==Nt" - - # Getting booleans for axes plot and getting figure+axes - axInv, axTMat, axSig, axc, axTxt = TFD.Plot_Inv_Basic_DefAxes(a4=a4, dpi=80) - - norm = mpl.colors.Normalize(vmin=Vminmax[0], vmax=Vminmax[1]) - cb = mpl.colorbar.ColorbarBase(axc, cmap=cmap, norm=norm, spacing='proportional') - axInv.set_title(Com) - - # Pre-plotting lines and image - axSig.plot(t, SXR, **Tempd) - axSig.set_xlim(np.min(t),np.max(t)) - - axTMat.set_xlim(0,NMes+1) - axTMat.set_ylim(min(np.nanmin(SXR).min(),np.nanmin(Retrofit).min()), max(np.nanmax(SXR).max(),np.nanmax(Retrofit).max())) - - axInv = Ves.plot(Lax=[axInv], Proj='Pol', Elt='P') - axInv.set_xlim(Ves._PRMin[0],Ves._PRMax[0]) - axInv.get_lines()[-1].set_zorder(10) - - axInv.autoscale(tight=True) - axInv.axis('equal') - axInv.set_autoscale_on(False) - - Tstr = axTxt.text(0.35,0.3, r"", color='k', size=14) - - BckgrdInv = axInv.figure.canvas.copy_from_bbox(axInv.bbox) - BckgrdTime = axInv.figure.canvas.copy_from_bbox(axSig.bbox) - BckgrdProf = axInv.figure.canvas.copy_from_bbox(axTMat.bbox) - BckgrdTxt = axInv.figure.canvas.copy_from_bbox(axTxt.bbox) - return axInv, axTMat, axSig, BckgrdInv, BckgrdTime, BckgrdProf, Tstr, BckgrdTxt - - -def _Plot_Inv_Config_Technical(Nt, NMes, t, Ves, SXR, Retrofit, Chi2N, mu, R, Nit, Com=None, Tempd=TFD.Tempd, Vminmax=None, cmap=None, Test=True, a4=False): - if Test: - assert isinstance(t,np.ndarray) and t.ndim==1 and t.size==Nt, "Arg t must be a 1D np.ndarray with t.size==Nt" - assert Com is None or type(Com) is str, "Arg Com must be None or a str !" - assert SXR is None or (isinstance(SXR,np.ndarray) and SXR.ndim==2 and SXR.shape[0]==Nt), "Arg SXR must be None or a 2D np.ndarray with SXR.shape[0]==Nt" - - # Getting booleans for axes plot and getting figure+axes - axInv, axTMat, LaxTime, axc, axTxt = TFD.Plot_Inv_Technical_DefAxes(a4=a4, dpi=80) - - norm = mpl.colors.Normalize(vmin=Vminmax[0], vmax=Vminmax[1]) - cb = mpl.colorbar.ColorbarBase(axc, cmap=cmap, norm=norm, spacing='proportional') - axInv.set_title(Com) - - # Pre-plotting lines and image - LaxTime[0].plot(t, SXR, **Tempd) - LaxTime[1].plot(t, Nit, **Tempd) - LaxTime[2].plot(t, Chi2N, **Tempd) - LaxTime[3].plot(t, mu, **Tempd) - LaxTime[4].plot(t, R, **Tempd) - - axTMat.set_xlim(0,NMes+1) - axTMat.set_ylim(min(np.nanmin(SXR).min(),np.nanmin(Retrofit).min()), max(np.nanmax(SXR).max(),np.nanmax(Retrofit).max())) - - axInv = Ves.plot(Lax=[axInv], Proj='Pol', Elt='P') - axInv.set_xlim(Ves._PRMin[0],Ves._PRMax[0]) - axInv.get_lines()[-1].set_zorder(10) - - axInv.autoscale(tight=True) - axInv.axis('equal') - axInv.set_autoscale_on(False) - - Tstr = axTxt.text(0.35,0.3, r"", color='k', size=14) - - BckgrdInv = axInv.figure.canvas.copy_from_bbox(axInv.bbox) - BckgrdTime = [] - for ii in range(0,len(LaxTime)): - LaxTime[ii].set_xlim(np.min(t),np.max(t)) - BckgrdTime.append(axInv.figure.canvas.copy_from_bbox(LaxTime[ii].bbox)) - BckgrdProf = axInv.figure.canvas.copy_from_bbox(axTMat.bbox) - BckgrdTxt = axInv.figure.canvas.copy_from_bbox(axTxt.bbox) - return axInv, axTMat, LaxTime, BckgrdInv, BckgrdTime, BckgrdProf, Tstr, BckgrdTxt - - -def _Plot_Inv_Config_Profiles(Nt, NMes, NL, LPath, t, Ves, SXR, Retrofit, LPts, LVals, Ll, Com=None, Tempd=TFD.Tempd, Vminmax=None, cmap=None, Test=True, a4=False): - if Test: - assert isinstance(t,np.ndarray) and t.ndim==1 and t.size==Nt, "Arg t must be a 1D np.ndarray with t.size==Nt" - assert Com is None or type(Com) is str, "Arg Com must be None or a str !" - assert SXR is None or (isinstance(SXR,np.ndarray) and SXR.ndim==2 and SXR.shape[0]==Nt), "Arg SXR must be None or a 2D np.ndarray with SXR.shape[0]==Nt" - - # Getting booleans for axes plot and getting figure+axes - axInv, axTMat, axSig, LaxP, axc, axTxt = TFD.Plot_Inv_Profiles_DefAxes(NL=NL, a4=a4, dpi=80) - - norm = mpl.colors.Normalize(vmin=Vminmax[0], vmax=Vminmax[1]) - cb = mpl.colorbar.ColorbarBase(axc, cmap=cmap, norm=norm, spacing='proportional') - axInv.set_title(Com) - - # Pre-plotting lines and image - axSig.plot(t, SXR, **Tempd) - axSig.set_xlim(np.min(t),np.max(t)) - - axTMat.set_xlim(0,NMes+1) - axTMat.set_ylim(min(np.nanmin(SXR).min(),np.nanmin(Retrofit).min()), max(np.nanmax(SXR).max(),np.nanmax(Retrofit).max())) - - axInv = Ves.plot(Lax=[axInv], Proj='Pol', Elt='P') - axInv.set_xlim(Ves._PRMin[0],Ves._PRMax[0]) - axInv.get_lines()[-1].set_zorder(10) - - axInv.autoscale(tight=True) - axInv.set_aspect(aspect='equal',adjustable='datalim') - axInv.set_autoscale_on(False) - - Tstr = axTxt.text(0.35,0.3, r"", color='k', size=14) - for ii in range(0,NL): - LaxP[ii].set_title(str(LPath[ii][0])+r" - "+str(LPath[ii][1])+'\n', fontsize=12, fontweight='bold') - LaxP[ii].set_xlim(Ll[ii].min(),Ll[ii].max()) - LaxP[ii].set_ylim(min(0,np.nanmin(LVals[ii])),np.nanmax(LVals[ii])) - LaxP[ii].axhline(0, c='k', ls='-', lw=1.) - - - can = axInv.figure.canvas - can.draw() - BckgrdInv = can.copy_from_bbox(axInv.bbox) - BckgrdTime = can.copy_from_bbox(axSig.bbox) - BckgrdProf = [can.copy_from_bbox(axTMat.bbox)] - for ii in range(0,NL): - BckgrdProf.append(can.copy_from_bbox(LaxP[ii].bbox)) - BckgrdTxt = can.copy_from_bbox(axTxt.bbox) - return axInv, axTMat, axSig, LaxP, BckgrdInv, BckgrdTime, BckgrdProf, Tstr, BckgrdTxt - - - -def _Plot_Inv_Config_Compare_Basic(NSol, Nt, NMes, t, Ves, SXR, RetroMinMax, LCom=None, Tempd=TFD.Tempd, Vminmax=None, cmap=None, LCol=None, Test=True, a4=False): - if Test: - assert isinstance(t,np.ndarray) and t.ndim==1 and t.size==Nt, "Arg t must be a 1D np.ndarray with t.size==Nt" - assert LCom is None or type(LCom) is list, "Arg LCom must be None or a list of str !" - assert SXR is None or (isinstance(SXR,np.ndarray) and SXR.ndim==2 and SXR.shape[0]==Nt), "Arg SXR must be None or a 2D np.ndarray with SXR.shape[0]==Nt" - - # Getting booleans for axes plot and getting figure+axes - LaxInv, axTMat, axSig, axc, LaxTxt = TFD.Plot_Inv_Compare_Basic_DefAxes(N=NSol, a4=a4, dpi=80) - - # Pre-plotting lines and image - axSig.plot(t, SXR, **Tempd) - axSig.set_xlim(np.min(t),np.max(t)) - - axTMat.set_xlim(0,NMes+1) - axTMat.set_ylim(min(np.nanmin(SXR).min(),RetroMinMax[0]), max(np.nanmax(SXR).max(),RetroMinMax[1])) - - norm = mpl.colors.Normalize(vmin=Vminmax[0], vmax=Vminmax[1]) - cb = mpl.colorbar.ColorbarBase(axc, cmap=cmap, norm=norm, spacing='proportional') - LTstr = [] - LProxy = [] - for ii in range(0,NSol): - LaxInv[ii].set_title(LCom[ii], color=LCol[ii], size=11) - - LaxInv[ii] = Ves.plot(Lax=[LaxInv[ii]], Proj='Pol', Elt='P', LegDict=None) - LaxInv[ii].set_xlim(Ves._PRMin[0],Ves._PRMax[0]) - LaxInv[ii].get_lines()[-1].set_zorder(10) - - LaxInv[ii].autoscale(tight=True) - LaxInv[ii].axis('equal') - LaxInv[ii].set_autoscale_on(False) - - LTstr.append(LaxTxt[ii].text(0.35,0.3, r"", color='k', size=12)) - LProxy.append(mpl.lines.Line2D([], [], color=LCol[ii], ls='-', label='Sol2D {0:1f}'.format(ii+1))) - - axTMat.legend(handles=LProxy, loc=1, prop={'size':10}, frameon=False) - - can = LaxInv[0].figure.canvas - BckgrdInv = [can.copy_from_bbox(aa.bbox) for aa in LaxInv] - BckgrdTime = can.copy_from_bbox(axSig.bbox) - BckgrdProf = can.copy_from_bbox(axTMat.bbox) - BckgrdTxt = [can.copy_from_bbox(aa.bbox) for aa in LaxTxt] - return LaxInv, axTMat, axSig, BckgrdInv, BckgrdTime, BckgrdProf, LTstr, BckgrdTxt - - -def _Plot_Inv_Config_Compare_Technical(NSol, Nt, NMes, t, Ves, SXR, RetroMinMax, LChi2N, LMu, LR, LNit, LCom=None, Tempd=TFD.Tempd, Vminmax=None, cmap=None, LCol=None, Test=True, a4=False): - if Test: - assert isinstance(t,np.ndarray) and t.ndim==1 and t.size==Nt, "Arg t must be a 1D np.ndarray with t.size==Nt" - assert LCom is None or type(LCom) is list, "Arg LCom must be None or a list of str !" - assert SXR is None or (isinstance(SXR,np.ndarray) and SXR.ndim==2 and SXR.shape[0]==Nt), "Arg SXR must be None or a 2D np.ndarray with SXR.shape[0]==Nt" - - # Getting booleans for axes plot and getting figure+axes - LaxInv, axTMat, LaxTime, axc, LaxTxt = TFD.Plot_Inv_Compare_Technical_DefAxes(N=NSol, a4=a4, dpi=80) - - norm = mpl.colors.Normalize(vmin=Vminmax[0], vmax=Vminmax[1]) - cb = mpl.colorbar.ColorbarBase(axc, cmap=cmap, norm=norm, spacing='proportional') - - # Pre-plotting lines and image - LaxTime[0].plot(np.tile(np.append(t,np.nan),(SXR.shape[1],1)).flatten(), np.concatenate((SXR.T,np.nan*np.ones((SXR.shape[1],1))),axis=1).flatten(), **Tempd) - Tempdbis = dict(Tempd) - del Tempdbis['c'] - for ii in range(0,NSol): - LaxTime[1].plot(t, LNit[ii], c=LCol[ii], **Tempdbis) - LaxTime[2].plot(t, LChi2N[ii], c=LCol[ii], **Tempdbis) - LaxTime[3].plot(t, LMu[ii], c=LCol[ii], **Tempdbis) - LaxTime[4].plot(t, LR[ii], c=LCol[ii], **Tempdbis) - LaxTime[2].set_yscale('log') - for ii in range(0,len(LaxTime)): - LaxTime[ii].set_xlim(np.min(t),np.max(t)) - - - axTMat.set_xlim(0,NMes+1) - axTMat.set_ylim(min(np.nanmin(SXR).min(),np.nanmin(RetroMinMax).min()), max(np.nanmax(SXR).max(),np.nanmax(RetroMinMax).max())) - - LTstr = [] - LProxy = [] - for ii in range(0,NSol): - LaxInv[ii].set_title(LCom[ii], color=LCol[ii], size=11) - - LaxInv[ii] = Ves.plot(Lax=[LaxInv[ii]], Proj='Pol', Elt='P', LegDict=None) - LaxInv[ii].set_xlim(Ves._PRMin[0],Ves._PRMax[0]) - LaxInv[ii].get_lines()[-1].set_zorder(10) - - LaxInv[ii].autoscale(tight=True) - LaxInv[ii].axis('equal') - LaxInv[ii].set_autoscale_on(False) - - LTstr.append(LaxTxt[ii].text(0.35,0.3, r"", color='k', size=12)) - LProxy.append(mpl.lines.Line2D([], [], color=LCol[ii], ls='-', label='Sol2D {0:1f}'.format(ii+1))) - - axTMat.legend(handles=LProxy, loc=1, prop={'size':10}, frameon=False) - - can = LaxInv[0].figure.canvas - BckgrdInv = [can.copy_from_bbox(aa.bbox) for aa in LaxInv] - BckgrdTime = [can.copy_from_bbox(aa.bbox) for aa in LaxTime] - BckgrdProf = can.copy_from_bbox(axTMat.bbox) - BckgrdTxt = [can.copy_from_bbox(aa.bbox) for aa in LaxTxt] - return LaxInv, axTMat, LaxTime, BckgrdInv, BckgrdTime, BckgrdProf, LTstr, BckgrdTxt - - -def _Plot_Inv_Config_Compare_Profiles(NSol, Nt, NMes, NL, LPath, t, Ves, SXR, RetroMinMax, LPts, LVals, Ll, LCom=None, Tempd=TFD.Tempd, Vminmax=None, cmap=None, LCol=None, Test=True, a4=False): - if Test: - assert isinstance(t,np.ndarray) and t.ndim==1 and t.size==Nt, "Arg t must be a 1D np.ndarray with t.size==Nt" - assert LCom is None or type(LCom) is list, "Arg LCom must be None or a list of str !" - assert SXR is None or (isinstance(SXR,np.ndarray) and SXR.ndim==2 and SXR.shape[0]==Nt), "Arg SXR must be None or a 2D np.ndarray with SXR.shape[0]==Nt" - - # Getting booleans for axes plot and getting figure+axes - LaxInv, axTMat, axSig, LaxP, LaxPbis, axc, LaxTxt = TFD.Plot_Inv_Compare_Profiles_DefAxes(N=NSol, NL=NL, a4=a4, dpi=80) - - norm = mpl.colors.Normalize(vmin=Vminmax[0], vmax=Vminmax[1]) - cb = mpl.colorbar.ColorbarBase(axc, cmap=cmap, norm=norm, spacing='proportional') - - # Pre-plotting lines and image - axSig.plot(np.tile(np.append(t,np.nan),(SXR.shape[1],1)).flatten(), np.concatenate((SXR.T,np.nan*np.ones((SXR.shape[1],1))),axis=1).flatten(), **Tempd) - axSig.set_xlim(np.min(t),np.max(t)) - - axTMat.set_xlim(0,NMes+1) - axTMat.set_ylim(min(np.nanmin(SXR).min(),np.nanmin(RetroMinMax).min()), max(np.nanmax(SXR).max(),np.nanmax(RetroMinMax).max())) - - LTstr = [] - LProxy = [] - for ii in range(0,NSol): - LaxInv[ii].set_title(LCom[ii], color=LCol[ii], size=11) - - LaxInv[ii] = Ves.plot(Lax=[LaxInv[ii]], Proj='Pol', Elt='P', LegDict=None) - LaxInv[ii].set_xlim(Ves._PRMin[0],Ves._PRMax[0]) - LaxInv[ii].get_lines()[-1].set_zorder(10) - - LaxInv[ii].autoscale(tight=True) - LaxInv[ii].axis('equal') - LaxInv[ii].set_autoscale_on(False) - - LTstr.append(LaxTxt[ii].text(0.35,0.3, r"", color='k', size=12)) - LProxy.append(mpl.lines.Line2D([], [], color=LCol[ii], ls='-', label='Sol2D {0:1f}'.format(ii+1))) - - axTMat.legend(handles=LProxy, loc=1, prop={'size':10}, frameon=False) - - can = LaxInv[0].figure.canvas - BckgrdTime = can.copy_from_bbox(axSig.bbox) - BckgrdInv = [can.copy_from_bbox(aa.bbox) for aa in LaxInv] - BckgrdProf = [can.copy_from_bbox(axTMat.bbox)] - for ii in range(0,NL): - LaxP[ii].set_title(str(LPath[ii][0])+r" - "+str(LPath[ii][1])+'\n', fontsize=12, fontweight='bold') - LaxP[ii].set_xlim(Ll[ii].min(),Ll[ii].max()) - Lmin = [np.nanmin(vv[ii]) for vv in LVals] - Lmax = [np.nanmax(vv[ii]) for vv in LVals] - LaxP[ii].set_ylim(min(0,min(Lmin)),max(Lmax)) - #LaxPbis[ii].set_ylim(min(0,np.nanmin(LVals[ii])),np.nanmax(LVals[ii])) - #LaxPbis[ii]..set_xlim(Ll[ii].min(),Ll[ii].max()) - BckgrdProf.append(can.copy_from_bbox(LaxP[ii].bbox)) - BckgrdTxt = [can.copy_from_bbox(aa.bbox) for aa in LaxTxt] - return LaxInv, axTMat, axSig, LaxP, LaxPbis, BckgrdInv, BckgrdTime, BckgrdProf, LTstr, BckgrdTxt - - - -# ------------ Interactive key handler ---------------- - -class _keyhandler(): - #def __init__(self, t, SXR, TMat, Retrofit, Vals, sigma, indt, axInv, axTMat, Laxtemp, BckgrdInv, BckgrdTime, BckgrdProf, Invd, vlined, SXRd, Sigmad, Retrod, KWargs, Vminmax, Norm, Com, shot): - def __init__(self, t, indt, Lax1DTime, Lax1DProf, Lax2DProf, LSig1DProf, LSig2DProf, LBckgd1DTime, LBckgd1DProf, LBckgd2DProf, LFPlot1DProf_init, LFPlot1DProf_up, LFPlot2DProf_init, LFPlot2DProf_up, vlined, Tstr, LBckgdTxt): - self.t, self.indt = t, indt - self.Lax1DTime, self.Lax1DProf, self.Lax2DProf = Lax1DTime, Lax1DProf, Lax2DProf - self.LSig1DProf, self.LSig2DProf = LSig1DProf, LSig2DProf - self.LBckgd1DTime, self.LBckgd1DProf, self.LBckgd2DProf = LBckgd1DTime, LBckgd1DProf, LBckgd2DProf - self.LFPlot1DProf_init, self.LFPlot1DProf_up = LFPlot1DProf_init, LFPlot1DProf_up - self.LFPlot2DProf_init, self.LFPlot2DProf_up = LFPlot2DProf_init, LFPlot2DProf_up - self.N1DTime, self.N1DProf, self.N2DProf = len(self.Lax1DTime), len(self.LSig1DProf), len(self.LSig2DProf) - self.vlined = vlined - self.LBckgdTxt = LBckgdTxt - self.Tstr = Tstr - self.Tstraxis = [] - for ii in range(0,len(Tstr)): - self.Tstraxis.append(self.Tstr[ii].get_axes()) - self.figure = Lax1DTime[0].figure - self.canvas = self.figure.canvas - self.initplot() - - def initplot(self): - self.L2DProf = [] - for ii in range(0,self.N2DProf): - self.L2DProf.append( self.LFPlot2DProf_init[ii](indt=self.indt, **self.LSig2DProf[ii]) ) - for aa in self.L2DProf[ii]: - self.Lax2DProf[ii].draw_artist(aa) - self.canvas.blit(self.Lax2DProf[ii].bbox) - - self.Lt = [] - for ii in range(0,self.N1DTime): - self.Lt.append( self.Lax1DTime[ii].axvline(self.t[self.indt], **self.vlined)) - self.Lax1DTime[ii].draw_artist(self.Lt[ii]) - self.canvas.blit(self.Lax1DTime[ii].bbox) - for ii in range(0,len(self.Tstr)): - self.Tstr[ii].set_text(r"t = {0:09.6f} s".format(self.t[self.indt])) - self.Tstraxis[ii].draw_artist(self.Tstr[ii]) - self.canvas.blit(self.Tstraxis[ii].bbox) - - self.L1DProf = [] - for ii in range(0,self.N1DProf): - self.L1DProf.append( self.LFPlot1DProf_init[ii](indt=self.indt, **self.LSig1DProf[ii]) ) - for aa in self.L1DProf[ii]: - self.Lax1DProf[ii].draw_artist(aa) - self.canvas.blit(self.Lax1DProf[ii].bbox) - - def update_t(self): - for ii in range(0,self.N1DTime): - self.canvas.restore_region(self.LBckgd1DTime[ii]) - self.Lt[ii].set_xdata([self.t[self.indt],self.t[self.indt]]) - self.Lax1DTime[ii].draw_artist(self.Lt[ii]) - self.canvas.blit(self.Lax1DTime[ii].bbox) - - for ii in range(0,self.N2DProf): - self.canvas.restore_region(self.LBckgd2DProf[ii]) - self.L2DProf[ii] = self.LFPlot2DProf_up[ii](indt=self.indt, **self.LSig2DProf[ii]) - for aa in self.L2DProf[ii]: - self.Lax2DProf[ii].draw_artist(aa) - self.canvas.blit(self.Lax2DProf[ii].bbox) - - for ii in range(0,self.N1DProf): - self.canvas.restore_region(self.LBckgd1DProf[ii]) - self.L1DProf[ii] = self.LFPlot1DProf_up[ii](indt=self.indt, LProf=self.L1DProf[ii], **self.LSig1DProf[ii]) - for aa in self.L1DProf[ii]: - self.Lax1DProf[ii].draw_artist(aa) - self.canvas.blit(self.Lax1DProf[ii].bbox) - - for ii in range(0,len(self.Tstr)): - self.canvas.restore_region(self.LBckgdTxt[ii]) - self.Tstr[ii].set_text(r"t = {0:09.6f} s".format(self.t[self.indt])) - self.Tstraxis[ii].draw_artist(self.Tstr[ii]) - self.canvas.blit(self.Tstraxis[ii].bbox) - - def onkeypress(self,event): - if event.name is 'key_press_event' and event.key == 'left': - self.indt -= 1 - self.indt = self.indt%self.t.size - self.update_t() - elif event.name is 'key_press_event' and event.key == 'right': - self.indt += 1 - self.indt = self.indt%self.t.size - self.update_t() - - def mouseclic(self,event): - if event.button == 1 and event.inaxes in self.Lax1DTime: - self.indt = np.argmin(np.abs(self.t-event.xdata)) - self.update_t() - - - -# --------------------------------------------------------- -# --------------------------------------------------------- -# ------------ Interactive plots functions ---------------- -# --------------------------------------------------------- - - -def Inv_Plot_Basic(Sol2, Com=None, Deriv=0, indt0=0, t0=None, DVect=TFD.BF2_DVect_DefR, SubP=TFD.InvPlotSubP, SubMode=TFD.InvPlotSubMode, InvPlotFunc=TFD.InvPlotF, InvLvls=TFD.InvLvls, Invd=TFD.Invdict, vlined=TFD.vlined, Tempd=TFD.Tempd, SXRd=TFD.InvSXRd, Sigmad=TFD.InvSigmad, Retrod=TFD.Retrod, VMinMax=[None,None], Norm=False, FreqIn=None, FreqOut=None, HarmIn=True, HarmOut=True, LCol=TFD.InvPlot_LCol, Test=True, a4=False): - """ - Plot a figure for basic visualisation of the solution, data and retrofit - """ - - if Test: - assert isinstance(Sol2, TFI.Sol2D), "Arg Sol2 must be a TFI.Sol2D instance !" - assert Com is None or type(Com) is str, "Arg Com must be None or a str !" - assert InvPlotFunc in ['imshow','contour','contourf'], "Arg PlotFunc must be in ['contour','contourf'] !" - - # Preparing data - BF2, Coefs, t, shot, Ves, SXR, sigma = Sol2.BF2, Sol2.Coefs, Sol2.t, Sol2.shot, Sol2.GMat.Ves, Sol2.data, Sol2._sigma - TMat = Sol2.GMat.MatLOS if Sol2._LOS else Sol2.GMat.Mat - - Nt, NMes = Coefs.shape[0], TMat.shape[0] - Retrofit = np.nan*np.ones((Nt,NMes)) - for ii in range(0,Nt): - Retrofit[ii,:] = TMat.dot(Coefs[ii,:])*1.e3 # In (mW) - SXR = SXR*1.e3 # In (mW) - sigma = sigma*1.e3 # In (mW) - - plot_ImageInv, InvSig, Vminmax = _getValsPlotF(Nt, InvPlotFunc, VMinMax, t, BF2, SubP, SubMode, Deriv, DVect, Coefs, Invd, InvLvls=InvLvls, FreqIn=FreqIn, FreqOut=FreqOut, HarmIn=HarmIn, HarmOut=HarmOut, Norm=Norm, Test=Test) - - # Defining init and update functions - axInv, axTMat, axSig, BckgrdInv, BckgrdTime, BckgrdProf, Tstr, BckgrdTxt = _Plot_Inv_Config_Basic(Nt, NMes, t, Ves, SXR, Retrofit, Com=Com, Tempd=Tempd, Vminmax=Vminmax, cmap=Invd['cmap'], Test=Test, a4=a4) - InvSig['axInv'] = axInv - axInv.figure.canvas.draw() - - LSig1DProf = {'Sig':SXR, 'LRetrofit':[Retrofit], 'ax':axTMat, 'sigma':Sol2._sigma, 'NMes':NMes, 'SXRd':SXRd, 'Retrod':Retrod, 'Sigmad':Sigmad, 'LCol':LCol} - - if not t0 is None: - indt0 = np.nanargmin(np.abs(t-t0)) - Keyhandler = _keyhandler(t, indt0, [axSig], [axTMat], [axInv], [LSig1DProf], [InvSig], [BckgrdTime], [BckgrdProf], [BckgrdInv], [_getSigmaProf_init], [_getSigmaProf_up], [plot_ImageInv], [plot_ImageInv], vlined, [Tstr], [BckgrdTxt]) - def on_press(event): - Keyhandler.onkeypress(event) - def on_clic(event): - Keyhandler.mouseclic(event) - Keyhandler.canvas.mpl_connect('key_press_event', on_press) - Keyhandler.canvas.mpl_connect('button_press_event', on_clic) - return {'1DConst':None, '1DTime':[axSig], '1DProf':[axTMat], '2DConst':None, '2DProf':[axInv]} - - -def Inv_Plot_Technical(Sol2, Com=None, Deriv=0, indt0=0, t0=None, DVect=TFD.BF2_DVect_DefR, SubP=TFD.InvPlotSubP, SubMode=TFD.InvPlotSubMode, InvPlotFunc=TFD.InvPlotF, InvLvls=TFD.InvLvls, Invd=TFD.Invdict, vlined=TFD.vlined, Tempd=TFD.Tempd, SXRd=TFD.InvSXRd, Sigmad=TFD.InvSigmad, Retrod=TFD.Retrod, VMinMax=[None,None], Norm=False, FreqIn=None, FreqOut=None, HarmIn=True, HarmOut=True, LCol=TFD.InvPlot_LCol, Test=True, a4=False): - """ - Plot a figure for visualisation of the solution with technical details regarding the inversion quality - """ - - if Test: - assert isinstance(Sol2, TFI.Sol2D), "Arg Sol2 must be a TFI.Sol2D instance !" - assert Com is None or type(Com) is str, "Arg Com must be None or a str !" - assert InvPlotFunc in ['imshow','contour','contourf'], "Arg PlotFunc must be in ['contour','contourf'] !" - - # Preparing data - BF2, Coefs, t, shot, Ves, SXR, sigma = Sol2.BF2, Sol2.Coefs, Sol2.t, Sol2.shot, Sol2.GMat.Ves, Sol2.data, Sol2._sigma - TMat = Sol2.GMat.MatLOS if Sol2._LOS else Sol2.GMat.Mat - - Nt, NMes = Coefs.shape[0], TMat.shape[0] - Retrofit = np.nan*np.ones((Nt,NMes)) - for ii in range(0,Nt): - Retrofit[ii,:] = TMat.dot(Coefs[ii,:])*1.e3 # In (mW) - SXR = SXR*1.e3 # In (mW) - sigma = sigma*1.e3 # In (mW) - - plot_ImageInv, InvSig, Vminmax = _getValsPlotF(Nt, InvPlotFunc, VMinMax, t, BF2, SubP, SubMode, Deriv, DVect, Coefs, Invd, InvLvls=InvLvls, FreqIn=FreqIn, FreqOut=FreqOut, HarmIn=HarmIn, HarmOut=HarmOut, Norm=Norm, Test=Test) - - # Defining init and update functions - if not hasattr(Sol2, '_Nit'): - Sol2._Nit = np.array([ss[0] for ss in Sol2._Spec]) - axInv, axTMat, LaxTime, BckgrdInv, BckgrdTime, BckgrdProf, Tstr, BckgrdTxt = _Plot_Inv_Config_Technical(Nt, NMes, t, Ves, SXR, Retrofit, Sol2._Chi2N, Sol2._Mu, Sol2._R, Sol2._Nit, Com=Com, Tempd=Tempd, Vminmax=Vminmax, cmap=Invd['cmap'], Test=Test, a4=a4) - InvSig['axInv'] = axInv - axInv.figure.canvas.draw() - - LSig1DProf = {'Sig':SXR, 'LRetrofit':[Retrofit], 'ax':axTMat, 'sigma':Sol2._sigma, 'NMes':NMes, 'SXRd':SXRd, 'Retrod':Retrod, 'Sigmad':Sigmad, 'LCol':LCol} - - if not t0 is None: - indt0 = np.nanargmin(np.abs(t-t0)) - Keyhandler = _keyhandler(t, indt0, LaxTime, [axTMat], [axInv], [LSig1DProf], [InvSig], BckgrdTime, [BckgrdProf], [BckgrdInv], [_getSigmaProf_init], [_getSigmaProf_up], [plot_ImageInv], [plot_ImageInv], vlined, [Tstr], [BckgrdTxt]) - def on_press(event): - Keyhandler.onkeypress(event) - def on_clic(event): - Keyhandler.mouseclic(event) - Keyhandler.canvas.mpl_connect('key_press_event', on_press) - Keyhandler.canvas.mpl_connect('button_press_event', on_clic) - return {'1DConst':None, '1DTime':LaxTime, '1DProf':[axTMat], '2DConst':None, '2DProf':[axInv]} - - -def Inv_Plot_Profiles(Sol2, indt0=0, t0=None, LPath=TFD.InvPlot_LPath, dl=TFD.InvPlot_dl, Com=None, Deriv=0, DVect=TFD.BF2_DVect_DefR, SubP=TFD.InvPlotSubP, SubMode=TFD.InvPlotSubMode, InvPlotFunc=TFD.InvPlotF, InvLvls=TFD.InvLvls, Invd=TFD.Invdict, vlined=TFD.vlined, Tempd=TFD.Tempd, SXRd=TFD.InvSXRd, Sigmad=TFD.InvSigmad, Retrod=TFD.Retrod, VMinMax=[None,None], Norm=False, FreqIn=None, FreqOut=None, HarmIn=True, HarmOut=True, LCol=TFD.InvPlot_LCol, Test=True, a4=False): - """ - Plot a figure for visualisation of the solution with technical details regarding the inversion quality - """ - - if Test: - assert isinstance(Sol2, TFI.Sol2D), "Arg Sol2 must be a TFI.Sol2D instance !" - assert Com is None or type(Com) is str, "Arg Com must be None or a str !" - assert InvPlotFunc in ['imshow','contour','contourf'], "Arg PlotFunc must be in ['contour','contourf'] !" - assert type(LPath) is list and all([hasattr(pp,'__getitem__') and len(pp)==2 and all([type(pi) is str or (hasattr(pi,'__getitem__') and len(pi)==2) for pi in pp]) for pp in LPath]), "Arg LPath must be a list of lines as (point,vector) !" - - # Preparing data - NL = len(LPath) - BF2, Coefs, t, shot, Ves, SXR, sigma = Sol2.BF2, Sol2.Coefs, Sol2.t, Sol2.shot, Sol2.GMat.Ves, Sol2.data, Sol2._sigma - TMat = Sol2.GMat.MatLOS if Sol2._LOS else Sol2.GMat.Mat - - Nt, NMes = Coefs.shape[0], TMat.shape[0] - Retrofit = np.nan*np.ones((Nt,NMes)) - for ii in range(0,Nt): - Retrofit[ii,:] = TMat.dot(Coefs[ii,:])*1.e3 # In (mW) - SXR = SXR*1.e3 # In (mW) - sigma = sigma*1.e3 # In (mW) - - plot_ImageInv, InvSig, Vminmax = _getValsPlotF(Nt, InvPlotFunc, VMinMax, t, BF2, SubP, SubMode, Deriv, DVect, Coefs, Invd, InvLvls=InvLvls, FreqIn=FreqIn, FreqOut=FreqOut, HarmIn=HarmIn, HarmOut=HarmOut, Norm=Norm, Test=Test) - LVals, LPts, Ll = _getProfVals(t, BF2, Ves, LPath, dl, Deriv, DVect, Coefs, FreqIn=FreqIn, FreqOut=FreqOut, HarmIn=HarmIn, HarmOut=HarmOut, Nt=Nt, NL=NL, Test=Test) - - # Defining init and update functions - if not hasattr(Sol2, '_Nit'): - Sol2._Nit = np.array([ss[0] for ss in Sol2._Spec]) - axInv, axTMat, LaxTime, LaxP, BckgrdInv, BckgrdTime, BckgrdProf, Tstr, BckgrdTxt = _Plot_Inv_Config_Profiles(Nt, NMes, NL, LPath, t, Ves, SXR, Retrofit, LPts, LVals, Ll, Com=Com, Tempd=Tempd, Vminmax=Vminmax, cmap=Invd['cmap'], Test=Test, a4=a4) - InvSig['axInv'] = axInv - axInv.figure.canvas.draw() - - LSig1DProf = [{'Sig':SXR, 'LRetrofit':[Retrofit], 'ax':axTMat, 'sigma':Sol2._sigma, 'NMes':NMes, 'SXRd':SXRd, 'Retrod':Retrod, 'Sigmad':Sigmad, 'LCol':LCol}] - for ii in range(0,NL): - LSig1DProf.append({'NL':NL, 'Lax':LaxP, 'LPts':LPts, 'LVals':LVals, 'Ll':Ll, 'ldict':Tempd}) - - finit = [_getEmissProf_init for ii in range(0,NL)] - fup = [_getEmissProf_up for ii in range(0,NL)] - - if not t0 is None: - indt0 = np.nanargmin(np.abs(t-t0)) - Keyhandler = _keyhandler(t, indt0, [LaxTime], [axTMat]+LaxP, [axInv], LSig1DProf, [InvSig], [BckgrdTime], BckgrdProf, [BckgrdInv], [_getSigmaProf_init]+finit, [_getSigmaProf_up]+fup, [plot_ImageInv], [plot_ImageInv], vlined, [Tstr], [BckgrdTxt]) - #Keyhandler = keyhandler(t, SXR, TMat, Retrofit, Vals, sigma, 0, axInv, axTMat, Laxtemp, BckgrdInv, BckgrdTime, BckgrdProf, Invd, vlined, SXRd, Sigmad, Retrod, KWargs, Vminmax, Norm, Com, shot) - def on_press(event): - Keyhandler.onkeypress(event) - def on_clic(event): - Keyhandler.mouseclic(event) - Keyhandler.canvas.mpl_connect('key_press_event', on_press) - Keyhandler.canvas.mpl_connect('button_press_event', on_clic) - return {'1DConst':None, '1DTime':[LaxTime], '1DProf':[axTMat]+LaxP, '2DConst':None, '2DProf':[axInv]} - - - - -# --------------------------------------------------------- -# --------------------------------------------------------- -# ------------- Compare plot functions -------------------- -# --------------------------------------------------------- - -def _UniformiseSol2D(Nt, NSol, LSXR, LRetrofit, Lsigma, LNames): - - LChan = sorted(list(set(itt.chain.from_iterable(LNames)))) - NMes = len(LChan) - MaxSXR, names = np.empty((Nt,NMes)), [] - Usigma = np.empty((NMes,)) - N, ii = NMes+1-1, 0 - while N>0: - inds = [not nn in names for nn in LNames[ii]] - if any(inds): - for jj in range(0,len(inds)): - if inds[jj]: - ind = LChan.index(LNames[ii][jj]) - MaxSXR[:,ind] = LSXR[ii][:,jj] - Usigma[ind] = Lsigma[ii][jj] - names.append(LNames[ii][jj]) - N -= 1 - ii += 1 - LRetro = [np.nan*np.ones((Nt,NMes)) for ii in range(0,NSol)] - RetroMinMax = [0,0] - for ii in range(0,NSol): - inds = np.array([nn in LNames[ii] for nn in LChan], dtype=bool) - LRetro[ii][:,inds] = LRetrofit[ii] - RetroMinMax[0] = min(RetroMinMax[0],np.nanmin(LRetrofit[ii])) - RetroMinMax[1] = max(RetroMinMax[1],np.nanmax(LRetrofit[ii])) - - return NMes, MaxSXR, LRetro, Usigma, LChan, RetroMinMax - - -def Inv_Compare_Basic(LSol2, LCom=None, Deriv=0, DVect=TFD.BF2_DVect_DefR, SubP=TFD.InvPlotSubP, SubMode=TFD.InvPlotSubMode, InvPlotFunc=TFD.InvPlotF, InvLvls=TFD.InvLvls, Invd=TFD.Invdict, vlined=TFD.vlined, Tempd=TFD.Tempd, SXRd=dict(TFD.InvSXRd), Sigmad=dict(TFD.InvSigmad), Retrod=dict(TFD.Retrod), VMinMax=[None,None], Norm=False, FreqIn=None, FreqOut=None, HarmIn=True, HarmOut=True, Test=True, a4=False, Com=None, LCol=TFD.InvPlot_LCol): - """ - Plot a figure for basic visualisation of the solution, data and retrofit - """ - if Test: - assert type(LSol2) is list and all([isinstance(ss, TFI.Sol2D) for ss in LSol2]), "Arg LSol2 must be a list of TFI.Sol2D instance !" - assert LCom is None or type(LCom) is list, "Arg LCom must be None or a list of str !" - assert InvPlotFunc in ['imshow','contour','contourf'], "Arg PlotFunc must be in ['contour','contourf'] !" - - # Preparing data - NSol = len(LSol2) - shot, t, Ves, Nt = LSol2[0].shot, LSol2[0].t, LSol2[0].GMat.Ves, LSol2[0].Coefs.shape[0] - LBF2, LCoefs, LSXR, Lsigma, LTMat, LNMes, LRetrofit = [], [], [], [], [], [], [] - LInvSig, LVminmax = [], [] - for ii in range(0,NSol): - LBF2.append(0), LCoefs.append(0), LSXR.append(0), Lsigma.append(0), LTMat.append(0), LInvSig.append(0), LVminmax.append(0) - LBF2[ii], LCoefs[ii], LSXR[ii], Lsigma[ii] = LSol2[ii].BF2, LSol2[ii].Coefs, LSol2[ii].data, LSol2[ii]._sigma - LTMat[ii] = LSol2[ii].GMat.MatLOS if LSol2[ii]._LOS else LSol2[ii].GMat.Mat - LNMes.append(LTMat[ii].shape[0]) - LRetrofit.append(np.nan*np.ones((Nt,LNMes[ii]))) - for jj in range(0,Nt): - LRetrofit[ii][jj,:] = LTMat[ii].dot(LCoefs[ii][jj,:])*1.e3 # In (mW) - LSXR[ii] = LSXR[ii]*1.e3 # In (mW) - Lsigma[ii] = Lsigma[ii]*1.e3 # In (mW) - - plot_ImageInv, LInvSig[ii], LVminmax[ii] = _getValsPlotF(Nt, InvPlotFunc, VMinMax, t, LBF2[ii], SubP, SubMode, Deriv, DVect, LCoefs[ii], Invd, InvLvls=InvLvls, FreqIn=FreqIn, FreqOut=FreqOut, HarmIn=HarmIn, HarmOut=HarmOut, Norm=Norm, Test=Test) - - - # Defining init and update functions - MaxNMes, MaxSXR, LRetro, Usigma, LChan, RetroMinMax = _UniformiseSol2D(Nt, NSol, LSXR, LRetrofit, Lsigma, [ss._LNames for ss in LSol2]) - MaxVminmax = [np.min([vv[0] for vv in LVminmax]), np.max([vv[1] for vv in LVminmax])] - - LaxInv, axTMat, axSig, BckgrdInv, BckgrdTime, BckgrdProf, LTstr, BckgrdTxt = _Plot_Inv_Config_Compare_Basic(NSol, Nt, MaxNMes, t, Ves, MaxSXR, RetroMinMax, LCom=LCom, Tempd=Tempd, Vminmax=MaxVminmax, cmap=Invd['cmap'], LCol=LCol, Test=Test, a4=a4) - for ii in range(0,NSol): - LInvSig[ii]['axInv'] = LaxInv[ii] - LInvSig[ii]['Vminmax'] = MaxVminmax - LaxInv[0].figure.canvas.draw() - - LSig1DProf = {'Sig':MaxSXR, 'LRetrofit':LRetro, 'ax':axTMat, 'sigma':Usigma, 'NMes':MaxNMes, 'SXRd':SXRd, 'Retrod':Retrod, 'Sigmad':Sigmad, 'LCol':LCol} - - LFPlot1DProf_init = [_getSigmaProf_init for ii in range(0,NSol)] - LFPlot1DProf_up = [_getSigmaProf_up for ii in range(0,NSol)] - LFPlot2DProf_init = [plot_ImageInv for ii in range(0,NSol)] - Keyhandler = _keyhandler(t, 0, [axSig], [axTMat], LaxInv, [LSig1DProf], LInvSig, [BckgrdTime], [BckgrdProf], BckgrdInv, LFPlot1DProf_init, LFPlot1DProf_up, LFPlot2DProf_init, LFPlot2DProf_init, vlined, LTstr, BckgrdTxt) - def on_press(event): - Keyhandler.onkeypress(event) - def on_clic(event): - Keyhandler.mouseclic(event) - Keyhandler.canvas.mpl_connect('key_press_event', on_press) - Keyhandler.canvas.mpl_connect('button_press_event', on_clic) - return {'1DConst':None, '1DTime':[axSig], '1DProf':[axTMat], '2DConst':None, '2DProf':LaxInv} - - - -def Inv_Compare_Technical(LSol2, LCom=None, Deriv=0, DVect=TFD.BF2_DVect_DefR, SubP=TFD.InvPlotSubP, SubMode=TFD.InvPlotSubMode, InvPlotFunc=TFD.InvPlotF, InvLvls=TFD.InvLvls, Invd=TFD.Invdict, vlined=TFD.vlined, Tempd=TFD.Tempd, SXRd=dict(TFD.InvSXRd), Sigmad=dict(TFD.InvSigmad), Retrod=dict(TFD.Retrod), VMinMax=[None,None], Norm=False, FreqIn=None, FreqOut=None, HarmIn=True, HarmOut=True, Test=True, a4=False, Com=None, LCol=TFD.InvPlot_LCol): - """ - Plot a figure for basic visualisation of the solution, data and retrofit - """ - - if Test: - assert type(LSol2) is list and all([isinstance(ss, TFI.Sol2D) for ss in LSol2]), "Arg LSol2 must be a list of TFI.Sol2D instance !" - assert LCom is None or type(LCom) is list, "Arg LCom must be None or a list of str !" - assert InvPlotFunc in ['imshow','contour','contourf'], "Arg PlotFunc must be in ['contour','contourf'] !" - - # Preparing data - NSol = len(LSol2) - shot, t, Ves, Nt = LSol2[0].shot, LSol2[0].t, LSol2[0].GMat.Ves, LSol2[0].Coefs.shape[0] - LBF2, LCoefs, LSXR, Lsigma, LTMat, LNMes, LRetrofit = [], [], [], [], [], [], [] - LInvSig, LVminmax = [], [] - for ii in range(0,NSol): - LBF2.append(0), LCoefs.append(0), LSXR.append(0), Lsigma.append(0), LTMat.append(0), LInvSig.append(0), LVminmax.append(0) - LBF2[ii], LCoefs[ii], LSXR[ii], Lsigma[ii] = LSol2[ii].BF2, LSol2[ii].Coefs, LSol2[ii].data, LSol2[ii]._sigma - LTMat[ii] = LSol2[ii].GMat.MatLOS if LSol2[ii]._LOS else LSol2[ii].GMat.Mat - LNMes.append(LTMat[ii].shape[0]) - LRetrofit.append(np.nan*np.ones((Nt,LNMes[ii]))) - for jj in range(0,Nt): - LRetrofit[ii][jj,:] = LTMat[ii].dot(LCoefs[ii][jj,:])*1.e3 # In (mW) - LSXR[ii] = LSXR[ii]*1.e3 # In (mW) - Lsigma[ii] = Lsigma[ii]*1.e3 # In (mW) - - plot_ImageInv, LInvSig[ii], LVminmax[ii] = _getValsPlotF(Nt, InvPlotFunc, VMinMax, t, LBF2[ii], SubP, SubMode, Deriv, DVect, LCoefs[ii], Invd, InvLvls=InvLvls, FreqIn=FreqIn, FreqOut=FreqOut, HarmIn=HarmIn, HarmOut=HarmOut, Norm=Norm, Test=Test) - - # Defining init and update functions - MaxNMes, MaxSXR, LRetro, Usigma, LChan, RetroMinMax = _UniformiseSol2D(Nt, NSol, LSXR, LRetrofit, Lsigma, [ss._LNames for ss in LSol2]) - MaxVminmax = [np.min([vv[0] for vv in LVminmax]), np.max([vv[1] for vv in LVminmax])] - - for ii in range(0,NSol): - if not hasattr(LSol2[ii], '_Nit'): - LSol2[ii]._Nit = np.array([ss[0] for ss in LSol2[ii]._Spec]) - LChi2N, LMu, LR, LNit = [ss._Chi2N for ss in LSol2], [ss._Mu for ss in LSol2], [ss._R for ss in LSol2], [ss._Nit for ss in LSol2] - LaxInv, axTMat, LaxTime, BckgrdInv, BckgrdTime, BckgrdProf, LTstr, BckgrdTxt = _Plot_Inv_Config_Compare_Technical(NSol, Nt, MaxNMes, t, Ves, MaxSXR, RetroMinMax, LChi2N, LMu, LR, LNit, LCom=LCom, Tempd=Tempd, Vminmax=MaxVminmax, cmap=Invd['cmap'], LCol=LCol, Test=Test, a4=a4) - for ii in range(0,NSol): - LInvSig[ii]['axInv'] = LaxInv[ii] - LInvSig[ii]['Vminmax'] = MaxVminmax - LaxInv[0].figure.canvas.draw() - - LSig1DProf = {'Sig':MaxSXR, 'LRetrofit':LRetro, 'ax':axTMat, 'sigma':Usigma, 'NMes':MaxNMes, 'SXRd':SXRd, 'Retrod':Retrod, 'Sigmad':Sigmad, 'LCol':LCol} - - LFPlot1DProf_init = [_getSigmaProf_init for ii in range(0,NSol)] - LFPlot1DProf_up = [_getSigmaProf_up for ii in range(0,NSol)] - LFPlot2DProf_init = [plot_ImageInv for ii in range(0,NSol)] - Keyhandler = _keyhandler(t, 0, LaxTime, [axTMat], LaxInv, [LSig1DProf], LInvSig, BckgrdTime, [BckgrdProf], BckgrdInv, LFPlot1DProf_init, LFPlot1DProf_up, LFPlot2DProf_init, LFPlot2DProf_init, vlined, LTstr, BckgrdTxt) - def on_press(event): - Keyhandler.onkeypress(event) - def on_clic(event): - Keyhandler.mouseclic(event) - Keyhandler.canvas.mpl_connect('key_press_event', on_press) - Keyhandler.canvas.mpl_connect('button_press_event', on_clic) - return {'1DConst':None, '1DTime':LaxTime, '1DProf':[axTMat], '2DConst':None, '2DProf':LaxInv} - - - - -def Inv_Compare_Profiles(LSol2, LPath=TFD.InvPlot_LPath, dl=TFD.InvPlot_dl, LCom=None, Deriv=0, DVect=TFD.BF2_DVect_DefR, SubP=TFD.InvPlotSubP, SubMode=TFD.InvPlotSubMode, InvPlotFunc=TFD.InvPlotF, InvLvls=TFD.InvLvls, Invd=TFD.Invdict, vlined=TFD.vlined, Tempd=TFD.Tempd, SXRd=dict(TFD.InvSXRd), Sigmad=dict(TFD.InvSigmad), Retrod=dict(TFD.Retrod), VMinMax=[None,None], Norm=False, FreqIn=None, FreqOut=None, HarmIn=True, HarmOut=True, Test=True, a4=False, Com=None, LCol=TFD.InvPlot_LCol): - """ - Plot a figure for basic visualisation of the solution, data and retrofit - """ - - if Test: - assert type(LSol2) is list and all([isinstance(ss, TFI.Sol2D) for ss in LSol2]), "Arg LSol2 must be a list of TFI.Sol2D instance !" - assert LCom is None or type(LCom) is list, "Arg LCom must be None or a list of str !" - assert InvPlotFunc in ['imshow','contour','contourf'], "Arg PlotFunc must be in ['contour','contourf'] !" - assert type(LPath) is list and all([hasattr(pp,'__getitem__') and len(pp)==2 and all([type(pi) is str or (hasattr(pi,'__getitem__') and len(pi)==2) for pi in pp]) for pp in LPath]), "Arg LPath must be a list of lines as (point,vector) !" - - # Preparing data - NL = len(LPath) - - # Preparing data - NSol = len(LSol2) - shot, t, Ves, Nt = LSol2[0].shot, LSol2[0].t, LSol2[0].GMat.Ves, LSol2[0].Coefs.shape[0] - LBF2, LCoefs, LSXR, Lsigma, LTMat, LNMes, LRetrofit = [], [], [], [], [], [], [] - LInvSig, LVminmax = [], [] - LLVals = [] - for ii in range(0,NSol): - LBF2.append(0), LCoefs.append(0), LSXR.append(0), Lsigma.append(0), LTMat.append(0), LInvSig.append(0), LVminmax.append(0) - LBF2[ii], LCoefs[ii], LSXR[ii], Lsigma[ii] = LSol2[ii].BF2, LSol2[ii].Coefs, LSol2[ii].data, LSol2[ii]._sigma - LTMat[ii] = LSol2[ii].GMat.MatLOS if LSol2[ii]._LOS else LSol2[ii].GMat.Mat - LNMes.append(LTMat[ii].shape[0]) - LRetrofit.append(np.nan*np.ones((Nt,LNMes[ii]))) - for jj in range(0,Nt): - LRetrofit[ii][jj,:] = LTMat[ii].dot(LCoefs[ii][jj,:])*1.e3 # In (mW) - LSXR[ii] = LSXR[ii]*1.e3 # In (mW) - Lsigma[ii] = Lsigma[ii]*1.e3 # In (mW) - - plot_ImageInv, LInvSig[ii], LVminmax[ii] = _getValsPlotF(Nt, InvPlotFunc, VMinMax, t, LBF2[ii], SubP, SubMode, Deriv, DVect, LCoefs[ii], Invd, InvLvls=InvLvls, FreqIn=FreqIn, FreqOut=FreqOut, HarmIn=HarmIn, HarmOut=HarmOut, Norm=Norm, Test=Test) - LVals, LPts, Ll = _getProfVals(t, LBF2[ii], Ves, LPath, dl, Deriv, DVect, LCoefs[ii], FreqIn=FreqIn, FreqOut=FreqOut, HarmIn=HarmIn, HarmOut=HarmOut, Nt=Nt, NL=NL, Test=Test) - LLVals.append(LVals) - - - # Defining init and update functions - MaxNMes, MaxSXR, LRetro, Usigma, LChan, RetroMinMax = _UniformiseSol2D(Nt, NSol, LSXR, LRetrofit, Lsigma, [ss._LNames for ss in LSol2]) - - MaxVminmax = [np.min([vv[0] for vv in LVminmax]), np.max([vv[1] for vv in LVminmax])] - LaxInv, axTMat, axSig, LaxP, LaxPbis, BckgrdInv, BckgrdTime, BckgrdProf, LTstr, BckgrdTxt = _Plot_Inv_Config_Compare_Profiles(NSol, Nt, MaxNMes, NL, LPath, t, Ves, MaxSXR, RetroMinMax, LPts, LLVals, Ll, LCom=LCom, Tempd=Tempd, Vminmax=MaxVminmax, cmap=Invd['cmap'], LCol=LCol, Test=Test, a4=a4) - - - for ii in range(0,NSol): - LInvSig[ii]['axInv'] = LaxInv[ii] - LInvSig[ii]['Vminmax'] = MaxVminmax - LaxInv[0].figure.canvas.draw() - - LSig1DProf = [{'Sig':MaxSXR, 'LRetrofit':LRetro, 'ax':axTMat, 'sigma':Usigma, 'NMes':MaxNMes, 'SXRd':SXRd, 'Retrod':Retrod, 'Sigmad':Sigmad, 'LCol':LCol}] - for ii in range(0,NL): - LSig1DProf.append({'NL':NL, 'Lax':LaxP, 'LPts':LPts, 'LVals':LLVals, 'Ll':Ll, 'ldict':Tempd, 'NSol':NSol, 'LCol':LCol}) - - LFPlot1DProf_init = [_getSigmaProf_init for ii in range(0,NSol)] - LFPlot1DProf_up = [_getSigmaProf_up for ii in range(0,NSol)] - LFPlot2DProf_init = [plot_ImageInv for ii in range(0,NSol)] - - finit = [_getSigmaProf_init]+[_getEmissProf_init for ii in range(0,NL)] - fup = [_getSigmaProf_up]+[_getEmissProf_up for ii in range(0,NL)] - Keyhandler = _keyhandler(t, 0, [axSig], [axTMat]+LaxP, LaxInv, LSig1DProf, LInvSig, [BckgrdTime], BckgrdProf, BckgrdInv, finit, fup, LFPlot2DProf_init, LFPlot2DProf_init, vlined, LTstr, BckgrdTxt) - def on_press(event): - Keyhandler.onkeypress(event) - def on_clic(event): - Keyhandler.mouseclic(event) - Keyhandler.canvas.mpl_connect('key_press_event', on_press) - Keyhandler.canvas.mpl_connect('button_press_event', on_clic) - return {'1DConst':None, '1DTime':[axSig], '1DProf':[axTMat]+LaxP, '2DConst':None, '2DProf':LaxInv} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -def Inv_PlotFFTPow(BF2, Coefs, RZPts=None, t=None, Com=None, shot=None, Ves=None, SXR=None, sigma=None, TMat=None, Chi2N=None, Mu=None, R=None, Nit=None, Deriv=0, DVect=TFD.BF2_DVect_DefR, SubP=TFD.InvPlotSubP, SubMode=TFD.InvPlotSubMode, InvPlotFunc=TFD.InvPlotF, InvLvls=TFD.InvLvls, Invd=TFD.Invdict, vlined={'c':'k','ls':'--','lw':1.}, Tempd=TFD.Tempd, SXRd=TFD.InvSXRd, Sigmad=TFD.InvSigmad, Retrod=TFD.Retrod, VMinMax=[None,None], Test=True, - DTF=None, RatDef=100, Method='Max', Trunc=0.60, Inst=True, SpectNorm=True, cmapPow=plt.cm.gray_r, a4=False): - if Test: - assert isinstance(BF2, TFM.BF2D), "Arg nb. 1 (BF2) must be a TFM.BF2D instance !" - assert isinstance(Coefs, np.ndarray) and Coefs.shape[1]==BF2.NFunc, "Arg nb. 2 (Coefs) must be a np.ndarray instance with shape (Nt,BF2.NFunc) !" - assert isinstance(t,np.ndarray) and t.ndim==1 and t.size==Coefs.shape[0], "Arg t must be a 1D np.ndarray with t.size==Coefs.shape[0]" - #assert GM2D is None or isinstance(GM2D,TFMC.GMat2D), "Arg GM2D must be None or a TFMC.GMat2D instance !" - assert Com is None or type(Com) is str, "Arg Com must be None or a str !" - assert shot is None or type(shot) is int, "Arg shot must be None or a shot number (int) !" - assert SXR is None or (isinstance(SXR,np.ndarray) and SXR.ndim==2 and SXR.shape[0]==Coefs.shape[0]), "Arg SXR must be None or a 2D np.ndarray with SXR.shape[0]==Coefs.shape[0]" - assert sigma is None or (not SXR is None and isinstance(sigma,np.ndarray) and sigma.size%SXR.shape[1]==0), "Arg sigma must be None or a np.ndarray (1D or 2D) !" - assert TMat is None or (not SXR is None and TMat.shape==(SXR.shape[1],BF2.NFunc)), "Arg TMat must be None or a 2D np.ndarray with TMat.shape==(SXR.shape[1],BF2.NFunc) !" - assert Chi2N is None or (isinstance(Chi2N,np.ndarray) and Chi2N.ndim==1 and Chi2N.size==Coefs.shape[0]), "Arg Chi2N must be None or a 1D np.ndarray with Chi2N.size==Coefs.shape[0]" - assert Mu is None or (isinstance(Mu,np.ndarray) and Mu.ndim==1 and Mu.size==Coefs.shape[0]), "Arg Mu must be None or a 1D np.ndarray with Mu.size==Coefs.shape[0]" - assert R is None or (isinstance(R,np.ndarray) and R.ndim==1 and R.size==Coefs.shape[0]), "Arg R must be None or a 1D np.ndarray with R.size==Coefs.shape[0]" - assert Nit is None or (isinstance(Nit,np.ndarray) and Nit.ndim==1 and Nit.size==Coefs.shape[0]), "Arg Nit must be None or a 1D np.ndarray with Nit.size==Coefs.shape[0]" - assert InvPlotFunc in ['imshow','contour','contourf'], "Arg PlotFunc must be in ['contour','contourf'] !" - - # Function building the mesh for plotting - Nt = Coefs.shape[0] - def getmeshVals(Reg): - Rplot, Zplot, nR, nZ = BF2.get_XYplot(SubP=SubP, SubMode=SubMode) - if Reg=='Reg': - extent = (BF2.Mesh.MeshR.Cents.min(), BF2.Mesh.MeshR.Cents.max(), BF2.Mesh.MeshZ.Cents.min(), BF2.Mesh.MeshZ.Cents.max()) - Rplot,Zplot = np.mgrid[extent[0]:extent[1]:complex(nR), extent[2]:extent[3]:complex(nZ)] - Rplot,Zplot = Rplot.T,Zplot.T - Points = np.array([Rplot.flatten(), np.zeros((nR*nZ,)), Zplot.flatten()]) - indnan = ~BF2.Mesh.isInside(np.array([Rplot.flatten(),Zplot.flatten()])) - Vals = np.nan*np.ones((Nt,nR*nZ)) - Vals[:,~indnan] = BF2.get_TotVal(Points[:,~indnan], Deriv=Deriv, DVect=DVect, Coefs=Coefs, Test=Test) - IndNoNan = (~indnan).nonzero()[0] - V = 2 if Inst else 1 - for ii in range(0,IndNoNan.size): - if ii==0 or (ii+1)%1000==0: - print " Getting dominant frequency for point",ii+1, "/", IndNoNan.size - Pow, MainFreq, Freq = TFT.Fourier_MainFreqPowSpect(Vals[:,IndNoNan[ii]], t, DTF=DTF, RatDef=RatDef, Method=Method, Trunc=Trunc, V=V, Test=Test) - Vals[:,IndNoNan[ii]] = MainFreq*1.e-3 # (kHz) - #Vals[:,indnan] = np.ma.masked - if Reg=='Irreg': - return Rplot, Zplot, nR, nZ, Vals - elif Reg=='Reg': - return extent, nR, nZ, Vals - - def getLPow(RZPts): - Vals = np.nan*np.ones((Nt,RZPts.shape[1])) - indnan = ~BF2.Mesh.isInside(np.array([RZPts[0,:],RZPts[1,:]])) - Vals[:,~indnan] = BF2.get_TotVal(np.array([RZPts[0,~indnan], np.zeros((np.sum(~indnan))), RZPts[1,~indnan]]), Deriv=0, Coefs=Coefs, Test=Test) - if Inst: - Spects = [list(TFT.FourierPowSpect_V2(Vals[:,ii], t, DTF=DTF, RatDef=RatDef, Test=Test)) for ii in range(0,RZPts.shape[1])] - else: - Spects = [list(TFT.FourierPowSpect(Vals[:,ii], t, DTF=DTF, RatDef=RatDef, Test=Test)) for ii in range(0,RZPts.shape[1])] - if SpectNorm: - for ii in range(0,RZPts.shape[1]): - Spects[ii][0] = Spects[ii][0]/np.tile(np.nanmax(Spects[ii][0],axis=1),(Spects[ii][0].shape[1],1)).T - else: - for ii in range(0,RZPts.shape[1]): - Spects[ii][0] = Spects[ii][0]/np.nanmax(Spects[ii][0]) - return Spects - - if RZPts is None: - RZPts = np.tile(Ves.BaryS,(8,1)).T + np.tile(Ves._PRMax-Ves.BaryS,(8,1)).T*np.linspace(0,0.8,8) - LPowFreq = getLPow(RZPts) - - Vminmax = VMinMax[:] - if InvPlotFunc=='imshow': - extent, nR, nZ, Vals = getmeshVals('Reg') - if Vminmax[0] is None: - Vminmax[0] = np.nanmin([0,np.nanmin(Vals)]) - if Vminmax[1] is None: - Vminmax[1] = 0.95*np.nanmax(Vals) - interp = ['nearest','bilinear','bicubic'][BF2.Deg] - KWargs = {'Vminmax':Vminmax, 'nR':nR, 'nZ':nZ, 'axInv':None, 'Invd':Invd, 'interp':interp, 'extent':extent} - def plot_ImageInv(vals, Vminmax=None, nR=None, nZ=None, axInv=None, Invd=None, extent=None, interp=None): - Inv = axInv.imshow(vals.reshape((nZ,nR)), extent=extent, cmap=Invd['cmap'], origin='lower', aspect='auto', interpolation=interp, zorder=0, vmin=Vminmax[0], vmax=Vminmax[1]) - return Inv - else: - Rplot, Zplot, nR, nZ, Vals = getmeshVals('Irreg') - if Vminmax[0] is None: - Vminmax[0] = np.nanmin([0,np.nanmin(Vals)]) - if Vminmax[1] is None: - Vminmax[1] = 0.95*np.nanmax(Vals) - KWargs = {'Vminmax':Vminmax, 'nR':nR, 'nZ':nZ, 'axInv':None, 'Invd':Invd, 'Rplot':Rplot, 'Zplot':Zplot, 'InvLvls':InvLvls} - def plot_ImageInv(vals, Vminmax=None, nR=None, nZ=None, axInv=None, Invd=None, Rplot=None, Zplot=None, InvLvls=None): - pltfunc = axInv.contour if InvPlotFunc=='contour' else axInv.contourf - Inv = pltfunc(Rplot, Zplot, vals.reshape((nZ,nR)), InvLvls, zorder=0, vmin=Vminmax[0], vmax=Vminmax[1], **Invd) - Inv.axes = axInv - Inv.figure = axInv.figure - def draw(self,renderer): - for cc in self.collections: cc.draw(renderer) - Inv.draw = types.MethodType(draw,Inv,None) - return Inv - - # Defining init and update functions for anim with and without TMatOn - axInv, axTMat, Laxtemp, BckgrdInv, BckgrdTime, BckgrdProf, SXR, Retrofit = Plot_Inv_Config_PowSpect(Coefs, LPowFreq, RZPts, t=t, Com=Com, shot=shot, Ves=Ves, SXR=SXR, TMat=TMat, Tempd=Tempd, Vminmax=Vminmax, cmap=Invd['cmap'], cmap2=cmapPow, Test=Test, a4=a4) - KWargs['axInv'] = axInv - axInv.figure.canvas.draw() - class keyhandler(): - def __init__(self, t, SXR, TMat, Retrofit, Vals, sigma, indt, axInv, axTMat, Laxtemp, BckgrdInv, BckgrdTime, BckgrdProf, Invd, vlined, SXRd, Sigmad, Retrod, KWargs, Com, shot): - self.t = t - self.indt = indt - self.SXR = SXR - self.TMat = TMat - if not TMat is None: - self.NMes = TMat.shape[0] - self.Retrofit = Retrofit - self.Vals = Vals - self.KWargs = KWargs - self.sigma = sigma*1.e3 # (mW) - self.axInv = axInv - self.Laxtemp = Laxtemp - self.Ntemp = len(Laxtemp) - self.axTMat = axTMat - self.canvas = axInv.figure.canvas - self.BckgrdInv = BckgrdInv - self.BckgrdTime = BckgrdTime - self.BckgrdProf = BckgrdProf - self.Invd, self.vlined, self.SXRd, self.Sigmad, self.Retrod = Invd, vlined, SXRd, Sigmad, Retrod - self.shot, self.Com = shot, Com - self.initplot() - - def initplot(self): - self.Inv = plot_ImageInv(self.Vals[0,:], **self.KWargs) - self.axInv.draw_artist(self.Inv) - self.canvas.blit(self.axInv.bbox) - self.Lt = [] - for ii in range(0,self.Ntemp): - self.Lt.append(self.Laxtemp[ii].axvline(self.t[0],**self.vlined)) - self.Laxtemp[ii].draw_artist(self.Lt[ii]) - self.canvas.blit(self.Laxtemp[ii].bbox) - if not self.TMat is None: - if not self.sigma is None: - sigma = self.sigma if self.sigma.ndim==1 else self.sigma[0,:] - self.Sigma = self.axTMat.fill_between(range(1,self.NMes+1), self.SXR[0,:]+sigma, self.SXR[0,:]-sigma, **self.Sigmad) - self.lSXR = self.axTMat.plot(range(1,self.NMes+1), self.SXR[0,:], **self.SXRd)[0] - self.Retro = self.axTMat.plot(range(1,self.NMes+1),self.Retrofit[0,:], **self.Retrod)[0] - self.axTMat.draw_artist(self.Sigma) - self.axTMat.draw_artist(self.lSXR) - self.axTMat.draw_artist(self.Retro) - self.canvas.blit(self.axTMat.bbox) - - def update_t(self): - print " Selected time = ", self.t[self.indt], " s" - for ii in range(0,self.Ntemp): - self.canvas.restore_region(self.BckgrdTime[ii]) - self.Lt[ii].set_xdata([self.t[self.indt],self.t[self.indt]]) - self.Laxtemp[ii].draw_artist(self.Lt[ii]) - self.canvas.blit(self.Laxtemp[ii].bbox) - if not self.TMat is None: - self.canvas.restore_region(self.BckgrdProf) - if not self.sigma is None: - sigma = self.sigma if self.sigma.ndim==1 else self.sigma[0,:] - self.Sigma = self.axTMat.fill_between(range(1,self.NMes+1), self.SXR[self.indt,:]+sigma, self.SXR[self.indt,:]-sigma, **self.Sigmad) - self.lSXR.set_ydata(self.SXR[self.indt,:]) - self.Retro.set_ydata(self.Retrofit[self.indt,:]) - self.axTMat.draw_artist(self.Sigma) - self.axTMat.draw_artist(self.lSXR) - self.axTMat.draw_artist(self.Retro) - self.canvas.blit(self.axTMat.bbox) - self.canvas.restore_region(self.BckgrdInv) - self.Inv = plot_ImageInv(self.Vals[self.indt,:], **self.KWargs) - self.axInv.draw_artist(self.Inv) - self.canvas.blit(self.axInv.bbox) - - def onkeypress(self,event): - if event.name is 'key_press_event' and event.key == 'left': - self.indt -= 1 - self.indt = self.indt%self.t.size - self.update_t() - elif event.name is 'key_press_event' and event.key == 'right': - self.indt += 1 - self.indt = self.indt%self.t.size - self.update_t() - - def mouseclic(self,event): - if event.button == 1 and event.inaxes in self.Laxtemp: - self.indt = np.argmin(np.abs(self.t-event.xdata)) - self.update_t() - - Keyhandler = keyhandler(t, SXR, TMat, Retrofit, Vals, sigma, 0, axInv, axTMat, Laxtemp, BckgrdInv, BckgrdTime, BckgrdProf, Invd, vlined, SXRd, Sigmad, Retrod, KWargs, Com, shot) - def on_press(event): - Keyhandler.onkeypress(event) - def on_clic(event): - Keyhandler.mouseclic(event) - Keyhandler.axInv.figure.canvas.mpl_connect('key_press_event', on_press) - #Keyhandler.axInv.figure.canvas.mpl_connect('key_release_event', on_press) - Keyhandler.axInv.figure.canvas.mpl_connect('button_press_event', on_clic) - return axInv, axTMat, Laxtemp - - - - - - -def Plot_Inv_Config_PowSpect(Coefs, LPowFreq, RZPts, t=None, Com=None, shot=None, Ves=None, SXR=None, TMat=None, Chi2N=None, Mu=None, R=None, Nit=None, Tempd=TFD.Tempd, Vminmax=None, cmap=None, cmap2=None, Test=True, a4=False): - if Test: - assert isinstance(t,np.ndarray) and t.ndim==1 and t.size==Coefs.shape[0], "Arg t must be a 1D np.ndarray with t.size==Coefs.shape[0]" - assert Com is None or type(Com) is str, "Arg Com must be None or a str !" - assert shot is None or type(shot) is int, "Arg shot must be None or a shot number (int) !" - assert SXR is None or (isinstance(SXR,np.ndarray) and SXR.ndim==2 and SXR.shape[0]==Coefs.shape[0]), "Arg SXR must be None or a 2D np.ndarray with SXR.shape[0]==Coefs.shape[0]" - assert Chi2N is None or (isinstance(Chi2N,np.ndarray) and Chi2N.ndim==1 and Chi2N.size==Coefs.shape[0]), "Arg Chi2N must be None or a 1D np.ndarray with Chi2N.size==Coefs.shape[0]" - assert Mu is None or (isinstance(Mu,np.ndarray) and Mu.ndim==1 and Mu.size==Coefs.shape[0]), "Arg Mu must be None or a 1D np.ndarray with Mu.size==Coefs.shape[0]" - assert R is None or (isinstance(R,np.ndarray) and R.ndim==1 and R.size==Coefs.shape[0]), "Arg R must be None or a 1D np.ndarray with R.size==Coefs.shape[0]" - assert Nit is None or (isinstance(Nit,np.ndarray) and Nit.ndim==1 and Nit.size==Coefs.shape[0]), "Arg Nit must be None or a 1D np.ndarray with Nit.size==Coefs.shape[0]" - - # Function building the mesh for plotting - Nt = Coefs.shape[0] - # Precomputing retrofit - if not TMat is None: - Retrofit = np.nan*np.ones((Nt,TMat.shape[0])) - for ii in range(0,Nt): - Retrofit[ii,:] = TMat.dot(Coefs[ii,:])*1.e3 # In (mW) - if not SXR is None: - SXR = SXR*1.e3 # In (mW) - - NPts = len(LPowFreq) - axInv, axc, axRetro, axSXR, Lax = TFD.Plot_Inv_FFTPow_DefAxes(NPts=NPts, a4=a4) - - norm = mpl.colors.Normalize(vmin=Vminmax[0], vmax=Vminmax[1]) - cb = mpl.colorbar.ColorbarBase(axc, cmap=cmap, norm=norm, spacing='proportional') - axInv.set_title(Com+'\n#{0}'.format(shot)) - - # Pre-plotting lines and images - axSXR.plot(t, SXR, **Tempd) - axSXR.set_xlim(np.min(t),np.max(t)) - axRetro.set_xlim(0,TMat.shape[0]+1) - axRetro.set_ylim(min(np.nanmin(SXR).min(),np.nanmin(Retrofit).min()), max(np.nanmax(SXR).max(),np.nanmax(Retrofit).max())) - Marks = ['o','+','s','x','v','D','<','*','>','p','^'] - for ii in range(0,NPts): - Lax[ii].imshow(LPowFreq[ii][0].T, extent=(t.min(),t.max(),LPowFreq[ii][1].min()*1.e-3,LPowFreq[ii][1].max()*1.e-3), cmap=cmap2, origin='lower', aspect='auto', interpolation='bilinear', zorder=0, vmin=0, vmax=1) - Lax[ii].set_xlim(t.min(),t.max()) - Lax[ii].set_ylim(LPowFreq[ii][1].min()*1.e-3,LPowFreq[ii][1].max()*1.e-3) - axInv.plot(RZPts[0,ii],RZPts[1,ii],ls='none',marker=Marks[ii],markersize=8,markerfacecolor='k', zorder=100+ii) - if not Ves is None: - axInv = Ves.plot(Lax=[axInv], Proj='Pol', Elt='P') - axInv.set_xlim(Ves._PRMin[0],Ves._PRMax[0]) - axInv.get_lines()[-1].set_zorder(10) - axInv.autoscale(tight=True) - axInv.axis('equal') - axInv.set_autoscale_on(False) - Lax = [axInv]+Lax - - BckgrdInv = axInv.figure.canvas.copy_from_bbox(axInv.bbox) - BckgrdTime = [axInv.figure.canvas.copy_from_bbox(aa.bbox) for aa in Lax] - BckgrdProf = axInv.figure.canvas.copy_from_bbox(axRetro.bbox) - return axInv, axRetro, Lax, BckgrdInv, BckgrdTime, BckgrdProf, SXR, Retrofit - - - - - -############################################################################################################################################## -############################################################################################################################################## -############################################################################################################################################## -########### Animated plots -############################################################################################################################################## -############################################################################################################################################## - - - - - - -def Inv_MakeAnim(BF2, Coefs, t=None, Com=None, shot=None, Ves=None, SXR=None, sigma=None, TMat=None, Chi2N=None, Mu=None, R=None, Nit=None, Deriv=0, indt0=0, DVect=TFD.BF2_DVect_DefR, SubP=TFD.InvPlotSubP, SubMode=TFD.InvPlotSubMode, blit=TFD.InvAnimBlit, interval=TFD.InvAnimIntervalms, repeat=TFD.InvAnimRepeat, repeat_delay=TFD.InvAnimRepeatDelay, InvPlotFunc=TFD.InvPlotF, InvLvls=TFD.InvLvls, Invd=TFD.Invdict, Tempd=TFD.Tempd, Retrod=TFD.Retrod, TimeScale=TFD.InvAnimTimeScale, VMinMax=[None,None], Test=True, Hybrid=False, FName=None): - if Test: - assert isinstance(BF2, TFM.BF2D), "Arg nb. 1 (BF2) must be a TFM.BF2D instance !" - assert isinstance(Coefs, np.ndarray) and Coefs.shape[1]==BF2.NFunc, "Arg nb. 2 (Coefs) must be a np.ndarray instance with shape (Nt,BF2.NFunc) !" - assert isinstance(t,np.ndarray) and t.ndim==1 and t.size==Coefs.shape[0], "Arg t must be a 1D np.ndarray with t.size==Coefs.shape[0]" - #assert GM2D is None or isinstance(GM2D,TFMC.GMat2D), "Arg GM2D must be None or a TFMC.GMat2D instance !" - assert Com is None or type(Com) is str, "Arg Com must be None or a str !" - assert shot is None or type(shot) is int, "Arg shot must be None or a shot number (int) !" - assert SXR is None or (isinstance(SXR,np.ndarray) and SXR.ndim==2 and SXR.shape[0]==Coefs.shape[0]), "Arg SXR must be None or a 2D np.ndarray with SXR.shape[0]==Coefs.shape[0]" - assert sigma is None or (not SXR is None and isinstance(sigma,np.ndarray) and sigma.size%SXR.shape[1]==0), "Arg sigma must be None or a np.ndarray (1D or 2D) !" - assert TMat is None or (not SXR is None and TMat.shape==(SXR.shape[1],BF2.NFunc)), "Arg TMat must be None or a 2D np.ndarray with TMat.shape==(SXR.shape[1],BF2.NFunc) !" - assert Chi2N is None or (isinstance(Chi2N,np.ndarray) and Chi2N.ndim==1 and Chi2N.size==Coefs.shape[0]), "Arg Chi2N must be None or a 1D np.ndarray with Chi2N.size==Coefs.shape[0]" - assert Mu is None or (isinstance(Mu,np.ndarray) and Mu.ndim==1 and Mu.size==Coefs.shape[0]), "Arg Mu must be None or a 1D np.ndarray with Mu.size==Coefs.shape[0]" - assert R is None or (isinstance(R,np.ndarray) and R.ndim==1 and R.size==Coefs.shape[0]), "Arg R must be None or a 1D np.ndarray with R.size==Coefs.shape[0]" - assert Nit is None or (isinstance(Nit,np.ndarray) and Nit.ndim==1 and Nit.size==Coefs.shape[0]), "Arg Nit must be None or a 1D np.ndarray with Nit.size==Coefs.shape[0]" - assert InvPlotFunc in ['imshow','contour','contourf'], "Arg PlotFunc must be in ['contour','contourf'] !" - - # Function building the mesh for plotting - Nt = Coefs.shape[0] - def getmeshVals(Reg): - Rplot, Zplot, nR, nZ = BF2.get_XYplot(SubP=SubP, SubMode=SubMode) - if Reg=='Reg': - extent = (BF2.Mesh.MeshR.Cents.min(), BF2.Mesh.MeshR.Cents.max(), BF2.Mesh.MeshZ.Cents.min(), BF2.Mesh.MeshZ.Cents.max()) - Rplot,Zplot = np.mgrid[extent[0]:extent[1]:complex(nR), extent[2]:extent[3]:complex(nZ)] - Rplot,Zplot = Rplot.T,Zplot.T - Points = np.array([Rplot.flatten(), np.zeros((nR*nZ,)), Zplot.flatten()]) - indnan = ~BF2.Mesh.isInside(np.array([Rplot.flatten(),Zplot.flatten()])) - Vals = np.nan*np.ma.ones((Nt,nR*nZ)) - Vals[:,~indnan] = BF2.get_TotVal(Points[:,~indnan], Deriv=Deriv, DVect=DVect, Coefs=Coefs, Test=Test) - Vals[:,indnan] = np.ma.masked - if Reg=='Irreg': - return Rplot, Zplot, nR, nZ, Vals - elif Reg=='Reg': - return extent, nR, nZ, Vals - - # Precomputing retrofit - if not TMat is None: - Retrofit = np.nan*np.ones((Nt,SXR.shape[1])) - for ii in range(0,Nt): - Retrofit[ii,:] = TMat.dot(Coefs[ii,:]) - if not SXR is None: - SXR = SXR*1.e3 # In (mW) - - # Setting interval for anim and Com for title - if not t is None and interval is None: - interval = np.mean(np.diff(t))*1.e3*TimeScale # (s -> ms) - if Com is None: - Com = "Interval = {0} ms\nSpeed x{1}".format(interval,np.mean(np.diff(t))/interval) - else: - Com = Com+"\nInterval = {0} ms\nSpeed x{1}".format(interval,np.mean(np.diff(t))/interval) - - # Getting booleans for axes plot and getting figure+axes - ComOn, shotOn, tOn, SXROn, TMatOn, Chi2NOn, MuOn, ROn, NitOn = not Com is None, not shot is None, not t is None, not SXR is None, not TMat is None, not Chi2N is None, not Mu is None, not R is None, not Nit is None - TempOn = [SXROn, NitOn, Chi2NOn, MuOn, ROn] - Temp = [SXR, Nit, Chi2N, Mu, R] # SXR in (mW) - Temp = [Temp[ii] for ii in range(0,len(Temp)) if TempOn[ii]] - axInv, axTMat, Laxtemp = TFD.Plot_Inv_Anim_DefAxes(SXR=SXROn, TMat=TMatOn, Chi2N=Chi2NOn, Mu=MuOn, R=ROn, Nit=NitOn) - - # Pre-plotting lines and image - Invd['cmap'].set_bad(alpha=0.) - NL = len(Laxtemp) - Llinetemp = [] - for ii in range(0,NL): - Laxtemp[ii].set_xlim(np.min(t),np.max(t)) - Laxtemp[ii].plot(t, Temp[ii], **Tempd) - Llinetemp.append(Laxtemp[ii].plot([t[indt0],t[indt0]],Laxtemp[ii].get_ylim(), c='k', ls='--', lw=1)[0]) - - VMinMax = [] - if InvPlotFunc=='imshow': - extent, nR, nZ, Vals = getmeshVals('Reg') - if VMinMax[0] is None: - VMinMax[0] = np.min([0,Vals.min()]) - if VMinMax[1] is None: - VMinMax[1] = 0.9*Vals.max() - if BF2.Deg==0: - interp='nearest' - elif BF2.Deg==1: - interp='bilinear' - elif BF2.Deg==2: - interp='bicubic' - Inv = axInv.imshow(Vals[indt0,:].reshape((nZ,nR)), extent=extent, cmap=Invd['cmap'], origin='lower', aspect='auto', interpolation=interp, zorder=0, vmin=VMinMax[0], vmax=VMinMax[1]) - else: - Rplot, Zplot, nR, nZ, Vals = getmeshVals('Irreg') - if VMinMax[0] is None: - VMinMax[0] = np.min([0,Vals.min()]) - if VMinMax[1] is None: - VMinMax[1] = 0.9*Vals.max() - if InvPlotFunc=='contour': - Inv = axInv.contour(Rplot, Zplot, Vals[indt0,:].reshape((nZ,nR)), InvLvls, zorder=0, vmin=VMinMax[0], vmax=VMinMax[1], **Invd) - elif InvPlotFunc=='contourf': - Inv = axInv.contourf(Rplot, Zplot, Vals[indt0,:].reshape((nZ,nR)), InvLvls, zorder=0, vmin=VMinMax[0], vmax=VMinMax[1], **Invd) - Inv.axes = axInv - Inv.figure = axInv.figure - def draw(self, renderer): - for cc in self.collections: cc.draw(renderer) - Inv.draw = types.MethodType(draw,Inv,None) - - plt.colorbar(Inv, ax=axInv, shrink=0.8) - if not Ves is None: - axInv = Ves.plot(Lax=[axInv], Proj='Pol', Elt='P') - axInv.set_xlim(Ves._PRMin[0],Ves._PRMax[0]) - axInv.get_lines()[-1].set_zorder(10) - axInv.autoscale(tight=True) - axInv.axis('equal') - axInv.set_autoscale_on(False) - axInv.set_title(Com, fontsize=12, fontweight='bold') - - # Defining init and update functions for anim with and without TMatOn - if TMatOn: - NMes = TMat.shape[0] - TMat = TMat*1.e3 # In (mW) - if sigma.ndim==1: - SigmaSXR = axTMat.fill_between(range(1,NMes+1), SXR[indt0,:]+sigma, SXR[indt0,:]-sigma, facecolor=(0.8,0.8,0.8,0.5), label='Errorbar') - else: - SigmaSXR = axTMat.fill_between(range(1,NMes+1), SXR[indt0,:]+sigma[indt0,:], SXR[indt0,:]-sigma[indt0,:], facecolor=(0.8,0.8,0.8,0.5), label='Errorbar') - LSXR, = axTMat.plot(range(1,NMes+1), SXR[indt0,:], label='Data', **Tempd) - LRetro, = axTMat.plot(range(1,NMes+1), TMat.dot(Coefs[indt0,:]), label='Retrofit', **Retrod) - - def init(): - for ii in range(0,NL): - Llinetemp[ii].set_xdata(np.ma.array([0,0],mask=True)) - LSXR.set_ydata(np.ma.array(range(1,NMes+1),mask=True)) - LRetro.set_ydata(np.ma.array(range(1,NMes+1),mask=True)) - return Llinetemp+[LSXR, LRetro, Inv, SigmaSXR] - - def update(indt, axInv, axTMat, InvPlotFunc, NL): - if InvPlotFunc=='imshow': - Inv = axInv.imshow(Vals[indt,:].reshape((nZ,nR)), extent=extent, cmap=Invd['cmap'], origin='lower', vmin=VMinMax[0], vmax=VMinMax[1], aspect='auto', interpolation=interp, zorder=0) - else: - #axInv.collections.remove(axInv.collections[1]) - if InvPlotFunc=='contour': - Inv = axInv.contour(Rplot, Zplot, Vals[indt,:].reshape((nZ,nR)), InvLvls, zorder=0, vmin=VMinMax[0], vmax=VMinMax[1], **Invd) - elif InvPlotFunc=='contourf': - Inv = axInv.contourf(Rplot, Zplot, Vals[indt,:].reshape((nZ,nR)), InvLvls, zorder=0, vmin=VMinMax[0], vmax=VMinMax[1], **Invd) - Inv.axes = axInv - Inv.figure = axInv.figure - def draw(self,renderer): - for cc in self.collections: cc.draw(renderer) - Inv.draw = types.MethodType(draw,Inv,None) - #axTMat.collections.remove(axTMat.collections[0]) - #if sigma.ndim==1: - # SigmaSXR = axTMat.fill_between(range(1,NMes+1), SXR[indt,:]+sigma, SXR[indt,:]-sigma, facecolor=(0.8,0.8,0.8,0.5), label='Errorbar') - #else: - # SigmaSXR = axTMat.fill_between(range(1,NMes+1), SXR[indt,:]+sigma[indt,:], SXR[indt,:]-sigma[indt,:], facecolor=(0.8,0.8,0.8,0.5), label='Errorbar') - for ii in range(0,NL): - Llinetemp[ii].set_xdata([t[indt],t[indt]]) - LSXR.set_ydata(SXR[indt,:]) - LRetro.set_ydata(TMat.dot(Coefs[indt,:])) - return Llinetemp+[LSXR, LRetro, Inv, SigmaSXR] - - else: - def init(): - for ii in range(0,NL): - Llinetemp[ii].set_xdata([0,0]) - return Llinetemp#+[Inv] - - def update(indt, axInv, InvPlotFunc, NL): - #for coll in axInv.collections: - # axInv.collections.remove(coll) - #if InvPlotFunc=='contour': - # Inv = axInv.contour(Rplot, Zplot, Vals[indt,:].reshape((nZ,nR)), InvLvls, **Invd) - #elif InvPlotFunc=='contourf': - # Inv = axInv.contourf(Rplot, Zplot, Vals[indt,:].reshape((nZ,nR)), InvLvls, **Invd) - for ii in range(0,NL): - Llinetemp[ii].set_xdata([t[indt],t[indt]]) - return Llinetemp#+[Inv] - - if Hybrid: - if FName is None: - FName = str(shot) - for ii in range(0,len(t)): - LUp = update(ii, axInv, InvPlotFunc, NL) - axInv.figure.canvas.draw() - axInv.figure.savefig("/afs/ipp-garching.mpg.de/home/d/didiv/Python/Results/Others/"+FName+"_{0:04.0f}.jpg".format(ii)) - - else: - ani = anim.FuncAnimation(axInv.figure, update, frames=range(0,len(t)), fargs=(axInv, axTMat, InvPlotFunc, NL), blit=blit, interval=interval, repeat=repeat, repeat_delay=repeat_delay, init_func=init) - return ani, axInv, axTMat, Laxtemp - - - - - - - - - - - diff --git a/tofu/inv/ToFu_TreatForPostTreat.py b/tofu/inv/ToFu_TreatForPostTreat.py deleted file mode 100644 index a8143d606..000000000 --- a/tofu/inv/ToFu_TreatForPostTreat.py +++ /dev/null @@ -1,330 +0,0 @@ - - - - - - - - - -################################################################# -################################################################# -# --------- Miscellaneous Post-treatment ------------------------ -################################################################# - - - -def SpiralRadiusCenter(t, Pts, Freq, Ord=3, Method='CvH', Test=True): - """ Compute the estimated generalized geometric radius from surface spanned by one period of a spiral, and compute the estimated center of rotation - Inputs : - t (Nt,) np.ndarray, a 1D array of Nt time points - Pts (2,Nt) np.ndarray, trajectory of the point to be tracked, in 2D cartesian coordinates - Freq (Nt,) np.ndarray, a 1D array of the instantaneous estimated frequency of rotation - Ord int, the number of times the algorithm for estimating the center of rotation should be used recursively (optionnal, default=3, recommended >= 3) - Method str in ['Pure', 'CvH', 'FAv'], Method used for computing the center of rotation, 'Pure' assumes all polygons are simple, 'CvH' computes their convex hull and 'FAv' computes a Moving Average at chosen frequency - Test bool, if True then all the inputs are tested for conformity - Outputs : - r (Nt,) np.ndarray, a 1D array of the estimated generalized geometric radius, defined as sqrt(S/(2pi)), with S the surface spanned by one period - C (2,Nt) np.ndarray, a 2D array represneting the 2D cartesian coordinates, as a functio of time of the estimated center of rotation - - Method described further in [1] - [1] D. Vezinet, personal Notes, 'Deriving a radius from spiraling hot core with unknown center, unknown growth rate and non-circular base', May 2015 - """ - - if Test: - assert isinstance(t,np.ndarray) and t.ndim==1, "Arg t must be a (Nt,) np.ndarray !" - assert isinstance(Pts,np.ndarray) and Pts.ndim==2 and Pts.shape==(2,t.size), "Arg Pts must be a (2,Nt) np.ndarray !" - assert isinstance(Freq,np.ndarray) and Freq.ndim==1 and Freq.size==t.size, "Arg Freq must be a (Nt,) np.ndarray !" - assert type(Ord) is int and Ord>0, "Arg Ord must be a strictly positive int !" - assert Method in ['Pure', 'CvH', 'FAv'], "Arg Method must be a str in ['Pure', 'CvH', 'FAv'] !" - - # Initialising - Nt = t.size - SS = np.nan*np.ones((Nt,)) - CC = np.nan*np.ones((2,Nt)) - t = np.copy(t) - - indnan = ~(np.any(np.isnan(Pts),axis=0) | np.isnan(Freq)) - t = t[indnan] - Pts = Pts[:,indnan] - Freq = Freq[indnan] - - Nt = t.size - T2 = 0.5/Freq - ss = np.nan*np.ones((Nt,)) - cc = np.nan*np.ones((2,Nt)) - LC = [] - - # Getting the interval on which the surface can be calculated - tbis = np.array([t+T2,t-T2]) - indtS = (t>=t[np.argmin(np.abs(t[~np.isnan(t)].min()-tbis[1,:]))]) & (t<=t[np.argmin(np.abs(t[~np.isnan(t)].max()-tbis[0,:]))]) - IndtS = indtS.nonzero()[0] - - # Computing - for ii in range(0,IndtS.size): - indt = (t >= t[IndtS[ii]]-T2[IndtS[ii]]) & (t <= t[IndtS[ii]]+T2[IndtS[ii]]) - pp = plg.Polygon(Pts[:,indt].T) - ss[IndtS[ii]] = pp.area() - if Method=='Pure': - cc[:,IndtS[ii]] = pp.center() - elif Method=='CvH': - cc[:,IndtS[ii]] = plgUtils.convexHull(pp).center() - elif Method=='FAv': - cc[:,IndtS[ii]] = np.mean(Pts[:,indt],axis=1) - - SS[indnan] = ss - if Ord==1: - CC[:,indnan] = cc - return np.sqrt(SS/np.pi), CC - - t1, t2 = t[indtS].min(), t[indtS].max() - for oo in range(2,Ord+1): - indtC = (t>=t[np.argmin(np.abs(t1-tbis[1,:]))]) & (t<=t[np.argmin(np.abs(t2-tbis[0,:]))]) - IndtC = indtC.nonzero()[0] - cctemp = np.nan*np.ones((2,Nt)) - if Method=='Pure': - for ii in range(0,IndtC.size): - indt = (t >= t[IndtC[ii]]-T2[IndtC[ii]]) & (t <= t[IndtC[ii]]+T2[IndtC[ii]]) - pp = plg.Polygon(cc[:,indt].T) - cctemp[:,IndtC[ii]] = pp.center() - elif Method=='CvH': - for ii in range(0,IndtC.size): - indt = (t >= t[IndtC[ii]]-T2[IndtC[ii]]) & (t <= t[IndtC[ii]]+T2[IndtC[ii]]) - pp = plgUtils.convexHull(plg.Polygon(cc[:,indt].T)) - cctemp[:,IndtC[ii]] = pp.center() - elif Method=='FAv': - for ii in range(0,IndtC.size): - indt = (t >= t[IndtC[ii]]-T2[IndtC[ii]]) & (t <= t[IndtC[ii]]+T2[IndtC[ii]]) - cctemp[:,IndtC[ii]] = np.mean(cc[:,indt],axis=1) - cc[:] = np.copy(cctemp) - t1, t2 = t[indtC].min(), t[indtC].max() - CC[:,indnan] = cc - return np.sqrt(SS/np.pi), CC - - - -def SpiralRadiusCenter_V2(t, Pts, Freq, Frac=None, Ord=3, ElMet='Perim', Test=True): - """ Compute the estimated generalized geometric radius from surface spanned by a fraction of a period of a spiral, and compute the estimated center of rotation - Inputs : - t (Nt,) np.ndarray a 1D array of Nt time points - Pts (2,Nt) np.ndarray trajectory of the point to be tracked, in 2D cartesian coordinates - Freq (Nt,) np.ndarray a 1D array of the instantaneous estimated frequency of rotation - Frac float in ]0.5,1.] fraction of a period to use for the averaging, if None (default) uses the maximum value compatible witrh sampling frequency and <= 1 - Ord int the number of times the algorithm for estimating the center of rotation should be used recursively (optionnal, default=3, recommended >= 3) - ElMet str flag indicating which method to use for estimating the ellipticity - Test bool if True then all the inputs are tested for conformity - Outputs : - r (Nt,) np.ndarray, a 1D array of the estimated generalized geometric radius, defined as sqrt(S/(2pi)), with S the surface spanned by one period - C (2,Nt) np.ndarray, a 2D array represneting the 2D cartesian coordinates, as a functio of time of the estimated center of rotation - Ellipt (Nt,) np.ndarray, estimate of the ellipticity of the trajectory - - Method described further in [1] - [1] D. Vezinet, personal Notes, 'Deriving a radius from spiraling hot core with unknown center, unknown growth rate and non-circular base', May 2015 - """ - - if Test: - assert isinstance(t,np.ndarray) and t.ndim==1, "Arg t must be a (Nt,) np.ndarray !" - assert isinstance(Pts,np.ndarray) and Pts.ndim==2 and Pts.shape==(2,t.size), "Arg Pts must be a (2,Nt) np.ndarray !" - assert isinstance(Freq,np.ndarray) and Freq.ndim==1 and Freq.size==t.size, "Arg Freq must be a (Nt,) np.ndarray !" - assert type(Ord) is int and Ord>0, "Arg Ord must be a strictly positive int !" - assert Frac is None or (type(Frac) is float and Frac>0.5 and Frac<=1.), "Arg Frac must be None or a float in ]0.5,1.]" - - # Initialising - Nt = t.size - SS = np.nan*np.ones((Nt,)) - CC = np.nan*np.ones((2,Nt)) - LL = np.nan*np.ones((Nt,)) - t = np.copy(t) - - indnan = ~(np.any(np.isnan(Pts),axis=0) | np.isnan(Freq)) - t = t[indnan] - Pts = Pts[:,indnan] - Freq = Freq[indnan] - - Nt = t.size - T2 = 0.5/Freq - ss = np.nan*np.ones((Nt,)) - cc = np.nan*np.ones((2,Nt)) - ll = np.nan*np.ones((Nt,)) - LC = [] - - # Getting the good Frac value - Frac = Get_AlphaFromtFreq(t,Freq, Frac=Frac) - assert np.all(Frac>0.5) and np.all(Frac<=1.), "Frac could not be computed in ]0.5,1], fsampling or fmode must be incompatible !" - - # Getting the interval on which the surface can be calculated - tbis = np.array([t+Frac*T2,t-Frac*T2]) - indtS = (t>=t[np.argmin(np.abs(np.nanmin(t)-tbis[1,:]))]) & (t<=t[np.argmin(np.abs(np.nanmax(t)-tbis[0,:]))]) - IndtS = indtS.nonzero()[0] - - # Computing - for ii in range(0,IndtS.size): - indt = (t >= t[IndtS[ii]]-Frac[IndtS[ii]]*T2[IndtS[ii]]) & (t <= t[IndtS[ii]]+Frac[IndtS[ii]]*T2[IndtS[ii]]) - pp = np.concatenate((Pts[:,indt],(Pts[:,indt])[:,0:1]),axis=1) - try: - li = np.hypot(pp[0,:-1]-pp[0,1:], pp[1,:-1]-pp[1,1:]) - pp = plgUtils.convexHull(plg.Polygon(Pts[:,indt].T)) - ss[IndtS[ii]] = pp.area() - cc[:,IndtS[ii]] = pp.center() - ll[IndtS[ii]] = np.sum(li) - except: - pp = list(set([tuple(pppp) for pppp in Pts[:,indt].T])) - if len(pp)>=3: - try: - pp.append(pp[0]) - pp = np.array(pp).T - li = np.hypot(pp[0,:-1]-pp[0,1:], pp[1,:-1]-pp[1,1:]) - pp = plgUtils.convexHull(plg.Polygon(pp.T)) - ss[IndtS[ii]] = pp.area() - cc[:,IndtS[ii]] = pp.center() - ll[IndtS[ii]] = np.sum(li) - except: - ss[IndtS[ii]] = 0 - cc[:,IndtS[ii]] = np.mean(np.array(list(set([tuple(pppp) for pppp in Pts[:,indt].T]))).T,axis=1) - else: - ss[IndtS[ii]] = 0 - cc[:,IndtS[ii]] = np.mean(np.array(pp).T,axis=1) - - SS[indnan] = ss - LL[indnan] = ll - if Ord==1: - CC[:,indnan] = cc - return np.sqrt(SS/np.pi), CC - - t1, t2 = t[indtS].min(), t[indtS].max() - for oo in range(2,Ord+1): - indtC = (t>=t[np.argmin(np.abs(t1-tbis[1,:]))]) & (t<=t[np.argmin(np.abs(t2-tbis[0,:]))]) - IndtC = indtC.nonzero()[0] - cctemp = np.nan*np.ones((2,Nt)) - for ii in range(0,IndtC.size): - indt = (t >= t[IndtC[ii]]-Frac[IndtC[ii]]*T2[IndtC[ii]]) & (t <= t[IndtC[ii]]+Frac[IndtC[ii]]*T2[IndtC[ii]]) - pp = plgUtils.convexHull(plg.Polygon(cc[:,indt].T)) - try: - cctemp[:,IndtC[ii]] = pp.center() - except Exception: - pp = list(set([tuple(cccc) for cccc in cc[:,indt].T])) - if len(pp)>=3: - try: - cctemp[:,IndtC[ii]] = plgUtils.convexHull(plg.Polygon(pp)).center() - except: - cctemp[:,IndtC[ii]] = np.mean(np.array(pp).T,axis=1) - else: - cctemp[:,IndtC[ii]] = np.mean(np.array(pp).T,axis=1) - cc[:] = np.copy(cctemp) - t1, t2 = t[indtC].min(), t[indtC].max() - CC[:,indnan] = cc - - Ellip = LL**2/(4.*np.pi*SS) + np.sqrt((LL**2/(4.*np.pi*SS))**2-1.) - - return np.sqrt(SS/np.pi), CC, Ellip - - -def Get_AlphaFromtFreq(t,Freq, Frac=None): - assert Frac is None or (type(Frac) is float and Frac>0.5 and Frac<=1.), "Arg Frac must be None or a float in ]0.5,1.]" - fs = 1./np.mean(np.diff(t)) - N = np.floor(0.5*fs/Freq) if Frac is None else np.floor(Frac*0.5*fs/Freq) - return N*2.*Freq/fs - - -def SpiralAsym(t, Pts, Freq, Val, Frac=1., Test=True): - """ Compute the estimated generalized geometric radius from surface spanned by a fraction of a period of a spiral, and compute the estimated center of rotation - Inputs : - t (Nt,) np.ndarray a 1D array of Nt time points - Pts (2,Nt) np.ndarray trajectory of the point to be tracked, in 2D cartesian coordinates - Freq (Nt,) np.ndarray a 1D array of the instantaneous estimated frequency of rotation - Frac float in ]0.5,1.] fraction of a period to use for the averaging, if None (default) uses the maximum value compatible witrh sampling frequency and <= 1 - Test bool if True then all the inputs are tested for conformity - Outputs : - r (Nt,) np.ndarray, a 1D array of the estimated generalized geometric radius, defined as sqrt(S/(2pi)), with S the surface spanned by one period - C (2,Nt) np.ndarray, a 2D array represneting the 2D cartesian coordinates, as a functio of time of the estimated center of rotation - - Method described further in [1] - [1] D. Vezinet, personal Notes, 'Deriving a radius from spiraling hot core with unknown center, unknown growth rate and non-circular base', May 2015 - """ - if Test: - assert isinstance(t,np.ndarray) and t.ndim==1, "Arg t must be a (Nt,) np.ndarray !" - assert isinstance(Pts,np.ndarray) and Pts.ndim==2 and Pts.shape==(2,t.size), "Arg Pts must be a (2,Nt) np.ndarray !" - assert isinstance(Freq,np.ndarray) and Freq.ndim==1 and Freq.size==t.size, "Arg Freq must be a (Nt,) np.ndarray !" - assert Frac is None or (type(Frac) is float and Frac>0.5 and Frac<=1.), "Arg Frac must be None or a float in ]0.5,1.]" - - # Initialising - t = np.copy(t) - Nt = t.size - - indnan = ~(np.any(np.isnan(Pts),axis=0) | np.isnan(Freq)) - t = t[indnan] - Pts = Pts[:,indnan] - Freq = Freq[indnan] - Val = Val[indnan] - - EmissMoy = np.nan*np.ones((Nt,)) - Asym = np.nan*np.ones((Nt,)) - Ellip = np.nan*np.ones((Nt,)) - RMin, RMax = np.nan*np.ones((Nt,)), np.nan*np.ones((Nt,)) - - Nt = t.size - T2 = 0.5/Freq - emissmoy = np.nan*np.ones((Nt,)) - asym = np.nan*np.ones((Nt,)) - ellip = np.nan*np.ones((Nt,)) - Rmin, Rmax = np.nan*np.ones((Nt,)), np.nan*np.ones((Nt,)) - - # Getting the good Frac value - Frac = Get_AlphaFromtFreq(t,Freq, Frac=Frac) - assert np.all(Frac>0.5) and np.all(Frac<=1.), "Frac could not be computed in ]0.5,1], fsampling or fmode must be incompatible !" - - # Getting the interval on which the surface can be calculated - tbis = np.array([t+Frac*T2,t-Frac*T2]) - indtS = (t>=t[np.argmin(np.abs(np.nanmin(t)-tbis[1,:]))]) & (t<=t[np.argmin(np.abs(np.nanmax(t)-tbis[0,:]))]) - IndtS = indtS.nonzero()[0] - - # Computing - for ii in range(0,IndtS.size): - indt = (t >= t[IndtS[ii]]-Frac[IndtS[ii]]*T2[IndtS[ii]]) & (t <= t[IndtS[ii]]+Frac[IndtS[ii]]*T2[IndtS[ii]]) - emissmoy[IndtS[ii]] = np.mean(Val[indt]) - indsortR = np.argsort(Pts[0,indt]) - indsortZ = np.argsort(Pts[1,indt]) - vals = Val[indt][indsortR] - asym[IndtS[ii]] = (np.mean(vals[-3:]) - np.mean(vals[:3]))/emissmoy[IndtS[ii]] - Rmin[IndtS[ii]] = np.mean(Pts[0,indt][indsortR][:3]) - Rmax[IndtS[ii]] = np.mean(Pts[0,indt][indsortR][-3:]) - Zmin = np.mean(Pts[1,indt][indsortZ][:3]) - Zmax = np.mean(Pts[1,indt][indsortZ][-3:]) - ellip[IndtS[ii]] = (Zmax-Zmin)/(Rmax[IndtS[ii]]-Rmin[IndtS[ii]]) - - - EmissMoy[indnan] = emissmoy - Asym[indnan] = asym - Ellip[indnan] = ellip - RMin[indnan], RMax[indnan] = Rmin, Rmax - - return EmissMoy, Asym, Ellip, RMin, RMax - - - -def FindrbinEdges(t, r, Freq, LDt, Drmin=0.005, NTmin=1., Test=True): - - for ii in range(0,len(LDt)): - indt = (t>=LDt[ii][0]) & (t<=LDt[ii][1]) - t0 = (LDt[ii][1]+LDt[ii][0])/2. - indt0 = np.nanargmin(np.abs(t-t0)) - indt1, indt2 = np.nanargmin(np.abs(t-LDt[ii][0])), np.nanargmin(np.abs(t-LDt[ii][1])) - dt = LDt[ii][1]-LDt[ii][0] - r1, r2 = r[indt1], r[indt2] - dr = np.abs(r1-r2) - if dt < NTmin/Freq[indt0] or dr 0.) for aa in [epsrel,SubP,SubTheta,SubPind,epsrelLOS,SubPLOS]]), "Args [epsrel,SubP,SubTheta,SubPind,epsrelLOS,SubPLOS] must be int, float or np.float64/32 !" - assert all([ss is None or ss.lower() in ['rel','abs'] for ss in [SubMode,SubThetaMode,SubModeLOS]]), "Args [SubMode,SubThetaMode,SubModeLOS] must be in ['rel','abs'] !" - assert type(Fast) is bool, "Arg Fast must be a bool !" - for ss, vv in zip(['Iso','Mode','epsrel','SubP','SubMode','SubTheta','SubThetaMode','Fast'],[Iso,Mode,epsrel,SubP,SubMode,SubTheta,SubThetaMode,Fast]): - if not vv is None: - setattr(self,'_Mat_'+ss, vv) - if not SubPind is None: - self._indMat_SubP = SubPind - for ss, vv in zip(['Mode','epsrel','SubMode','SubP'],[ModeLOS,epsrelLOS,SubModeLOS,SubPLOS]): - if not vv is None: - setattr(self,'_MatLOS_'+ss, vv) - - def _CalcAllMat(self, indMat=None, Mat=None, MatLOS=None, Calcind=True, Calc=True, CalcLOS=True, Verb=True): - if True in [Calcind,Calc,CalcLOS]: - print " Computing GMat2D :", self.Id.Name - if Calcind or True in [Calc,CalcLOS]: - self._set_indMat(indMat=indMat, Verb=Verb) - if CalcLOS: - self._set_MatLOS(MatLOS=MatLOS, Verb=Verb) - if Calc: - self._set_Mat(Mat=Mat, Verb=Verb) - - - def set_Id(self,Val, dtime=None): - assert type(Val) is str or isinstance(Val,TFPF.ID), "Arg Id should be string or an TFPF.ID instance !" - if type(Val) is str: - if self._Mode=='quad': - ext = self._Mode + str(self._epsrel) - else: - ext = self._Mode + '_SubP' + str(self._SubP) + '_SubMode' + self._SubMode + '_SubTheta' + str(self._SubTheta) - Val = TFPF.ID('GMat2D',Val+'_'+ext, dtime=dtime) - self._Id = Val - - def _set_BF2(self,BF2, Store=True, Calcind=True, Calc=True, CalcLOS=True): - assert isinstance(BF2,TFM.BF2D), "Arg BF2 must be a TFM.BF2D instance !" - self._Id.set_LObj([BF2.Id]) - self._BF2_Deg = BF2.Deg - self._BF2_NCents = BF2.Mesh.NCents - self._BF2_NFunc = BF2.NFunc - self._BF2 = BF2 if Store else None - self._CalcAllMat(Calcind=Calcind, Calc=Calc, CalcLOS=CalcLOS) - - def _set_LD(self, LDetect, StoreTor=True, StoreLD=True, Calcind=True, Calc=True, CalcLOS=True): - assert isinstance(LDetect,TFG.GDetect) or isinstance(LDetect,TFG.Detect) or (type(LDetect) is list and (all([isinstance(gd,TFG.GDetect) for gd in LDetect]) or all([isinstance(gd,TFG.Detect) for gd in LDetect]))), "Arg GD must be a TFG.GDetect or TFG.Detect instance or a list of such !" - if isinstance(LDetect,TFG.GDetect): - LDetect = LDetect.LDetect - if isinstance(LDetect,TFG.Detect): - LDetect = [LDetect] - assert all([TFPF.CheckSameObj(LDetect[0].Ves,dd.Ves, ['Poly']) for dd in LDetect]), "All Detect objects must have the same Ves object !" - self._Id.set_LObj([LDetect[0].Ves.Id]) - self._Tor = LDetect[0].Ves if StoreTor else None - self._LD_Id = [ll.Id for ll in LDetect] - self._Id.set_LObj(self._LD_Id) - self._LD_nDetect = len(LDetect) - self._LD = LDetect if StoreLD else None - self._CalcAllMat(Calcind=Calcind, Calc=Calc, CalcLOS=CalcLOS) - - def Store(self, StoreBF2=True, StoreLD=False, StoreTor=True): - assert type(StoreBF2) is bool and type(StoreLD) is bool, "Args StoreBF2 and StoreLD must be bool !" - if self._BF2 is None and StoreBF2: - self._BF2 = self.BF2 - elif not self._BF2 is None and not StoreBF2: - self._BF2 = None - if self._LD is None and StoreLD: - self._LD = self.LD - elif not self._LD is None and not StoreLD: - self._LD = None - if self._Tor is None and StoreTor: - self._Tor = self.Ves - elif not self._Tor is None and not StoreTor: - self._Tor = None - - def get_Tor(self): - try: - PathFileExt = self.Id.LObj['Ves']['SavePath'][0]+self.Id.LObj['Ves']['SaveName'][0]+'.npz' - tor = TFPF.Open(PathFileExt) - print "Detect "+ self.Id.Name +" : associated Ves object was loaded from "+self.Id.LObj['Ves']['SavePath'][0]+self.Id.LObj['Ves']['SaveName'][0]+".npz" - return tor - except: - try: - warnings.warn("Detect "+ self.Id.Name +" : associated Ves object could not be loaded from "+self.Id.LObj['Ves']['SavePath'][0]+self.Id.LObj['Ves']['SaveName'][0]+".npz") - except: - warnings.warn("Detect "+ self.Id.Name +" : associated Ves object could not be loaded (no matching PathFileExt) !") - - def select(self, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='or', InOut='In', Out=bool): - return TFPF.SelectFromIdLObj(self.Id.LObj['Detect'], Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut, Out=Out) - - def _set_indMat(self, indMat=None, SubP=None, Verb=True): - assert indMat is None or (isinstance(indMat,np.ndarray) and indMat.dtype.name=='bool') or isinstance(indMat,scpsp.csr_matrix), "Arg indMat must be a np.ndarray instance with dtype=bool !" - self._init_CompParam(SubPind=SubP) - if indMat is None: - indMat = Calc_indMatrix_2D(self.BF2, self.LD, SubP=self._indMat_SubP, Verb=Verb, Test=True) - else: - assert indMat.ndim==2 and indMat.shape == (self.LD_nDetect,self._BF2_NCents), "Arg indMat not the right shape !" - self._indMat = indMat - - def _set_Mat(self, Mat=None, Iso=None, Mode=None, epsrel=None, SubP=None, SubMode=None, SubTheta=None, SubThetaMode=None, Fast=True, Verb=True, Test=True): - assert Mat is None or isinstance(Mat,np.ndarray) or isinstance(Mat,scpsp.csr_matrix), "Arg Mat must be a np.ndarray or scp.sparse.csr_matrix instance !" - self._init_CompParam( Iso=Iso, Mode=Mode, epsrel=epsrel, SubP=SubP, SubMode=SubMode, SubTheta=SubTheta, SubThetaMode=SubThetaMode, Fast=Fast) - if Mat is None: - if self._Mat_Iso=='Iso': - Mat = Calc_GeomMatrix_2D_Iso(self.BF2, self.LD, self._indMat, Mode=self._Mat_Mode, epsrel=self._Mat_epsrel, SubP=self._Mat_SubP, SubMode=self._Mat_SubMode, SubTheta=self._Mat_SubTheta, SubThetaMode=self._Mat_SubThetaMode, Fast=self._Mat_Fast, Verb=Verb, Test=Test) - else: - print "Not coded yet" - else: - assert Mat.ndim == 2 and Mat.shape == (self.LD_nDetect,self.BF2_NFunc), "Arg Mat not the right shape !" - self._Mat_csr = scpsp.csr_matrix(Mat) - - def _set_MatLOS(self, MatLOS=None, BF2=None, LD=None, Mode=None, epsrel=None, SubP=None, SubMode=None, Verb=True, Test=True): - assert MatLOS is None or isinstance(MatLOS,np.ndarray) or isinstance(MatLOS,scpsp.csr_matrix), "Arg MatLOS must be a np.ndarray or scp.sparse.csr_matrix instance !" - self._init_CompParam(ModeLOS=Mode, epsrelLOS=epsrel, SubPLOS=SubP, SubModeLOS=SubMode) - if MatLOS is None: - MatLOS = Calc_GeomMatrix_LOS_Iso(self.BF2, self.LD, self._indMat, Mode=self._MatLOS_Mode, epsrel=self._MatLOS_epsrel, SubP=self._MatLOS_SubP, SubMode=self._MatLOS_SubMode, Verb=Verb, Test=Test) - else: - assert MatLOS.ndim==2 and MatLOS.shape == (self.LD_nDetect,self.BF2_NFunc), "Arg MatLOS not the right shape !" - self._MatLOS_csr = scpsp.csr_matrix(MatLOS) - - def get_SubGMat2D(self, Name=None, ind=None, Val=None, Crit='Name',PreExp=None,PostExp=None,Log='or',InOut='In'): - assert ind is None or isinstance(ind,np.ndarray) and 'int' in ind.dtype.name, "Arg ind must be a np.ndarray of int !" - if ind is None: - ind = TFPF.SelectFromIdLObj(self.Id.LObj['Detect'], Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut, Out=int) - indMat = self._indMat[ind,:] - Mat = self._Mat_csr.todense()[ind,:] - MatLOS = self._MatLOS_csr.todense()[ind,:] - Id = copy.deepcopy(self.Id) - if Name is None: - Name = Id.Name+'_Reduced' - Id.set_Name(Name) - for kk in Id._LObj['Detect'].keys(): - Id._LObj['Detect'][kk] = [self.Id.LObj['Detect'][kk][ii] for ii in ind] - GM = GMat2D(Id, BF2=None, LD=None, Mat=None, indMat=None, MatLOS=None, Calcind=False, Calc=False, CalcLOS=False) - GM._init_CompParam(Mode=self._Mat_Mode, epsrel=self._Mat_epsrel, SubP=self._Mat_SubP, SubMode=self._Mat_SubMode, SubTheta=self._Mat_SubTheta, SubThetaMode=self._Mat_SubThetaMode, Fast=self._Mat_Fast, Iso=self._Mat_Iso, - SubPind=self._indMat_SubP, ModeLOS=self._MatLOS_Mode, epsrelLOS=self._MatLOS_epsrel, SubPLOS=self._MatLOS_SubP, SubModeLOS=self._MatLOS_SubMode) - GM._BF2 = None - GM._BF2_NFunc = self.BF2_NFunc - GM._BF2_Deg = self.BF2_Deg - GM._BF2_NCents = self._BF2_NCents - GM._Tor = None - GM._LD = None - GM._LD_nDetect = ind.size - GM._set_indMat(indMat=indMat, Verb=False) - GM._set_MatLOS(MatLOS=MatLOS, Verb=False) - GM._set_Mat(Mat=Mat, Verb=False) - return GM - - def get_Sig(self, Coefs=1., LOS=False): - assert type(Coefs) is float or (isinstance(Coefs,np.ndarray) and Coefs.size==self.BF2_NFunc), "Arg Coefs must be a (self.BF2_NFunc,) np.ndarray !" - if Coefs.ndim==2: - Coefs = Coefs.flatten() - if type(Coefs) is float: - Coefs = Coefs*np.ones((self.BF_NFunc,)) - if LOS: - return np.array(self._MatLOS_csr.dot(Coefs)) - else: - return np.array(self._Mat_csr.dot(Coefs)) - - def plot_OneDetect_PolProj(self, EltDet='PCL', Name=None, Val=None, Crit='Name',PreExp=None,PostExp=None,Log='or',InOut='In', ind=None, axP=None, axM=None, axBF=None, Mask=False, TLOS=False, SubP=TFD.GMPlotDetSubP, SubMode=TFD.GMPlotDetSubPMode, Cdict=TFD.GMPlotDetCd, Ldict=TFD.GMPlotDetLd, LdictLOS=TFD.GMPlotDetLOSd, KWArgMesh=TFD.GMPlotDetKWArgMesh, KWArgDet=TFD.GMPlotDetKWArgDet, a4=False): - assert not (self._Mat_csr is None and self._MatLOS_csr is None) and not (self._Mat_csr is None and not TLOS), "Geometry matrix not computed yet !" - assert ind is None or type(ind) is int, "Arg int must be an integer (index of detector to be plotted) !" - if ind is None: - #ind = TFPF.SelectFromListId(self._LD_Id, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut, Out=int)[0] - ind = TFPF.SelectFromIdLObj(self.Id.LObj['Detect'], Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut, Out=int)[0] - D = self.LD[ind] - BF2 = self.BF2 - Ti = np.array(self._Mat_csr[ind,:].todense()).flatten() if not self._Mat_csr is None else None - TiLOS = np.array(self._MatLOS_csr[ind,:].todense()).flatten() if (not self._MatLOS_csr is None and TLOS) else None - axP, axM, axBF = Plot_GeomMatrix_Detect(D, BF2, Ti, axPol=axP, axMesh=axM, axBF=axBF, Mask=Mask, indMask=self._indMat[ind,:], TLOS=TLOS, TiLOS=TiLOS, SubP=SubP, SubMode=SubMode, Cdict=Cdict, Ldict=Ldict, LdictLOS=LdictLOS, Test=False, a4=a4) - if not axP is None: - axP = BF2.Mesh.plot(ax=axP, **KWArgMesh) - axP = D.plot(Lax=[axP], Proj='Pol', **KWArgDet) - return axP, axM, axBF - - def plot_OneBF_PolProj(self, ind, axP=None, axD=None, axDred=None, TLOS=False, SubP=TFD.GMPlotBFSubP, SubMode=TFD.GMPlotBFSubPMode, - Cdict=TFD.GMPlotDetCd, Ldict=TFD.GMPlotDetLd, LdictLOS=TFD.GMPlotDetLOSd, KWArgMesh=TFD.GMPlotDetKWArgMesh, KWArgTor=TFD.GMPlotDetKWArgTor, KWArgDet=TFD.GMPlotBFDetd, a4=False): - assert type(ind) is int, "Arg int must be an int !" - assert not (self._Mat_csr is None and self._MatLOS_csr is None) and not (self._Mat_csr is None and not TLOS), "Geometry matrix not computed yet !" - Ti = np.array(self._Mat_csr[:,ind].todense()).flatten() if not self._Mat_csr is None else None - TiLOS = np.array(self._MatLOS_csr[:,ind].todense()).flatten() if (not self._MatLOS_csr is None and TLOS) else None - LD = self.LD - axP, axD, axDred = Plot_GeomMatrix_BFunc(LD, self.Id.LObj['Detect']['Name'], ind, Ti=Ti, axPol=axP, axD=axD, axDred=axDred, TLOS=TLOS, TiLOS=TiLOS, Ldict=Ldict, LdictLOS=LdictLOS, KWArgDet=KWArgDet, Test=True, a4=a4) - if not axP is None: - BF2 = self.BF2 - axP = BF2.plot_Ind(Ind=ind, ax=axP, Elt='S', EltM='') - axP = BF2.Mesh.plot(ax=axP, **KWArgMesh) - axP = LD[0].Ves.plot(Lax=[axP], Proj='Pol', **KWArgTor) - return axP, axD, axDred - - def plot_sum(self, axD=None, axBF=None, TLOS=False, Ldict=TFD.GMPlotDetLd, LdictLOS=TFD.GMPlotDetLOSd, LegDict=TFD.TorLegd, a4=False): - assert axD is None or isinstance(axD,plt.Axes), "Arg axD must be None, 'None' or a plt.Axes instance !" - assert axBF is None or isinstance(axBF,plt.Axes), "Arg axBF must be None, 'None' or a plt.Axes instance !" - assert type(Ldict) is dict, "Arg Ldict must be a dict !" - if axD is None and axBF is None: - axD, axBF = TFD.Plot_BF2_sum_DefAxes(a4=a4) - if not axD is None: - axD.plot(np.arange(0,self.LD_nDetect), self._Mat_csr.sum(axis=1), label=self.Id.NameLTX, **Ldict) - if TLOS: - axD.plot(np.arange(0,self.LD_nDetect), self._MatLOS_csr.sum(axis=1), label=self.Id.NameLTX+' LOS', **LdictLOS) - axD.set_xlim(0,self.LD_nDetect-1) - if not LegDict is None: - axD.legend(**LegDict) - if not axBF is None: - axBF.plot(np.arange(0,self.BF2_NFunc), self._Mat_csr.sum(axis=0).T, label=self.Id.NameLTX, **Ldict) - if TLOS: - axBF.plot(np.arange(0,self.BF2_NFunc), self._MatLOS_csr.sum(axis=0).T, label=self.Id.NameLTX+' LOS', **LdictLOS) - axBF.set_xlim(0,self.BF2_NFunc-1) - if not LegDict is None: - axBF.legend(**LegDict) - axD.figure.canvas.draw() - return axD, axBF - - def plot_Sig(self, Coefs=1., ind=0, ax1=None, ax2=None, ax3=None, ax4=None, TLOS=False, LOSRef=None, SubP=TFD.GMSigPlotSubP, SubMode=TFD.GMSigPlotSubPMode, NC=TFD.GMSigPlotNC, - Sdict=TFD.GMSigPlotSd, SLOSdict=TFD.GMSigPlotSd.copy(), LOSdict=TFD.GMSigPlotSLOSd.copy(), Cdict=TFD.GMSigPlotCd, a4=False): - assert type(Coefs) is float or (isinstance(Coefs,np.ndarray) and Coefs.size==self.BF2_NFunc), "Arg Coefs must be a (self.BF2_NFunc,) np.ndarray !" - assert all([type(bb) is bool for bb in [TLOS]]), "Args [TLOS] must be bool !" - if Coefs.ndim==2: - Coefs = Coefs.flatten() - if type(Coefs) is float: - Coefs = Coefs*np.ones((self.BF_NFunc,)) - BF2, LD = self.BF2, self.LD - Mes = self.get_Sig(Coefs,LOS=False) - if TLOS: - MesLOS = self.get_Sig(Coefs,LOS=True) - if LOSRef is None: - LOSRef = LD[0]._LOSRef - - if all([aa is None for aa in [ax1,ax2,ax3,ax4]]): - ax1, ax2, ax3, ax4 = TFD.Plot_SynDiag_DefAxes(a4=a4) - if ax1 is None: - ax1 = TFD.Plot_SynDiag_DefAxes(a4=a4)[0] - if not ax2 is None: - ax2 = BF2.Mesh.plot(ax=ax2, Elt='M') - ax2 = LD[0].Ves.plot(Lax=[ax2],Proj='Pol') - if not ax3 is None: - ax3 = BF2.plot(ax=ax3, Deriv=0, Coefs=Coefs, SubP=SubP, SubMode=SubMode, NC=NC, Totdict=Cdict) - ax3 = LD[0].Ves.plot(Lax=[ax3], Elt='P',Proj='Pol') - XL, YL = ax3.get_xlim(), ax3.get_ylim() - - Xticks, XTicksLab = [], [] - if not ax4 is None: - ax4 = LD[0].Ves.plot(Lax=[ax4], Elt='P',Proj='Pol') - LCams = sorted(list(set([dd.Id.USRdict['CamHead'] for dd in LD]))) - II = 1 - for ii in range(0,len(LCams)): - ind = [jj for jj in range(0,len(LD)) if LD[jj].Id.USRdict['CamHead']==LCams[ii]] - ll = ax1.plot(np.arange(II,II+len(ind)), Mes[ind], label=LCams[ii], **Sdict) - if TLOS: - SLOSdict['c'], SLOSdict['ls'] = ll[0].get_color(), '--' - ax1.plot(np.arange(II,II+len(ind)), MesLOS[ind], label=LCams[ii]+' LOS '+LOSRef, **SLOSdict) - if not ax4 is None: - LOSdict['Ldict']['c'] = ll[0].get_color() - ax4 = TFG.Plot_PolProj_GLOS([LD[jj].LOS[LOSRef]['LOS'] for jj in ind], Leg=LCams[ii]+' '+LOSRef, ax=ax4, **LOSdict) - ax4.set_xlim(XL), ax4.set_ylim(YL) - Xticks.append(range(II,II+len(ind))) - XTicksLab.append([LD[jj].Id.Name for jj in ind]) - II += len(ind) - Xticks = list(itt.chain.from_iterable(Xticks)) - XTicksLab = list(itt.chain.from_iterable(XTicksLab)) - ax1.set_xlim(0,self.LD_nDetect+1) - ax1.set_xticks(Xticks) - ax1.set_xticklabels(XTicksLab, rotation=40) - if not ax2 is None: - ax2.set_xlim(XL), ax2.set_ylim(YL) - plt.gcf().canvas.draw() - return ax1, ax2, ax3, ax4 - - def save(self,SaveName=None,Path=None,Mode='npz'): - if Path is None: - Path = self.Id.SavePath - else: - assert type(Path) is str, "Arg Path must be a str !" - self._Id.SavePath = Path - if SaveName is None: - SaveName = self.Id.SaveName - else: - assert type(SaveName) is str, "Arg SaveName must be a str !" - self.Id.SaveName = SaveName - Ext = '.npz' if 'npz' in Mode else '.pck' - TFPF.save(self, Path+SaveName+Ext) - - -""" -############################################################################### -############################################################################### - Computation functions -############################################################################### -""" - - -def Calc_GeomMatrix_2D_Iso(BF2, LD, indMat, Mode='quad', epsrel=TFD.GMMatepsrel, SubP=TFD.GMindMSubP, SubMode=TFD.GMindMSubPMode, SubTheta=TFD.GMindMSubTheta, SubThetaMode=TFD.GMindMSubThetaMode, Fast=True, Verb=True, Test=True): - if Test: - assert isinstance(BF2,TFM.BF2D), "Arg BF2 must be a TFM.BF2D instance !" - assert Mode=='quad' or Mode=='simps' or Mode=='trapz', "Arg Mode must be 'quad', 'simps' or 'trapz' !" - assert isinstance(LD,TFG.GDetect) or isinstance(LD,TFG.Detect) or (type(LD) is list and (all([isinstance(gd,TFG.GDetect) for gd in LD]) or all([isinstance(gd,TFG.Detect) for gd in LD]))), "Arg LD must be a TFG.GDetect or TFG.Detect instance or a list of such !" - if isinstance(LD,TFG.GDetect): - LD = LD.LDetect - if isinstance(LD,TFG.Detect): - LD = [LD] - - ND = len(LD) - T = np.zeros((ND,BF2.NFunc)) - err = np.nan*np.ones((ND,BF2.NFunc)) - if Mode=='quad': # Check and debug - RZLim = BF2._get_Func_SuppBounds() - for ii in range(0,ND): - if Fast and LD[ii]._SAngPol_Reg: - if Verb: - print " Computing Mat for ", LD[ii].Id.Name, "(fast lane)" - ind = np.unique(BF2._Cents_Funcind[:,indMat[ii,:]]) - ind = ind[~np.isnan(ind)].astype(int) - for jj in range(0,ind.size): - #print " Computing Geom. matrix for " + LD[ii].Id.Name + " and BFunc nb. " + str(jj+1) + " / " + str(ind.size) - ZMin = lambda y, jj=jj: RZLim[2,ind[jj]] - ZMax = lambda y, jj=jj: RZLim[3,ind[jj]] - FF = LD[ii]._get_SAngIntMax(Proj='Pol', SAng='Int') - if BF2.Deg==0: - def FuncSABF(x3,x2,ii=ii,jj=jj): - return x2 * FF(np.array([[x2],[x3]]))[0] - else: - def FuncSABF(x3,x2,ii=ii,jj=jj): - return x2 * BF2._LFunc[ind[jj]](np.array([[x2],[x3]]))[0] * FF(np.array([[x2],[x3]]))[0] - T[ii,ind[jj]], err[ii,ind[jj]] = GG.dblquad_custom(FuncSABF, RZLim[0,ind[jj]], RZLim[1,ind[jj]], ZMin, ZMax, epsrel=epsrel) - else: - if Verb: - print " Computing Mat for ", LD[ii].Id.Name, "(slow lane)" - LPolys = [LD[ii].Poly]+[aa.Poly for aa in LD[ii].LApert] - ind = np.unique(BF2._Cents_Funcind[:,indMat[ii,:]]) - ind = ind[~np.isnan(ind)].astype(int) - for jj in range(0,ind.size): - #print " Computing Geom. matrix for " + LD[ii].Id.Name + " and BFunc nb. " + str(jj+1) + " / " + str(ind.size) - RMin = lambda x, jj=jj: RZLim[0,ind[jj]] - RMax = lambda x, jj=jj: RZLim[1,ind[jj]] - ZMin = lambda x,y, jj=jj: RZLim[2,ind[jj]] - ZMax = lambda x,y, jj=jj: RZLim[3,ind[jj]] - - if BF2.Deg==0: - def FuncSABF(x3,x2,x1,ii=ii,jj=jj): - P = np.array([np.cos(x1)*x2,np.sin(x1)*x2,x3]) - return x2 * GG.Calc_SAngVect_LPolys1Point_Flex(LPolys, P, LD[ii].SAng_P.flatten(), LD[ii].SAng_nP.flatten(), LD[ii].SAng_e1.flatten(), LD[ii].SAng_e2.flatten())[0] - else: - def FuncSABF(x3,x2,x1,ii=ii,jj=jj): - P = np.array([np.cos(x1)*x2,np.sin(x1)*x2,x3]) - return x2 * BF2._LFunc[ind[jj]](np.array([[x2],[x3]]))[0] * GG.Calc_SAngVect_LPolys1Point_Flex(LPolys, P, LD[ii].SAng_P.flatten(), LD[ii].SAng_nP.flatten(), LD[ii].SAng_e1.flatten(), LD[ii].SAng_e2.flatten())[0] - T[ii,ind[jj]], err[ii,ind[jj]] = GG.tplquad_custom(FuncSABF, LD[ii].Span_Theta[0], LD[ii].Span_Theta[1], RMin, RMax, ZMin, ZMax, epsrel=epsrel) - """ - except Warning: - R = np.linspace(RMin(0),RMax(0),30) - Z = np.linspace(ZMin(0,0),ZMax(0,0),30) - Theta = np.linspace(LD[ii].Span_Theta[0],LD[ii].Span_Theta[1],20) - R, Theta, Z = np.meshgrid(R, Theta, Z) - Val = np.zeros(R.shape) - for ll in range(0,R.shape[0]): - for gg in range(0,R.shape[1]): - for kk in range(0,R.shape[2]): - Val[ll,gg,kk] = FuncSABF(Z[ll,gg,kk],R[ll,gg,kk],Theta[ll,gg,kk]) - indT = np.any(np.any(Val>0,2),1).nonzero()[0][2] - plt.figure(), plt.contourf(R[indT,:,:],Z[indT,:,:],Val[indT,:,:]), plt.draw() - - def FuncSABF2D(x3,x2,ii=ii,jj=jj): - P = np.array([[np.cos(Theta[indT,0,0])*x2],[np.sin(Theta[indT,0,0])*x2],[x3]]) - return x2 * BF2._LFunc[ind[jj]](np.array([[x2],[x3]]))[0] * TFG.Calc_SolAngVect_DetectApert_Fast(LD[ii], P, PBary, nPtemp, e1, e2)[0] - - A, res = GG.dblquad_custom(FuncSABF2D, RZLim[0,ind[jj]], RZLim[1,ind[jj]], lambda x,jj=jj:RZLim[2,ind[jj]], lambda x,jj=jj:RZLim[3,ind[jj]],epsabs=0,epsrel=1e-2, limit=100) - """ - else: - MinMesh = min(np.min(BF2.Mesh.MeshR._Lengths),np.min(BF2.Mesh.MeshZ._Lengths)) - Supps = BF2._get_Func_SuppBounds() - if SubMode.lower()=='rel': - DMin = SubP*min(np.min([np.min(dd._ConeWidth) for dd in LD]), MinMesh) - else: - DMin = SubP - DMin = max(DMin,TFD.GMMatDMinInf) - for ii in range(0,ND): - ind = np.unique(BF2._Cents_Funcind[:,indMat[ii,:]]) - ind = ind[~np.isnan(ind)].astype(int) - if Fast and LD[ii]._SAngPol_Reg: - if Verb: - print " Computing Mat for " + LD[ii].Id.Name + " ({0}) BFunc, DMin = {1} m)".format(ind.size,DMin) - if Mode=='simps': - FF = GG.dblsimps_custom - elif Mode=='trapz': - FF = GG.dbltrapz_custom - elif Mode=='nptrapz': - FF = GG.dblnptrapz_custom - for jj in range(0,ind.size): - NR, NZ = math.ceil((Supps[1,ind[jj]]-Supps[0,ind[jj]])/DMin), math.ceil((Supps[3,ind[jj]]-Supps[2,ind[jj]])/DMin) - if BF2.Deg>0: - R, Z = np.linspace(Supps[0,ind[jj]],Supps[1,ind[jj]],NR), np.linspace(Supps[2,ind[jj]],Supps[3,ind[jj]],NZ) - else: - R, Z = np.linspace(Supps[0,ind[jj]],Supps[1,ind[jj]]-DMin/1000.,NR), np.linspace(Supps[2,ind[jj]],Supps[3,ind[jj]]-DMin/1000.,NZ) - PtsRZ = np.array([np.tile(R,(NZ,1)).T.flatten(), np.tile(Z,(NR,1)).flatten()]) - Val = BF2._LFunc[ind[jj]](PtsRZ) * LD[ii]._get_SAngIntMax(Proj='Pol', SAng='Int')(PtsRZ) # !!! R was already included in SAngInt !!! - T[ii,ind[jj]] = FF(Val.reshape((NR,NZ)), x=R, y=Z) - else: - nind = math.ceil(ind.size/5.) - P, nP, e1, e2 = LD[ii]._SAngPlane - LPolys = [LD[ii].Poly]+[aa.Poly for aa in LD[ii].LApert] - if SubThetaMode.lower()=='rel': - NT= np.round(1./SubTheta) - else: - NT= np.round((LD[ii]._Span_Theta[1]-LD[ii]._Span_Theta[0])/SubTheta) - Theta = np.linspace(LD[ii]._Span_Theta[0], LD[ii]._Span_Theta[1], NT, endpoint=True) - if Mode=='simps': - FF = GG.tplsimps_custom - elif Mode=='trapz': - FF = GG.tpltrapz_custom - elif Mode=='nptrapz': - FF = GG.tplnptrapz_custom - for jj in range(0,ind.size): - if Verb and (jj==0 or (jj+1)%nind==0): - print " Computing Mat for " + LD[ii].Id.Name + " and BFunc nb. " + str(jj+1) + " / " + str(ind.size) - NR, NZ = math.ceil((Supps[1,ind[jj]]-Supps[0,ind[jj]])/DMin), math.ceil((Supps[3,ind[jj]]-Supps[2,ind[jj]])/DMin) - if BF2.Deg>0: - R, Z = np.linspace(Supps[0,ind[jj]],Supps[1,ind[jj]],NR), np.linspace(Supps[2,ind[jj]],Supps[3,ind[jj]],NZ) - else: - R, Z = np.linspace(Supps[0,ind[jj]],Supps[1,ind[jj]]-DMin/1000.,NR), np.linspace(Supps[2,ind[jj]],Supps[3,ind[jj]]-DMin/1000.,NZ) - Rvf, Thetavf, Zvf = np.meshgrid(R, Theta, Z, indexing='ij') - Rvf, Thetavf, Zvf = Rvf.flatten(order='F'), Thetavf.flatten(order='F'), Zvf.flatten(order='F') - Points = np.array([Rvf*np.cos(Thetavf), Rvf*np.sin(Thetavf), Zvf]) - inds = LD[ii]._isOnGoodSide(Points) & LD[ii].isInside(Points,In='(X,Y,Z)') - Val = np.zeros((NR*NT*NZ,)) - if np.any(inds): - Val[inds] = Rvf[inds] * BF2._LFunc[ind[jj]](np.array([Rvf[inds],Zvf[inds]])) * GG.Calc_SAngVect_LPolysPoints_Flex(LPolys, Points[:,inds], P, nP, e1, e2)[0] - T[ii,ind[jj]] = FF(Val.reshape((NR,NT,NZ),order='F'), x=R, y=Theta, z=Z) - return T - - -def Calc_indMatrix_2D(BF2, LD, SubP=TFD.GMindMSubP, Verb=True, Test=True): - if Test: - assert isinstance(BF2,TFM.BF2D), "Arg BF2 must be a TFM.BF2D instance !" - assert isinstance(LD,TFG.GDetect) or isinstance(LD,TFG.Detect) or (type(LD) is list and (all([isinstance(gd,TFG.GDetect) for gd in LD]) or all([isinstance(gd,TFG.Detect) for gd in LD]))), "Arg LD must be a TFG.GDetect or TFG.Detect instance or a list of such !" - if isinstance(LD,TFG.GDetect): - LD = LD.LDetect - if isinstance(LD,TFG.Detect): - LD = [LD] - ND = len(LD) - MinDL = SubP*min(np.min([np.min(dd._ConeWidth) for dd in LD]), min(np.min(BF2.Mesh.MeshR._Lengths),np.min(BF2.Mesh.MeshZ._Lengths))) - MinDL = max(MinDL,TFD.GMMatDMinInf) - indMat = np.zeros((ND,BF2.Mesh.NCents),dtype=bool) - N = math.ceil(BF2.Mesh.NCents/5.) - for jj in range(0,BF2.Mesh.NCents): - if Verb and (jj==0 or (jj+1)%N==0): - print " Computing ind matrix for ", jj+1, "/", BF2.Mesh.NCents - R,Z = np.unique(BF2.Mesh.Knots[0,BF2.Mesh._Cents_Knotsind[:,jj]]), np.unique(BF2.Mesh.Knots[1,BF2.Mesh._Cents_Knotsind[:,jj]]) - DR, DZ = list(np.linspace(R[0],R[1],math.ceil(abs(R[1]-R[0])/MinDL),endpoint=True)), list(np.linspace(Z[0],Z[1],math.ceil(abs(Z[1]-Z[0])/MinDL),endpoint=True)) - NR, NZ = len(DR), len(DZ) - for ii in range(0,ND): - indMat[ii,jj] = np.any(LD[ii].isInside(np.array([[R[0]]*NZ+[R[1]]*NZ+DR+DR, DZ+DZ+[Z[0]]*NR+[Z[1]]*NR]),In='(R,Z)')) - return indMat - - -""" -def Calc_indMatrix_2D(BF2, LD, SubP=TFD.GMindMSubP, SubMode=TFD.GMindMSubPMode, SubTheta=TFD.GMindMSubTheta, SubThetaMode=TFD.GMindMSubThetaMode, Test=True): # Not used ? - if Test: - assert isinstance(BF2,TFM.BF2D), "Arg BF2 must be a TFM.BF2D instance !" - assert isinstance(LD,TFG.Detect) or (type(LD) is list and [isinstance(dd,TFG.Detect) for dd in LD]), "Arg LD must be a TFG.Detect instance or a list of such !" - # assert Method in ['Vis','ConePoly'], "Arg Method must be in ['Vis','ConePoly'] !" - - SubMode, SubThetaMode = SubMode.lower(), SubThetaMode.lower() - if isinstance(LD,TFG.Detect): - LD = [LD] - ND = len(LD) - indMat = np.zeros((ND,BF2.Mesh.NCents),dtype=bool) - for ii in range(0,ND): - print " Computing ind matrix for " + LD[ii].Id.Name - if SubThetaMode=='rel': - NT= np.round(1./SubTheta) - else: - NT= np.round((LD[ii].Span_Theta[1]-LD[ii].Span_Theta[0])/SubTheta) - Theta = np.linspace(LD[ii].Span_Theta[0], LD[ii].Span_Theta[1], NT, endpoint=True) - #LPolys = [LD[ii].Poly] + [aa.Poly for aa in LD[ii].LApert] - for jj in range(0,BF2.Mesh.NCents): - R, Z = TFM.Calc_SumMeshGrid2D(np.unique(BF2.Mesh.Knots[0,BF2.Mesh._Cents_Knotsind[:,jj]]), np.unique(BF2.Mesh.Knots[1,BF2.Mesh._Cents_Knotsind[:,jj]]), SubP=SubP, SubMode=SubMode, Test=False) - NR, NZ = R.size, Z.size - RZ = R.reshape((NR,1)).dot(np.ones((1,NZ))).flatten() - RT = R.reshape((NR,1)).dot(np.ones((1,NT))).flatten() - TR = np.ones((NR,1)).dot(Theta.reshape((1,NT))).flatten() - TZ = Theta.reshape((NT,1)).dot(np.ones((1,NZ))).flatten() - ZR = np.ones((NR,1)).dot(Z.reshape((1,NZ))).flatten() - ZT = np.ones((NT,1)).dot(Z.reshape((1,NZ))).flatten() - RR = np.concatenate((R[0]*np.ones((NR*NT,)), R[-1]*np.ones((NR*NT,)), RZ, RZ, RT, RT)) - TT = np.concatenate((TZ, TZ, Theta[-1]*np.ones((NR*NZ,)), Theta[-1]*np.ones((NR*NZ,)), TR, TR)) - Points = np.array([RR*np.cos(TT), RR*np.sin(TT), np.concatenate((ZT,TZ,ZR,ZR,Z[0]*np.ones((NR*NT,)),Z[-1]*np.ones((NR*NT,))))]) - indMat[ii,jj] = np.any(LD[ii].isinside_ConePoly(Points)) - return indMat -""" - - -def Calc_GeomMatrix_LOS_Iso(BF2, LD, indMat, Mode='quad', epsrel=TFD.GMMatepsrel, SubP=TFD.GMindMSubP, SubMode='Rel', LOSRef=None, Verb=True, Test=True): - if Test: - assert isinstance(BF2,TFM.BF2D), "Arg BF2 must be a TFM.BF2D instance !" - assert isinstance(LD,TFG.GDetect) or isinstance(LD,TFG.Detect) or (type(LD) is list and (all([isinstance(gd,TFG.GDetect) for gd in LD]) or all([isinstance(gd,TFG.Detect) for gd in LD]))), "Arg LD must be a TFG.GDetect or TFG.Detect instance or a list of such !" - assert Mode in ['quad','simps','trapz','nptrapz'], "Arg Mode must be in ['quad','simps','trapz','nptrapz'] !" - SubMode = SubMode.lower() - - if isinstance(LD,TFG.GDetect): - LD = LD.LDetect - if isinstance(LD,TFG.Detect): - LD = [LD] - ND = len(LD) - T = np.zeros((ND,BF2.NFunc)) - err = np.nan*np.ones((ND,BF2.NFunc)) - Poly = BF2._get_Func_Supps() - Vin = np.array([[0.,-1.,0.,1.],[1.,0.,-1.,0.]]) - if LOSRef is None: - LOSRef = LD[0]._LOSRef - if Mode=='quad': - for ii in range(0,ND): - if Verb: - print " Computing MatLOS for " + LD[ii].Id.Name - ThetaLim = (LD[ii]._Span_Theta[0], LD[ii]._Span_Theta[1]) - ind = np.unique(BF2._Cents_Funcind[:,indMat[ii,:]]) - ind = ind[~np.isnan(ind)].astype(int) - for jj in range(0,ind.size): - SIn, SOut = GG.Calc_InOut_LOS_PIO(LD[ii].LOS[LOSRef]['LOS'].D.reshape((3,1)), LD[ii].LOS[LOSRef]['LOS'].u.reshape((3,1)), Poly[ind[jj]], Vin) - if SIn.shape[1]>0 and SOut.shape[1]>0: - if SIn.shape[1]>1: - sp = np.sum((SIn-np.tile(LD[ii].LOS[LOSRef]['LOS'].D,(SIn.shape[1],1)).T)**2,axis=0) - SIn = SIn[:,np.argmin(sp)] - if SOut.shape[1]>1: - sp = np.sum((SOut-np.tile(LD[ii].LOS[LOSRef]['LOS'].D,(SOut.shape[1],1)).T)**2,axis=0) - SOut = SOut[:,np.argmin(sp)] - Thetas = (np.arctan2(SIn[1],SIn[0]), np.arctan2(SOut[1],SOut[0])) - if Thetas[0]>=ThetaLim[0] and Thetas[0]<=ThetaLim[1] and Thetas[1]>=ThetaLim[0] and Thetas[1]<=ThetaLim[1]: - SIn, SOut = SIn.flatten(), SOut.flatten() - DMax = np.linalg.norm(SOut-SIn) - nS = (SOut-SIn)/DMax - def FuncSABF(ss): - P = SIn + nS*ss - return BF2._LFunc[ind[jj]](np.array([[np.hypot(P[0],P[1])],[P[2]]]))[0] - T[ii,ind[jj]], err[ii,ind[jj]] = scpinteg.quad(FuncSABF, 0, DMax, epsabs=0., epsrel=epsrel) - T[ii,:] = T[ii,:] * LD[ii].LOS[LOSRef]['Etend'] - else: - if Mode=='trapz': - F = scpinteg.trapz - elif Mode=='simps': - F = scpinteg.simps - elif Mode=='nptrapz': - F = np.trapz - for ii in range(0,ND): - if Verb: - print " Computing MatLOS for " + LD[ii].Id.Name - NP = round(1./SubP) - ind = np.unique(BF2._Cents_Funcind[:,indMat[ii,:]]) - ind = ind[~np.isnan(ind)].astype(int) - for jj in range(0,ind.size): - SIn, SOut = GG.Calc_InOut_LOS_PIO( LD[ii].LOS[LOSRef]['LOS'].D.reshape((3,1)), LD[ii].LOS[LOSRef]['LOS'].u.reshape((3,1)), Poly[ind[jj]], Vin) - if SIn.shape[1]>0 and SOut.shape[1]>0: - if SIn.shape[1]>1: - sp = np.sum((SIn-np.tile(LD[ii].LOS[LOSRef]['LOS'].D,(SIn.shape[1],1)).T)**2,axis=0) - SIn = SIn[:,np.argmin(sp)] - if SOut.shape[1]>1: - sp = np.sum((SOut-np.tile(LD[ii].LOS[LOSRef]['LOS'].D,(SOut.shape[1],1)).T)**2,axis=0) - SOut = SOut[:,np.argmin(sp)] - Thetas = (np.arctan2(SIn[1,0],SIn[0,0]), np.arctan2(SOut[1,0],SOut[0,0])) - if Thetas[0]>=LD[ii]._Span_Theta[0] and Thetas[0]<=LD[ii]._Span_Theta[1] and Thetas[1]>=LD[ii]._Span_Theta[0] and Thetas[1]<=LD[ii]._Span_Theta[1]: - SIn, SOut = SIn.flatten(), SOut.flatten() - DMax = np.linalg.norm(SOut-SIn) - nS = (SOut-SIn)/DMax - DV = DMax*SubP if SubMode=='rel' else DMax/SubP - NP = math.ceil(DMax/DV) - ss = np.linspace(0,DMax,NP,endpoint=True) - Val = BF2._LFunc[ind[jj]](np.array([np.hypot(SIn[0]+nS[0]*ss,SIn[1]+nS[1]*ss), SIn[2]+nS[2]*ss])) - T[ii,ind[jj]] = F(Val, x=ss) - T[ii,:] = T[ii,:] * LD[ii].LOS[LOSRef]['Etend'] - return T - - -def Regroup_GMat2D(LGMat, Id=None, dtime=None, CompGM=True): # Finish update and debugging !!!! - assert type(LGMat) is list and all([isinstance(GMat,GMat2D) for GMat in LGMat]), "Arg LGMat must be a list of GMat2D instances !" - assert all([L.Id.BF2_SaveName==LGMat[0].Id.BF2_SaveName for L in LGMat]), "All GeomMat2 instances must have the same TFM.BF2D instance !" - assert all([L.Mat_Mode==LGMat[0].Mat_Mode and L.Mat_epsrel==LGMat[0].Mat_epsrel and L.Mat_SubP==LGMat[0].Mat_SubP and L.Mat_SubMode==LGMat[0].Mat_SubMode and L.Mat_SubTheta==LGMat[0].Mat_SubTheta]), "All GeomMat2 instances must have the same computation mode and parameters for Mat !" - assert all([L.Mat_Iso==LGMat[0].Mat_Iso for L in LGMat]), "All GeomMat2 instances must have the same Mat_Iso !" - assert all([L.MatLOS_Mode==LGMat[0].MatLOS_Mode and L.MatLOS_epsrel==LGMat[0].MatLOS_epsrel and L.MatLOS_SubP==LGMat[0].MatLOS_SubP and L.MatLOS_SubMode==LGMat[0].MatLOS_SubMode]), "All GeomMat2 instances must have the same computation mode and parameters for MatLOS !" - assert all([L.indMat_SubP==LGMat[0].indMat_SubP and L.indMat_SubMode==LGMat[0].indMat_SubMode and L.indMat_SubTheta==LGMat[0].indMat_SubTheta]), "All GeomMat2 instances must have the same computation parameters for indMat !" - assert Id is None or type(Id) is str, "Arg Id must be None or a str !" - assert dtime is None or isinstance(dtime,dtm.datetime), "Arg dtime must be None or a dtm.datetime instance !" - - LD = [] - GDetect_nGDetect, GDetect_Names, GDetect_SaveNames, LDetect_GD_SaveNames, LDetect_GD_Names = 0, [], [], [], [] - indMat, Mat, MatLOS = [], [], [] - for ii in range(0,len(LGMat)): - LD += LGMat[ii].get_LD() - GDetect_nGDetect += LGMat[ii].Id.GDetect_nGDetect - GDetect_Names += LGMat[ii].Id.GDetect_Names - GDetect_SaveNames += LGMat[ii].Id.GDetect_SaveNames - LDetect_GD_SaveNames += LGMat[ii].Id.LDetect_GD_SaveNames - LDetect_GD_Names += LGMat[ii].Id.LDetect_GD_Names - indMat.append(LGMat[ii].indMat) - Mat.append(LGMat[ii].Mat_csr.todense()) - MatLOS.append(LGMat[ii].MatLOS_csr.todense()) - indMat = np.concatenate(tuple(indMat),axis=0) - Mat = np.concatenate(tuple(Mat),axis=0) - MatLOS = np.concatenate(tuple(MatLOS),axis=0) - - if Id is None: - Id = '' - for ii in range(0,len(LGMat)): - Id += LGMat[ii].Id.Name+'_' - Id = Id[:-1] - if dtime is None: - dts = [mm.Id.dtime for mm in LGMat] - if all([dd==dts[0] for dd in dts]): - dtime = dts[0] - else: - dtime = dtm.datetime.now() - - GM = GMat2D(Id, LGMat[0].get_BF2(), LD, Mat=Mat, indMat=indMat, MatLOS=MatLOS, CompGM=CompGM, Iso=LGMat[0].Mat_Iso, dTime=dtime, - Mode=LGMat[0].Mat_Mode, epsrel=LGMat[0].Mat_epsrel, SubP=LGMat[0].Mat_SubP, SubMode=LGMat[0].Mat_SubMode, SubTheta=LGMat[0].Mat_SubTheta, SubThetaMode=LGMat[0].Mat_SubThetaMode, - SubPind=LGMat[0].indMat_SubP, SubModeind=LGMat[0].indMat_SubMode, SubThetaind=LGMat[0].indMat_SubTheta, SubThetaModeind=LGMat[0].indMat_SubThetaMode, - ModeLOS=LGMat[0].MatLOS_Mode, epsrelLOS=LGMat[0].MatLOS_epsrel, SubPLOS=LGMat[0].MatLOS_SubP, SubModeLOS=LGMat[0].MatLOS_SubMode) - - GM.Id.GDetect_nGDetect = GDetect_nGDetect - GM.Id.GDetect_Names = GDetect_Names - GM.Id.GDetect_SaveNames = GDetect_SaveNames - GM.Id.LDetect_GD_SaveNames = LDetect_GD_SaveNames - GM.Id.LDetect_GD_Names = LDetect_GD_Names - print " Created (but not saved) : "+GM.Id.SaveName - return GM - - -""" -############################################################################### -############################################################################### - Plotting functions -############################################################################### -""" - -def Plot_GeomMatrix_Detect(D, BF2, Ti=None, axPol=None, axMesh=None, axBF=None, Mask=False, indMask='', TLOS=False, TiLOS=None, SubP=TFD.GMPlotDetSubP, SubMode=TFD.GMPlotDetSubPMode, - Cdict=TFD.GMPlotDetCd, Ldict=TFD.GMPlotDetLd, LdictLOS=TFD.GMPlotDetLOSd, Test=True, a4=False): - if Test: - assert isinstance(D, TFG.Detect), "Arg D must be a Detect instance !" - assert isinstance(BF2, TFM.BF2D), "Arg BF2 must be a BF2D instance !" - assert not (Ti is None and TiLOS is None), "No geometry matrix available !" - assert Ti is None or (isinstance(Ti, np.ndarray) and (Ti.shape==(BF2.NFunc,) or Ti.shape==(1,BF2.NFunc))), "Arg Ti must be a (N,) or (1,N) np.ndarray (line of the geometry matrix) !" - assert all([ax is None or isinstance(ax,plt.Axes) for ax in [axPol,axMesh,axBF]]), "Args axPol, axMesh and axBF must be plt.Axes instances or None !" - assert type(SubP) is float, "Arg SubP must be a float !" - assert SubMode.lower() in ['rel','abs'], "Arg SubMode must be 'rel' or 'abs' !" - assert type(Cdict) is dict, "Arg Cdict must be dict !" - assert type(Ldict) is dict, "Arg Ldict must be dict !" - assert type(Mask) is bool and ((Mask and isinstance(indMask,np.ndarray) and indMask.size==BF2.NFunc and indMask.dtype.name=='bool') or ~Mask), "Arg Mask must be a bool and arg indMask must be a np.ndarray of bool !" - if not Mask: - indMask = np.ones((BF2.Mesh.NCents,),dtype=bool) - RZLim = BF2._get_Func_SuppBounds() - if not Ti is None: - ind = Ti.nonzero()[0] - indC = np.unique(BF2._Func_Centsind[:,ind]) - Val = np.zeros((ind.size,BF2.Mesh.NCents)) - for ii in range(0,ind.size): - Val[ii,indC] = Ti[ind[ii]]*(indMask[indC] & (BF2.Mesh.Cents[0,indC]>=RZLim[0,ind[ii]]) & (BF2.Mesh.Cents[0,indC]=RZLim[2,ind[ii]]) & (BF2.Mesh.Cents[1,indC]=RZLim[0,ind[ii]]) & (BF2.Mesh.Cents[0,indCLOS]=RZLim[2,ind[ii]]) & (BF2.Mesh.Cents[1,indCLOS]0).nonzero()[0] if not Ti is None else np.logical_and(indMask,ValLOS>0).nonzero()[0] - patch = [] - for ii in range(0,indMask.size): - Rk = np.unique(BF2.Mesh.Knots[0,BF2.Mesh._Cents_Knotsind[:,indMask[ii]]]) - Zk = np.unique(BF2.Mesh.Knots[1,BF2.Mesh._Cents_Knotsind[:,indMask[ii]]]) - patch.append(patches.Polygon(np.array([[Rk[0], Zk[0]], [Rk[1], Zk[0]], [Rk[1], Zk[1]], [Rk[0], Zk[1]]]), True)) - ppp = PcthColl(patch, **Cdict) - if not Ti is None: - ppp.set_array(Val[indC]) - else: - ppp.set_array(ValLOS[indCLOS]) - CNb = axPol.add_collection(ppp) - cbar = plt.colorbar(CNb, ax=axPol, orientation='vertical', fraction=0.10, pad=0.05, shrink=0.8, panchor=(1.0,0.0),anchor=(0.0,0.0), extend='neither') - if not axMesh==None: - if not Ti is None: - axMesh.plot(np.arange(0,BF2.Mesh.NCents), Val, label=D.Id.NameLTX, **Ldict) - if not TiLOS is None: - axMesh.plot(np.arange(0,BF2.Mesh.NCents), ValLOS, label=D.Id.NameLTX+' LOS', **LdictLOS) - if not axBF==None: - if not Ti is None: - axBF.plot(np.arange(0,BF2.NFunc), Ti, label=D.Id.NameLTX, **Ldict) - if not TiLOS is None: - axBF.plot(np.arange(0,BF2.NFunc), TiLOS, label=D.Id.NameLTX+' LOS', **LdictLOS) - return axPol, axMesh, axBF - - -def Plot_GeomMatrix_BFunc(LD, Names, Nb, Ti=None, axPol=None, axD=None, axDred=None, TLOS=False, TiLOS=None, Ldict=TFD.GMPlotDetLd, LdictLOS=TFD.GMPlotDetLOSd, KWArgDet=TFD.GMPlotBFDetd, a4=False, Test=True): - if Test: - assert type(LD) is list and all([isinstance(D,TFG.Detect) for D in LD]), "Arg LD must be a list of TFG.Detect instances !" - assert type(Names) is list and all([type(N) is str for N in Names]), "Arg Names must be a list of str !" - assert all([tt is None or (isinstance(tt,np.ndarray) and (tt.shape==(len(LD),) or tt.shape==(len(LD),1))) for tt in [Ti,TiLOS]]), "Arg Ti must be a (N,) or (N,1) np.ndarray (column of the geometry matrix) !" - assert not (Ti is None and TiLOS is None), "No geometry matrix was provided !" - assert all([ax==None or ax=='None' or isinstance(ax,plt.Axes) for ax in [axPol,axD,axDred]]), "Args axPol, axD and axDred must be plt.Axes instances or None !" - assert type(Ldict) is dict, "Arg Ldict must be dict !" - - if axPol is None and axD is None and axDred is None: - axPol, axD, axDred = TFD.Plot_GeomMatrix_Mesh_DefAxes(a4=a4) - nD = len(LD) - ind = Ti.nonzero()[0] if (not Ti is None) else TiLOS.nonzero()[0] - if not axPol is None: - Col = plt.cm.jet - NC = Col.N - for ii in range(0,len(ind)): - cc = Col(int((Ti[ind[ii]]-np.min(Ti))*NC/(np.max(Ti)-np.min(Ti)))) if not Ti is None else Col(int((TiLOS[ind[ii]]-np.min(TiLOS))*NC/(np.max(TiLOS)-np.min(TiLOS)))) - KWArgDet['Ldict']['c'] = cc - KWArgDet['Conedict']['facecolors'] = (cc[0],cc[1],cc[2],KWArgDet['Conedict']['facecolors'][3]) - LD[ind[ii]].plot(Proj='Pol', Lax=[axPol], **KWArgDet) - - if not axD is None: - if not Ti is None: - axD.plot(np.arange(0,nD), Ti, label='BF nb. '+ str(Nb), **Ldict) - if TLOS and not TiLOS is None: - axD.plot(np.arange(0,nD), TiLOS, label='BF nb. '+ str(Nb)+' LOS', **LdictLOS) - axD.set_xlabel('Detect index (starts at 0)') - - if not axDred is None: - Names = [Names[ii] for ii in ind] - Names = [Name.replace('_',' ') for Name in Names] - if not Ti is None: - axDred.plot(np.arange(1,ind.size+1), Ti[ind], label='BF nb. '+ str(Nb), **Ldict) - if TLOS and not TiLOS is None: - axDred.plot(np.arange(1,ind.size+1), TiLOS[ind], label='BF nb. '+ str(Nb)+' LOS', **LdictLOS) - axDred.set_xlim(0,ind.size+1) - axDred.set_xticks(np.arange(1,ind.size+1)) - axDred.set_xticklabels(Names, rotation=60) - axDred.set_xlabel('') - return axPol, axD, axDred - - diff --git a/tofu/matcomp/__init__.py b/tofu/matcomp/__init__.py deleted file mode 100644 index 8b1378917..000000000 --- a/tofu/matcomp/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/tofu/mesh/Profile.prof b/tofu/mesh/Profile.prof deleted file mode 100644 index c30ca4c30adad35e5ace11581f2b7d54c90e4405..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3463 zcmd5;&1=*^6koqTKv)qkLZx7B*FuxsRxCoB^$Vp?t*jp)sA)EvWYcDoG&2F$st3J@ zpm^{ql-57MOYtUc5y4xff{6G5*51Slg5p7ZlS$Te#$BwoOBePro1J<2z4w0a_hvY? zCXqyRj_8mS4ypeeI_{<7~}S*@sV#& z-%FLnaNrsB!wyl=k!ZTEh@C+ZIXV{IGA=rHd#4z@NX!WPg^YLrm62$f`RHGvQ$!}# z+FV5)R16J;o5_v<57MyXBEc=2jAu(aTrX}O_Y;p*-zLM&lxEv`Wn=%UKSyawxiDpcJt;>)x z-E&H@tnJ+ZStGnuEQ1;Xt5%=7lEmu;sS4t2kvPFU)ADq`#PkvdeqgV>LPeu z26D@^LV-}F;1!stlU$YBF$v}3-V=`-Jj8?k`(hUx&KytrpCgLayK@+Eu2egM6*hD~ z#JaTAs4_UH{xRe1?&F@Bk>XFuc)7h}>h+CeHtdZ5=x5Gl80a5e&VeWg5^-3uR5^1* z?y+&7%c>5|T~pS0o9K8q+1DGQj7dZ@VGMS3Unps)C@heo1+FDlemLJ88ykpksx<6P zA<&&rZrD*b@mssYq}FE+=LirQWerGSQ8tp;5cW*lkb;{84xW^pf^YGcpNdppzjJo{ z!5GwmOV%O^!BFv$ES<}oe-9FifZ6&I4NVYy0}5i@QHJuPX7X&A0M0m diff --git a/tofu/mesh/Profiling.py b/tofu/mesh/Profiling.py deleted file mode 100644 index 2430fdde1..000000000 --- a/tofu/mesh/Profiling.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -# filename: profile.py - -import pstats, cProfile - -import _bsplines_cy as bsp_cy - - - -#cProfile.runctx("bsp_cy.Calc_1D_IntOp(Method='quad')", globals(), locals(), "Profile.prof") -cProfile.runctx("bsp_cy.Calc_1D_LinIntOp(Method='')", globals(), locals(), "Profile.prof") - -s = pstats.Stats("Profile.prof") -s.strip_dirs().sort_stats("time").print_stats() - - - - diff --git a/tofu/mesh/__init__.py b/tofu/mesh/__init__.py deleted file mode 100644 index b5b329924..000000000 --- a/tofu/mesh/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -#! /usr/bin/python - - -""" -Load all core packages and modules which are all machine-independent, diagnostic-independent and code-independent - - -Created on Tuesday 07 June 2016 - -@version: 0.9 -@author: didiervezinet -@author_email: didier.vezinet@gmail.com -""" - - -from ._core import * - -#del _core - -__author__ = "Didier Vezinet" - - - - - - diff --git a/tofu/mesh/_bsplines.py b/tofu/mesh/_bsplines.py deleted file mode 100644 index f89cb3c7c..000000000 --- a/tofu/mesh/_bsplines.py +++ /dev/null @@ -1,1585 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Aug 25 10:03:58 2014 - -@author: didiervezinet -""" - -import numpy as np -import scipy.sparse as scpsp -import scipy.interpolate as scpinterp - - -# ToFu-specific -import tofu.defaults as TFD - - - - - -""" -############################################################################### -############################################################################### - B-spline definitions -############################################################################### -""" - -# Direct definitions of b-splines and their derivatives for degrees 0-3 - -def _Nj0(x,xa,xb): - def Nfunc(x): - a = np.zeros((x.size,)) - a[(x >= xa) & (x < xb)] = 1. - return a - return Nfunc - -def _Nj1(x, x0,x1,x2): - def Nfunc(x): - A = np.zeros((x.size,)) - Ind = (x>=x0)&(x=x0)&(xx=x1)&(xx=x0)&(x=x1)&(x=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x3)&(xx=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x3)&(xx=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x3)&(xx=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x3)&(xx=Deriv, "Arg Deg and Deriv must be int and Deg >= Deriv !" - assert isinstance(Knots,np.ndarray) and Knots.ndim==1 and np.all(Knots==np.unique(Knots)) and Knots.size>Deg+1 , "Arg Knots must be a 1-dim np.ndarray of unique increasing floats with Knots.size>Deg+1 !" - NKnots = Knots.size - NCents = NKnots-1 - NbF = NKnots-1-Deg - LFunc = [] - if Deg==0: - Func_Knotsind = np.array([np.arange(0,NKnots-1),np.arange(1,NKnots)]) - Func_Centsind = np.arange(0,NCents).reshape((1,NbF)) - Knots_Funcind = np.array([np.concatenate(([np.nan],np.arange(0,NbF))),np.concatenate((np.arange(0,NbF),[np.nan]))]) - Cents_Funcind = np.arange(0,NbF).reshape((1,NCents)) - MaxPos = np.mean(np.array([Knots[:-1],Knots[1:]]),axis=0) - for ii in range(0,NbF): - LFunc.append(_Nj0(0,Knots[ii],Knots[ii+1])) - elif Deg==1: - Func_Knotsind = np.array([np.arange(0,NKnots-2),np.arange(1,NKnots-1),np.arange(2,NKnots)]) - Func_Centsind = np.array([np.arange(0,NCents-1),np.arange(1,NCents)]) - Knots_Funcind = np.array([np.concatenate(([np.nan,np.nan],np.arange(0,NbF))),np.concatenate(([np.nan],np.arange(0,NbF),[np.nan])),np.concatenate((np.arange(0,NbF),[np.nan,np.nan]))]) - Cents_Funcind = np.array([np.concatenate(([np.nan],np.arange(0,NbF))),np.concatenate((np.arange(0,NbF),[np.nan]))]) - MaxPos = np.copy(Knots[1:-1]) - if Deriv==0: - for ii in range(0,NbF): - LFunc.append(_Nj1(0,Knots[ii],Knots[ii+1],Knots[ii+2])) - elif Deriv==1: - for ii in range(0,NbF): - LFunc.append(_Nj1D1(0,Knots[ii],Knots[ii+1],Knots[ii+2])) - elif Deg==2: - Func_Knotsind = np.array([np.arange(0,NKnots-3),np.arange(1,NKnots-2),np.arange(2,NKnots-1),np.arange(3,NKnots)]) - Func_Centsind = np.array([np.arange(0,NCents-2),np.arange(1,NCents-1),np.arange(2,NCents)]) - Knots_Funcind = np.array([np.concatenate(([np.nan,np.nan,np.nan],np.arange(0,NbF))),np.concatenate(([np.nan,np.nan],np.arange(0,NbF),[np.nan])),np.concatenate(([np.nan],np.arange(0,NbF),[np.nan,np.nan])),np.concatenate((np.arange(0,NbF),[np.nan,np.nan,np.nan]))]) - Cents_Funcind = np.array([np.concatenate(([np.nan,np.nan],np.arange(0,NbF))),np.concatenate(([np.nan],np.arange(0,NbF),[np.nan])),np.concatenate((np.arange(0,NbF),[np.nan,np.nan]))]) - MaxPos = np.mean(np.array([Knots[1:-2],Knots[2:-1]]),axis=0) - if Deriv==0: - for ii in range(0,NbF): - LFunc.append(_Nj2(0,Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3])) - elif Deriv==1: - for ii in range(0,NbF): - LFunc.append(_Nj2D1(0,Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3])) - elif Deriv==2: - for ii in range(0,NbF): - LFunc.append(_Nj2D2(0,Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3])) - elif Deg==3: - Func_Knotsind = np.array([np.arange(0,NKnots-4),np.arange(1,NKnots-3),np.arange(2,NKnots-2),np.arange(3,NKnots-1),np.arange(4,NKnots)]) - Func_Centsind = np.array([np.arange(0,NCents-3),np.arange(1,NCents-2),np.arange(2,NCents-1),np.arange(3,NCents)]) - Knots_Funcind = np.array([np.concatenate(([np.nan,np.nan,np.nan,np.nan],np.arange(0,NbF))),np.concatenate(([np.nan,np.nan,np.nan],np.arange(0,NbF),[np.nan])),np.concatenate(([np.nan,np.nan],np.arange(0,NbF),[np.nan,np.nan])),np.concatenate(([np.nan],np.arange(0,NbF),[np.nan,np.nan,np.nan])),np.concatenate((np.arange(0,NbF),[np.nan,np.nan,np.nan,np.nan]))]) - Cents_Funcind = np.array([np.concatenate(([np.nan,np.nan,np.nan],np.arange(0,NbF))),np.concatenate(([np.nan,np.nan],np.arange(0,NbF),[np.nan])),np.concatenate(([np.nan],np.arange(0,NbF),[np.nan,np.nan])),np.concatenate((np.arange(0,NbF),[np.nan,np.nan,np.nan]))]) - MaxPos = np.copy(Knots[2:-2]) - if Deriv==0: - for ii in range(0,NbF): - LFunc.append(_Nj3(0,Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3],Knots[ii+4])) - elif Deriv==1: - for ii in range(0,NbF): - LFunc.append(_Nj3D1(0,Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3],Knots[ii+4])) - elif Deriv==2: - for ii in range(0,NbF): - LFunc.append(_Nj3D2(0,Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3],Knots[ii+4])) - elif Deriv==3: - for ii in range(0,NbF): - LFunc.append(_Nj3D3(0,Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3],Knots[ii+4])) - return LFunc, Func_Knotsind, Func_Centsind, Knots_Funcind, Cents_Funcind, MaxPos - -def BSpline_TotFunc(Deg, Knots, Deriv=0, Coefs=1., thr=1.e-8, thrmode='rel', Test=True): - if Test: - assert Deriv in [0,1,2,3,'D0','D1','D2','D3','D0N2','D0ME','D1N2','D1FI','D2N2','D3N2'], "Arg Deriv must be in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI','D2N2','D3N2'] !" - assert type(Coefs) in [int,float] or (isinstance(Coefs,np.ndarray) and Coefs.ndim==1 and Coefs.size==Knots.size-1-Deg), "Arg Coefs must be a flot or a 1D np.ndarray !" - if type(Deriv) is str: - intDeriv = int(Deriv[1]) - else: - intDeriv = Deriv - LF = BSpline_LFunc(Deg, Knots, Deriv=intDeriv, Test=Test)[0] - if type(Coefs) in [int,float]: - Coefs = float(Coefs)*np.ones((len(LF),)) - if Deriv in [0,1,2,3,'D0','D1','D2','D3']: - Func = lambda x,Coefs=Coefs,LF=LF: np.sum(np.concatenate(tuple([Coefs[ii]*LF[ii](x).reshape((1,x.size)) for ii in range(0,len(LF))]),axis=0),axis=0, keepdims=False) - elif Deriv in ['D0N2','D1N2','D2N2','D3N2']: - Func = lambda x,Coefs=Coefs,LF=LF: np.sum(np.concatenate(tuple([Coefs[ii]*LF[ii](x).reshape((1,x.size)) for ii in range(0,len(LF))]),axis=0),axis=0, keepdims=False)**2 - elif Deriv=='D1FI': - lf = BSpline_LFunc(Deg, Knots, Deriv=0, Test=Test)[0] - Func = lambda x,Coefs=Coefs,LF=LF: np.sum(np.concatenate(tuple([Coefs[ii]*LF[ii](x).reshape((1,x.size)) for ii in range(0,len(LF))]),axis=0),axis=0, keepdims=False)**2/np.sum(np.concatenate(tuple([Coefs[ii]*lf[ii](x).reshape((1,x.size)) for ii in range(0,len(LF))]),axis=0),axis=0, keepdims=False) - elif Deriv=='D0ME': - ext = [Knots[0],Knots[-1]] - def Func(x,coefs=Coefs, LF=LF, ext=ext, thr=thr, thrmode=thrmode): - g = np.sum([coefs[jj]*LF[jj](x).reshape((1,x.size)) for jj in range(0,NF)],axis=0) - Int = np.nanmean(g)*(ext[1]-ext[0]) # To be finished !!! replace with the real integral of the function to make it a distribution function !!! - g = g / Int - if thr is not None: - thr = thr if thrmode=='abs' else np.nanmax(g)*thr - g[gDeg+1 , "Arg Knots must be a 1-dim np.ndarray of unique increasing floats with Knots.size>Deg+1 !" - assert Deriv in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI'], "Arg Deriv must be in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI'] !" - if type(Deriv) is str: - intDeriv = int(Deriv[1]) - else: - intDeriv = Deriv - assert Deg > 0 and intDeriv= 0 - sols = np.array([(-B[ind]+np.sqrt(Delta[ind]))/(2.*A[ind]), (-B[ind]-np.sqrt(Delta[ind]))/(2.*A[ind])]) - ind = (sols>=Int[0,ind]) & (sols=Int[0,:]-Eps) & (sols=0, "Arg Deg must be a positive int !" - assert (type(Deriv) is int and Deriv<=Deg) or (type(Deriv) is str and Deriv in ['D0','D1','D2','D3','D0N2','D1N2','D2N2','D3N2','D1FI'] and int(Deriv[1])<=Deg), "Arg Deriv must be a int or a str !" - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - - NKnots = Knots.size - NFunc = NKnots-Deg-1 - A = np.zeros((NFunc,NFunc)) - if not 'N' in Deriv and not 'FI' in Deriv: - m = 0 - if Dbis==0: - if Deg==0: - A = np.diff(Knots) - elif Deg==1: - A = 0.5*(Knots[2:]-Knots[0:-2]) - elif Deg==2: - Int1 = (Knots[1:-2] - Knots[0:-3])**2 / (3.*(Knots[2:-1]-Knots[0:-3])) - Int21 = ( Knots[2:-1]**2 - 2.*Knots[1:-2]**2 + Knots[1:-2]*Knots[2:-1] + 3.*Knots[0:-3]*(Knots[1:-2]-Knots[2:-1]) ) / (6.*(Knots[2:-1]-Knots[0:-3])) - Int22 = ( -2.*Knots[2:-1]**2 + Knots[1:-2]**2 + Knots[1:-2]*Knots[2:-1] + 3.*Knots[3:]*(Knots[2:-1]-Knots[1:-2]) ) / (6.*(Knots[3:]-Knots[1:-2])) - Int3 = ( Knots[3:] - Knots[2:-1] )**2 / (3.*(Knots[3:]-Knots[1:-2])) - A = Int1+Int21+Int22+Int3 - elif Deg==3: - print "NOT CODED YET !" - Int1 = (Knots[1:-3]-Knots[0:-4])**3/(4.*(Knots[3:-1]-Knots[0:-4])*(Knots[2:-2]-Knots[0:-4])) - Int211 = ( (Knots[2:-2]-Knots[0:-4])**4/4. - (Knots[1:-3]-Knots[0:-4])**3*(Knots[2:-2]-Knots[1:-3] + (Knots[1:-3]-Knots[0:-4])/4.) ) / ( 3.*(Knots[3:-1]-Knots[0:-4])*(Knots[2:-2]-Knots[0:-4])*(Knots[2:-2]-Knots[1:-3]) ) - Int212 = ( -Knots[2:-2]**4-Knots[1:-3]**4/12. + (Knots[0:-4]+Knots[3:-1])*(Knots[2:-2]**3-Knots[1:-3]*Knots[2:-2]**2/2.+Knots[1:-3]**3/6.) + Knots[1:-3]*Knots[2:-2]**3/3. - Knots[0:-4]*Knots[3:-1]*(Knots[2:-2]**2+Knots[1:-3]**2)/2. + Knots[0:-4]*Knots[1:-3]*Knots[2:-2]*Knots[3:-4] ) / ( (Knots[3:-1]-Knots[0:-4])*(Knots[2:-2]-Knots[1:-3])*(Knots[3:-1]-Knots[1:-3]) ) - Int22 = (Knots[2:-2]-Knots[1:-3])**2*( (Knots[4:]-Knots[2:-2]) + (Knots[2:-2]-Knots[1:-3]) ) / ( (Knots[4:]-Knots[1:-3])*(Knots[3:-1]-Knots[1:-3]) ) - Int31 = ( (Knots[3:-1]-Knots[2:-2])**2*( (Knots[2:-2]-Knots[0:-4]) + (Knots[3:-1]-Knots[2:-2])/4. ) ) / ( 3.*((Knots[3:-1]-Knots[0:-4])*(Knots[3:-1]-Knots[1:-3])) ) - Int321 = 0 # To be finished - Int322 = 0 # To be finished - Int4 = 0 # To be finished - A = Int1+Int211+Int212+Int22+Int31+Int321+Int322+Int4 - - elif Dbis>=1: - A = np.zeros((NFunc,)) - - elif 'N2' in Deriv: - m = 1 - if Dbis==0: - if Deg==0: - A = scpsp.diags([np.diff(Knots)],[0],shape=None,format=SpaFormat) - elif Deg==1: - d0 = (Knots[2:]-Knots[0:-2])/3. - dp1 = (Knots[2:-1]-Knots[1:-2])/6. - A = scpsp.diags([d0,dp1,dp1], [0,1,-1],shape=None,format=SpaFormat) - elif Deg==2: - print "NOT CODED YET !" - d0 = (Knots[1:-2]-Knots[0:-3])**3/(5.*(Knots[2:-1]-Knots[0:-3])**2) + 0 + 0 # To be finished - dp1 = 0 # To be finished - dp2 = 0 # To be finished - A = scpsp.diags([d0,dp1,dp1,dp2,dp2], [0,1,-1,2,-2],shape=None,format=SpaFormat) - elif Deg==3: - print "NOT CODED YET !" - A = 0 - elif Dbis==1: - if Deg==1: - print "NOT CODED YET !" - A = 0 - elif Deg==2: - print "NOT CODED YET !" - A = 0 - elif Deg==3: - print "NOT CODED YET !" - A = 0 - elif Dbis==2: - if Deg==2: - print "NOT CODED YET !" - A = 0 - elif Deg==3: - print "NOT CODED YET !" - A = 0 - elif Dbis==3: - if Deg==3: - print "NOT CODED YET !" - A = 0 - - if not Sparse: - A = np.array(A.todense()) - - return A, m - - - - - -############################################ -##### Computing functions -############################################ - - -def Calc_BF1D_Weights(LFunc, Points, Test=True): - if Test: - assert type(LFunc) is list, "Arg LFunc must be a list of functions !" - assert isinstance(Points,np.ndarray) and Points.ndim==1, "Arg Points must be a (N,) np.ndarray !" - NFunc = len(LFunc) - Wgh = np.zeros((Points.size, NFunc)) - for ii in range(0,NFunc): - Wgh[:,ii] = LFunc[ii](Points) - return Wgh - -def Calc_BF2D_Weights(LFunc, PointsRZ, Test=True): - if Test: - assert type(LFunc) is list, "Arg LFunc must be a list of functions !" - assert isinstance(PointsRZ,np.ndarray) and PointsRZ.ndim==2, "Arg Points must be a (2,N) np.ndarray !" - NFunc = len(LFunc) - Wgh = np.zeros((PointsRZ.shape[1], NFunc)) - for ii in range(0,NFunc): - Wgh[:,ii] = LFunc[ii](PointsRZ) - return Wgh - - -def BF2D_get_Op(BF2, Points, Deriv=0, indFin=None, Test=True): # To be updated to take into account only fraction of BF - """ Return the operator to compute the desired quantity on NP points (to be multiplied by Coefs) Y = Op(Coefs) for NF basis functions - Input : - BF2 A BF2D instance - Points A (3,NP) np.ndarray indicating (X,Y,Z) cylindrical coordinates of points at which to evaluate desired quantity (automatically converted to (R,Z) coordinates) - Deriv A flag indicating the desired quantity in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Lapl','D2N2-Lapl'] - Test A bool Flag indicating whether inputs shall be tested for conformity - Output : - A The operator itself as a 2D or 3D numpy array - m Flag indicating the kind of operation necessary - = 0 Y = A.dot(C) (Y = AC, with A.shape=(NP,NF)) - = 1 Y = C.dot(A.dot(C)) (Y = tCAC, with A.shape=(NF,NP,NF)) - = 2 Y = sum( C.dot(A[:].dot(C)) ) (e.g.: Y = tCArC + tCAzC with Ar.shape==Az.shape=(NF,NP,NF), you can compute a scalar product with each component if necessary) - """ - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert isinstance(Points,np.ndarray) and Points.ndim==2 and Points.shape[0] in [2,3], "Arg Points must be a (2-3,NP) np.ndarray !" - assert Deriv in [0,1,2,'D0','D0N2','D1','D1N2','D2','D2N2'], "Arg Deriv must be in [0,1,2,'D0','D0N2','D1','D1N2','D2','D2N2'] !" - assert indFin is None or (isinstance(indFin,np.ndarray) and indFin.dtype.name in ['bool','int32','int64','int']), "Arg indFin must be None or a np.naddary of bool or int !" - - if indFin is None: - indFin = np.arange(0,BF2.NFunc) - if indFin.dtype.name=='bool': - indFin = indFin.nonzero()[0] - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - NF = indFin.size - NP = Points.shape[1] - if Points.shape[0]==3: - RZ = np.array([np.hypot(Points[0,:],Points[1,:]),Points[2,:]]) - else: - RZ = np.copy(Points) - - QuadR, QuadZ = BF2._get_quadPoints() - QuadR, QuadZ = QuadR[:,indFin], QuadZ[:,indFin] - if Deriv=='D0': - m = 0 - A = np.zeros((NP,NF)) - for ii in range(0,NF): - A[:,ii] = BF2._LFunc[indFin[ii]](RZ) - return A, m - elif Deriv=='D0N2': # Update in progress from here... - m = 1 - A = np.zeros((NF,NP,NF)) - for ii in range(0,NF): - Yii = BF2._LFunc[ii](RZ) - A[ii,:,ii] = Yii**2 - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - A[ii,:,Ind[jj]] = Yii*BF2._LFunc[Ind[jj]](RZ) - return A, m - elif Deriv=='D1' and BF2.Deg>=1: - m = 2 - Ar, Az = np.zeros((NP,NF)), np.zeros((NP,NF)) - for ii in range(0,NF): - Ar[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Az[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - return (Ar,Az), m - elif Deriv=='D1N2' and BF2.Deg>=1: - m = 2 - AR, AZ = np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)) - for ii in range(0,NF): - rii, zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Rii, Zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - AR[ii,:,ii] = (Rii*zii)**2 - AZ[ii,:,ii] = (rii*Zii)**2 - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - AR[ii,:,Ind[jj]] = Rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=1)[0][0](RZ[0,:]) * zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=0)[0][0](RZ[1,:]) - AZ[ii,:,Ind[jj]] = rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=0)[0][0](RZ[0,:]) * Zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=1)[0][0](RZ[1,:]) - return (AR,AZ), m - elif Deriv=='D2' and BF2.Deg>=2: - m = 2 - Arr, Azz, Arz = np.zeros((NP,NF)), np.zeros((NP,NF)), np.zeros((NP,NF)) - for ii in range(0,NF): - Arr[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=2)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Azz[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=2)[0][0](RZ[1,:]) - Arz[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - return (Arr,Azz,Arz), m - elif Deriv=='D2N2' and BF2.Deg>=2: - m = 2 - ARR, AZZ, ARZ, Arrzz = np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)) - for ii in range(0,NF): - rii, zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Rii, Zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - RRii, ZZii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=2)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=2)[0][0](RZ[1,:]) - ARR[ii,:,ii] = (RRii*zii)**2 - AZZ[ii,:,ii] = (rii*ZZii)**2 - ARZ[ii,:,ii] = (Rii*Zii)**2 - Arrzz[ii,:,ii] = RRii*ZZii - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - ARR[ii,:,Ind[jj]] = RRii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=2)[0][0](RZ[0,:]) * zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=0)[0][0](RZ[1,:]) - AZZ[ii,:,Ind[jj]] = rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=0)[0][0](RZ[0,:]) * ZZii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=2)[0][0](RZ[1,:]) - ARZ[ii,:,Ind[jj]] = Rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=1)[0][0](RZ[0,:]) * Zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=1)[0][0](RZ[1,:]) - return (ARR,AZZ,ARZ, Arrzz), m - - -def BF2D_get_TotFunc(BF2, Deriv=0, DVect=TFD.BF2_DVect_DefR, Coefs=1., Test=True): - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert type(Deriv) in [int,str], "Arg Deriv must be a int or a str !" - assert type(Coefs) is float or (isinstance(Coefs,np.ndarray) and Coefs.size==BF2.NFunc), "Arg Coefs must be a float or a np.ndarray !" - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - - if type(Coefs) is float: - Coefs = Coefs.np.ones((BF2.NFunc,)) - - NF = BF2.NFunc - QuadR, QuadZ = BF2._get_quadPoints() - if Deriv in [0,'D0']: - LF = BF2._LFunc - return lambda Points, Coefs=Coefs, LF=LF, NF=NF: np.sum(np.concatenate(tuple([Coefs[jj]*LF[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - elif Deriv=='D0N2': - LF = BF2._LFunc - return lambda Points, Coefs=Coefs, LF=LF, NF=NF: np.sum(np.concatenate(tuple([Coefs[jj]*LF[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0)**2 - - elif Dbis==1: - LDR = [] - LDZ = [] - for ii in range(0,NF): - LDR.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=1, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=0, Test=Test)[0](PointsRZ[1,:])) - LDZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=0, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=1, Test=Test)[0](PointsRZ[1,:])) - if Deriv=='D1': - def FTot(Points, Coefs=Coefs, DVect=DVect, NF=NF, LDR=LDR, LDZ=LDZ): - DVect = DVect(Points) - Theta = np.arctan2(Points[1,:],Points[0,:]) - eR = np.array([np.cos(Theta),np.sin(Theta),np.zeros((Theta.size,))]) - DVect = np.array([np.sum(DVect*eR,axis=0), DVect[2,:]]) - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0)*DVect[0,:] - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0)*DVect[1,:] - return ValR+ValZ - elif Deriv=='D1N2': - def FTot(Points, Coefs=Coefs, NF=NF, LDR=LDR, LDZ=LDZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return ValR**2+ValZ**2 - elif Deriv=='D1FI': - LF = BF2._LFunc - def FTot(Points, Coefs=Coefs, NF=NF, LF=LF, LDR=LDR, LDZ=LDZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - Val = np.sum(np.concatenate(tuple([Coefs[jj]*LF[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return (ValR**2+ValZ**2)/Val - - elif Dbis==2: - LDRR, LDZZ = [], [] - for ii in range(0,NF): - LDRR.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=2, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=0, Test=Test)[0](PointsRZ[1,:])) - LDZZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=0, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=2, Test=Test)[0](PointsRZ[1,:])) - if Deriv=='D2-Lapl': - def FTot(Points, Coefs=Coefs, NF=NF, LDRR=LDRR, LDZZ=LDZZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return ValR+ValZ - elif Deriv=='D2N2-Lapl': - def FTot(Points, Coefs=Coefs, NF=NF, LDRR=LDRR, LDZZ=LDZZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return (ValR+ValZ)**2 - else: - LDR, LDZ, LDRZ= [], [], [] - for ii in range(0,NF): - LDR.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=1, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=0, Test=Test)[0](PointsRZ[1,:])) - LDZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=0, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=1, Test=Test)[0](PointsRZ[1,:])) - LDRZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=1, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=1, Test=Test)[0](PointsRZ[1,:])) - if Deriv=='D2-Gauss': - def FTot(Points, Coefs=Coefs, NF=NF, LDR=LDR, LDZ=LDZ, LDRR=LDRR, LDZZ=LDZZ, LDRZ=LDRZ): - ValRR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValRZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDRZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return (ValRR*ValZZ-ValRZ**2)/(1. + ValR**2 + ValZ**2)**2 - elif Deriv=='D2-Mean': - def FTot(Points, Coefs=Coefs, NF=NF, LDR=LDR, LDZ=LDZ, LDRR=LDRR, LDZZ=LDZZ, LDRZ=LDRZ): - ValRR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValRZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDRZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return ((1.+ValR**2)*ValZZ - 2.*ValR*ValZ*ValRZ + (1.+ValZ**2)*ValRR)/(2.*(1. + ValR**2 + ValZ**2)**(1.5)) - - return FTot - - -def Calc_BF2D_Val(LFunc, Points, Coef=1., Test=True): - if Test: - assert type(LFunc) is list, "Arg LFunc must be a list of functions !" - assert isinstance(Points,np.ndarray) and (Points.shape[0]==2 or Points.shape[0]==3), "Arg Points must be a (2,N) or (3,N) np.ndarray !" - assert (type(Coef) is float and Coef==1.) or (isinstance(Coef,np.ndarray) and Coef.shape[0]==len(LFunc)), "Arg Coef must be a (BF2.NFunc,1) np.ndarray !" - - if Points.shape[0]==3: - R = np.sqrt(np.sum(Points[0:2,:]**2,axis=0,keepdims=False)) - Points = np.array([[R],[Points[2,:]]]) - - NFunc = len(LFunc) - Val = np.zeros((Points.shape[1],)) - Coef = Coef*np.ones((NFunc,1)) - for ii in range(0,NFunc): - Val = Val + Coef[ii]*LFunc[ii](Points) - - return Val - - - - - - - - - -def Calc_Integ_BF2(BF2, Coefs=1., Mode='Vol', Test=True): - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert Mode=='Vol' or Mode=='Surf', "Arg Mode must be 'Vol' or 'Surf' !" - assert type(Coefs) is float or (isinstance(Coefs,np.ndarray) and Coefs.size==BF2.NFunc), "Arg Coefs must be a (BF2.NFunc,) np.ndarray !" - assert BF2.Deg <= 3, "Arg BF2 should not have Degree > 3 !" - - if type(Coefs) is float: - Coefs = Coefs*np.ones((BF2.NFunc,)) - if Mode=='Surf': - if BF2.Deg==0: - Supp = BF2.get_Func_SuppRZ() - Int = np.sum(Coefs.flatten()*(Supp[1,:]-Supp[0,:])*(Supp[3,:]-Supp[2,:])) - elif BF2.Deg==1: - Supp = BF2.get_Func_SuppRZ() - Int = np.sum(Coefs.flatten()*0.25*(Supp[1,:]-Supp[0,:])*(Supp[3,:]-Supp[2,:])) - elif BF2.Deg==2: - QR, QZ = BF2._get_quadPoints() - IntR1 = (QR[1,:]-QR[0,:])**2/(3.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**2 -2.*QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[0,:]*(QR[1,:]-QR[2,:]))/(6*(QR[2,:]-QR[0,:])) - IntR22 = (-2.*QR[2,:]**2+QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[3,:]*(QR[2,:]-QR[1,:]))/(6.*(QR[3,:]-QR[1,:])) - IntR3 = (QR[3,:]-QR[2,:])**2/(3.*(QR[3,:]-QR[1,:])) - IntZ1 = (QZ[1,:]-QZ[0,:])**2/(3.*(QZ[2,:]-QZ[0,:])) - IntZ21 = (QZ[2,:]**2 -2*QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[0,:]*(QZ[1,:]-QZ[2,:]))/(6*(QZ[2,:]-QZ[0,:])) - IntZ22 = (-2.*QZ[2,:]**2+QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[3,:]*(QZ[2,:]-QZ[1,:]))/(6.*(QZ[3,:]-QZ[1,:])) - IntZ3 = (QZ[3,:]-QZ[2,:])**2/(3.*(QZ[3,:]-QZ[1,:])) - Int = np.sum(Coefs.flatten() * (IntR1+IntR21+IntR22+IntR3) * (IntZ1+IntZ21+IntZ22+IntZ3)) - elif BF2.Deg==3: - print "NOT CODED YET !" - - else: - if BF2.Deg==0: - Supp = BF2.get_Func_SuppRZ() - Int = np.sum( Coefs.flatten() * 2.*np.pi * 0.5*(Supp[1,:]**2-Supp[0,:]**2)*(Supp[3,:]-Supp[2,:])) - elif BF2.Deg==1: - Supp = BF2.get_Func_SuppRZ() - QuadR, QuadZ = BF2._get_quadPoints() - Int = np.sum( Coefs.flatten() * 2.*np.pi * 0.5*(QuadR[2,:]**2-QuadR[0,:]**2 + QuadR[1,:]*(QuadR[2,:]-QuadR[0,:]))*(Supp[3,:]-Supp[2,:])/6.) - elif BF2.Deg==2: - QR, QZ = BF2._get_quadPoints() - IntR1 = (3.*QR[1,:]**3+QR[0,:]**3 -5.*QR[0,:]*QR[1,:]**2+QR[0,:]**2*QR[1,:])/(12.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**3 -3.*QR[1,:]**3+QR[1,:]**2*QR[2,:]+QR[1,:]*QR[2,:]**2 -2.*QR[0,:]*QR[2,:]**2 -2.*QR[0,:]*QR[1,:]*QR[2,:] +4.*QR[0,:]*QR[1,:]**2)/(12.*(QR[2,:]-QR[0,:])) - IntR22 = ( -3.*QR[2,:]**3+QR[1,:]**3+QR[1,:]*QR[2,:]**2+QR[1,:]**2*QR[2,:]+4.*QR[2,:]**2*QR[3,:]-2.*QR[1,:]*QR[2,:]*QR[3,:]-2.*QR[1,:]**2*QR[3,:] )/(12.*(QR[3,:]-QR[1,:])) - IntR3 = ( QR[3,:]**3 +3.*QR[2,:]**3 -5.*QR[2,:]**2*QR[3,:]+QR[2,:]*QR[3,:]**2)/(12.*(QR[3,:]-QR[1,:])) - IntZ1 = (QZ[1,:]-QZ[0,:])**2/(3.*(QZ[2,:]-QZ[0,:])) - IntZ21 = (QZ[2,:]**2 -2*QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[0,:]*(QZ[1,:]-QZ[2,:]))/(6*(QZ[2,:]-QZ[0,:])) - IntZ22 = (-2.*QZ[2,:]**2+QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[3,:]*(QZ[2,:]-QZ[1,:]))/(6.*(QZ[3,:]-QZ[1,:])) - IntZ3 = (QZ[3,:]-QZ[2,:])**2/(3.*(QZ[3,:]-QZ[1,:])) - Int = np.sum(Coefs.flatten() * 2.*np.pi * (IntR1+IntR21+IntR22+IntR3) * (IntZ1+IntZ21+IntZ22+IntZ3)) - elif BF2.Deg==3: - print "NOT CODED YET !" - - return Int - - - - - - - -def Calc_IntOp_BSpline2D(BF2, Deriv=0, Mode='Vol', Sparse=TFD.L1IntOpSpa, SpaFormat=TFD.L1IntOpSpaFormat, Test=True): - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert Mode in ['Surf','Vol'], "Arg Mode must be in ['Surf','Vol'] !" - assert (type(Deriv) is int and Deriv<=BF2.Deg) or (type(Deriv) is str and Deriv in ['D0','D1','D2','D3','D0N2','D1N2','D2N2','D3N2','D1FI'] and int(Deriv[1])<=BF2.Deg), "Arg Deriv must be a int or a str !" - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - - if Deriv=='D0': - m = 0 - if BF2.Deg==0: - Supp = BF2._get_Func_SuppBounds() - if Mode=='Surf': - A = (Supp[1,:]-Supp[0,:]) * (Supp[3,:]-Supp[2,:]) - else: - A = 0.5*(Supp[1,:]**2-Supp[0,:]**2) * (Supp[3,:]-Supp[2,:]) - elif BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - if Mode=='Surf': - A = 0.25*(Supp[1,:]-Supp[0,:])*(Supp[3,:]-Supp[2,:]) - else: - QuadR, QuadZ = BF2._get_quadPoints() - A = 0.5*(QuadR[2,:]**2-QuadR[0,:]**2 + QuadR[1,:]*(QuadR[2,:]-QuadR[0,:])) * (Supp[3,:]-Supp[2,:])/6. - elif BF2.Deg==2: - QR, QZ = BF2._get_quadPoints() - - IntZ1 = (QZ[1,:]-QZ[0,:])**2/(3.*(QZ[2,:]-QZ[0,:])) - IntZ21 = (QZ[2,:]**2 -2*QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[0,:]*(QZ[1,:]-QZ[2,:]))/(6*(QZ[2,:]-QZ[0,:])) - IntZ22 = (-2.*QZ[2,:]**2+QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[3,:]*(QZ[2,:]-QZ[1,:]))/(6.*(QZ[3,:]-QZ[1,:])) - IntZ3 = (QZ[3,:]-QZ[2,:])**2/(3.*(QZ[3,:]-QZ[1,:])) - IntZ = IntZ1+IntZ21+IntZ22+IntZ3 - - if Mode=='Surf': - IntR1 = (QR[1,:]-QR[0,:])**2/(3.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**2 -2.*QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[0,:]*(QR[1,:]-QR[2,:]))/(6*(QR[2,:]-QR[0,:])) - IntR22 = (-2.*QR[2,:]**2+QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[3,:]*(QR[2,:]-QR[1,:]))/(6.*(QR[3,:]-QR[1,:])) - IntR3 = (QR[3,:]-QR[2,:])**2/(3.*(QR[3,:]-QR[1,:])) - else: - IntR1 = (3.*QR[1,:]**3+QR[0,:]**3 -5.*QR[0,:]*QR[1,:]**2+QR[0,:]**2*QR[1,:])/(12.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**3 -3.*QR[1,:]**3+QR[1,:]**2*QR[2,:]+QR[1,:]*QR[2,:]**2 -2.*QR[0,:]*QR[2,:]**2 -2.*QR[0,:]*QR[1,:]*QR[2,:] +4.*QR[0,:]*QR[1,:]**2)/(12.*(QR[2,:]-QR[0,:])) - IntR22 = ( -3.*QR[2,:]**3+QR[1,:]**3+QR[1,:]*QR[2,:]**2+QR[1,:]**2*QR[2,:]+4.*QR[2,:]**2*QR[3,:]-2.*QR[1,:]*QR[2,:]*QR[3,:]-2.*QR[1,:]**2*QR[3,:] )/(12.*(QR[3,:]-QR[1,:])) - IntR3 = ( QR[3,:]**3 +3.*QR[2,:]**3 -5.*QR[2,:]**2*QR[3,:]+QR[2,:]*QR[3,:]**2)/(12.*(QR[3,:]-QR[1,:])) - IntR = IntR1+IntR21+IntR22+IntR3 - A = IntR*IntZ - elif BF2.Deg==3: - print "NOT CODED YET !" - A = 0 - - elif Deriv=='D0N2': - m = 1 - if BF2.Deg==0: - Supp = BF2._get_Func_SuppBounds() - if Mode=='Surf': - A = scpsp.diags([(Supp[1,:]-Supp[0,:]) * (Supp[3,:]-Supp[2,:])],[0],shape=None,format=SpaFormat) - else: - A = scpsp.diags([0.5*(Supp[1,:]**2-Supp[0,:]**2) * (Supp[3,:]-Supp[2,:])],[0],shape=None,format=SpaFormat) - elif BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - if Mode=='Surf': - d0R, d0Z = (Supp[1,:]-Supp[0,:])/3., (Supp[3,:]-Supp[2,:])/3. - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intR = (kR[1]-kR[0])/6. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZ = (kZ[1]-kZ[0])/6. - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - else: - d0R, d0Z = (QR[2,:]**2-QR[0,:]**2 + 2.*QR[1,:]*(QR[2,:]-QR[0,:]))/12., (Supp[3,:]-Supp[2,:])/3. - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intR = (kR[1]**2-kR[0]**2)/12. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZ = (kZ[1]-kZ[0])/6. - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - A = scpsp.vstack(LL,format='csr') - elif BF2.Deg==2: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - if Mode=='Surf': - d0R21 = (QR[2,:]-QR[1,:])*(10.*QR[0,:]**2+6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2 - 5.*QR[0,:]*(3.*QR[1,:]+QR[2,:]))/(30.*(QR[2,:]-QR[0,:])**2) - d0R22 = (QR[2,:]-QR[1,:])*(10.*QR[3,:]**2+6.*QR[2,:]**2+3.*QR[1,:]*QR[2,:]+QR[1,:]**2 - 5.*QR[3,:]*(3.*QR[2,:]+QR[1,:]))/(30.*(QR[3,:]-QR[1,:])**2) - d0R23 = ( 3.*QR[1,:]**2 + 4.*QR[1,:]*QR[2,:] + 3.*QR[2,:]**2 - 5.*QR[0,:]*(QR[1,:]+QR[2,:]-2.*QR[3,:]) -5.*QR[3,:]*(QR[1,:]+QR[2,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (QR[1,:]-QR[0,:])**3/(5.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (QR[3,:]-QR[2,:])**3/(5.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intR = (QR[1,ii]-QR[0,ii])**3/(30.*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR = ( 6.*QR[1,ii]**2 - QR[0,ii]*(9.*QR[1,ii]+QR[2,ii]-10.*QR[3,ii]) + QR[2,ii]*(QR[2,ii]-4.*QR[3,ii]) +3.*QR[1,ii]*(QR[2,ii]-2.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) + ( QR[0,ii]**2 + 3.*QR[0,ii]*QR[1,ii] + 6.*QR[1,ii]**2 - 2.*QR[0,Ind[jj]]*(2.*QR[0,ii]+3.*QR[1,ii] - 5.*QR[2,ii]) - QR[0,ii]*QR[2,ii] -9.*QR[1,ii]*QR[2,ii] )*(QR[1,ii]-QR[0,ii])**2/(30.*(QR[0,Ind[jj]]-QR[2,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intR = (QR[3,ii]-QR[2,ii])**3/(30.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR = ( 6.*QR[2,ii]**2 - QR[1,ii]*(9.*QR[2,ii]+QR[3,ii]-10.*QR[3,Ind[jj]]) + QR[3,ii]*(QR[3,ii]-4.*QR[3,Ind[jj]]) +3.*QR[2,ii]*(QR[3,ii]-2.*QR[3,Ind[jj]]) )*(QR[3,ii]-QR[2,ii])**2/(30.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) + ( QR[1,ii]**2 + 3.*QR[1,ii]*QR[2,ii] + 6.*QR[2,ii]**2 - 2.*QR[0,ii]*(2.*QR[1,ii]+3.*QR[2,ii] - 5.*QR[3,ii]) - QR[1,ii]*QR[3,ii] -9.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[0,ii]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZ = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZ = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZ = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZ = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - A = scpsp.vstack(LL,format='csr') - - elif Mode=='Vol': - d0R21 = (10*QR[1,:]**3 + 6.*QR[1,:]**2*QR[2,:] + 3.*QR[1,:]*QR[2,:]**2 + QR[2,:]**3 + 5.*QR[0,:]**2*(3.*QR[1,:]+QR[2,:]) - 4.*QR[0,:]*(6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[2,:]-QR[0,:])**2) - d0R22 = (10*QR[2,:]**3 + 6.*QR[2,:]**2*QR[1,:] + 3.*QR[2,:]*QR[1,:]**2 + QR[1,:]**3 + 5.*QR[3,:]**2*(3.*QR[2,:]+QR[1,:]) - 4.*QR[3,:]*(6.*QR[2,:]**2+3.*QR[2,:]*QR[1,:]+QR[1,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[3,:]-QR[1,:])**2) - d0R23 = (2.*QR[1,:]**3 + QR[1,:]*QR[2,:]*(3.*QR[2,:]-4.*QR[3,:]) +(2.*QR[2,:]-3.*QR[3,:])*QR[2,:]**2 +3.*(QR[2,:]-QR[3,:])*QR[1,:]**2 + QR[0,:]*(-3.*QR[1,:]**2-4.*QR[1,:]*QR[2,:]-3.*QR[2,:]**2+5.*QR[1,:]*QR[3,:]+5.*QR[2,:]*QR[3,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[3,:]-QR[1,:])*(QR[2,:]-QR[0,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (5.*QR[1,:]+QR[0,:])*(QR[1,:]-QR[0,:])**3/(30.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (5.*QR[2,:]+QR[3,:])*(QR[3,:]-QR[2,:])**3/(30.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intR = (QR[1,ii]+QR[0,ii])*(QR[1,ii]-QR[0,ii])**3/(60.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR1A = ( -2.*QR[0,Ind[jj]]*QR[0,ii] + QR[0,ii]**2 - 3.*QR[0,Ind[jj]]*QR[1,ii] + 2.*QR[0,ii]*QR[1,ii] + 2.*QR[1,ii]**2 )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intR1B = - ( QR[0,ii]**2 + 2.*QR[1,ii]*(5.*QR[1,ii]-6.*QR[2,ii]) + QR[0,ii]*(4.*QR[1,ii]-3.*QR[2,ii]) )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2A = ( 10.*QR[1,ii]**2 + 4.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[0,ii]*(4.*QR[1,ii]+QR[2,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2B = - ( 2.*QR[1,ii]**2 + 2.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[1,ii]*QR[3,ii] -2.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR = intR1A + intR1B + intR2A + intR2B - - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intR = (QR[3,ii]+QR[2,ii])*(QR[3,ii]-QR[2,ii])**3/(60.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR1A = ( -2.*QR[0,ii]*QR[1,ii] + QR[1,ii]**2 - 3.*QR[0,ii]*QR[2,ii] + 2.*QR[1,ii]*QR[2,ii] + 2.*QR[2,ii]**2 )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR1B = - ( QR[1,ii]**2 + 2.*QR[2,ii]*(5.*QR[2,ii]-6.*QR[3,ii]) + QR[1,ii]*(4.*QR[2,ii]-3.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2A = ( 10.*QR[2,ii]**2 + 4.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[1,ii]*(4.*QR[2,ii]+QR[3,ii]) )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2B = - ( 2.*QR[2,ii]**2 + 2.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[2,ii]*QR[3,Ind[jj]] -2.*QR[3,ii]*QR[3,Ind[jj]] )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])*(QR[3,Ind[jj]]-QR[2,ii])) - intR = intR1A + intR1B + intR2A + intR2B - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZ = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZ = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZ = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZ = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - A = scpsp.vstack(LL,format='csr') - - elif Deriv=='D1N2': - m = 2 - if BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - - if Mode=='Surf': - d0R, d0Z = (Supp[1,:]-Supp[0,:])/3., (Supp[3,:]-Supp[2,:])/3. - d0DR, d0DZ = (QR[2,:]-QR[0,:])/((QR[2,:]-QR[1,:])*(QR[1,:]-QR[0,:])), (QZ[2,:]-QZ[0,:])/((QZ[2,:]-QZ[1,:])*(QZ[1,:]-QZ[0,:])) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDR = d0DR[ii] - intRDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intRDR = -1./(kR[1]-kR[0]) - intRDZ = (kR[1]-kR[0])/6. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZDR = (kZ[1]-kZ[0])/6. - intZDZ = -1./(kZ[1]-kZ[0]) - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - else: - d0R, d0Z = (QR[2,:]**2-QR[0,:]**2 + 2.*QR[1,:]*(QR[2,:]-QR[0,:]))/12., (Supp[3,:]-Supp[2,:])/3. - d0DR, d0DZ = 0.5*(QR[1,:]+QR[0,:])/(QR[1,:]-QR[0,:]) + 0.5*(QR[2,:]+QR[1,:])/(QR[2,:]-QR[1,:]), (QZ[2,:]-QZ[0,:])/((QZ[2,:]-QZ[1,:])*(QZ[1,:]-QZ[0,:])) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDR = d0DR[ii] - intRDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intRDR = -0.5*(kR[1]+kR[0])/(kR[1]-kR[0]) - intRDZ = (kR[1]**2-kR[0]**2)/12. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZDR = (kZ[1]-kZ[0])/6. - intZDZ = -1./(kZ[1]-kZ[0]) - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - AR, AZ = scpsp.vstack(LLR,format='csr'), scpsp.vstack(LLZ,format='csr') - A = (AR,AZ) - - elif BF2.Deg==2: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - if Mode=='Surf': - d0R21 = (QR[2,:]-QR[1,:])*(10.*QR[0,:]**2+6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2 - 5.*QR[0,:]*(3.*QR[1,:]+QR[2,:]))/(30.*(QR[2,:]-QR[0,:])**2) - d0R22 = (QR[2,:]-QR[1,:])*(10.*QR[3,:]**2+6.*QR[2,:]**2+3.*QR[1,:]*QR[2,:]+QR[1,:]**2 - 5.*QR[3,:]*(3.*QR[2,:]+QR[1,:]))/(30.*(QR[3,:]-QR[1,:])**2) - d0R23 = ( 3.*QR[1,:]**2 + 4.*QR[1,:]*QR[2,:] + 3.*QR[2,:]**2 - 5.*QR[0,:]*(QR[1,:]+QR[2,:]-2.*QR[3,:]) -5.*QR[3,:]*(QR[1,:]+QR[2,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (QR[1,:]-QR[0,:])**3/(5.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (QR[3,:]-QR[2,:])**3/(5.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DR = 4.*(QR[1,:]-QR[0,:])/(3.*(QR[2,:]-QR[0,:])**2) + 4.*( QR[0,:]**2 + QR[1,:]**2 + QR[2,:]**2 + (QR[2,:]-2.*QR[3,:])*QR[1,:] - QR[2,:]*QR[3,:] + QR[3,:]**2 + (-QR[1,:]-2.*QR[2,:]+QR[3,:])*QR[0,:] )*(QR[2,:]-QR[1,:])/(3.*(QR[2,:]-QR[0,:])**2*(QR[3,:]-QR[1,:])**2) + 4.*(QR[3,:]-QR[2,:])/(3.*(QR[3,:]-QR[1,:])**2) - d0DZ = 4.*(QZ[1,:]-QZ[0,:])/(3.*(QZ[2,:]-QZ[0,:])**2) + 4.*( QZ[0,:]**2 + QZ[1,:]**2 + QZ[2,:]**2 + (QZ[2,:]-2.*QZ[3,:])*QZ[1,:] - QZ[2,:]*QZ[3,:] + QZ[3,:]**2 + (-QZ[1,:]-2.*QZ[2,:]+QZ[3,:])*QZ[0,:] )*(QZ[2,:]-QZ[1,:])/(3.*(QZ[2,:]-QZ[0,:])**2*(QZ[3,:]-QZ[1,:])**2) + 4.*(QZ[3,:]-QZ[2,:])/(3.*(QZ[3,:]-QZ[1,:])**2) - - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDZ = d0R[ii] - intRDR = d0DR[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDZ = (QR[1,ii]-QR[0,ii])**3/(30.*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - intRDR = 2.*(QR[0,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intRDZ = ( 6.*QR[1,ii]**2 - QR[0,ii]*(9.*QR[1,ii]+QR[2,ii]-10.*QR[3,ii]) + QR[2,ii]*(QR[2,ii]-4.*QR[3,ii]) +3.*QR[1,ii]*(QR[2,ii]-2.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) + ( QR[0,ii]**2 + 3.*QR[0,ii]*QR[1,ii] + 6.*QR[1,ii]**2 - 2.*QR[0,Ind[jj]]*(2.*QR[0,ii]+3.*QR[1,ii] - 5.*QR[2,ii]) - QR[0,ii]*QR[2,ii] -9.*QR[1,ii]*QR[2,ii] )*(QR[1,ii]-QR[0,ii])**2/(30.*(QR[0,Ind[jj]]-QR[2,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - intRDR = 2.*(2.*QR[0,Ind[jj]]-QR[0,ii]-2.*QR[1,ii]+QR[2,ii])*(QR[1,ii]-QR[0,ii])/(3.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) + 2.*(QR[0,ii]-2.*QR[1,ii]-QR[2,ii]+2.*QR[3,ii])*(QR[2,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDZ = (QR[3,ii]-QR[2,ii])**3/(30.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - intRDR = 2.*(QR[2,ii]-QR[3,ii])/(3.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intRDZ = ( 6.*QR[2,ii]**2 - QR[1,ii]*(9.*QR[2,ii]+QR[3,ii]-10.*QR[3,Ind[jj]]) + QR[3,ii]*(QR[3,ii]-4.*QR[3,Ind[jj]]) +3.*QR[2,ii]*(QR[3,ii]-2.*QR[3,Ind[jj]]) )*(QR[3,ii]-QR[2,ii])**2/(30.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) + ( QR[1,ii]**2 + 3.*QR[1,ii]*QR[2,ii] + 6.*QR[2,ii]**2 - 2.*QR[0,ii]*(2.*QR[1,ii]+3.*QR[2,ii] - 5.*QR[3,ii]) - QR[1,ii]*QR[3,ii] -9.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[0,ii]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - intRDR = 2.*(2.*QR[0,ii]-QR[1,ii]-2.*QR[2,ii]+QR[3,ii])*(QR[2,ii]-QR[1,ii])/(3.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) + 2.*(QR[1,ii]-2.*QR[2,ii]-QR[3,ii]+2.*QR[3,Ind[jj]])*(QR[3,ii]-QR[2,ii])/(3.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDZ = 2.*(QZ[0,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[1,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - intZDZ = 2.*(2.*QZ[0,Ind[jj]]-QZ[0,ii]-2.*QZ[1,ii]+QZ[2,ii])*(QZ[1,ii]-QZ[0,ii])/(3.*(QZ[1,ii]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) + 2.*(QZ[0,ii]-2.*QZ[1,ii]-QZ[2,ii]+2.*QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDZ = 2.*(QZ[2,ii]-QZ[3,ii])/(3.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[2,ii])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDZ = 2.*(2.*QZ[0,ii]-QZ[1,ii]-2.*QZ[2,ii]+QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) + 2.*(QZ[1,ii]-2.*QZ[2,ii]-QZ[3,ii]+2.*QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[2,ii])/(3.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - elif Mode=='Vol': - d0R21 = (10*QR[1,:]**3 + 6.*QR[1,:]**2*QR[2,:] + 3.*QR[1,:]*QR[2,:]**2 + QR[2,:]**3 + 5.*QR[0,:]**2*(3.*QR[1,:]+QR[2,:]) - 4.*QR[0,:]*(6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[2,:]-QR[0,:])**2) - d0R22 = (10*QR[2,:]**3 + 6.*QR[2,:]**2*QR[1,:] + 3.*QR[2,:]*QR[1,:]**2 + QR[1,:]**3 + 5.*QR[3,:]**2*(3.*QR[2,:]+QR[1,:]) - 4.*QR[3,:]*(6.*QR[2,:]**2+3.*QR[2,:]*QR[1,:]+QR[1,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[3,:]-QR[1,:])**2) - d0R23 = (2.*QR[1,:]**3 + QR[1,:]*QR[2,:]*(3.*QR[2,:]-4.*QR[3,:]) +(2.*QR[2,:]-3.*QR[3,:])*QR[2,:]**2 +3.*(QR[2,:]-QR[3,:])*QR[1,:]**2 + QR[0,:]*(-3.*QR[1,:]**2-4.*QR[1,:]*QR[2,:]-3.*QR[2,:]**2+5.*QR[1,:]*QR[3,:]+5.*QR[2,:]*QR[3,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[3,:]-QR[1,:])*(QR[2,:]-QR[0,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (5.*QR[1,:]+QR[0,:])*(QR[1,:]-QR[0,:])**3/(30.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (5.*QR[2,:]+QR[3,:])*(QR[3,:]-QR[2,:])**3/(30.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DR = (QR[1,:]-QR[0,:])*(QR[0,:]+3.*QR[1,:])/(3.*(QR[2,:]-QR[0,:])**2) + ( (3.*QR[1,:]+QR[2,:])/(QR[2,:]-QR[0,:])**2 + (QR[1,:]+3.*QR[2,:])/(QR[3,:]-QR[1,:])**2 - 2.*(QR[1,:]+QR[2,:])/((QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) )*(QR[2,:]-QR[1,:])/3. + (QR[3,:]-QR[2,:])*(QR[3,:]+3.*QR[2,:])/(3.*(QR[3,:]-QR[1,:])**2) - d0DZ = 4.*(QZ[1,:]-QZ[0,:])/(3.*(QZ[2,:]-QZ[0,:])**2) + 4.*( QZ[0,:]**2 + QZ[1,:]**2 + QZ[2,:]**2 + (QZ[2,:]-2.*QZ[3,:])*QZ[1,:] - QZ[2,:]*QZ[3,:] + QZ[3,:]**2 + (-QZ[1,:]-2.*QZ[2,:]+QZ[3,:])*QZ[0,:] )*(QZ[2,:]-QZ[1,:])/(3.*(QZ[2,:]-QZ[0,:])**2*(QZ[3,:]-QZ[1,:])**2) + 4.*(QZ[3,:]-QZ[2,:])/(3.*(QZ[3,:]-QZ[1,:])**2) - - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDZ = d0R[ii] - intRDR = d0DR[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDZ = (QR[1,ii]+QR[0,ii])*(QR[1,ii]-QR[0,ii])**3/(60.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intRDR = (QR[0,ii]+QR[1,ii])*(QR[0,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR1A = ( -2.*QR[0,Ind[jj]]*QR[0,ii] + QR[0,ii]**2 - 3.*QR[0,Ind[jj]]*QR[1,ii] + 2.*QR[0,ii]*QR[1,ii] + 2.*QR[1,ii]**2 )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intR1B = - ( QR[0,ii]**2 + 2.*QR[1,ii]*(5.*QR[1,ii]-6.*QR[2,ii]) + QR[0,ii]*(4.*QR[1,ii]-3.*QR[2,ii]) )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2A = ( 10.*QR[1,ii]**2 + 4.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[0,ii]*(4.*QR[1,ii]+QR[2,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2B = - ( 2.*QR[1,ii]**2 + 2.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[1,ii]*QR[3,ii] -2.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intRDZ = intR1A + intR1B + intR2A + intR2B - intRDR = ( -QR[0,ii]**2 + (QR[0,ii]+3.*QR[1,ii])*QR[0,Ind[jj]] + (-3.*QR[1,ii]+QR[2,ii])*QR[1,ii] +(-2.*QR[1,ii]+QR[2,ii])*QR[0,ii] )*(QR[1,ii]-QR[0,ii])/(3.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) + ( -3.*QR[1,ii]**2 + (QR[1,ii]+QR[2,ii])*QR[0,ii] + (-QR[2,ii]+QR[3,ii])*QR[2,ii] + (-2.*QR[2,ii]+3.*QR[3,ii])*QR[1,ii] )*(QR[2,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDZ = (QR[3,ii]+QR[2,ii])*(QR[3,ii]-QR[2,ii])**3/(60.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - intRDR = (QR[2,ii]+QR[3,ii])*(QR[2,ii]-QR[3,ii])/(3.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR1A = ( -2.*QR[0,ii]*QR[1,ii] + QR[1,ii]**2 - 3.*QR[0,ii]*QR[2,ii] + 2.*QR[1,ii]*QR[2,ii] + 2.*QR[2,ii]**2 )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR1B = - ( QR[1,ii]**2 + 2.*QR[2,ii]*(5.*QR[2,ii]-6.*QR[3,ii]) + QR[1,ii]*(4.*QR[2,ii]-3.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2A = ( 10.*QR[2,ii]**2 + 4.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[1,ii]*(4.*QR[2,ii]+QR[3,ii]) )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2B = - ( 2.*QR[2,ii]**2 + 2.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[2,ii]*QR[3,Ind[jj]] -2.*QR[3,ii]*QR[3,Ind[jj]] )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])*(QR[3,Ind[jj]]-QR[2,ii])) - intRDZ = intR1A + intR1B + intR2A + intR2B - intRDR = ( -QR[1,ii]**2 + (QR[1,ii]+3.*QR[2,ii])*QR[0,ii] + (-3.*QR[2,ii]+QR[3,ii])*QR[2,ii] +(-2.*QR[2,ii]+QR[3,ii])*QR[1,ii] )*(QR[2,ii]-QR[1,ii])/(3.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) + ( -3.*QR[2,ii]**2 + (QR[2,ii]+QR[3,ii])*QR[1,ii] + (-QR[3,ii]+QR[3,Ind[jj]])*QR[3,ii] + (-2.*QR[3,ii]+3.*QR[3,Ind[jj]])*QR[2,ii] )*(QR[3,ii]-QR[2,ii])/(3.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDZ = 2.*(QZ[0,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[1,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - intZDZ = 2.*(2.*QZ[0,Ind[jj]]-QZ[0,ii]-2.*QZ[1,ii]+QZ[2,ii])*(QZ[1,ii]-QZ[0,ii])/(3.*(QZ[1,ii]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) + 2.*(QZ[0,ii]-2.*QZ[1,ii]-QZ[2,ii]+2.*QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDZ = 2.*(QZ[2,ii]-QZ[3,ii])/(3.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[2,ii])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDZ = 2.*(2.*QZ[0,ii]-QZ[1,ii]-2.*QZ[2,ii]+QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) + 2.*(QZ[1,ii]-2.*QZ[2,ii]-QZ[3,ii]+2.*QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[2,ii])/(3.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - AR, AZ = scpsp.vstack(LLR,format='csr'), scpsp.vstack(LLZ,format='csr') - A = (AR,AZ) - - - elif Deriv=='D1FI': - m = 3 - if BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - - - - - elif 'D2N2' in Deriv: - m = 2 - if BF2.Deg==2: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - - if Mode=='Surf': - d0R21 = (QR[2,:]-QR[1,:])*(10.*QR[0,:]**2+6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2 - 5.*QR[0,:]*(3.*QR[1,:]+QR[2,:]))/(30.*(QR[2,:]-QR[0,:])**2) - d0R22 = (QR[2,:]-QR[1,:])*(10.*QR[3,:]**2+6.*QR[2,:]**2+3.*QR[1,:]*QR[2,:]+QR[1,:]**2 - 5.*QR[3,:]*(3.*QR[2,:]+QR[1,:]))/(30.*(QR[3,:]-QR[1,:])**2) - d0R23 = ( 3.*QR[1,:]**2 + 4.*QR[1,:]*QR[2,:] + 3.*QR[2,:]**2 - 5.*QR[0,:]*(QR[1,:]+QR[2,:]-2.*QR[3,:]) -5.*QR[3,:]*(QR[1,:]+QR[2,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (QR[1,:]-QR[0,:])**3/(5.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (QR[3,:]-QR[2,:])**3/(5.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DDR = 4./((QR[1,:]-QR[0,:])*(QR[2,:]-QR[0,:])**2) + 4.*(QR[3,:]+QR[2,:]-QR[1,:]-QR[0,:])**2/((QR[2,:]-QR[1,:])*(QR[3,:]-QR[1,:])**2*(QR[2,:]-QR[0,:])**2) + 4./((QR[3,:]-QR[2,:])*(QR[3,:]-QR[1,:])**2) - d0DDZ = 4./((QZ[1,:]-QZ[0,:])*(QZ[2,:]-QZ[0,:])**2) + 4.*(QZ[3,:]+QZ[2,:]-QZ[1,:]-QZ[0,:])**2/((QZ[2,:]-QZ[1,:])*(QZ[3,:]-QZ[1,:])**2*(QZ[2,:]-QZ[0,:])**2) + 4./((QZ[3,:]-QZ[2,:])*(QZ[3,:]-QZ[1,:])**2) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDDR = d0DDR[ii] - intRDDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDDR = 4./((kR[1]-kR[0])*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - intRDDZ = (QR[1,ii]-QR[0,ii])**3/(30.*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intRDDR = -4.*(QR[2,ii]+QR[1,ii]-QR[1,Ind[jj]]-QR[0,Ind[jj]])/((QR[2,Ind[jj]]-QR[1,Ind[jj]])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - 4.*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[3,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])**2) - intRDDZ = ( 6.*QR[1,ii]**2 - QR[0,ii]*(9.*QR[1,ii]+QR[2,ii]-10.*QR[3,ii]) + QR[2,ii]*(QR[2,ii]-4.*QR[3,ii]) +3.*QR[1,ii]*(QR[2,ii]-2.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) + ( QR[0,ii]**2 + 3.*QR[0,ii]*QR[1,ii] + 6.*QR[1,ii]**2 - 2.*QR[0,Ind[jj]]*(2.*QR[0,ii]+3.*QR[1,ii] - 5.*QR[2,ii]) - QR[0,ii]*QR[2,ii] -9.*QR[1,ii]*QR[2,ii] )*(QR[1,ii]-QR[0,ii])**2/(30.*(QR[0,Ind[jj]]-QR[2,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDDR = 4./((kR[1]-kR[0])*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - intRDDZ = (QR[3,ii]-QR[2,ii])**3/(30.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intRDDR = -4.*(QR[3,Ind[jj]]+QR[2,Ind[jj]]-QR[2,ii]-QR[1,ii])/((QR[3,ii]-QR[2,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) - 4.*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) - intRDDZ = ( 6.*QR[2,ii]**2 - QR[1,ii]*(9.*QR[2,ii]+QR[3,ii]-10.*QR[3,Ind[jj]]) + QR[3,ii]*(QR[3,ii]-4.*QR[3,Ind[jj]]) +3.*QR[2,ii]*(QR[3,ii]-2.*QR[3,Ind[jj]]) )*(QR[3,ii]-QR[2,ii])**2/(30.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) + ( QR[1,ii]**2 + 3.*QR[1,ii]*QR[2,ii] + 6.*QR[2,ii]**2 - 2.*QR[0,ii]*(2.*QR[1,ii]+3.*QR[2,ii] - 5.*QR[3,ii]) - QR[1,ii]*QR[3,ii] -9.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[0,ii]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common knots..." - - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDDR = d0Z[ii] - intZDDZ = d0DDZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDDZ = -4.*(QZ[2,ii]+QZ[1,ii]-QZ[1,Ind[jj]]-QZ[0,Ind[jj]])/((QZ[2,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])**2) - intZDDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDDZ = -4.*(QZ[3,Ind[jj]]+QZ[2,Ind[jj]]-QZ[2,ii]-QZ[1,ii])/((QZ[3,ii]-QZ[2,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common knots..." - - llR[0,Ind[jj]] = intRDDR*intZDDR - llZ[0,Ind[jj]] = intRDDZ*intZDDZ - llR[0,ii] = d0DDR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DDZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - elif Mode=='Vol': - d0R21 = (10*QR[1,:]**3 + 6.*QR[1,:]**2*QR[2,:] + 3.*QR[1,:]*QR[2,:]**2 + QR[2,:]**3 + 5.*QR[0,:]**2*(3.*QR[1,:]+QR[2,:]) - 4.*QR[0,:]*(6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[2,:]-QR[0,:])**2) - d0R22 = (10*QR[2,:]**3 + 6.*QR[2,:]**2*QR[1,:] + 3.*QR[2,:]*QR[1,:]**2 + QR[1,:]**3 + 5.*QR[3,:]**2*(3.*QR[2,:]+QR[1,:]) - 4.*QR[3,:]*(6.*QR[2,:]**2+3.*QR[2,:]*QR[1,:]+QR[1,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[3,:]-QR[1,:])**2) - d0R23 = (2.*QR[1,:]**3 + QR[1,:]*QR[2,:]*(3.*QR[2,:]-4.*QR[3,:]) +(2.*QR[2,:]-3.*QR[3,:])*QR[2,:]**2 +3.*(QR[2,:]-QR[3,:])*QR[1,:]**2 + QR[0,:]*(-3.*QR[1,:]**2-4.*QR[1,:]*QR[2,:]-3.*QR[2,:]**2+5.*QR[1,:]*QR[3,:]+5.*QR[2,:]*QR[3,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[3,:]-QR[1,:])*(QR[2,:]-QR[0,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (5.*QR[1,:]+QR[0,:])*(QR[1,:]-QR[0,:])**3/(30.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (5.*QR[2,:]+QR[3,:])*(QR[3,:]-QR[2,:])**3/(30.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DDR = 2.*(QR[1,:]+QR[0,:])/((QR[1,:]-QR[0,:])*(QR[2,:]-QR[0,:])**2) + 2.*(QR[2,:]+QR[1,:])*(QR[3,:]+QR[2,:]-QR[1,:]-QR[0,:])**2/((QR[2,:]-QR[1,:])*(QR[3,:]-QR[1,:])**2*(QR[2,:]-QR[0,:])**2) + 2.*(QR[3,:]+QR[2,:])/((QR[3,:]-QR[2,:])*(QR[3,:]-QR[1,:])**2) - d0DDZ = 4./((QZ[1,:]-QZ[0,:])*(QZ[2,:]-QZ[0,:])**2) + 4.*(QZ[3,:]+QZ[2,:]-QZ[1,:]-QZ[0,:])**2/((QZ[2,:]-QZ[1,:])*(QZ[3,:]-QZ[1,:])**2*(QZ[2,:]-QZ[0,:])**2) + 4./((QZ[3,:]-QZ[2,:])*(QZ[3,:]-QZ[1,:])**2) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - Ind = np.asarray([int(xxx) for xxx in Ind], dtype=int) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDDR = d0DDR[ii] - intRDDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDDR = 2.*(kR[1]+kR[0])/((kR[1]-kR[0])*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - intRDDZ = (QR[1,ii]+QR[0,ii])*(QR[1,ii]-QR[0,ii])**3/(60.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR1A = ( -2.*QR[0,Ind[jj]]*QR[0,ii] + QR[0,ii]**2 - 3.*QR[0,Ind[jj]]*QR[1,ii] + 2.*QR[0,ii]*QR[1,ii] + 2.*QR[1,ii]**2 )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intR1B = - ( QR[0,ii]**2 + 2.*QR[1,ii]*(5.*QR[1,ii]-6.*QR[2,ii]) + QR[0,ii]*(4.*QR[1,ii]-3.*QR[2,ii]) )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2A = ( 10.*QR[1,ii]**2 + 4.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[0,ii]*(4.*QR[1,ii]+QR[2,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2B = - ( 2.*QR[1,ii]**2 + 2.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[1,ii]*QR[3,ii] -2.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intRDDZ = intR1A + intR1B + intR2A + intR2B - intRDDR = -2.*(QR[1,ii]+QR[0,ii])*(QR[2,ii]+QR[1,ii]-QR[0,ii]-QR[0,Ind[jj]])/((QR[1,ii]-QR[0,ii])*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - 2.*(QR[2,ii]+QR[1,ii])*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[3,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDDR = 2.*(kR[1]+kR[0])/((kR[1]-kR[0])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])*(QR[3,ii]-QR[1,ii])) - intRDDZ = (QR[3,ii]+QR[2,ii])*(QR[3,ii]-QR[2,ii])**3/(60.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR1A = ( -2.*QR[0,ii]*QR[1,ii] + QR[1,ii]**2 - 3.*QR[0,ii]*QR[2,ii] + 2.*QR[1,ii]*QR[2,ii] + 2.*QR[2,ii]**2 )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR1B = - ( QR[1,ii]**2 + 2.*QR[2,ii]*(5.*QR[2,ii]-6.*QR[3,ii]) + QR[1,ii]*(4.*QR[2,ii]-3.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2A = ( 10.*QR[2,ii]**2 + 4.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[1,ii]*(4.*QR[2,ii]+QR[3,ii]) )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2B = - ( 2.*QR[2,ii]**2 + 2.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[2,ii]*QR[3,Ind[jj]] -2.*QR[3,ii]*QR[3,Ind[jj]] )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])*(QR[3,Ind[jj]]-QR[2,ii])) - intRDDZ = intR1A + intR1B + intR2A + intR2B - intRDDR = -2.*(QR[2,ii]+QR[1,ii])*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) - 2.*(QR[3,ii]+QR[2,ii])*(QR[3,Ind[jj]]+QR[3,ii]-QR[2,ii]-QR[1,ii])/((QR[3,ii]-QR[2,ii])*(QR[3,Ind[jj]]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common knots..." - - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDDR = d0Z[ii] - intZDDZ = d0DDZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDDZ = -4.*(QZ[2,ii]+QZ[1,ii]-QZ[1,Ind[jj]]-QZ[0,Ind[jj]])/((QZ[2,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])**2) - intZDDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDDZ = -4.*(QZ[3,Ind[jj]]+QZ[2,Ind[jj]]-QZ[2,ii]-QZ[1,ii])/((QZ[3,ii]-QZ[2,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common knots..." - - llR[0,Ind[jj]] = intRDDR*intZDDR - llZ[0,Ind[jj]] = intRDDZ*intZDDZ - llR[0,ii] = d0DDR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DDZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - AR, AZ = scpsp.vstack(LLR,format='csr'), scpsp.vstack(LLZ,format='csr') - A = (AR,AZ) - - if not Sparse: - if m in [0,1]: - A = A.toarray() - elif m==2: - A = (A[0].toarray(),A[1].toarray()) - - return A, m - - - - - - - - - - - - - - - - - - - -def Calc_BF2D_DerivFunc(BF2, Deriv, Test=True): - if Test: - assert isinstance(BF2, BF2D), "Arg BF2 must be a MeshBase2D instance !" - assert type(Deriv) is int, "Arg Deriv must be a int !" - - KnR, KnZ = BF2._get_quadPoints() - if Deriv==1: - LFuncR, LFuncZ = [], [] - for ii in range(0,BF2.NFunc): - LFuncR.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=0, Test=False)[0](X[1,:])*BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=Deriv, Test=False)[0](X[0,:])) - LFuncZ.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=0, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=Deriv, Test=False)[0](X[1,:])) - return LFuncR, LFuncZ - elif Deriv==2: - # Formulas for Gauss and Mean curvature were found on http://en.wikipedia.org/wiki/Differential_geometry_of_surfaces - DRR, DRZ, DZZ = [], [], [] - for ii in range(0,BF2.NFunc): - DRR.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=Deriv, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=0, Test=False)[0](X[1,:])) - DRZ.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=1, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=1, Test=False)[0](X[1,:])) - DZZ.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=0, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=Deriv, Test=False)[0](X[1,:])) - return DRR, DRZ, DZZ - - - - -def Get_MinMax(BF2, Coefs=1., Ratio=0.05, SubP=0.004, SubP1=0.015, SubP2=0.001, TwoSteps=False, SubMode='abs', Deriv='D0', Margin=0.2, Test=True): - assert Ratio is None or (type(Ratio) is float and Ratio>0 and Ratio<1), "Arg Ratio must be None or a float in ]0;1[ !" - if TwoSteps: - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP1, SubMode='abs', Test=Test) - else: - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP, SubMode='abs', Test=Test) - nx, ny = X.size, Y.size - dS = np.mean(np.diff(X))*np.mean(np.diff(Y)) - Xplot, Yplot = np.tile(X,(ny,1)), np.tile(Y,(nx,1)).T - Points = np.array([Xplot.flatten(), Yplot.flatten()]) - Vals = BF2.get_TotVal(Points, Deriv=Deriv, Coefs=Coefs, Test=Test) - - def getminmaxRatioFloat(valsmax, valsmin, indmax, indmin, Ratio, Ptsmin, Ptsmax): - DV = valsmax[indmax]-valsmin[indmin] - imin, imax = valsmin<=valsmin[indmin]+Ratio*DV, valsmax>=valsmax[indmax]-Ratio*DV - PMin = np.array([np.sum(Ptsmin[0,imin]*valsmin[imin])/np.sum(valsmin[imin]), np.sum(Ptsmin[1,imin]*valsmin[imin])/np.sum(valsmin[imin])]) - PMax = np.array([np.sum(Ptsmax[0,imax]*valsmax[imax])/np.sum(valsmax[imax]), np.sum(Ptsmax[1,imax]*valsmax[imax])/np.sum(valsmax[imax])]) - VMin, VMax = np.mean(valsmin[imin]), np.mean(valsmax[imax]) - return PMin, PMax, VMin, VMax - - def get_XYgridFine(DXmin, DYmin, DXmax, DYmax, Margin, subp): - DXmin, DYmin = [DXmin[0]-Margin*(DXmin[1]-DXmin[0]), DXmin[1]+Margin*(DXmin[1]-DXmin[0])], [DYmin[0]-Margin*(DYmin[1]-DYmin[0]), DYmin[1]+Margin*(DYmin[1]-DYmin[0])] - DXmax, DYmax = [DXmax[0]-Margin*(DXmax[1]-DXmax[0]), DXmax[1]+Margin*(DXmax[1]-DXmax[0])], [DYmax[0]-Margin*(DYmax[1]-DYmax[0]), DYmax[1]+Margin*(DYmax[1]-DYmax[0])] - Nxmin, Nymin = (DXmin[1]-DXmin[0])/subp, (DYmin[1]-DYmin[0])/subp - Nxmax, Nymax = (DXmax[1]-DXmax[0])/subp, (DYmax[1]-DYmax[0])/subp - Xmin, Ymin = np.linspace(DXmin[0],DXmin[1], Nxmin), np.linspace(DYmin[0],DYmin[1], Nymin) - Xmax, Ymax = np.linspace(DXmax[0],DXmax[1], Nxmax), np.linspace(DYmax[0],DYmax[1], Nymax) - Ptsmin = np.array([np.tile(Xmin,(Nymin,1)).flatten(), np.tile(Ymin,(Nxmin,1)).T.flatten()]) - Ptsmax = np.array([np.tile(Xmax,(Nymax,1)).flatten(), np.tile(Ymax,(Nxmax,1)).T.flatten()]) - return Ptsmin, Ptsmax - - def get_minmaxFine(vals, indmaxi, indmini, coefs, Points=Points, ratio=0.02, SubP2=SubP2, Ratio=Ratio, Test=Test): - DV = vals[indmaxi]-vals[indmini] - imin, imax = vals<=vals[indmini]+ratio*DV, vals>=vals[indmaxi]-ratio*DV - xminmin, xminmax = np.min(Points[0,imin]), np.max(Points[0,imin]) - xmaxmin, xmaxmax = np.min(Points[0,imax]), np.max(Points[0,imax]) - yminmin, yminmax = np.min(Points[1,imin]), np.max(Points[1,imin]) - ymaxmin, ymaxmax = np.min(Points[1,imax]), np.max(Points[1,imax]) - Ptsmin, Ptsmax = get_XYgridFine([xminmin,xminmax], [yminmin,yminmax], [xmaxmin, xmaxmax], [ymaxmin, ymaxmax], Margin, SubP2) - valsmin, valsmax = BF2.get_TotVal(Ptsmin, Deriv=Deriv, Coefs=coefs, Test=Test), BF2.get_TotVal(Ptsmax, Deriv=Deriv, Coefs=coefs, Test=Test) - indmin, indmax = np.nanargmin(valsmin), np.nanargmax(valsmax) - if Ratio is None: - return Ptsmin[:,indmin], Ptsmax[:,indmax], valsmin[indmin], valsmax[indmax] - else: - return getminmaxRatioFloat(valsmax, valsmin, indmax, indmin, Ratio, Ptsmin, Ptsmax) - - if not hasattr(Coefs,'__getitem__') or Coefs.ndim==1: - indmin, indmax = np.nanargmin(Vals), np.nanargmax(Vals) - if TwoSteps: - PMin, PMax, VMin, VMax = get_minmaxFine(Vals, indmax, indmin, Coefs, Points=Points, ratio=0.02, SubP2=SubP2, Ratio=Ratio, Test=Test) - else: - if Ratio is None: - PMin, PMax = Points[:,indmin], Points[:,indmax] - VMin, VMax = Vals[indmin], Vals[indmax] - else: - PMin, PMax, VMin, VMax = getminmaxRatioFloat(Vals, Vals, indmax, indmin, Ratio, Points, Points) - Surf = (Vals >= Vals(np.nanargmax(Vals))*0.5).sum()*dS - else: - indmin, indmax = np.nanargmin(Vals,axis=1), np.nanargmax(Vals,axis=1) - if TwoSteps: - ratio = 0.02 if Ratio is None else Ratio+0.02 - mmin, mmax = np.nanmin(Vals,axis=1).max(), np.nanmax(Vals,axis=1).min() - DV = np.max(np.nanmax(Vals,axis=1)-np.nanmin(Vals,axis=1)) - assert mmin+ratio*DV <= mmax-ratio*DV, "Profile changes too much !" - imin, imax = np.any(Vals<=mmin+ratio*DV,axis=0), np.any(Vals>=mmax-ratio*DV,axis=0) - DXmin, DYmin = [Points[0,imin].min(), Points[0,imin].max()], [Points[1,imin].min(), Points[1,imin].max()] - DXmax, DYmax = [Points[0,imax].min(), Points[0,imax].max()], [Points[1,imax].min(), Points[1,imax].max()] - Ptsmin, Ptsmax = get_XYgridFine(DXmin, DYmin, DXmax, DYmax, Margin, SubP2) - Valsmin, Valsmax = BF2.get_TotVal(Ptsmin, Deriv=Deriv, Coefs=Coefs, Test=Test), BF2.get_TotVal(Ptsmax, Deriv=Deriv, Coefs=Coefs, Test=Test) - else: - Ptsmin, Ptsmax = Points, Points - Valsmin, Valsmax = Vals, Vals - indmin, indmax = np.nanargmin(Valsmin,axis=1), np.nanargmax(Valsmax,axis=1) - if Ratio is None: - PMin, PMax = Ptsmin[:,indmin].T, Ptsmax[:,indmax].T - VMin, VMax = np.nanmin(Valsmin,axis=1), np.nanmax(Valsmax,axis=1) - else: - Nt = Coefs.shape[0] - PMin, PMax = np.empty((Nt,2)), np.empty((Nt,2)) - VMin, VMax = np.empty((Nt,)), np.empty((Nt,)) - for ii in range(0,Nt): - PMin[ii,:], PMax[ii,:], VMin[ii], VMax[ii] = getminmaxRatioFloat(Valsmax[ii,:], Valsmin[ii,:], indmax[ii], indmin[ii], Ratio, Ptsmin, Ptsmax) - Surf = np.sum(Vals >= np.tile(np.nanmax(Vals,axis=1)*0.5,(Vals.shape[1],1)).T,axis=1)*dS - - return PMin, PMax, VMin, VMax, Surf - - - - - - - - -def Calc_GetRoots(BF2, Deriv=0., Coefs=1., Test=True): - if Test: - assert isinstance(BF2, BF2D), "Arg BF2 must be a BF2D instance !" - assert Deriv in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI'], "Arg Deriv must be in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI'] !" - if type(Deriv) is str: - intDeriv = int(Deriv[1]) - else: - intDeriv = Deriv - assert BF2.Deg > 0 and intDeriv0)) and C4.size==4: - Inds[ii] = True - A = C4[0]+C4[3] - C4[1]+C4[2] - B = C4[1]*Kts[1,1] - C4[3]*Kts[1,0] - C4[0]*Kts[1,1] + C4[2]*Kts[1,0] - C = C4[1]*Kts[0,0] - C4[3]*Kts[0,0] - C4[0]*Kts[0,1] + C4[2]*Kts[0,1] - D = Kts[0,1]*(C4[0]*Kts[1,1]-C4[2]*Kts[1,0]) - Kts[0,0]*(C4[1]*Kts[1,1]-C4[3]*Kts[1,0]) - if A==0.: - if C==0.: - if B==0.: - Shape[ii] = ['all',[]] if D==0. else ['',[]] # Else not possible - else: - Shape[ii] = ['x',[-D/B]] - else: - Shape[ii] = ['yx',[-B/C,-D/C]] - else: - if -C/A>Kts[0,1] or -C/A0)) and C9.size==9: - Inds[ii] = True - print " Not finished yet !" - - - - - if intDeriv==1: - if Deriv[1]=='D1N2': - if BF2.Deg==2: - for ii in range(0,NCents): - ind = BF2._Cents_Funcind[:,ii] - C9 = Coefs[np.unique(ind[~np.isnan(ind)]).astype(int)] - Kts = BF2.Mesh.Knots[:,np.unique(BF2.Mesh._Cents_Knotsind[:,ii])] - - #A0, B0 = - #A1, B1 = - #A2, B2 = - #alpha0, beta0, gam0 = - #alpha1, beta1, gam1 = - #alpha2, beta2, gam2 = - return Inds, Pts, Shape - - - - - - diff --git a/tofu/mesh/_bsplines_cy.pyx b/tofu/mesh/_bsplines_cy.pyx deleted file mode 100644 index ccd58040a..000000000 --- a/tofu/mesh/_bsplines_cy.pyx +++ /dev/null @@ -1,1269 +0,0 @@ -# cython: profile=True -# -*- coding: utf-8 -*- -""" -Created on Mon Aug 25 10:03:58 2014 - -@author: didiervezinet -""" - -import numpy as np -cimport numpy as cnp -import math -import scipy.sparse as scpsp -import scipy.interpolate as scpinterp - -# ToFu-specific - - -ctypedef cnp.float_t DTYPE_t - - -""" -############################################################################### -############################################################################### - B-spline definitions -############################################################################### -""" - -# Scipy definition - - -def get_scpKnotsCoefs_From_KnotsDeg(knts, Deg): - knts2 = [knts[0]]*(1+Deg) + knts[1:-1].tolist() + [knts[-1]]*(1+Deg) - coefs = [0.]*Deg + [1.] + [0.]*(len(knts2)-Deg-1) - return knts2, coefs - -def _NjD_scp(kntsf, coefsf, int Deg=1, int der=0): - NFunc = lambda x, Deg=Deg, kntsf=kntsf, coefsf=coefsf, der=der: scpinterp.splev(x, (kntsf, coefsf, Deg), der=der, ext=1) - return NFunc - - - - -# Direct definitions of b-splines and their derivatives for degrees 0-3 - -def _Nj0(xa, xb): - def Nfunc(x): - a = np.zeros(np.shape(x)) - a[(x >= xa) & (x < xb)] = 1. - return a - return Nfunc - -def _Nj1(x0, x1, x2): - def Nfunc(x): - A = np.zeros(np.shape(x)) - Ind = (x>=x0)&(x=x0)&(xx=x1)&(xx=x0)&(x=x1)&(x=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x3)&(xx=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x3)&(xx=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x3)&(xx=x0)&(x=x0)&(xx=x1)&(xx=x2)&(xx=x3)&(xx=Deriv, "Arg Deg and Deriv must be int and Deg >= Deriv !" - assert np.all(Knots==np.unique(Knots)) and Knots.size>Deg+1 , "Arg Knots must be a 1-dim np.ndarray of unique increasing floats with Knots.size>Deg+1 !" - cdef list LFunc - cdef int NKnots = Knots.size - cdef int NbF = NKnots-1-Deg, NCents = NKnots-1 - cdef Py_ssize_t ii - - if Deg==0: - temp = np.arange(0,NbF) - Func_Knotsind = np.array([temp,temp+1]) - Func_Centsind = temp.reshape((1,NbF)) - Knots_Funcind = np.array([np.concatenate(([np.nan],temp)),np.concatenate((temp,[np.nan]))]) - Cents_Funcind = np.copy(Func_Centsind) - MaxPos = 0.5*(Knots[:-1]+Knots[1:]) - if not Mode=='scp': - LFunc = [_Nj0(Knots[ii],Knots[ii+1]) for ii in range(0,NCents)] - elif Deg==1: - temp = np.arange(0,NbF) - Func_Knotsind = np.array([temp,temp+1,temp+2]) - Func_Centsind = np.array([temp,temp+1]) - Knots_Funcind = np.array([np.concatenate(([np.nan,np.nan],temp)),np.concatenate(([np.nan],temp,[np.nan])),np.concatenate((temp,[np.nan,np.nan]))]) - Cents_Funcind = np.array([np.concatenate(([np.nan],temp)),np.concatenate((temp,[np.nan]))]) - MaxPos = Knots[1:-1] - if not Mode=='scp': - if Deriv==0: - LFunc = [_Nj1(Knots[ii],Knots[ii+1],Knots[ii+2]) for ii in range(0,NbF)] - elif Deriv==1: - LFunc = [_Nj1D1(Knots[ii],Knots[ii+1],Knots[ii+2]) for ii in range(0,NbF)] - elif Deg==2: - temp = np.arange(0,NbF) - Func_Knotsind = np.array([temp,temp+1,temp+2,temp+3]) - Func_Centsind = np.array([temp,temp+1,temp+2]) - Knots_Funcind = np.array([np.concatenate(([np.nan,np.nan,np.nan],temp)),np.concatenate(([np.nan,np.nan],temp,[np.nan])),np.concatenate(([np.nan],temp,[np.nan,np.nan])),np.concatenate((temp,[np.nan,np.nan,np.nan]))]) - Cents_Funcind = np.array([np.concatenate(([np.nan,np.nan],temp)),np.concatenate(([np.nan],temp,[np.nan])),np.concatenate((temp,[np.nan,np.nan]))]) - MaxPos = 0.5*(Knots[1:-2]+Knots[2:-1]) - if not Mode=='scp': - if Deriv==0: - LFunc = [_Nj2(Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3]) for ii in range(0,NbF)] - elif Deriv==1: - LFunc = [_Nj2D1(Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3]) for ii in range(0,NbF)] - elif Deriv==2: - LFunc = [_Nj2D2(Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3]) for ii in range(0,NbF)] - elif Deg==3: - temp = np.arange(0,NbF) - Func_Knotsind = np.array([temp,temp+1,temp+2,temp+3,temp+4]) - Func_Centsind = np.array([temp,temp+1,temp+2,temp+3]) - Knots_Funcind = np.array([np.concatenate(([np.nan,np.nan,np.nan,np.nan],temp)),np.concatenate(([np.nan,np.nan,np.nan],temp,[np.nan])),np.concatenate(([np.nan,np.nan],temp,[np.nan,np.nan])), - np.concatenate(([np.nan],temp,[np.nan,np.nan,np.nan])),np.concatenate((temp,[np.nan,np.nan,np.nan,np.nan]))]) - Cents_Funcind = np.array([np.concatenate(([np.nan,np.nan,np.nan],temp)),np.concatenate(([np.nan,np.nan],temp,[np.nan])),np.concatenate(([np.nan],temp,[np.nan,np.nan])),np.concatenate((temp,[np.nan,np.nan,np.nan]))]) - MaxPos = Knots[2:-2] - if not Mode=='scp': - if Deriv==0: - LFunc = [_Nj3(Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3],Knots[ii+4]) for ii in range(0,NbF)] - elif Deriv==1: - LFunc = [_Nj3D1(Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3],Knots[ii+4]) for ii in range(0,NbF)] - elif Deriv==2: - LFunc = [_Nj3D2(Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3],Knots[ii+4]) for ii in range(0,NbF)] - elif Deriv==3: - LFunc = [_Nj3D3(Knots[ii],Knots[ii+1],Knots[ii+2],Knots[ii+3],Knots[ii+4]) for ii in range(0,NbF)] - - scp_Lkntsf, scp_Lcoeff = None, None - if Mode=='scp': - scp_Lkntsf, scp_Lcoeff = zip(*[get_scpKnotsCoefs_From_KnotsDeg(Knots[ii:ii+Deg+2], Deg) for ii in range(0,NbF)]) - LFunc = [_NjD_scp(scp_Lkntsf[ii], scp_Lcoeff[ii], Deg=Deg, der=Deriv) for ii in range(0,NbF)] - - return LFunc, Func_Knotsind, Func_Centsind, Knots_Funcind, Cents_Funcind, MaxPos, scp_Lkntsf, scp_Lcoeff - - - - -# Total of the functions in 1D - -def BSpline_TotFunc(int Deg, cnp.ndarray[cnp.float64_t, ndim=1] Knots, Deriv=0, Coefs=1., thr=1.e-8, thrmode='rel', Abs=True, Mode='scp', Test=True): - if Test: - assert Deriv in [0,1,2,3,'D0','D1','D2','D3','D0N2','D0ME','D1N2','D1FI','D2N2','D3N2'], "Arg Deriv must be in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI','D2N2','D3N2'] !" - assert type(Coefs) in [int,float] or (isinstance(Coefs,np.ndarray) and Coefs.ndim in [1,2] and Knots.size-1-Deg in Coefs.shape), "Arg Coefs must be a int / float or a np.ndarray !" - intDeriv = int(Deriv[1]) if type(Deriv) is str else Deriv - assert Deg>=intDeriv, "Arg Deriv cannot be larger that Deg !" - assert Knots.size-1>Deg, "There should be enough knots to allow at least one b-spline !" - - # Preparing input - cdef list Func = [] - cdef int NF = Knots.size-1-Deg - Coefs = float(Coefs)*np.ones((NF,)) if type(Coefs) in [int,float] else Coefs - Coefs = Coefs.T if Coefs.ndim==2 and Coefs.shape[0]==Knots.size-1-Deg else Coefs - Coefs = Coefs.reshape((1,Coefs.size)) if Coefs.ndim==1 else Coefs - cdef int Nt = Coefs.shape[0] - cdef Py_ssize_t ii, jj - - intDeriv = int(Deriv[1]) if type(Deriv) is str else Deriv - LF = BSpline_LFunc(Deg, Knots, Deriv=intDeriv, Mode=Mode, Test=Test)[0] - - # Computing - if Deriv in [0,1,2,3,'D0','D1','D2','D3']: - for ii in range(0,Nt): - Func.append(lambda x,coefs=Coefs[ii,:],LF=LF: np.sum([coefs[jj]*LF[jj](x) for jj in range(0,NF)],axis=0)) - - elif Deriv in ['D0N2','D1N2','D2N2','D3N2']: - for ii in range(0,Nt): - Func.append(lambda x,coefs=Coefs[ii,:],LF=LF: np.sum([coefs[jj]*LF[jj](x) for jj in range(0,NF)],axis=0)**2) - - elif Deriv=='D1FI': - lf = BSpline_LFunc(Deg, Knots, Deriv=0, Mode=Mode, Test=Test)[0] - Span = [Knots[0],Knots[-1]] - for ii in range(0,Nt): - def ff(x, coefs=Coefs[ii,:], LF=LF, lf=lf, thr=thr, thrmode=thrmode, Span=Span, Abs=Abs): - grad2 = np.sum([coefs[jj]*LF[jj](x) for jj in range(0,NF)],axis=0)**2 - g = np.sum([coefs[jj]*lf[jj](x) for jj in range(0,NF)],axis=0) - g = np.abs(g) if Abs else g - if thr is not None: - thr = thr if thrmode=='abs' else np.nanmax(g)*thr - ind = (x>=Span[0]) & (x<=Span[1]) - g[ind & (g=Span[0]) & (x<=Span[1]) - g[ind & (gDeg+1 , "Arg Knots must be a 1-dim np.ndarray of unique increasing floats with Knots.size>Deg+1 !" - assert Deriv in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI'], "Arg Deriv must be in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI'] !" - if type(Deriv) is str: - intDeriv = int(Deriv[1]) - else: - intDeriv = Deriv - assert Deg > 0 and intDeriv= 0 - sols = np.array([(-B[ind]+np.sqrt(Delta[ind]))/(2.*A[ind]), (-B[ind]-np.sqrt(Delta[ind]))/(2.*A[ind])]) - ind = (sols>=Int[0,ind]) & (sols=Int[0,:]-Eps) & (sols=0 and Deg<=3, "Arg Deg must be a positive int !" - if type(Deriv) is int: - assert Deriv<=Deg, "Arg Deriv must be smaller than Deg !" - elif type(Deriv) is str: - assert int(Deriv[1])<=Deg and Deriv in ['D0','D1','D2','D3','D0N2','D1N2','D2N2','D3N2'], "Arg Deriv must be smaller than Deg and in ['D0','D1','D2','D3','D0N2','D1N2'] !" - assert Mode in ['Vol','Surf'], "Arg Mode must be in ['Vol','Surf'] !" - assert LFunc is None or (type(LFunc) is list and all([hasattr(ff,'__call__') for ff in LFunc])), "Arg LFunc must be a list of callables !" - assert type(LFunc_Mode) is str, "Arg LFunc_Mode must be a str !" - assert quad_pts is None or type(quad_pts) is np.ndarray, "Arg quad_pts must be a np.ndarray !" - assert quad_w is None or (type(quad_w) is np.ndarray and quad_w.shape==quad_pts.shape), "Arg quad_w must be a np.ndarray of same shape as quad_pts !" - assert quad_aa is None or (type(quad_aa) is np.ndarray and quad_aa.shape==(quad_w.shape[1],)), "Arg quad_aa must be a np.ndarray of shape (quad_w.shape[1],) !" - - cdef int intDeriv = int(Deriv[1]) if type(Deriv) is str else Deriv - cdef int NKnots = Knots.size - cdef int NFunc = NKnots-Deg-1 - cdef Py_ssize_t ii, jj, Nt = Coefs.shape[0] - cdef list Int = [0 for jj in range(0,Nt)] - - LFunc = BSpline_LFunc(Deg, Knots, Deriv=intDeriv, Mode=LFunc_Mode, Test=True)[0] if LFunc is None else LFunc - assert len(LFunc)==NFunc, "Arg LFunc does not have the proper number of functions !" - if quad_pts is None: - quad_pts, quad_w, quad_aa, N = get_IntQuadPts(Knots, Deg, Deriv, intDeriv, Mode=Mode, N=N) - - if Deriv in [0,1,2,3,'D0','D1','D2','D3']: - if Mode=='Surf': - for jj in range(0,Nt): - Int[jj] = np.sum([Coefs[jj,ii]*np.sum(quad_aa*np.sum(quad_w*LFunc[ii](quad_pts),axis=0)) for ii in range(0,NFunc)]) - elif Mode=='Vol': - for jj in range(0,Nt): - Int[jj] = np.sum([Coefs[jj,ii]*np.sum(quad_aa*np.sum(quad_w*quad_pts*LFunc[ii](quad_pts),axis=0)) for ii in range(0,NFunc)]) - - elif Deriv in ['D0N2','D1N2','D2N2','D3N2']: - if Mode=='Surf': - for jj in range(0,Nt): - Int[jj] = np.sum(quad_aa*np.sum(quad_w*np.sum([LFunc[ii](quad_pts) for ii in range(0,NFunc)], axis=0)**2, axis=0)) - elif Mode=='Vol': - for jj in range(0,Nt): - Int[jj] = np.sum(quad_aa*np.sum(quad_w*quad_pts*np.sum([LFunc[ii](quad_pts) for ii in range(0,NFunc)], axis=0)**2, axis=0)) - - elif Deriv=='D1FI': - lf = BSpline_LFunc(Deg, Knots, Deriv=0, Mode=Mode, Test=Test)[0] - Span = [Knots[0],Knots[-1]] - for jj in range(0,Nt): - grad2 = np.sum([Coefs[jj,ii]*LFunc[ii](quad_pts) for ii in range(0,NFunc)],axis=0)**2 - g = np.sum([Coefs[jj,ii]*lf[ii](quad_pts) for ii in range(0,NFunc)],axis=0) - g = np.abs(g) if Abs else g - if thr is not None: - thr = thr if thrmode=='abs' else np.nanmax(g)*thr - ind = (quad_pts>=Span[0]) & (quad_pts<=Span[1]) - g[ind & (g=Span[0]) & (quad_pts<=Span[1]) - g[ind & (g=0 and Deg<=3, "Arg Deg must be a positive int !" - if type(Deriv) is int: - assert Deriv<=Deg, "Arg Deriv must be smaller than Deg !" - elif type(Deriv) is str: - assert int(Deriv[1])<=Deg and Deriv in ['D0','D1','D2','D3','D0N2','D1N2','D2N2','D3N2'], "Arg Deriv must be smaller than Deg and in ['D0','D1','D2','D3','D0N2','D1N2'] !" - assert Mode in ['Vol','Surf'], "Arg Mode must be in ['Vol','Surf'] !" - assert Method is None or Method in ['quad','exact'], "Arg Method must be None or in ['quad','exact'] !" - assert LFunc is None or (type(LFunc) is list and all([hasattr(ff,'__call__') for ff in LFunc])), "Arg LFunc must be a list of callables !" - assert type(LFunc_Mode) is str, "Arg LFunc_Mode must be a str !" - assert quad_pts is None or type(quad_pts) is np.ndarray, "Arg quad_pts must be a np.ndarray !" - assert quad_w is None or (type(quad_w) is np.ndarray and quad_w.shape==quad_pts.shape), "Arg quad_w must be a np.ndarray of same shape as quad_pts !" - assert quad_aa is None or (type(quad_aa) is np.ndarray and quad_aa.shape==(quad_w.shape[1],)), "Arg quad_aa must be a np.ndarray of shape (quad_w.shape[1],) !" - assert type(Sparse) is bool, "Arg Sparse must be a bool !" - assert SpaFormat is None or (type(SpaFormat) is str and SpaFormat in ['dia','bsr','coo','csc','csr']), "Arg SpaFormat must be None or in ['dia','bsr','coo','csc','csr'] !" - - cdef int intDeriv = int(Deriv[1]) if type(Deriv) is str else Deriv - cdef int NKnots = Knots.size - cdef int NFunc = NKnots-Deg-1 - if LFunc is not None: - assert len(LFunc)==NFunc, "Arg LFunc does not have the proper number of functions !" - - if Method is None: - Lcases = [Deriv in [0,1,2,3,'D0','D1','D2','D3'], Deriv=='D0N2' and Deg<=2, Deriv=='D1N2' and Deg<=2] - if any(Lcases): - Method = 'exact' - else: - Method = 'quad' - - m = 0 if Deriv in [0,1,2,3,'D0','D1','D2','D3'] else 1 - if Method=='quad': - A = _Calc_1D_IntOp_Quad(Knots, Deg, Deriv, intDeriv, NKnots, NFunc, Mode=Mode, LFunc=LFunc, LFunc_Mode=LFunc_Mode, quad_pts=quad_pts, quad_w=quad_w, quad_aa=quad_aa, N=N) - elif Method=='exact': - A = _Calc_1D_IntOp_Exact(Knots, Deg, Deriv, intDeriv, NKnots, NFunc, LFunc=LFunc, Mode=Mode) - if m==1: - if not Sparse: - A = A.toarray() - elif SpaFormat is not None and not SpaFormat=='dia': - A = eval('scpsp.'+SpaFormat+'_matrix(A)') - return A, m - - -cdef _Calc_1D_IntOp_Quad(cnp.ndarray[cnp.float64_t, ndim=1] Knots, int Deg, Deriv, intDeriv, NKnots, NFunc, Mode='Vol', LFunc=None, LFunc_Mode='scp', quad_pts=None, quad_w=None, quad_aa=None, N=None): - - cdef Py_ssize_t ii - - LFunc = BSpline_LFunc(Deg, Knots, Deriv=intDeriv, Mode=LFunc_Mode, Test=True)[0] if LFunc is None else LFunc - if quad_pts is None: - quad_pts, quad_w, quad_aa, N = get_IntQuadPts(Knots, Deg, Deriv, intDeriv, Mode=Mode, N=N) - - if Deriv in [0,1,2,3,'D0','D1','D2','D3']: - if Mode=='Surf': - A = np.asarray([np.sum(quad_aa*np.sum(quad_w*LFunc[ii](quad_pts),axis=0)) for ii in range(0,NFunc)]) - else: - A = np.asarray([np.sum(quad_aa*np.sum(quad_w*quad_pts*LFunc[ii](quad_pts),axis=0)) for ii in range(0,NFunc)]) - - elif Deriv in ['D0N2','D1N2','D2N2','D3N2']: - Ld, Lo = [], [] - if Mode=='Surf': - d0 = np.asarray([np.sum(quad_aa*np.sum(quad_w*(LFunc[ii](quad_pts))**2,axis=0)) for ii in range(0,NFunc)]) - Ld, Lo = Ld+[d0], Lo+[0] - if Deg>=1: - d1 = np.asarray([np.sum(quad_aa[1:-1]*np.sum(quad_w[:,1:-1]*LFunc[ii](quad_pts[:,1:-1])*LFunc[ii+1](quad_pts[:,1:-1]),axis=0)) for ii in range(0,NFunc-1)]) - Ld, Lo = Ld+[d1,d1], Lo+[-1,1] - if Deg>=2: - d2 = np.asarray([np.sum(quad_aa[2:-2]*np.sum(quad_w[:,2:-2]*LFunc[ii](quad_pts[:,2:-2])*LFunc[ii+2](quad_pts[:,2:-2]),axis=0)) for ii in range(0,NFunc-2)]) - Ld, Lo = Ld+[d2,d2], Lo+[-2,2] - if Deg>=3: - d3 = np.asarray([np.sum(quad_aa[3:-3]*np.sum(quad_w[:,3:-3]*LFunc[ii](quad_pts[:,3:-3])*LFunc[ii+3](quad_pts[:,3:-3]),axis=0)) for ii in range(0,NFunc-3)]) - Ld, Lo = Ld+[d3,d3], Lo+[-3,3] - else: - d0 = np.asarray([np.sum(quad_aa*np.sum(quad_w*quad_pts*(LFunc[ii](quad_pts))**2,axis=0)) for ii in range(0,NFunc)]) - Ld, Lo = Ld+[d0], Lo+[0] - if Deg>=1: - d1 = np.asarray([np.sum(quad_aa[1:-1]*np.sum(quad_w[:,1:-1]*quad_pts[:,1:-1]*LFunc[ii](quad_pts[:,1:-1])*LFunc[ii+1](quad_pts[:,1:-1]),axis=0)) for ii in range(0,NFunc-1)]) - Ld, Lo = Ld+[d1,d1], Lo+[-1,1] - if Deg>=2: - d2 = np.asarray([np.sum(quad_aa[2:-2]*np.sum(quad_w[:,2:-2]*quad_pts[:,2:-2]*LFunc[ii](quad_pts[:,2:-2])*LFunc[ii+2](quad_pts[:,2:-2]),axis=0)) for ii in range(0,NFunc-2)]) - Ld, Lo = Ld+[d2,d2], Lo+[-2,2] - if Deg>=3: - d3 = np.asarray([np.sum(quad_aa[3:-3]*np.sum(quad_w[:,3:-3]*quad_pts[:,3:-3]*LFunc[ii](quad_pts[:,3:-3])*LFunc[ii+3](quad_pts[:,3:-3]),axis=0)) for ii in range(0,NFunc-3)]) - Ld, Lo = Ld+[d3,d3], Lo+[-3,3] - - A = scpsp.diags(Ld, Lo, shape=(NFunc,NFunc)) - - return A - - -cdef _Calc_1D_IntOp_Exact(cnp.ndarray[cnp.float64_t, ndim=1] Knots, int Deg, Deriv, intDeriv, NKnots, NFunc, LFunc=None, Mode='Vol'): - - if Deg==0: - x0, x1 = Knots[:-1], Knots[1:] - elif Deg==1: - x0, x1, x2 = Knots[:-2], Knots[1:-1], Knots[2:] - if Deriv in ['D0N2','D1N2','D2N2','D3N2']: - x1d, x2d = Knots[1:-2], Knots[2:-1] - elif Deg==2: - x0, x1, x2, x3 = Knots[:-3], Knots[1:-2], Knots[2:-1], Knots[3:] - if Deriv in ['D0N2','D1N2','D2N2','D3N2']: - x0d1, x1d1, x2d1, x3d1, x4d1 = Knots[:-4], Knots[1:-3], Knots[2:-2], Knots[3:-1], Knots[4:] - x1d2, x2d2, x3d2, x4d2 = Knots[1:-4], Knots[2:-3], Knots[3:-2], Knots[4:-1] - elif Deg==3: - x0, x1, x2, x3, x4, A1, B1, C1, D1, Den1, Den1m, A2, B2, C2, D2, Den2, Den2m = _get_TermsDeg3_1D(Knots) - if Deriv in ['D0N2','D1N2','D2N2','D3N2']: - x0d1, x1d1, x2d1, x3d1, x4d1, x5d1 = Knots[:-5], Knots[1:-4], Knots[2:-3], Knots[3:-2], Knots[4:-1], Knots[5:] - A1d1, A2d1 = _get_TermsDeg3_1D_A12(x0d1,x1d1,x2d1,x3d1,x4d1) - B1d1, B2d1 = _get_TermsDeg3_1D_B12(x0d1,x1d1,x2d1,x3d1,x4d1) - A1_1d1, A2_1d1 = _get_TermsDeg3_1D_A12(x1d1,x2d1,x3d1,x4d1,x5d1) - B1_1d1, B2_1d1 = _get_TermsDeg3_1D_B12(x1d1,x2d1,x3d1,x4d1,x5d1) - - x0d2, x1d2, x2d2, x3d2, x4d2, x5d2, x6d2 = Knots[:-6], Knots[1:-5], Knots[2:-4], Knots[3:-3], Knots[4:-2], Knots[5:-1], Knots[6:] - A2d2 = _get_TermsDeg3_1D_A12(x0d2,x1d2,x2d2,x3d2,x4d2)[1] - B2d2 = _get_TermsDeg3_1D_B12(x0d2,x1d2,x2d2,x3d2,x4d2)[1] - A1_2d2 = _get_TermsDeg3_1D_A12(x2d2,x3d2,x4d2,x5d2,x6d2)[0] - B1_2d2 = _get_TermsDeg3_1D_B12(x2d2,x3d2,x4d2,x5d2,x6d2)[0] - - x1d3, x2d3, x3d3, x4d3, x5d3, x6d3 = Knots[1:-6], Knots[2:-5], Knots[3:-4], Knots[4:-3], Knots[5:-2], Knots[6:-1] - - - # Integral of the function or of its derivatives - if Deriv in [0,1,2,3,'D0','D1','D2','D3']: - if intDeriv==0: - if Deg==0: - x0, x1 = Knots[:-1], Knots[1:] - A = x1-x0 if Mode=='Surf' else (x1**2-x0**2)/2. - - elif Deg==1: - A = (x2-x0)/2. if Mode=='Surf' else (x2**2 + x1*(x2-x0) - x0**2)/6. - - elif Deg==2: - if Mode=='Surf': - I1 = (x1 - x0)**2 / (3.*(x2-x0)) - I2 = ( x2**2 + x1*x2 - 2.*x1**2 + 3.*x0*(x1-x2) ) / (6.*(x2-x0)) + ( -2.*x2**2 + x1*x2 + x1**2 + 3.*x3*(x2-x1) ) / (6.*(x3-x1)) - I3 = (x3 - x2)**2 / (3.*(x3-x1)) - else: - I1 = (3.*x1+x0)*(x1-x0)**2 / (12.*(x2-x0)) - I2 = (x2-x1)*(x2**2+2.*x1*x2+3.*x1**2 - 2.*x0*(x2+2.*x1)) / (12.*(x2-x0)) - (x2-x1)*(x1**2+2.*x1*x2+3.*x2**2 - 2.*x3*(2.*x2+x1)) / (12.*(x3-x1)) - I3 = (3.*x2+x3)*(x3-x2)**2 / (12.*(x3-x1)) - A = I1 + I2 + I3 - - elif Deg==3: - if Mode=='Surf': - I1 = ( (x1**4-x0**4)/4. - 3.*x0*(x1**3-x0**3)/3. + 3.*x0**2*(x1**2-x0**2)/2. - (x1-x0)*x0**3 ) / ((x3-x0)*(x2-x0)*(x1-x0)) - #I2 = (A1*(x2**4-x1**4)/4. + B1*(x2**3-x1**3)/3. + C1*(x2**2-x1**2)/2. + D1*(x2-x1)) / Den1 - #I3 = (A2*(x3**4-x2**4)/4. + B2*(x3**3-x2**3)/3. + C2*(x3**2-x2**2)/2. + D2*(x3-x2)) / Den2 - I2 = (A1*(x2**3+x2**2*x1+x2*x1**2+x1**3)/4. + B1*(x2**2+x2*x1+x1**2)/3. + C1*(x2+x1)/2. + D1) / Den1m - I3 = (A2*(x3**3+x3**2*x2+x3*x2**2+x2**3)/4. + B2*(x3**2+x3*x2+x2**2)/3. + C2*(x3+x2)/2. + D2) / Den2m - I4 = ( -(x4**4-x3**4)/4. + 3.*x4*(x4**3-x3**3)/3. - 3.*x4**2*(x4**2-x3**2)/2. + (x4-x3)*x4**3 ) / ((x4-x3)*(x4-x2)*(x4-x1)) - else: - I1 = ( 12.*(x1**5-x0**5) - 45.*x0*(x1**4-x0**4) + 60.*x0**2*(x1**3-x0**3) - 30.*x0**3*(x1**2-x0**2) ) / (60.*(x3-x0)*(x2-x0)*(x1-x0)) - #I2 = ( 12.*A1*(x2**5-x1**5) + 15.*B1*(x2**4-x1**4) + 20.*C1*(x2**3-x1**3) + 30.*D1*(x2**2-x1**2) ) / (60.*Den1) - #I3 = ( 12.*A2*(x3**5-x2**5) + 15.*B2*(x3**4-x2**4) + 20.*C2*(x3**3-x2**3) + 30.*D2*(x3**2-x2**2) ) / (60.*Den2) - I2 = ( 12.*A1*(x2**4+x2**3*x1+x2**2*x1**2+x2*x1**3+x1**4) + 15.*B1*(x2**3+x2**2*x1+x2*x1**2+x1**3) + 20.*C1*(x2**2+x2*x1+x1**2) + 30.*D1*(x2+x1) ) / (60.*Den1m) - I3 = ( 12.*A2*(x3**4+x3**3*x2+x3**2*x2**2+x3*x2**3+x2**4) + 15.*B2*(x3**3+x3**2*x2+x3*x2**2+x2**3) + 20.*C2*(x3**2+x3*x2+x2**2) + 30.*D2*(x3+x2) ) / (60.*Den2m) - I4 = -( 12.*(x4**5-x3**5) - 45.*x4*(x4**4-x3**4) + 60.*x4**2*(x4**3-x3**3) - 30.*x4**3*(x4**2-x3**2) ) / (60.*(x4-x3)*(x4-x2)*(x4-x1)) - A = I1 + I2 + I3 + I4 - - elif intDeriv==1: - if Deg==1: - if Mode=='Surf': - A = np.zeros((NFunc,)) - else: - A = -(x2-x0)/2. - - elif Deg==2: - if Mode=='Surf': - I1 = (x1-x0)/(x2-x0) - I2 = ( x3*x2**2 - x2**3 + x2**2*x1 + x2**2*x0 - 2.*x2*x1*x0 + x3*x1**2 + x2*x1**2 - x1**3 - 2.*x3*x2*x1 + x1**2*x0 ) / ((x2-x1)*(x2-x0)*(x3-x1)) - I3 = -(x3-x2)/(x3-x1) - else: - I1 = (2.*x1**2 - x1*x0 - x0**2) / (3.*(x2-x0)) - I2 = (-x2**2 - x2*x1 - 4.*x1**2 + 3.*x0*x2 + 3.*x0*x1) / (6.*(x2-x0)) + (-4.*x2**2 - x2*x1 - x1**2 + 3.*x3*x2 + 3.*x3*x1) / (6.*(x3-x1)) - I3 = (-x3**2 - x3*x2 + 2.*x2**2) / (3.*(x3-x1)) - A = I1 + I2 + I3 - - elif Deg==3: - if Mode=='Surf': - I1 = ((x1**3-x0**3) - 3.*x0*(x1**2-x0**2) + 3.*x0**2*(x1-x0)) / ((x3-x0)*(x2-x0)*(x1-x0)) - #I2 = ( A1*(x2**3-x1**3) + B1*(x2**2-x1**2) + C1*(x2-x1) ) / Den1 - #I3 = ( A2*(x3**3-x2**3) + B2*(x3**2-x2**2) + C2*(x3-x2) ) / Den2 - I2 = ( A1*(x2**2+x2*x1+x1**2) + B1*(x2+x1) + C1 ) / Den1m - I3 = ( A2*(x3**2+x3*x2+x2**2) + B2*(x3+x2) + C2 ) / Den2m - I4 = ( -(x4**3-x3**3) + 3.*x4*(x4**2-x3**2) - 3.*x4**2*(x4-x3)) / ((x4-x3)*(x4-x2)*(x4-x1)) - else: - I1 = ( 3.*x1**3 - 5.*x1**2*x0 + x1*x0**2 + x0**3 ) / (4.*(x3-x0)*(x2-x0)) - #I2 = ( 9.*A1*(x2**4-x1**4) + 8.*B1*(x2**3-x1**3) + 6.*C1*(x2**2-x1**2) ) / (12.*Den1) - #I3 = ( 9.*A2*(x3**4-x2**4) + 8.*B2*(x3**3-x2**3) + 6.*C2*(x3**2-x2**2) ) / (12.*Den2) - I2 = ( 9.*A1*(x2**3+x2**2*x1+x2*x1**2+x1**3) + 8.*B1*(x2**2+x2*x1+x1**2) + 6.*C1*(x2+x1) ) / (12.*Den1m) - I3 = ( 9.*A2*(x3**3+x3**2*x2+x2*x3**2+x2**3) + 8.*B2*(x3**2+x3*x2+x2**2) + 6.*C2*(x3+x2) ) / (12.*Den2m) - I4 = ( -x4**3 + 5.*x4*x3**2 - x4**2*x3 - 3.*x3**3 ) / (4.*(x4-x2)*(x4-x1)) - A = I1 + I2 + I3 + I4 - - elif intDeriv==2: - if Deg==2: - if Mode=='Surf': - I1 = 2./(x2-x0) - I2 = -2.*(x3+x2-x1-x0) / ((x2-x0)*(x3-x1)) - I3 = 2./(x3-x1) - else: - I1 = (x1+x0) / (x2-x0) - I2 = - (x2+x1) / (x2-x0) - (x2+x1) / (x3-x1) - I3 = (x3+x2) / (x3-x1) - A = I1 + I2 + I3 - - elif Deg==3: - if Mode=='Surf': - I1 = 3.*(x1-x0) / ((x3-x0)*(x2-x0)) - #I2 = ( 3.*A1*(x2**2-x1**2) + 2.*B1*(x2-x1) ) / Den1 - #I3 = ( 3.*A2*(x3**2-x2**2) + 2.*B2*(x3-x2) ) / Den2 - I2 = ( 3.*A1*(x2+x1) + 2.*B1 ) / Den1m - I3 = ( 3.*A2*(x3+x2) + 2.*B2 ) / Den2m - I4 = 3.*(x4-x3) / ((x4-x2)*(x4-x1)) - else: - I1 = ( 2.*x1**2 - x1*x0 - x0**2 ) / ((x3-x0)*(x2-x0)) - #I2 = ( 2.*A1*(x2**3-x1**3) + B1*(x2**2-x1**2) ) / Den1 - #I3 = ( 2.*A2*(x3**3-x2**3) + B2*(x3**2-x2**2) ) / Den2 - I2 = ( 2.*A1*(x2**2+x2*x1+x1**2) + B1*(x2+x1) ) / Den1m - I3 = ( 2.*A2*(x3**2+x3*x2+x2**2) + B2*(x3+x2) ) / Den2m - I4 = ( x4**2 + x4*x3 - 2.*x3**2 ) / ((x4-x2)*(x4-x1)) - A = I1 + I2 + I3 + I4 - - elif intDeriv==3: - if Deg==3: - if Mode=='Surf': - I1 = 6./((x3-x0)*(x2-x0)) - #I2 = 6.*A1*(x2-x1) / Den1 - #I3 = 6.*A2*(x3-x2) / Den2 - I2 = 6.*A1 / Den1m - I3 = 6.*A2 / Den2m - I4 = -6/((x4-x2)*(x4-x1)) - else: - I1 = 3.*(x1+x0) / ((x3-x0)*(x2-x0)) - #I2 = 3.*A1*(x2**2-x1**2) / Den1 - #I3 = 3.*A2*(x3**2-x2**2) / Den2 - I2 = 3.*A1*(x2+x1) / Den1m - I3 = 3.*A2*(x3+x2) / Den2m - I4 = -3.*(x4+x3) / ((x4-x2)*(x4-x1)) - A = I1 + I2 + I3 + I4 - - - - # Integral of the squared norm of the function or of its derivatives - elif Deriv == 'D0N2': - if Deg==0: - if Mode=='Surf': - d0 = x1-x0 - else: - d0 = (x1**2-x0**2)/2. - A = scpsp.diags([d0], [0], shape=(NFunc,NFunc)) - - elif Deg==1: - if Mode=='Surf': - d0 = (x2-x0)/3. - d1 = (x2d-x1d)/6. - - else: - I1 = (3.*x1**3 - 5.*x1**2*x0 + x1*x0**2 + x0**3) / (12.*(x1-x0)) - I2 = ( x2**3 + x2**2*x1 - 5.*x2*x1**2 + 3.*x1**3 ) / (12.*(x2-x1)) - d0 = I1 + I2 - d1 = (x2d**2-x1d**2)/12. - A = scpsp.diags([d0,d1,d1], [0,-1,1], shape=(NFunc,NFunc)) - - elif Deg==2: - if Mode=='Surf': - I1 = (x1-x0)**3 / (5.*(x2-x0)**2) - I2_1 = (x2-x1)*( x2**2 + 3.*x2*x1 + 6.*x1**2 - 5.*x0*(x2+3.*x1) + 10.*x0**2 ) / (30.*(x2-x0)**2) - I2_2 = (x2-x1)*( -3.*x2**2 - 4.*x2*x1 - 3.*x1**2 + 5.*(x3+x0)*(x2+x1) - 10.*x3*x0 ) / (30.*(x2-x0)*(x3-x1)) - I2_3 = (x2-x1)*( 6.*x2**2 + 3.*x2*x1 + x1**2 - 5.*x3*(3.*x2+x1) + 10.*x3**2 ) / (30.*(x3-x1)**2) - I2 = I2_1 + I2_2 + I2_3 - I3 = (x3-x2)**3 / (5.*(x3-x1)**2) - d0 = I1 + I2 + I3 - - Id1_1 = (3.*x2d1+2.*x1d1-5.*x0d1)*(x2d1-x1d1)**2 / (60.*(x3d1-x1d1)*(x2d1-x0d1)) + (5.*x3d1-4.*x2d1-x1d1)*(x2d1-x1d1)**2 / (20.*(x3d1-x1d1)**2) - Id1_2 = (4.*x2d1+x3d1-5.*x1d1)*(x3d1-x2d1)**2 / (20.*(x3d1-x1d1)**2) + (5.*x4d1-2.*x3d1-3.*x2d1)*(x3d1-x2d1)**2 / (60.*(x4d1-x2d1)*(x3d1-x1d1)) - d1 = Id1_1 + Id1_2 - d2 = (x3d2-x2d2)**3 / (30.*(x4d2-x2d2)*(x3d2-x1d2)) - else: - I1 = (5.*x1+x0)*(x1-x0)**3 / (30.*(x2-x0)**2) - I2_1 = (x2-x1) * ( x2**3 + 3.*x2**2*x1 + 6.*x2*x1**2 + 10.*x1**3 - 4.*x0*(x2**2+3.*x2*x1+6.*x1**2) + 5.*x0**2*(x2+3.*x1) ) / (60.*(x2-x0)**2) - I2_2 = (x2-x1) * ( -2.*x2**3 - 3.*x2**2*x1 - 3.*x2*x1**2 - 2.*x1**3 + (x3+x0)*(3.*x2**2+4.*x2*x1+3.*x1**2) - 5.*x3*x0*(x2+x1) ) / (30.*(x2-x0)*(x3-x1)) - I2_3 = (x2-x1) * ( 10.*x2**3 + 6.*x2**2*x1 + 3.*x2*x1**2 + x1**3 - 4.*x3*(6.*x2**2+3.*x2*x1+x1**2) + 5.*x3**2*(3.*x2+x1) ) / (60.*(x3-x1)**2) - I2 = I2_1 + I2_2 + I2_3 - I3 = (x3+5.*x2)*(x3-x2)**2 / (30.*(x3-x1)**2) - d0 = I1 + I2 + I3 - - Id1_1 = (x2d1-x1d1)**2 * ( 2.*x2d1**2+2.*x2d1*x1d1+x1d1**2 - x0d1*(3.*x2d1+2.*x1d1) ) / (60.*(x3d1-x1d1)*(x2d1-x0d1)) \ - + (x2d1-x1d1)**2 * ( -10.*x2d1**2-4.*x2d1*x1d1-x1d1**2 + 3.*x3d1*(4.*x2d1+x1d1) ) / (60.*(x3d1-x1d1)**2) - Id1_2 = (x3d1-x2d1)**2 * ( x3d1**2+4.*x3d1*x2d1+10.*x2d1**2 - 3.*x1d1*(x3d1+4.*x2d1) ) / (60.*(x3d1-x1d1)**2) \ - + (x3d1-x2d1)**2 * ( -x3d1**2-2.*x3d1*x2d1-2.*x2d1**2 + x4d1*(2.*x3d1+3.*x2d1) ) / (60.*(x4d1-x2d1)*(x3d1-x1d1)) - d1 = Id1_1 + Id1_2 - d2 = (x3d2+x2d2)*(x3d2-x2d2)**3 / (60.*(x4d2-x2d2)*(x3d2-x1d2)) - - A = scpsp.diags([d0,d1,d1,d2,d2], [0,-1,1,-2,2], shape=(NFunc,NFunc)) - - elif Deg==3: - assert not Deg==3, "Exact expressions have not been coded for D0N2 of Deg=3 yet (in process, to be finished) !" - if Mode=='Surf': - I1 = (x1-x0)**5 / (7.*(x3-x0)**2*(x2-x0)**2) # Ok - I2 = (_D0N2_Deg3_Surf(x2, A1,B1,C1,D1) - _D0N2_Deg3_Surf(x1, A1,B1,C1,D1)) / (210.*Den1**2) # Wrong or not accurate enough => Needs simplifying ? - I3 = (_D0N2_Deg3_Surf(x3, A2,B2,C2,D2) - _D0N2_Deg3_Surf(x2, A2,B2,C2,D2)) / (210.*Den2**2) # Wrong or not accurate enough => Needs simplifying ? - I4 = (x4-x3)**5 / (7.*(x4-x2)**2*(x4-x1)**2) # Ok - d0 = I1 + I2 + I3 + I4 - - Id1_1 = 0 - Id1_2 = 0 - Id1_3 = 0 - d1 = Id1_1 + Id1_2 + Id1_3 - - Id2_1 = 0 - Id2_2 = 0 - d2 = Id2_1 + Id2_2 - - d3 = 0 - - else: - I1 = (x1-x0)**5 / (7.*(x3-x0)**2*(x2-x0)**2) - I2 = 0 - I3 = 0 - I4 = (x4-x3)**5 / (7.*(x4-x2)**2*(x4-x1)**2) - d0 = I1 + I2 + I3 + I4 - - Id1_1 = 0 - Id1_2 = 0 - Id1_3 = 0 - d1 = Id1_1 + Id1_2 + Id1_3 - - Id2_1 = 0 - Id2_2 = 0 - d2 = Id2_1 + Id2_2 - - d3 = 0 - - A = scpsp.diags([d0,d1,d1,d2,d2,d3,d3], [0,-1,1,-2,2,-3,3], shape=(NFunc,NFunc)) - - - elif Deriv == 'D1N2': - if Deg==1: - if Mode=='Surf': - d0 = 1./(x1-x0) + 1./(x2-x1) - d1 = -1./(x2d-x1d) - else: - d0 = (x1+x0)/(2.*(x1-x0)) + (x2+x1)/(2.*(x2-x1)) - d1 = -(x2d+x1d)/(2.*(x2d-x1d)) - A = scpsp.diags([d0,d1,d1], [0,-1,1], shape=(NFunc,NFunc)) - - elif Deg==2: - if Mode=='Surf': - I1 = 4.*(x1-x0) / (3.*(x2-x0)**2) - I2 = 4.*(x2-x1) * ( x2**2 + x2*x1 + x1**2 + x3**2 + x3*x0 + x0**2 - x3*(x2+2.*x1) - x0*(2.*x2+x1) ) / (3.*(x3-x1)**2*(x2-x0)**2) - I3 = 4.*(x3-x2) / (3.*(x3-x1)**2) - d0 = I1 + I2 + I3 - - Id1_1 = 2.*(x2d1-x1d1)*( x3d1 - 2.*x2d1 - x1d1 + 2.*x0d1 ) / (3.*(x3d1-x1d1)**2*(x2d1-x0d1)) - Id1_2 = 2.*(x3d1-x2d1)*( -2.*x4d1 + x3d1 + 2.*x2d1 - x1d1 ) / (3.*(x4d1-x2d1)*(x3d1-x1d1)**2) - d1 = Id1_1 + Id1_2 - d2 = -2.*(x3d2-x2d2) / (3.*(x4d2-x2d2)*(x3d2-x1d2)) - else: - I1 = (3.*x1+x0)*(x1-x0) / (3.*(x2-x0)**2) - I2 = (x2-x1) * ( 3.*(x2+x1)*(x2**2+x1**2) + x3**2*(x2+3.*x1) + x0**2*(3.*x2+x1) - 2.*x3*(x2**2+2.*x1*x2+3.*x1**2) -2.*x0*(3.*x2**2+2.*x2*x1+x1**2) + 2.*x3*x0*(x2+x1) ) / (3.*(x3-x1)**2*(x2-x0)**2) - I3 = (x3+3.*x2)*(x3-x2) / (3.*(x3-x1)**2) - d0 = I1 + I2 + I3 - - Id1_1 = (x2d1-x1d1) * ( -(3.*x2d1**2 + 2.*x2d1*x1d1 + x1d1**2) + x3d1*(x2d1+x1d1) + x0d1*(3.*x2d1+x1d1) ) / (3.*(x3d1-x1d1)**2*(x2d1-x0d1)) - Id1_2 = (x3d1-x2d1) * ( x3d1**2 + 2.*x3d1*x2d1 + 3.*x2d1**2 - x4d1*(x3d1+3.*x2d1) - x1d1*(x3d1+x2d1) ) / (3.*(x4d1-x2d1)*(x3d1-x1d1)**2) - d1 = Id1_1 + Id1_2 - d2 = -(x3d2+x2d2)*(x3d2-x2d2) / (3.*(x4d2-x2d2)*(x3d2-x1d2)) - A = scpsp.diags([d0,d1,d1,d2,d2], [0,-1,1,-2,2], shape=(NFunc,NFunc)) - - elif Deg==3: - assert not Deg==3, "Exact expressions have not been coded for D1N2 of Deg=3 yet (in process, to be finished) !" - if Mode=='Surf': - I1 = 9.*(x1-x0)**3 / (5.*(x3-x0)**2*(x2-x0)**2) # Ok - I2 = (_D1N2_Deg3_Surf(x2, A1, B1, C1) - _D1N2_Deg3_Surf(x1, A1, B1, C1)) / (15.*Den1**2) # Ok but simpify ? - I3 = (_D1N2_Deg3_Surf(x3, A2, B2, C2) - _D1N2_Deg3_Surf(x2, A2, B2, C2)) / (15.*Den2**2) # Ok but simpify ? - I4 = 9.*(x4-x3)**3 / (5.*(x4-x2)**2*(x4-x1)**2) # Ok - d0 = I1 + I2 + I3 + I4 - - Id1_1 = 0 - Id1_2 = 0 - Id1_3 = 0 - d1 = Id1_1 + Id1_2 + Id1_3 - - Id2_1 = 0 - Id2_2 = 0 - d2 = Id2_1 + Id2_2 - - d3 = -3.*(x4d3-x3d3)**3 / (10.*(x6d3-x3d3)*(x5d3-x3d3)*(x4d3-x2d3)*(x4d3-x1d3)) # Ok - - else: - I1 = 0 - I2 = 0 - I3 = 0 - I4 = 0 - d0 = I1 + I2 + I3 + I4 - - Id1_1 = 0 - Id1_2 = 0 - Id1_3 = 0 - d1 = Id1_1 + Id1_2 + Id1_3 - - Id2_1 = 0 - Id2_2 = 0 - d2 = Id2_1 + Id2_2 - - d3 = 0 - - A = scpsp.diags([d0,d1,d1,d2,d2,d3,d3], [0,-1,1,-2,2,-3,3], shape=(NFunc,NFunc)) - - elif Deriv == 'D2N2': - if Deg==2: - if Mode=='Surf': - I1 = 4. / ((x2-x0)**2*(x1-x0)) - I2 = 4.*(x3+x2-x1-x0)**2 / ((x3-x1)**2*(x2-x1)*(x2-x0)**2) - I3 = 4. / ((x3-x2)*(x3-x1)**2) - d0 = I1 + I2 + I3 - - Id1_1 = -4.*(x3d1+x2d1-x1d1-x0d1) / ((x3d1-x1d1)**2*(x2d1-x1d1)*(x2d1-x0d1)) - Id1_2 = -4.*(x4d1+x3d1-x2d1-x1d1) / ((x4d1-x2d1)*(x3d1-x2d1)*(x3d1-x1d1)**2) - d1 = Id1_1 + Id1_2 - - d2 = 4. / ((x4d2-x2d2)*(x3d2-x2d2)*(x3d2-x1d2)) - else: - I1 = 2.*(x1+x0) / ((x2-x0)**2*(x1-x0)) - I2 = 2.*(x3+x2-x1-x0)**2*(x2+x1) / ((x3-x1)**2*(x2-x1)*(x2-x0)**2) - I3 = 2.*(x3+x2) / ((x3-x2)*(x3-x1)**2) - d0 = I1 + I2 + I3 - - Id1_1 = -2.*(x3d1+x2d1-x1d1-x0d1)*(x2d1+x1d1) / ((x3d1-x1d1)**2*(x2d1-x1d1)*(x2d1-x0d1)) - Id1_2 = -2.*(x4d1+x3d1-x2d1-x1d1)*(x3d1+x2d1) / ((x4d1-x2d1)*(x3d1-x2d1)*(x3d1-x1d1)**2) - d1 = Id1_1 + Id1_2 - - d2 = 2.*(x3d2+x2d2) / ((x4d2-x2d2)*(x3d2-x2d2)*(x3d2-x1d2)) - A = scpsp.diags([d0,d1,d1,d2,d2], [0,-1,1,-2,2], shape=(NFunc,NFunc)) - - elif Deg==3: - if Mode=='Surf': - I1 = 12.*(x1-x0) / ((x3-x0)**2*(x2-x0)**2) - I2 = (12.*A1**2*(x2**2+x2*x1+x1**2) + 12.*A1*B1*(x2+x1) + 4.*B1**2) / (Den1m**2*(x2-x1)) - I3 = (12.*A2**2*(x3**2+x3*x2+x2**2) + 12.*A2*B2*(x3+x2) + 4.*B2**2) / (Den2m**2*(x3-x2)) - I4 = 12.*(x4-x3) / ((x4-x2)**2*(x4-x1)**2) - d0 = I1 + I2 + I3 + I4 - - Id1_1 = 6.*( A1d1*(2.*x2d1+x1d1) + B1d1 ) / ((x4d1-x1d1)**2*(x3d1-x1d1)**2*(x3d1-x0d1)*(x2d1-x0d1)) - Id1_2 = 2.*( 6.*A2d1*A1_1d1*(x3d1**2+x3d1*x2d1+x2d1**2) + 3.*(A1_1d1*B2d1 + A2d1*B1_1d1)*(x3d1+x2d1) + 2.*B2d1*B1_1d1 ) / ((x5d1-x2d1)*(x4d1-x2d1)**2*(x4d1-x1d1)**2*(x3d1-x2d1)*(x3d1-x1d1)**2*(x3d1-x0d1)) - Id1_3 = 6.*( A2_1d1*(x4d1+2.*x3d1) + B2_1d1 ) / ((x5d1-x3d1)*(x5d1-x2d1)*(x4d1-x3d1)*(x4d1-x2d1)**2*(x4d1-x1d1)**2) - d1 = Id1_1 + Id1_2 + Id1_3 - - Id2_1 = 6.*( A2d2*(2.*x3d2 + x2d2) + B2d2 ) / ((x5d2-x2d2)*(x4d2-x2d2)**2*(x4d2-x1d2)*(x3d2-x1d2)*(x3d2-x0d2)) - Id2_2 = 6.*( A1_2d2*(x4d2+2.*x3d2) + B1_2d2 ) / ((x6d2-x3d2)*(x5d2-x3d2)*(x5d2-x2d2)*(x4d2-x2d2)**2*(x4d2-x1d2)) - d2 = Id2_1 + Id2_2 - - d3 = 6.*(x4d3-x3d3) / ((x6d3-x3d3)*(x5d3-x3d3)*(x4d3-x2d3)*(x4d3-x1d3)) - - else: - I1 = 3.*(3.*x1+x0)*(x1-x0) / ((x3-x0)**2*(x2-x0)**2) - I2 = ( 9.*A1**2*(x2**3+x2**2*x1+x2*x1**2+x1**3) + 8.*A1*B1*(x2**2+x2*x1+x1**2) + 2.*B1**2*(x2+x1) ) / ((x4-x1)**2*(x3-x1)**2*(x3-x0)**2*(x2-x1)*(x2-x0)**2) - I3 = ( 9.*A2**2*(x3**3+x3**2*x2+x3*x2**2+x2**3) + 8.*A2*B2*(x3**2+x3*x2+x2**2) + 2.*B2**2*(x3+x2) ) / ((x4-x2)**2*(x4-x1)**2*(x3-x2)*(x3-x1)**2*(x3-x0)**2) - I4 = 3.*(x4+3.*x3)*(x4-x3) / ((x4-x2)**2*(x4-x1)**2) - d0 = I1 + I2 + I3 + I4 - - Id1_1 = ( 3.*A1d1*(3.*x2d1**2+2.*x2d1*x1d1+x1d1**2) + 2.*B1d1*(2.*x2d1+x1d1) ) / ((x4d1-x1d1)**2*(x3d1-x1d1)**2*(x3d1-x0d1)*(x2d1-x0d1)) - Id1_2 = ( 9.*A2d1*A1_1d1*(x3d1**3+x3d1**2*x2d1+x3d1*x2d1**2+x2d1**3) + 4.*(A1_1d1*B2d1 + A2d1*B1_1d1)*(x3d1**2+x3d1*x2d1+x2d1**2) + 2.*B2d1*B1_1d1*(x3d1+x2d1) ) / ((x5d1-x2d1)*(x4d1-x2d1)**2*(x4d1-x1d1)**2*(x3d1-x2d1)*(x3d1-x1d1)**2*(x3d1-x0d1)) - Id1_3 = ( 3.*A2_1d1*(x4d1**2+2.*x4d1*x3d1+3.*x3d1**2) + 2.*B2_1d1*(x4d1+2.*x3d1) ) / ((x5d1-x3d1)*(x5d1-x2d1)*(x4d1-x2d1)**2*(x4d1-x1d1)**2) - d1 = Id1_1 + Id1_2 + Id1_3 - - Id2_1 = ( 3.*A2d2*(3.*x3d2**2+2.*x3d2*x2d2+x2d2**2) + 2.*B2d2*(2.*x3d2+x2d2) ) / ((x5d2-x2d2)*(x4d2-x2d2)**2*(x4d2-x1d2)*(x3d2-x1d2)*(x3d2-x0d2)) - Id2_2 = ( 3.*A1_2d2*(x4d2**2+2.*x4d2*x3d2+3.*x3d2**2) + 2.*B1_2d2*(x4d2+2.*x3d2) ) / ((x6d2-x3d2)*(x5d2-x3d2)*(x5d2-x2d2)*(x4d2-x2d2)**2*(x4d2-x1d2)) - d2 = Id2_1 + Id2_2 - - d3 = 3.*(x4d3**2-x3d3**2) / ((x6d3-x3d3)*(x5d3-x3d3)*(x4d3-x2d3)*(x4d3-x1d3)) - - A = scpsp.diags([d0,d1,d1,d2,d2,d3,d3], [0,-1,1,-2,2,-3,3], shape=(NFunc,NFunc)) - - elif Deriv == 'D3N2': - if Deg==3: - if Mode=='Surf': - I1 = 36. / ((x3-x0)**2*(x2-x0)**2*(x1-x0)) - I2 = 36.*A1**2 / ((x4-x1)**2*(x3-x1)**2*(x3-x0)**2*(x2-x1)*(x2-x0)**2) - I3 = 36.*A2**2 / ((x4-x2)**2*(x4-x1)**2*(x3-x2)*(x3-x1)**2*(x3-x0)**2) - I4 = 36./((x4-x3)*(x4-x2)**2*(x4-x1)**2) - d0 = I1 + I2 + I3 + I4 - - Id1_1 = 36.*A1d1 / ((x4d1-x1d1)**2 *(x3d1-x1d1)**2*(x3d1-x0d1)*(x2d1-x1d1)**2*(x2d1-x0d1)) - Id1_2 = 36.*A2d1*A1_1d1 / ((x5d1-x2d1)*(x4d1-x2d1)**2*(x4d1-x1d1)**2*(x3d1-x2d1)*(x3d1-x1d1)**2*(x3d1-x0d1)) - Id1_3 = -36.*A2_1d1 / ((x5d1-x3d1)*(x5d1-x2d1)*(x4d1-x3d1)*(x4d1-x2d1)**2*(x4d1-x1d1)**2) - d1 = Id1_1 + Id1_2 + Id1_3 - - Id2_1 = 36.*A2d2 / ((x5d2-x2d2)*(x4d2-x2d2)**2*(x4d2-x1d2)*(x3d2-x2d2)**2*(x3d2-x1d2)*(x3d2-x0d2)) - Id2_2 = -36.*A1_2d2 / ((x6d2-x3d2)*(x5d2-x3d2)*(x5d2-x2d2)*(x4d2-x3d2)**2*(x4d2-x2d2)**2*(x4d2-x1d2)) - d2 = Id2_1 + Id2_2 - - d3 = -36. / ((x6d3-x3d3)*(x5d3-x3d3)*(x4d3-x3d3)**2*(x4d3-x2d3)*(x4d3-x1d3)) - - else: - I1 = 18.*(x1+x0) / ((x3-x0)**2*(x2-x0)**2*(x1-x0)) - I2 = 18.*A1**2*(x2+x1) / ((x4-x1)**2*(x3-x1)**2*(x3-x0)**2*(x2-x1)*(x2-x0)**2) - I3 = 18.*A2**2*(x3+x2) / ((x4-x2)**2*(x4-x1)**2*(x3-x2)*(x3-x1)**2*(x3-x0)**2) - I4 = 18.*(x4+x3) /((x4-x3)*(x4-x2)**2*(x4-x1)**2) - d0 = I1 + I2 + I3 + I4 - - Id1_1 = 18.*A1d1*(x2d1+x1d1) / ((x4d1-x1d1)**2 *(x3d1-x1d1)**2*(x3d1-x0d1)*(x2d1-x1d1)**2*(x2d1-x0d1)) - Id1_2 = 18.*A2d1*A1_1d1*(x3d1+x2d1) / ((x5d1-x2d1)*(x4d1-x2d1)**2*(x4d1-x1d1)**2*(x3d1-x2d1)*(x3d1-x1d1)**2*(x3d1-x0d1)) - Id1_3 = -18.*A2_1d1*(x4d1+x3d1) / ((x5d1-x3d1)*(x5d1-x2d1)*(x4d1-x3d1)*(x4d1-x2d1)**2*(x4d1-x1d1)**2) - d1 = Id1_1 + Id1_2 + Id1_3 - - Id2_1 = 18.*A2d2*(x3d2+x2d2) / ((x5d2-x2d2)*(x4d2-x2d2)**2*(x4d2-x1d2)*(x3d2-x2d2)**2*(x3d2-x1d2)*(x3d2-x0d2)) - Id2_2 = -18.*A1_2d2*(x4d2+x3d2) / ((x6d2-x3d2)*(x5d2-x3d2)*(x5d2-x2d2)*(x4d2-x3d2)**2*(x4d2-x2d2)**2*(x4d2-x1d2)) - d2 = Id2_1 + Id2_2 - - d3 = -18.*(x4d3+x3d3) / ((x6d3-x3d3)*(x5d3-x3d3)*(x4d3-x3d3)**2*(x4d3-x2d3)*(x4d3-x1d3)) - - A = scpsp.diags([d0,d1,d1,d2,d2,d3,d3], [0,-1,1,-2,2,-3,3], shape=(NFunc,NFunc)) - - - - return A - - - - -cdef _D0N2_Deg3_Surf(x, A, B, C, D): - return 30.*A**2*x**7 + 70.*A*B*x**6 + 42.*(2.*A*C+B**2)*x**5 + 105.*(A*D+B*C)*x**4 + 70.*(2.*B*D+C**2)*x**3 + 210.*C*D*x**2 + 210.*D**2*x - -cdef _D1N2_Deg3_Surf(x, A, B, C): - return 27.*A**2*x**5 + 45.*A*B*x**4 + 10.*(2.*B**2+3.*A*C)*x**3 + 30.*B*C*x**2 + 15.*C**2*x - - - - - - - - - - - -""" -def Calc_IntOp_BSpline(cnp.ndarray[cnp.float64_t, ndim=1] Knots, int Deg, Deriv=0, Sparse=tfd.L1IntOpSpa, SpaFormat=tfd.L1IntOpSpaFormat, Test=True): - if Test: - assert isinstance(Knots,np.ndarray) and Knots.ndim==1, "Arg Knots must be a (N,) np.ndarray instance !" - assert type(Deg) is int and Deg>=0 and Deg<=3, "Arg Deg must be a positive int !" - if type(Deriv) is int: - assert Deriv<=Deg, "Arg Deriv must be smller than Deg !" - elif type(Deriv) is str: - assert int(Deriv[1])<=Deg and Deriv in ['D0','D1','D2','D3','D0N2','D1N2','D2N2','D3N2'], "Arg Deriv must be smaller than Deg and in ['D0','D1','D2','D3','D0N2','D1N2','D2N2','D3N2'] !" - - intDeriv = int(Deriv[1]) if type(Deriv) is str else Deriv - - NKnots = Knots.size - NFunc = NKnots-Deg-1 - A = np.zeros((NFunc,NFunc)) - if not 'N' in Deriv and not 'FI' in Deriv: - m = 0 - if Dbis==0: - if Deg==0: - A = np.diff(Knots) - elif Deg==1: - A = 0.5*(Knots[2:]-Knots[0:-2]) - elif Deg==2: - Int1 = (Knots[1:-2] - Knots[0:-3])**2 / (3.*(Knots[2:-1]-Knots[0:-3])) - Int21 = ( Knots[2:-1]**2 - 2.*Knots[1:-2]**2 + Knots[1:-2]*Knots[2:-1] + 3.*Knots[0:-3]*(Knots[1:-2]-Knots[2:-1]) ) / (6.*(Knots[2:-1]-Knots[0:-3])) - Int22 = ( -2.*Knots[2:-1]**2 + Knots[1:-2]**2 + Knots[1:-2]*Knots[2:-1] + 3.*Knots[3:]*(Knots[2:-1]-Knots[1:-2]) ) / (6.*(Knots[3:]-Knots[1:-2])) - Int3 = ( Knots[3:] - Knots[2:-1] )**2 / (3.*(Knots[3:]-Knots[1:-2])) - A = Int1+Int21+Int22+Int3 - elif Deg==3: - print "NOT CODED YET !" - Int1 = (Knots[1:-3]-Knots[0:-4])**3/(4.*(Knots[3:-1]-Knots[0:-4])*(Knots[2:-2]-Knots[0:-4])) - Int211 = ( (Knots[2:-2]-Knots[0:-4])**4/4. - (Knots[1:-3]-Knots[0:-4])**3*(Knots[2:-2]-Knots[1:-3] + (Knots[1:-3]-Knots[0:-4])/4.) ) / ( 3.*(Knots[3:-1]-Knots[0:-4])*(Knots[2:-2]-Knots[0:-4])*(Knots[2:-2]-Knots[1:-3]) ) - Int212 = ( -Knots[2:-2]**4-Knots[1:-3]**4/12. + (Knots[0:-4]+Knots[3:-1])*(Knots[2:-2]**3-Knots[1:-3]*Knots[2:-2]**2/2.+Knots[1:-3]**3/6.) + Knots[1:-3]*Knots[2:-2]**3/3. - Knots[0:-4]*Knots[3:-1]*(Knots[2:-2]**2+Knots[1:-3]**2)/2. + Knots[0:-4]*Knots[1:-3]*Knots[2:-2]*Knots[3:-4] ) / ( (Knots[3:-1]-Knots[0:-4])*(Knots[2:-2]-Knots[1:-3])*(Knots[3:-1]-Knots[1:-3]) ) - Int22 = (Knots[2:-2]-Knots[1:-3])**2*( (Knots[4:]-Knots[2:-2]) + (Knots[2:-2]-Knots[1:-3]) ) / ( (Knots[4:]-Knots[1:-3])*(Knots[3:-1]-Knots[1:-3]) ) - Int31 = ( (Knots[3:-1]-Knots[2:-2])**2*( (Knots[2:-2]-Knots[0:-4]) + (Knots[3:-1]-Knots[2:-2])/4. ) ) / ( 3.*((Knots[3:-1]-Knots[0:-4])*(Knots[3:-1]-Knots[1:-3])) ) - Int321 = 0 # To be finished - Int322 = 0 # To be finished - Int4 = 0 # To be finished - A = Int1+Int211+Int212+Int22+Int31+Int321+Int322+Int4 - - elif Dbis>=1: - A = np.zeros((NFunc,)) - - elif 'N2' in Deriv: - m = 1 - if Dbis==0: - if Deg==0: - A = scpsp.diags([np.diff(Knots)],[0],shape=None,format=SpaFormat) - elif Deg==1: - d0 = (Knots[2:]-Knots[0:-2])/3. - dp1 = (Knots[2:-1]-Knots[1:-2])/6. - A = scpsp.diags([d0,dp1,dp1], [0,1,-1],shape=None,format=SpaFormat) - elif Deg==2: - print "NOT CODED YET !" - d0 = (Knots[1:-2]-Knots[0:-3])**3/(5.*(Knots[2:-1]-Knots[0:-3])**2) + 0 + 0 # To be finished - dp1 = 0 # To be finished - dp2 = 0 # To be finished - A = scpsp.diags([d0,dp1,dp1,dp2,dp2], [0,1,-1,2,-2],shape=None,format=SpaFormat) - elif Deg==3: - print "NOT CODED YET !" - A = 0 - elif Dbis==1: - if Deg==1: - print "NOT CODED YET !" - A = 0 - elif Deg==2: - print "NOT CODED YET !" - A = 0 - elif Deg==3: - print "NOT CODED YET !" - A = 0 - elif Dbis==2: - if Deg==2: - print "NOT CODED YET !" - A = 0 - elif Deg==3: - print "NOT CODED YET !" - A = 0 - elif Dbis==3: - if Deg==3: - print "NOT CODED YET !" - A = 0 - - if not Sparse: - A = np.array(A.todense()) - - return A, m -""" - - - - - - - - - - diff --git a/tofu/mesh/_compute.py b/tofu/mesh/_compute.py deleted file mode 100644 index e99b3fbd2..000000000 --- a/tofu/mesh/_compute.py +++ /dev/null @@ -1,2452 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Aug 25 10:03:58 2014 - -@author: didiervezinet -""" - -import numpy as np - -import Polygon as plg -import scipy.sparse as scpsp -import scipy.interpolate as scpinterp - -import matplotlib.pyplot as plt -from mpl_toolkits.mplot3d import Axes3D -from matplotlib.path import Path -import matplotlib.patches as patches -from matplotlib.collections import PatchCollection as PcthColl - -import datetime as dtm - - -# ToFu-specific -import tofu.defaults as tfd -import tofu.pathfile as TFPF -from . import _bsplines_cy as _tfm_bs -from tofu.geom import _GG as TFGG # For Remap_2DFromFlat() only => make local version to get rid of dependency ? - - - - -""" -############################################################################### -############################################################################### - Default -############################################################################### -""" - -BS2Dict_Def = {'linewidth':0.,'rstride':1,'cstride':1, 'antialiased':False} -Tot2Dict_Def = {'color':(0.7,0.7,0.7),'linewidth':0.,'rstride':1,'cstride':1, 'antialiased':False} -SuppDict_Def = {'facecolor':(0.8,0.8,0.8), 'lw':0.} -PMaxDict_Def = {'color':'g', 'marker':'s', 'markersize':8, 'linestyle':'None', 'linewidth':1.} - - -""" -############################################################################### -############################################################################### - Mesh definitions -############################################################################### -""" - -############################################ -##### Computing functions for Mesh1D -############################################ - - -def _Mesh1D_set_Knots(Knots): - Knots = np.asarray(Knots) - NCents = Knots.size-1 - NKnots = Knots.size - Cents = (Knots[:-1]+Knots[1:])/2. - Lengths = np.diff(Knots) - Length = Knots.max()-Knots.min() - Bary = 0.5*(Knots[0]+Knots[-1]) - Cents_Knotsind = np.array([np.arange(0,NKnots-1),np.arange(1,NKnots)]) - Knots_Centsind = np.concatenate((np.array([[np.nan],[0]]),np.array([np.arange(0,NCents-1),np.arange(1,NCents)]), np.array([[NCents-1],[np.nan]])), axis=1) - return NKnots, Knots.astype(float), NCents, Cents.astype(float), Lengths.astype(float), float(Length), float(Bary), Cents_Knotsind.astype(int), Knots_Centsind - - -def _Mesh1D_sample(Knots, Sub=tfd.BF1Sub, SubMode=tfd.BF1SubMode, Test=True): - if Test: - assert hasattr(Knots,'__iter__') and np.asarray(Knots).ndim==1 and np.all(Knots==np.unique(Knots)), "Arg Knots must be a 1-dim iterable of unique values !" - assert type(Sub) is float, "Arg SubP must be a float !" - assert SubMode in ['rel','abs'], "Arg SubMode must be in ['rel','abs'] !" - - nKnots = len(Knots) - if SubMode=='abs': - sub = int(round((Knots[-1]-Knots[0])/Sub))+1 - X = np.linspace(Knots[0],Knots[-1],sub,endpoint=True) - else: - X = np.reshape(Knots,(1,nKnots)) - X = np.concatenate((X[:,:-1],X[:,1:]),axis=0) - sub = int(round(1./Sub)) - dd = np.delete(np.linspace(0,1,sub,endpoint=False),0) - Xtemp = np.dot(np.ones((sub-1,1)),X[0:1,:]) + np.dot(dd.reshape((sub-1,1)), np.diff(X,axis=0)) - X = np.concatenate((X[0:1,:],Xtemp,X[1:2,:]),axis=0) - X = np.unique(X.T.flatten()) - return X - - -############################################ -##### Computing functions for Mesh2D -############################################ - - - -def _Mesh2D_set_Cents_Knotsind(NCents, KnotsX1, KnotsX2, Cents, Knots): - Cents_Knotsind = np.zeros((4,NCents)) - for ii in range(0,NCents): - Rl = KnotsX1[KnotsX1 < Cents[0,ii]].max() - Rr = KnotsX1[KnotsX1 > Cents[0,ii]].min() - Zb = KnotsX2[KnotsX2 < Cents[1,ii]].max() - Zt = KnotsX2[KnotsX2 > Cents[1,ii]].min() - bl = np.where((Knots[0,:]==Rl)&(Knots[1,:]==Zb))[0][0] - br = np.where((Knots[0,:]==Rr)&(Knots[1,:]==Zb))[0][0] - tl = np.where((Knots[0,:]==Rl)&(Knots[1,:]==Zt))[0][0] - tr = np.where((Knots[0,:]==Rr)&(Knots[1,:]==Zt))[0][0] - Cents_Knotsind[:,ii] = np.array([bl,br,tr,tl]) - return Cents_Knotsind.astype(int) - - -def _Mesh2D_set_Knots_Centsind(NKnots, CentsX1, CentsX2, Knots, Cents, NCents): - Knots_Centsind = np.zeros((4,NKnots)) - for ii in range(0,NKnots): - indRl = CentsX1 < Knots[0,ii] - indRr = CentsX1 > Knots[0,ii] - indZb = CentsX2 < Knots[1,ii] - indZt = CentsX2 > Knots[1,ii] - RlBoo, RrBoo, ZbBoo, ZtBoo = np.any(indRl), np.any(indRr), np.any(indZb), np.any(indZt) - Rl = CentsX1[indRl].max() if RlBoo else False - Rr = CentsX1[indRr].min() if RrBoo else False - Zb = CentsX2[indZb].max() if ZbBoo else False - Zt = CentsX2[indZt].min() if ZtBoo else False - ind = (Cents[0,:]==Rl)&(Cents[1,:]==Zb) if RlBoo&ZbBoo else False - bl = np.where(ind)[0][0] if np.any(ind) else -NCents*10 - ind = (Cents[0,:]==Rl)&(Cents[1,:]==Zt) if RlBoo&ZtBoo else False - tl = np.where(ind)[0][0] if np.any(ind) else -NCents*10 - ind = (Cents[0,:]==Rr)&(Cents[1,:]==Zb) if RrBoo&ZbBoo else False - br = np.where(ind)[0][0] if np.any(ind) else -NCents*10 - ind = (Cents[0,:]==Rr)&(Cents[1,:]==Zt) if RrBoo&ZtBoo else False - tr = np.where(ind)[0][0] if np.any(ind) else -NCents*10 - Knots_Centsind[:,ii] = np.array([bl,br,tr,tl]) - return Knots_Centsind.astype(int) - - -def _Mesh2D_set_SurfVolBary(Knots, Cents_Knotsind, Cents, VType=None): - SuppX1 = np.array([Knots[0,Cents_Knotsind].min(axis=0), Knots[0,Cents_Knotsind].max(axis=0)]) - SuppX2 = np.array([Knots[1,Cents_Knotsind].min(axis=0), Knots[1,Cents_Knotsind].max(axis=0)]) - Surfs = ((np.diff(SuppX1,axis=0) * np.diff(SuppX2,axis=0)).flatten()).astype(float) - Surf = float(np.sum(Surfs)) - VolAngs = (0.5*np.diff(SuppX1**2,axis=0) * np.diff(SuppX2,axis=0)).flatten() if VType=='Tor' else None - VolAng = float(np.sum(VolAngs)) if VType=='Tor' else None - BaryS = np.sum(Cents*np.tile(Surfs,(2,1)),axis=1, keepdims=False)/Surf - CentsV = np.array([(2.*np.diff(SuppX1**3,axis=0)/(3.*np.diff(SuppX1**2,axis=0))).flatten(), 0.5*np.sum(SuppX2,axis=0)]) if VType=='Tor' else None - BaryV = np.sum(CentsV*np.tile(VolAngs,(2,1)),axis=1,keepdims=False)/VolAng if VType=='Tor' else None - return Surfs, Surf, VolAngs, VolAng, BaryS, BaryV, CentsV - - -def _Mesh2D_set_BoundPoly(Knots, Cents_Knotsind, NCents): - Poly = plg.Polygon(Knots[:,Cents_Knotsind[:,0]].T) - for ii in range(1,NCents): - Poly = Poly | plg.Polygon(Knots[:,Cents_Knotsind[:,ii]].T) - Poly = np.array(Poly[0]).T - return np.concatenate((Poly,Poly[:,0:1]),axis=1) - - -def _Mesh2D_get_SubMeshPolygon(Cents, Knots, Cents_Knotsind, Poly, InMode='Cents', NLim=1): - assert isinstance(Poly,np.ndarray) and Poly.ndim==2 and Poly.shape[0]==2, "Arg Poly must be a (2,N) np.ndarray !" - assert InMode in ['Cents','Knots'], "Arg InMode must be in ['Cents','Knots'] !" - if InMode=='Cents': - indIn = Path(Poly.T).contains_points(Cents.T) - else: - indIn = Path(Poly.T).contains_points(Knots.T) - NIn = np.sum(indIn[Cents_Knotsind],axis=0) - indIn = NIn >= NLim - return indIn - - -def _Mesh2D_get_CentBckg(NCentsX1, NCentsX2, CentsX1, CentsX2, Cents, NC): - NCents = NCentsX1*NCentsX2 - RCentBck = np.tile(CentsX1,(NCentsX2,1)).flatten() - ZCentBck = np.tile(CentsX2,(NCentsX1,1)).T.flatten() - indCentBckInMesh = np.zeros((NCents,),dtype=bool) - NumCentBck = np.nan*np.ones((NCents,)) - for ii in range(0,NC): - ind = (RCentBck==Cents[0,ii]) & (ZCentBck==Cents[1,ii]) - indCentBckInMesh[ind] = True - NumCentBck[ind] = ii - assert np.sum(indCentBckInMesh) == NC, " Wrong computation of Background Cents in Mesh !" - return np.array([RCentBck,ZCentBck]), indCentBckInMesh, NumCentBck - - -def _Mesh2D_get_KnotsBckg(NKX1, NKX2, KnotsX1, KnotsX2, Knots, NK): - NKnots = NKX1*NKX2 - RKnotBck = np.tile(KnotsX1,(NKX2,1)).flatten() - ZKnotBck = np.tile(KnotsX2,(NKX1,1)).T.flatten() - indKnotsBckInMesh = np.zeros((NKnots,),dtype=bool) - NumKnotBck = np.nan*np.ones((NKnots,)) - for ii in range(0,NK): - ind = (RKnotBck==Knots[0,ii]) & (ZKnotBck==Knots[1,ii]) - indKnotsBckInMesh[ind] = True - NumKnotBck[ind] = ii - assert np.sum(indKnotsBckInMesh) == NK, " Wrong computation of Background knots in Mesh !" - return np.array([RKnotBck,ZKnotBck]).astype(float), indKnotsBckInMesh, NumKnotBck - - -def _Mesh2D_isInside(Pts2D, BoundPoly): - assert isinstance(Pts2D,np.ndarray) and Pts2D.ndim==2 and Pts2D.shape[0]==2, "Arg Pts2D must be a (2,N) np.ndarray !" - return Path(BoundPoly.T).contains_points(Pts2D.T) - - -def _Mesh2D_sample(Knots, Sub=tfd.BF2Sub, SubMode=tfd.BF2SubMode, BoundPoly=None, Test=True): - if Test: - assert hasattr(Knots,'__iter__') and np.asarray(Knots).ndim==2 and np.asarray(Knots).shape[0]==2, "Arg Knots must be a 2-dim iterable !" - assert type(Sub) is float or (hasattr(Sub,'__iter__') and len(Sub)==2 and all([type(ss) is float for ss in Sub])), "Arg Sub must be a float !" - assert SubMode in ['rel','abs'], "Arg SubMode must be in ['rel','abs'] !" - assert BoundPoly is None or (type(BoundPoly) is np.ndarray and BoundPoly.ndim==2 and BoundPoly.shape[0]==2), "Arg BoundPoly must be a (2,N) np.ndarray !" - - Knots = np.asarray(Knots) - Sub = Sub if hasattr(Sub,'__iter__') else (Sub,Sub) - XX1 = _Mesh1D_sample(np.unique(Knots[0,:]), Sub=Sub[0], SubMode=SubMode, Test=Test) - XX2 = _Mesh1D_sample(np.unique(Knots[1,:]), Sub=Sub[0], SubMode=SubMode, Test=Test) - Pts = np.array([np.tile(XX1,(XX2.size,1)).flatten(), np.tile(XX2,(XX1.size,1)).T.flatten()]) - if BoundPoly is not None: - ind = _Mesh2D_isInside(Pts, BoundPoly) - Pts = Pts[:,ind] - return Pts - - - - -""" -############################################################################### -############################################################################### - LBF1D computing -############################################################################### -""" - - -def _LBF1D_get_Coefs(LFunc, NFunc, Knots, xx=None, yy=None, ff=None, Sub=tfd.BF1Sub, SubMode=tfd.BF1SubMode, Test=True): - if Test: - assert all([ss is None or type(ss) is np.ndarray and ss.ndim==1 for ss in [xx,yy]]), "Args xx and yy must be 1-dim np.ndarray !" - assert (xx is None and yy is None) or xx.size==yy.size, "Arg xx and yy must be provided together and they must have the same shape !" - assert ff is None or hasattr(ff,'__call__'), "Arg ff must be a callable function (with one arguments + optional kwdargs) !" - assert not all([xx is None or yy is None, ff is None]), "You must provide either a function (ff) or sampled data (xx and yy) !" - assert not all([ff is not None, Knots is None]), "Knots must be provided if ff is provided !" - - if ff is not None: - xx = _Mesh1D_sample(Knots, Sub=Sub, SubMode=SubMode, Test=Test) - yy = ff(xx) - - # Keep only points inside the Boundary - ind = (xx>=np.nanmin(Knots)) & (xx<=np.nanmax(Knots)) - xx, yy = xx[ind], yy[ind] - - A = _tfm_bs.Calc_BF1D_Weights(LFunc, xx) - Coefs, res, rank, sing = np.linalg.lstsq(A,yy) - if rank < NFunc: - xx1 = _Mesh1D_sample(Knots, Sub=Sub, SubMode=SubMode, Test=Test) - yy1 = scpinterp.interp1d(xx, yy, kind='linear', bounds_error=False, fill_value=0., assume_sorted=True)(xx1) - xx, yy = np.concatenate((xx,xx1)), np.concatenate((yy,yy1)) - xx, ind = np.unique(xx, return_index=True) - yy = yy[ind] - A = _tfm_bs.Calc_BF1D_Weights(LFunc, xx) - Coefs, res, rank, sing = np.linalg.lstsq(A,yy) - return Coefs, res - - - -def get_IntVal(N=None, Test=True): - - if not hasattr(Coefs,'__iter__'): - Coefs = Coefs*np.ones((NFunc,),dtype=float) - Coefs = np.asarray(Coefs) - Coefs = Coefs if Coefs.ndim==2 else np.tile(Coefs,(1,1)) - Nt = Coefs.shape[0] - - if Deriv in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D2N2','D3N2']: - A, m = self.get_IntOp(Deriv=Deriv, Method=Method, Mode=Mode, Sparse=True, SpaFormat=None, N=N, Test=Test) - if m==0: - Int = [A.dot(cc) for cc in Coefs] - elif m==1: - Int = [cc.dot(A.dot(cc)) for cc in Coefs] - - elif Deriv in ['D0ME','D1FI']: - Int = _tfm_bs.Calc_1D_IntVal_Quad(N=N) - - Int = np.array(Int) if Nt>1 else Int[0] - return Int - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -############################################ -##### Computing functions -############################################ - - -def Calc_SumMeshGrid2D(Knots1, Knots2, Sub=tfd.BF1Sub, SubMode=tfd.BF1SubMode, Test=True): - if Test: - assert isinstance(Knots1,np.ndarray) and Knots1.ndim==1, "Arg Knots must be a 1-dim np.ndarray !" - assert isinstance(Knots1,np.ndarray) and Knots1.ndim==1, "Arg Knots must be a 1-dim np.ndarray !" - assert type(Sub) is float, "Arg Sub must be a float !" - assert type(SubMode) is str and SubMode.lower() in ['rel','abs'], "Arg SubMode must be 'Rel' or 'Abs' !" - - SubMode = SubMode.lower() - X1, X2 = np.unique(Knots1), np.unique(Knots2) - nKnots1, nKnots2 = X1.size, X2.size - - if SubMode=='abs': - sub1, sub2 = int(round((X1[-1]-X1[0])/Sub)), int(round((X2[-1]-X2[0])/Sub)) - X1 = np.linspace(X1[0],X1[-1],sub1,endpoint=True) - X2 = np.linspace(X2[0],X2[-1],sub2,endpoint=True) - else: - X1, X2 = X1.reshape((1,nKnots1)), X2.reshape((1,nKnots2)) - X1, X2 = np.concatenate((X1[:,:-1],X1[:,1:]),axis=0), np.concatenate((X2[:,:-1],X2[:,1:]),axis=0) - sub = int(round(1./Sub)) - dd = np.delete(np.linspace(0,1,sub,endpoint=False),0) - Xtemp1 = np.dot(np.ones((sub-1,1)),X1[0:1,:]) + np.dot(dd.reshape((sub-1,1)), np.diff(X1,axis=0)) - Xtemp2 = np.dot(np.ones((sub-1,1)),X2[0:1,:]) + np.dot(dd.reshape((sub-1,1)), np.diff(X2,axis=0)) - X1, X2 = np.concatenate((X1[0:1,:],Xtemp1,X1[1:2,:]),axis=0), np.concatenate((X2[0:1,:],Xtemp2,X2[1:2,:]),axis=0) - X1, X2 = np.unique(X1.T.flatten()), np.unique(X2.T.flatten()) - return X1, X2 - - -""" -def Calc_IntOp_Elementary(Deg1, Deg2, BF1, BF2, K1, K2, D1, D2, Test=True): - F1 = BSplineDeriv(Deg1, K1, Deriv=D1, Test=False) - F2 = BSplineDeriv(Deg2, K2, Deriv=D2, Test=False) - -def Calc_IntOp_BSpline(Knots, Deg, Deriv=0, Sparse=tfd.L1IntOpSpa, SpaFormat=tfd.L1IntOpSpaFormat, Test=True): - if Test: - assert isinstance(Knots,np.ndarray) and Knots.ndim==1, "Arg Knots must be a (N,) np.ndarray instance !" - assert type(Deg) is int and Deg>=0, "Arg Deg must be a positive int !" - assert (type(Deriv) is int and Deriv<=Deg) or (type(Deriv) is str and Deriv in ['D0','D1','D2','D3','D0N2','D1N2','D2N2','D3N2','D1FI'] and int(Deriv[1])<=Deg), "Arg Deriv must be a int or a str !" - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - - NKnots = Knots.size - NFunc = NKnots-Deg-1 - A = np.zeros((NFunc,NFunc)) - if not 'N' in Deriv and not 'FI' in Deriv: - m = 0 - if Dbis==0: - if Deg==0: - A = np.diff(Knots) - elif Deg==1: - A = 0.5*(Knots[2:]-Knots[0:-2]) - elif Deg==2: - Int1 = (Knots[1:-2] - Knots[0:-3])**2 / (3.*(Knots[2:-1]-Knots[0:-3])) - Int21 = ( Knots[2:-1]**2 - 2.*Knots[1:-2]**2 + Knots[1:-2]*Knots[2:-1] + 3.*Knots[0:-3]*(Knots[1:-2]-Knots[2:-1]) ) / (6.*(Knots[2:-1]-Knots[0:-3])) - Int22 = ( -2.*Knots[2:-1]**2 + Knots[1:-2]**2 + Knots[1:-2]*Knots[2:-1] + 3.*Knots[3:]*(Knots[2:-1]-Knots[1:-2]) ) / (6.*(Knots[3:]-Knots[1:-2])) - Int3 = ( Knots[3:] - Knots[2:-1] )**2 / (3.*(Knots[3:]-Knots[1:-2])) - A = Int1+Int21+Int22+Int3 - elif Deg==3: - print "NOT CODED YET !" - Int1 = (Knots[1:-3]-Knots[0:-4])**3/(4.*(Knots[3:-1]-Knots[0:-4])*(Knots[2:-2]-Knots[0:-4])) - Int211 = ( (Knots[2:-2]-Knots[0:-4])**4/4. - (Knots[1:-3]-Knots[0:-4])**3*(Knots[2:-2]-Knots[1:-3] + (Knots[1:-3]-Knots[0:-4])/4.) ) / ( 3.*(Knots[3:-1]-Knots[0:-4])*(Knots[2:-2]-Knots[0:-4])*(Knots[2:-2]-Knots[1:-3]) ) - Int212 = ( -Knots[2:-2]**4-Knots[1:-3]**4/12. + (Knots[0:-4]+Knots[3:-1])*(Knots[2:-2]**3-Knots[1:-3]*Knots[2:-2]**2/2.+Knots[1:-3]**3/6.) + Knots[1:-3]*Knots[2:-2]**3/3. - Knots[0:-4]*Knots[3:-1]*(Knots[2:-2]**2+Knots[1:-3]**2)/2. + Knots[0:-4]*Knots[1:-3]*Knots[2:-2]*Knots[3:-4] ) / ( (Knots[3:-1]-Knots[0:-4])*(Knots[2:-2]-Knots[1:-3])*(Knots[3:-1]-Knots[1:-3]) ) - Int22 = (Knots[2:-2]-Knots[1:-3])**2*( (Knots[4:]-Knots[2:-2]) + (Knots[2:-2]-Knots[1:-3]) ) / ( (Knots[4:]-Knots[1:-3])*(Knots[3:-1]-Knots[1:-3]) ) - Int31 = ( (Knots[3:-1]-Knots[2:-2])**2*( (Knots[2:-2]-Knots[0:-4]) + (Knots[3:-1]-Knots[2:-2])/4. ) ) / ( 3.*((Knots[3:-1]-Knots[0:-4])*(Knots[3:-1]-Knots[1:-3])) ) - Int321 = 0 # To be finished - Int322 = 0 # To be finished - Int4 = 0 # To be finished - A = Int1+Int211+Int212+Int22+Int31+Int321+Int322+Int4 - - elif Dbis>=1: - A = np.zeros((NFunc,)) - - elif 'N2' in Deriv: - m = 1 - if Dbis==0: - if Deg==0: - A = scpsp.diags([np.diff(Knots)],[0],shape=None,format=SpaFormat) - elif Deg==1: - d0 = (Knots[2:]-Knots[0:-2])/3. - dp1 = (Knots[2:-1]-Knots[1:-2])/6. - A = scpsp.diags([d0,dp1,dp1], [0,1,-1],shape=None,format=SpaFormat) - elif Deg==2: - print "NOT CODED YET !" - d0 = (Knots[1:-2]-Knots[0:-3])**3/(5.*(Knots[2:-1]-Knots[0:-3])**2) + 0 + 0 # To be finished - dp1 = 0 # To be finished - dp2 = 0 # To be finished - A = scpsp.diags([d0,dp1,dp1,dp2,dp2], [0,1,-1,2,-2],shape=None,format=SpaFormat) - elif Deg==3: - print "NOT CODED YET !" - A = 0 - elif Dbis==1: - if Deg==1: - print "NOT CODED YET !" - A = 0 - elif Deg==2: - print "NOT CODED YET !" - A = 0 - elif Deg==3: - print "NOT CODED YET !" - A = 0 - elif Dbis==2: - if Deg==2: - print "NOT CODED YET !" - A = 0 - elif Deg==3: - print "NOT CODED YET !" - A = 0 - elif Dbis==3: - if Deg==3: - print "NOT CODED YET !" - A = 0 - - if not Sparse: - A = np.array(A.todense()) - - return A, m -""" - - - - -############################################ -##### Plotting functions -############################################ - - -def Plot_BSpline1D(Knots, FTot, LF, Elt='TL', ax='None', Name='', SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, LFdict=tfd.BF1Fd, Totdict=tfd.BF1Totd, LegDict=tfd.TorLegd, Test=True): - if Test: - assert ax=='None' or isinstance(ax,plt.Axes), "Arg ax must be a plt.Axes instance !" - assert type(Elt) is str, "Arg Elt must be a str !" - assert hasattr(FTot, '__call__') or FTot is None, "Arg FTot must be a function !" - assert (type(LF) is list and all([hasattr(ff,'__call__') for ff in LF])) or LF is None, "Arg BS must be a list of functions !" - assert type(LFdict) is dict, "Arg LFdict must be a dict !" - assert type(Totdict) is dict, "Arg Totdict must be a dict !" - - X = Calc_SumMeshGrid1D(Knots, SubP=SubP, SubMode=SubMode, Test=Test) - if ax=='None': - ax = tfd.Plot_BSpline_DefAxes('1D') - - if 'L' in Elt and not LF is None: - NBS = len(LF) - nx = X.size - Xplot = np.dot(np.ones((NBS,1)),X.reshape((1,nx))) - Y = np.nan*np.ones((NBS,nx)) - for ii in range(0,NBS): - Y[ii,:] = LF[ii](X) - ax.plot(Xplot.T, Y.T, **LFdict) - if 'T' in Elt and not FTot is None: - ax.plot(X, FTot(X), label=Name+' Tot', **Totdict) - - ax.set_xlim(np.min(X),np.max(X)) - if not LegDict is None: - ax.legend(**LegDict) - ax.figure.canvas.draw() - return ax - - - -def Plot_BSpline2D(BF2, ax='None', Elt='T', Deriv=0, Coefs=1., DVect=tfd.BF2_DVect_DefR, NC=tfd.BF2PlotNC, PlotMode=tfd.BF2PlotMode, SubP=tfd.BF2PlotSubP, SubMode=tfd.BF2PlotSubMode, Name='Tot', Totdict=tfd.BF2PlotTotd, LegDict=tfd.TorLegd, Test=True): - if Test: - assert ax=='None' or isinstance(ax,plt.Axes), "Arg ax must be a plt.Axes instance !" - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert type(Totdict) is dict, "Arg Totdict must be a dict !" - assert type(PlotMode) is str and PlotMode in ['contour','contourf','surf'], "Arg PlotMode must be in ['contour','contourf','surf'] !" - if type(Coefs) in [int,float]: - Coefs = Coefs*np.array((BF2._NFunc),dtype=float) - - Xplot, Yplot, nx, ny = BF2.get_XYplot(SubP=SubP, SubMode=SubMode) - PointsRZ = np.array([Xplot.flatten(),Yplot.flatten()]) - ind = BF2.Mesh.isInside(PointsRZ) - - Val = BF2.get_TotVal(PointsRZ,Deriv=Deriv,Coefs=Coefs,DVect=DVect, Test=Test) - Val[~ind] = np.nan - Val = Val.reshape(Xplot.shape) - - if PlotMode=='surf': - if ax=='None': - ax = tfd.Plot_BSpline_DefAxes('3D') - if 'T' in Elt: - ax.plot_surface(Xplot,Yplot,Val, label=Name, **Totdict) - else: - if ax=='None': - ax = tfd.Plot_BSpline_DefAxes('2D') - if PlotMode=='contour': - if 'T' in Elt: - ax.contour(Xplot,Yplot,Val, NC, label=Name, **Totdict) - elif PlotMode=='contourf': - if 'T' in Elt: - CC = ax.contourf(Xplot,Yplot,Val, NC, label=Name, **Totdict) - plt.colorbar(CC) - if not LegDict is None: - ax.legend(**LegDict) - ax.figure.canvas.draw() - return ax - - -def Plot_BSpline2D_Ind(BF2, Ind, ax='None', Elt='LPS', Coefs=1., NC=tfd.BF2PlotNC, PlotMode=tfd.BF2PlotMode, SubP=tfd.BF2PlotSubP, SubMode=tfd.BF2PlotSubMode, Name='Tot', Totdict=tfd.BF2PlotTotd, Sdict=tfd.BF2PlotIndSd, Pdict=tfd.BF2PlotIndPd, LegDict=tfd.TorLegd, Colorbar=True, Test=True): - if Test: - assert ax=='None' or isinstance(ax,plt.Axes), "Arg ax must be a plt.Axes instance !" - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert type(Totdict) is dict, "Arg Totdict must be a dict !" - assert type(PlotMode) is str and PlotMode in ['contour','contourf'], "Arg PlotMode must be in ['contour','contourf'] !" - - if type(Coefs) is float: - Coefs = Coefs*np.ones((BF2.NFunc,)) - - NInd = Ind.size - if ax=='None': - ax = tfd.Plot_BSpline_DefAxes('2D') - - if 'L' in Elt or 'S' in Elt: - Poly = BF2._get_Func_Supps() - Poly = [plg.Polygon(Poly[ii].T) for ii in Ind] - for ii in range(1,Ind.size): - Poly[0] = Poly[0] + Poly[ii] - Poly = Poly[0] - NPoly = len(Poly) - - if 'S' in Elt: # Plot support - NPoly = len(Poly) - patch = [patches.Polygon(np.array(Poly.contour(ii)), True) for ii in range(0,NPoly)] - ppp = PcthColl(patch, **Sdict) - ax.add_collection(ppp) - - if 'P' in Elt: # Plot Points of max value - PP = BF2._Func_MaxPos[:,Ind] - ax.plot(PP[0,:],PP[1,:], label=Name+' PMax', **Pdict) - - if 'L' in Elt: # Plot local value as contour or contourf - Hull = np.concatenate(tuple([np.array(Poly.contour(ii)) for ii in range(0,NPoly)]),axis=0) - MinR, MaxR = np.min(Hull[:,0]), np.max(Hull[:,0]) - MinZ, MaxZ = np.min(Hull[:,1]), np.max(Hull[:,1]) - - indKR = np.logical_and(BF2._Mesh._MeshR._Knots>=MinR,BF2._Mesh._MeshR._Knots<=MaxR) - indKZ = np.logical_and(BF2._Mesh._MeshZ._Knots>=MinZ,BF2._Mesh._MeshZ._Knots<=MaxZ) - KnotsR, KnotsZ = BF2._Mesh._MeshR._Knots[indKR], BF2._Mesh._MeshZ._Knots[indKZ] - Xplot, Yplot = Calc_SumMeshGrid2D(KnotsR, KnotsZ, SubP=SubP, SubMode=SubMode, Test=True) - nx, ny = Xplot.size, Yplot.size - Xplot, Yplot = np.dot(np.ones((ny,1)),Xplot.reshape((1,nx))), np.dot(Yplot.reshape((ny,1)),np.ones((1,nx))) - PointsRZ = np.array([Xplot.flatten(),Yplot.flatten()]) - - Val = np.sum(np.concatenate(tuple([Coefs[Ind[ii]]*BF2._LFunc[Ind[ii]](PointsRZ).reshape((1,PointsRZ.shape[1])) for ii in range(0,NInd)]),axis=0),axis=0) - indIn = np.array([Poly.isInside(PointsRZ[0,jj],PointsRZ[1,jj]) for jj in range(0,PointsRZ.shape[1])], dtype=bool) - Val[~indIn] = np.nan - Val = Val.reshape(Xplot.shape) - if PlotMode=='contour': - cc = ax.contour(Xplot,Yplot,Val, NC, label=Name, **Totdict) - elif PlotMode=='contourf': - cc = ax.contourf(Xplot,Yplot,Val, NC, label=Name, **Totdict) - if Colorbar: - plt.colorbar(cc,ax=ax,orientation='vertical', anchor=(0.,0.), panchor=(1.,0.), shrink=0.65) - - if not LegDict is None: - ax.legend(**LegDict) - ax.figure.canvas.draw() - return ax - - - -""" - -def Plot_BSpline2D_mlab(KnotsMultX, KnotsMultY, BSX, BSY, ax1='None', ax2='None',SubP=0.1, SubMode='Rel', BSDict=BS2Dict_Def, TotDict=Tot2Dict_Def): - assert isinstance(KnotsMultX,np.ndarray) and KnotsMultX.ndim==1, "Arg KnotsMultX must be a 1-dim np.ndarray !" - assert isinstance(KnotsMultY,np.ndarray) and KnotsMultY.ndim==1, "Arg KnotsMultY must be a 1-dim np.ndarray !" - assert ax1=='None' or isinstance(ax1,plt.Axes), "Arg ax1 must be a plt.Axes instance !" - assert ax2=='None' or isinstance(ax2,plt.Axes), "Arg ax2 must be a plt.Axes instance !" - assert type(SubP) is float, "Arg SubP must be a float !" - assert SubMode=='Rel' or SubMode=='Abs', "Arg SubMode must be 'Rel' or 'Abs' !" - assert type(BSX) is list, "Arg BSX must be a list of functions !" - assert type(BSY) is list, "Arg BSY must be a list of functions !" - assert type(BSDict) is dict, "Arg BSDict must be a dict !" - assert type(TotDict) is dict, "Arg TotDict must be a dict !" - - NBSX, NBSY = len(BSX), len(BSY) - NBS = NBSX*NBSY - KnotsUniqX, KnotsUniqY = np.unique(KnotsMultX), np.unique(KnotsMultY) - nKnotsX, nKnotsY = KnotsUniqX.size, KnotsUniqY.size - X, Y = KnotsUniqX, KnotsUniqY - - if SubMode=='Abs': - subX, subY = int(round((X[-1]-X[0])/SubP)), int(round((Y[-1]-Y[0])/SubP)) - X = np.linspace(X[0],X[-1],subX,endpoint=True) - Y = np.linspace(Y[0],Y[-1],subY,endpoint=True) - else: - X, Y = X.reshape((1,nKnotsX)), Y.reshape((1,nKnotsY)) - X, Y = np.concatenate((X[:,:-1],X[:,1:]),axis=0), np.concatenate((Y[:,:-1],Y[:,1:]),axis=0) - sub = int(round(1./SubP)) - dd = np.delete(np.linspace(0,1,sub,endpoint=False),0) - Xtemp = np.dot(np.ones((sub-1,1)),X[0:1,:]) + np.dot(dd.reshape((sub-1,1)), np.diff(X,axis=0)) - Ytemp = np.dot(np.ones((sub-1,1)),Y[0:1,:]) + np.dot(dd.reshape((sub-1,1)), np.diff(Y,axis=0)) - X, Y = np.concatenate((X[0:1,:],Xtemp,X[1:2,:]),axis=0), np.concatenate((Y[0:1,:],Ytemp,Y[1:2,:]),axis=0) - X, Y = np.unique(X.T.flatten()), np.unique(Y.T.flatten()) - nx, ny = X.size, Y.size - Xplot, Yplot = np.dot(np.ones((ny,1)),X.reshape((1,nx))), np.dot(Y.reshape((ny,1)),np.ones((1,nx))) - - Z = np.nan*np.ones((ny,nx,NBS)) - for ii in range(0,NBSX): - for jj in range(0,NBSY): - Z[:,:,(ii-1)*NBSX+jj] = BSX[ii](Xplot)*BSY[jj](Yplot) - - if ax1=='None' or ax2=='None': - f = Plot_BSpline_2Dmlab_DefFig() - - for ii in range(0,NBS): - ax1.plot_surface(Xplot,Yplot,Z[:,:,ii], **BSDict) - - ax2.plot_surface(Xplot,Yplot,np.sum(Z,axis=2), label='Tot', **TotDict) - f.draw() - return ax1, ax2 -""" - - -""" -############################################################################### -############################################################################### - MeshBase Objects and properties -############################################################################### -""" - - -class BF1D(object): - def __init__(self, Id, Mesh, Deg, dtime=None): - self.set_Id(Id,Deg=Deg, dtime=dtime) - self.set_Mesh(Mesh,Deg=Deg) - - @property - def Mesh(self): - """Return the knots""" - return self._Mesh - @Mesh.setter - def Mesh(self,Val): - """Set a new Knot vector and recompute all subsequent attributes""" - self.set_Mesh(Val) - @property - def Deg(self): - return self._Deg - @Deg.setter - def Deg(self,Val): - self.set_BF(Deg=Val) - - # Read-only attributes - @property - def Id(self): - """Return the Id""" - return self._Id - - def set_Id(self,Id,Deg=Deg, dtime=None): - assert type(Id) is str or isinstance(Id,TFPF.ID), "Arg Id should be string or an TFPF.ID instance !" - if type(Id) is str: - Id = TFPF.ID('BF1D',Id+'_D{0:01.0f}'.format(Deg), dtime=dtime) - self._Id = Id - - def set_Mesh(self,Mesh,Deg=None): - assert isinstance(Mesh,Mesh1D), "Arg Mesh must be a Mesh1D instance !" - self._Mesh = Mesh - self.set_BF(Deg=Deg) - - def set_BF(self,Deg=None): - assert Deg is None or (type(Deg) is int and Deg>=0 and Deg<=2), "Arg Deg must be a int with Deg>=0 and Deg<=2 !" - if not Deg is None: - self._Deg = Deg - self._LFunc, self._Func_Knotsind, self._Func_Centsind, self._Knots_Funcind, self._Cents_Funcind, self._Func_MaxPos = BSpline_LFunc(self._Deg, self._Mesh._Knots) - #self._LFunc, self._Func_Knotsind, indlK, self._Func_PMax = BSpline(self._Deg, self._Mesh._Knots) - self._NFunc = len(self._LFunc) - - def _get_Func_Supps(self): - Knots = self._Mesh._Knots[self._Func_Knotsind] - return np.array([Knots.min(axis=0),Knots.max(axis=0)]) - - def _get_Func_InterFunc(self): - if self._Deg==0: - return np.empty((0,)) - indF = np.empty((2*self._Deg+1,self._NFunc)) - return indF - - def get_TotFunc(self, Deriv=0, Coefs=1., Test=True): - return BSpline_TotFunc(self._Deg, self._Knots, Deriv=Deriv, Coefs=Coefs, Test=Test) - - def get_TotVal(self, Points, Deriv=0, Coefs=1., Test=True): - TF = BSpline_get_TotFunc(self.Deg, self.Mesh.Knots, Deriv=Deriv, Coefs=Coefs, Test=Test) - return Val - - def get_Funcs(self, Deriv=0, Test=True): - return BSpline_LFunc(self._Deg, self._Mesh._Knots, Deriv=Deriv, Test=Test) - - def get_Coefs(self,xx=None,yy=None,ff=None, SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, Test=True): - assert not all([xx is None or yy is None, ff is None]), "You must provide either a function (ff) or sampled data (xx and yy) !" - - if not ff is None: - xx = Calc_SumMeshGrid1D(self.Mesh.Knots, SubP=SubP, SubMode=SubMode, Test=Test) - yy = ff(xx) - - # Keep only points inside the Boundary - ind = np.logical_and(xx>=np.min(self.Mesh.Knots), xx<=np.max(self.Mesh.Knots)) - xx, yy = xx[ind], yy[ind] - - A = Calc_BF1D_Weights(self.LFunc, xx, Test=False) - Coefs, res, rank, sing = np.linalg.lstsq(A,yy) - if rank < self.NFunc: - xx1 = Calc_SumMeshGrid1D(self.Mesh.Knots, SubP=SubP, SubMode=SubMode, Test=Test) - yy1 = scpinterp.interp1d(xx, yy, kind='linear', bounds_error=False, fill_value=0., assume_sorted=True)(xx1) - xx, yy = np.concatenate((xx,xx1)), np.concatenate((yy,yy1)) - xx, ind = np.unique(xx, return_index=True) - yy = yy[ind] - A = Calc_BF1D_Weights(self.LFunc, xx, Test=False) - Coefs, res, rank, sing = np.linalg.lstsq(A,yy) - return Coefs, res - - def get_IntOp(self, Deriv=0, Sparse=tfd.L1IntOpSpa, SpaFormat=tfd.L1IntOpSpaFormat, Test=True): - return Calc_IntOp_BSpline(self.Mesh.Knots, self.Deg, Deriv=Deriv, Sparse=Sparse, SpaFormat=SpaFormat, Test=Test) - - def get_IntVal(self, Deriv=0, Coefs=1., Test=True): - A, m = Calc_IntOp_BSpline(self.Mesh.Knots, self.Deg, Deriv=Deriv, Sparse=True, Test=Test) - if type(Coefs) is float: - Coefs = Coefs*np.ones((self.NFunc,)) - if m==0: - Int = A.dot(Coefs) - elif m==1: - Int = Coefs.dot(A.dot(Coefs)) - else: - print 'Not coded yet !' - return Int - - def plot(self, ax='None', Coefs=1., Deriv=0, Elt='TL', SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, LFdict=tfd.BF1Fd, Totdict=tfd.BF1Totd, LegDict=tfd.TorLegd, Test=True): - if type(Coefs) is float: - Coefs = Coefs*np.ones((self.NFunc,)) - if 'T' in Elt: - TotF = BSpline_get_TotFunc(self.Deg, self.Mesh.Knots, Deriv=Deriv, Coefs=Coefs, Test=Test) - else: - TotF = None - if (type(Deriv) is int or Deriv in ['D0','D1','D2','D3']) and 'L' in Elt: - if not type(Deriv) is int: - Deriv = int(Deriv[1]) - LF1 = BSplineDeriv(self.Deg, self.Mesh.Knots, Deriv=Deriv, Test=Test) - LF = [lambda x,Coefs=Coefs,ii=ii: Coefs[ii]*LF1[ii](x) for ii in range(0,len(LF1))] - else: - LF = None - return Plot_BSpline1D(self.Mesh.Knots, TotF, LF, ax=ax, Elt=Elt, Name=self.Id.Name+' '+str(Deriv), SubP=SubP, SubMode=SubMode, LFdict=LFdict, Totdict=Totdict, LegDict=LegDict, Test=Test) - - def plot_Ind(self, ax='None', Ind=0, Coefs=1., Elt='LCK', y=0., SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, LFdict=tfd.BF1Fd, Kdict=tfd.M2Kd, Cdict=tfd.M2Cd, LegDict=tfd.TorLegd, Test=True): - assert type(Ind) in [int,list,np.ndarray], "Arg Ind must be a int, a list of int or a np.ndarray of int or booleans !" - if type(Ind) is int: - Ind = [Ind] - NInd = len(Ind) - elif type(Ind) is list: - NInd = len(Ind) - elif type(Ind) is np.ndarray: - assert (np.issubdtype(Ind.dtype,bool) and Ind.size==self.NFunc) or np.issubdtype(Ind.dtype,int), "Arg Ind must be a np.ndarray of boolenas with size==self.NFunc or a np.ndarray of int !" - NInd = Ind.size - - if type(Coefs) is float: - Coefs = Coefs*np.ones((self.NFunc,)) - if 'L' in Elt: - LF1 = BSplineDeriv(self.Deg, self.Mesh.Knots, Deriv=0, Test=Test) - LF = [lambda x,Coefs=Coefs,ii=ii: Coefs[Ind[ii]]*LF1[Ind[ii]](x) for ii in range(0,NInd)] - ax = Plot_BSpline1D(self.Mesh.Knots, None, LF, ax=ax, Elt=Elt, Name=self.Id.Name, SubP=SubP, SubMode=SubMode, LFdict=LFdict, LegDict=LegDict, Test=Test) - if 'C' in Elt or 'K' in Elt: - Cents = self.Mesh.Cents[self.Func_Centsind[:,Ind]].flatten() - Knots = self.Mesh.Knots[self.Func_Knotsind[:,Ind]].flatten() - ax = Plot_Mesh1D(Knots, Cents=Cents, y=y, Elt=Elt, Name=self.Id.NameLTX, ax=ax, Kdict=Kdict, Cdict=Cdict, LegDict=LegDict, Test=Test) - return ax - - def save(self,SaveName=None,Path=None,Mode='npz'): - if Path is None: - Path = self.Id.SavePath - else: - assert type(Path) is str, "Arg Path must be a str !" - self._Id.SavePath = Path - if SaveName is None: - SaveName = self.Id.SaveName - else: - assert type(SaveName) is str, "Arg SaveName must be a str !" - self.Id.SaveName = SaveName - Ext = '.npz' if 'npz' in Mode else '.pck' - TFPF.save(self, Path+SaveName+Ext) - - - -class BF2D(object): - - def __init__(self, Id, Mesh, Deg, dtime=None): - self.set_Id(Id,Deg=Deg, dtime=dtime) - self.set_Mesh(Mesh,Deg=Deg) - - @property - def Id(self): - return self._Id - @property - def Mesh(self): - return self._Mesh - @Mesh.setter - def Mesh(self,Val): - self.set_Mesh(Val) - @property - def Deg(self): - return self._Deg - @Deg.setter - def Deg(self,Val): - self.set_BF(Deg=Val) - @property - def NFunc(self): - return self._NFunc - - @property - def Surf(self): - indin = np.any(~np.isnan(self._Cents_Funcind),axis=0) - return np.sum(self.Mesh._Surfs[indin]) - - def set_Id(self,Id,Deg=Deg, dtime=None): - assert type(Id) is str or isinstance(Id,TFPF.ID), "Arg Id should be string or an TFPF.ID instance !" - if type(Id) is str: - Id = TFPF.ID('BF2D',Id+'_D{0:01.0f}'.format(Deg), dtime=dtime) - self._Id = Id - - def set_Mesh(self,Mesh,Deg=None): - assert isinstance(Mesh,Mesh2D), "Arg Mesh must be a Mesh2D instance !" - self._Mesh = Mesh - self.set_BF(Deg=Deg) - - def set_BF(self,Deg=None): - assert Deg is None or type(Deg) is int, "Arg Deg must be a int !" - if not Deg is None: - self._Deg = Deg - BSR, RF_Kind, RF_Cind, RK_Find, RC_Find, RMaxPos = BSpline_LFunc(self._Deg, self._Mesh._MeshR._Knots) - BSZ, ZF_Kind, ZF_Cind, ZK_Find, ZC_Find, ZMaxPos = BSpline_LFunc(self._Deg, self._Mesh._MeshZ._Knots) - nBR, nBZ = len(BSR), len(BSZ) - Func, F_Kind, F_Cind, F_MaxPos = [], [], [], [] - - CentBckg, indCentBckInMesh, NumCentBck = self._Mesh._get_CentBckg() - NCperF, NKperF = (self._Deg+1)**2, (self._Deg+2)**2 - for ii in range(0,nBZ): - for jj in range(0,nBR): - inds = ZF_Cind[:,ii].reshape((ZF_Cind.shape[0],1))*self._Mesh._MeshR._NCents + RF_Cind[:,jj] - if np.all(indCentBckInMesh[inds]): - Func.append(lambda RZ, ii=ii,jj=jj: BSR[jj](RZ[0,:])*BSZ[ii](RZ[1,:])) - F_Cind.append(NumCentBck[inds].reshape(NCperF,1).astype(int)) - F_Kind.append(np.unique(self._Mesh._Cents_Knotsind[:,F_Cind[-1][:,0]]).reshape(NKperF,1)) - F_MaxPos.append(np.array([[RMaxPos[jj]],[ZMaxPos[ii]]])) - self._LFunc = Func - self._NFunc = len(Func) - self._Func_Knotsind = np.concatenate(tuple(F_Kind),axis=1) - self._Func_Centsind = np.concatenate(tuple(F_Cind),axis=1) - self._Func_MaxPos = np.concatenate(tuple(F_MaxPos),axis=1) - self._Cents_Funcind = self._get_Cents_Funcind(Init=True) - self._Knots_Funcind = self._get_Knots_Funcind(Init=True) - self._Func_InterFunc = self._get_Func_InterFunc(Init=True) - - def _get_Cents_Funcind(self,Init=True): # To be updated with ability to select fraction of BF - Cent_indFunc = np.nan*np.ones(((self._Deg+1)**2,self._Mesh._NCents)) - for ii in range(0,self._Mesh._NCents): - inds = np.any(self._Func_Centsind==ii,axis=0) - Cent_indFunc[:inds.sum(),ii] = inds.nonzero()[0] - return Cent_indFunc - - def _get_Knots_Funcind(self,Init=True): # To be updated with ability to select fraction of BF - Knots_indFunc = np.nan*np.ones(((self._Deg+2)**2,self._Mesh._NKnots)) - for ii in range(0,self._Mesh._NKnots): - inds = np.any(self._Func_Knotsind==ii,axis=0) - Knots_indFunc[:inds.sum(),ii] = inds.nonzero()[0] - return Knots_indFunc - - def _get_Func_InterFunc(self,Init=True): # To be updated with ability to select fraction of BF - Func_InterFunc = np.nan*np.ones(((2*self._Deg+1)**2-1,self._NFunc)) - for ii in range(0,self.NFunc): - ind = self._Cents_Funcind[:,self._Func_Centsind[:,ii]].flatten() - ind = np.unique(ind[~np.isnan(ind)]) - ind = np.delete(ind,(ind==ii).nonzero()[0]) - Func_InterFunc[:ind.size,ii] = ind.astype(int) - return Func_InterFunc - - def _get_Func_InterFunc(self, Init=False, indFin=None): # To be updated with ability to select fraction of BF - assert indFin is None or (isnstance(indFin,np.ndarray) and indFin.dtype.name in ['bool','int32','int64','int']), "Arg indFin must be None or a np.naddary of bool or int !" - if indFin is None and not Init: - return self._Func_InterFunc - elif indFin is None: - indFin = np.arange(0,self._NFunc) - if indFin.dtype.name=='bool': - indFin = indFin.nonzero()[0] - NF = indFin.size - Func_InterFunc = np.nan*np.ones(((2*self._Deg+1)**2-1,NF)) # Update in progress from here... - for ii in range(0,NF): - ind = self._Cents_Funcind[:,self._Func_Centsind[:,ii]].flatten() - ind = np.unique(ind[~np.isnan(ind)]) - ind = np.delete(ind,(ind==ii).nonzero()[0]) - Func_InterFunc[:ind.size,ii] = ind.astype(int) - return Func_InterFunc - - def _get_quadPoints(self): - R = self._Mesh._Knots[0,self._Func_Knotsind] - Z = self._Mesh._Knots[1,self._Func_Knotsind] - QuadR, QuadZ = np.zeros((self._Deg+2,self._NFunc)), np.zeros((self._Deg+2,self._NFunc)) - for ii in range(0,self._NFunc): - QuadR[:,ii] = np.unique(R[:,ii]) - QuadZ[:,ii] = np.unique(Z[:,ii]) - return QuadR, QuadZ - - def _get_Func_SuppBounds(self): - Func_SuppRZ = np.nan*np.ones((4,self._NFunc)) - RKnots = self._Mesh._Knots[0,self._Func_Knotsind] - ZKnots = self._Mesh._Knots[1,self._Func_Knotsind] - Func_SuppRZ = np.concatenate((RKnots.min(axis=0,keepdims=True), np.max(RKnots,axis=0,keepdims=True), np.min(ZKnots,axis=0,keepdims=True), np.max(ZKnots,axis=0,keepdims=True)),axis=0) - return Func_SuppRZ - - def _get_Func_Supps(self): - R = self._Mesh._Knots[0,self._Func_Knotsind] - Z = self._Mesh._Knots[1,self._Func_Knotsind] - R = np.array([np.min(R,axis=0),np.max(R,axis=0)]) - Z = np.array([np.min(Z,axis=0),np.max(Z,axis=0)]) - return [np.array([[R[0,ii],R[1,ii],R[1,ii],R[0,ii],R[0,ii]],[Z[0,ii],Z[0,ii],Z[1,ii],Z[1,ii],Z[0,ii]]]) for ii in range(0,self._NFunc)] - - def get_SubBFPolygon_indin(self, Poly, NLim=3, Out=bool): - assert Out in [bool,int], "Arg Out must be in [bool,int] !" - indMeshout = ~self.Mesh.get_SubMeshPolygon(Poly, NLim=NLim, Out=bool) - indFout = self._Cents_Funcind[:,indMeshout] - indFout = np.unique(indFout[~np.isnan(indFout)]).astype(int) - indF = np.ones((self.NFunc,),dtype=bool) - indF[indFout] = False - if Out==int: - indF = indF.nonzero()[0] - return indF - - def get_SubBFPolygonind(self, Poly=None, NLim=3, indFin=None): - assert indFin is None or (isinstance(indFin,np.ndarray) and indFin.dtype.name in ['bool','int','int32','int64']), "Arg indFin must be None or a np.ndarray of bool or int !" - assert (not indFin is None and Poly is None) or (indFin is None and isinstance(Poly,np.ndarray) and Poly.ndim==2 and Poly.shape[0]==2), "If arg indFin is None, arg Poly must be a 2D np.ndarray instance !" - if indFin is None: - indFin = self.get_SubBFPolygon_indin(Poly, NLim=NLim, Out=int) - if indFin.dtype.name=='bool': - indFin = indFin.nonzero()[0] - IndMin = np.unique(self._Func_Centsind[:,indFin].flatten()) - Id, IdM = self.Id, self.Mesh.Id - Id._Name, IdM._Name = Id._Name+'_SubBF', Id._Name+'_SubMesh' - M = Mesh2D(IdM, self.Mesh, IndMin) - return BF2D(Id, M, self.Deg, self.Id.dtime) - - def get_TotFunc_FixPoints(self, Points, Deriv=0, Test=True): - assert Deriv in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Gauss','D2-Mean','D2N2-Lapl','D2N2-Vect'], "Arg Deriv must be in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Gauss','D2-Mean','D2N2-Lapl','D2N2-Vect'] !" - if Deriv in [0,'D0']: - AA, m = BF2D_get_Op(self, Points, Deriv=Deriv, Test=Test) - def FF(Coefs,AA=AA): - return AA.dot(Coefs) - elif Deriv in [1,2,'D1','D2']: - AA, m = BF2D_get_Op(self, Points, Deriv=Deriv, Test=Test) - def FF(Coefs, DVect,AA=AA): - dvR = np.hypot(DVect[0,:],DVect[1,:]) - return dvR*AA[0].dot(Coefs) + DVect[2,:]*AA[1].dot(Coefs) - elif Deriv == 'D0N2': - try: - AA, m = BF2D_get_Op(self, Points, Deriv=Deriv, Test=Test) - def FF(Coefs,AA=AA): - return Coefs.dot(AA.dot(Coefs)) - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv=0, Test=Test) - def FF(Coefs,AA=AA): - return AA.dot(Coefs)*AA.dot(Coefs) - elif Deriv=='D2-Gauss': - try: - AA, m = BF2D_get_Op(self, Points, Deriv=2, Test=Test) - BB, n = BF2D_get_Op(self, Points, Deriv='D2N2', Test=Test) - CC, n = BF2D_get_Op(self, Points, Deriv='D1N2', Test=Test) - AA, BB, CC = (AA[0],AA[1]), BB[2], CC[0]+CC[1] - def FF(Coefs, AA=AA, BB=BB, CC=CC): - return (AA[0].dot(Coefs) * AA[1].dot(Coefs) - Coefs.dot(BB.dot(Coefs))) / (1. + Coefs.dot(CC.dot(Coefs)))**2 - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv=2, Test=Test) - BB, n = BF2D_get_Op(self, Points, Deriv=1, Test=Test) - def FF(Coefs, AA=AA, BB=BB): - return (AA[0].dot(Coefs) * AA[1].dot(Coefs) - (AA[2].dot(Coefs))**2) / (1. + (BB[0].dot(Coefs))**2+(BB[1].dot(Coefs))**2)**2 - elif Deriv=='D2-Mean': - try: - AA, m = BF2D_get_Op(self, Points, Deriv=1, Test=Test) - BB, n = BF2D_get_Op(self, Points, Deriv='D1N2', Test=Test) - CC, p = BF2D_get_Op(self, Points, Deriv=2, Test=Test) - CC = (CC[0],CC[1],CC[2]) - def FF(Coefs,AA=AA,BB=BB,CC=CC): - return ( (1.+Coefs.dot(BB[0].dot(Coefs)))*CC[1].dot(Coefs) - 2.*AA[0].dot(Coefs)*AA[1].dot(Coefs)*CC[2].dot(Coefs) + (1.+Coefs.dot(BB[1].dot(Coefs)))*CC[0].dot(Coefs) ) / (2.*(1. + Coefs.dot((BB[0]+BB[1]).dot(Coefs)))**1.5) - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv=2, Test=Test) - BB, n = BF2D_get_Op(self, Points, Deriv=1, Test=Test) - def FF(Coefs,AA=AA,BB=BB): - return ( (1.+(BB[0].dot(Coefs))**2)*AA[1].dot(Coefs) - 2.*BB[0].dot(Coefs)*BB[1].dot(Coefs)*AA[2].dot(Coefs) + (1.+(BB[1].dot(Coefs))**2)*AA[0].dot(Coefs) ) / (2.*(1. + BB[0].dot(Coefs)**2+(BB[1].dot(Coefs))**2)**1.5) - else: - if 'D1' in Deriv: - try: - AA, m = BF2D_get_Op(self, Points, Deriv='D1N2', Test=Test) - AA = AA[0]+AA[1] - if Deriv=='D1N2': - def FF(Coefs,AA=AA): - return Coefs.dot(AA.dot(Coefs)) - elif Deriv=='D1FI': - B, n = BF2D_get_Op(self, Points, Deriv='D0', Test=Test) - def FF(Coefs,AA=AA,B=B): - return Coefs.dot(AA.dot(Coefs))/B.dot(Coefs) - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv='D1', Test=Test) - if Deriv=='D1N2': - def FF(Coefs,AA=AA): - return (AA[0].dot(Coefs))**2 + (AA[1].dot(Coefs))**2 - elif Deriv=='D1FI': - B, n = BF2D_get_Op(self, Points, Deriv='D0', Test=Test) - def FF(Coefs,AA=AA,B=B): - return ((AA[0].dot(Coefs))**2 + (AA[1].dot(Coefs))**2)/B.dot(Coefs) - elif 'D2' in Deriv: - try: - AA, m = BF2D_get_Op(self, Points, Deriv='D2N2', Test=Test) - if Deriv=='D2N2-Lapl': - AA, B = AA[0]+AA[1], AA[3] - def FF(Coefs,AA=AA,B=B): - return Coefs.dot(AA.dot(Coefs)) + 2.*B.dot(Coefs) - elif Deriv=='D2N2-Vect': - AA = AA[0]+AA[1] - def FF(Coefs,AA=AA): - return Coefs.dot(AA.dot(Coefs)) - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv='D2', Test=Test) - AA = (AA[0],AA[1]) - if Deriv=='D2N2-Lapl': - def FF(Coefs,AA=AA): - return (AA[0].dot(Coefs))**2 + (AA[1].dot(Coefs))**2 + 2.*AA[0].dot(Coefs)*AA[1].dot(Coefs) - elif Deriv=='D2N2-Vect': - AA = (AA[0],AA[1]) - def FF(Coefs,AA=AA): - return (AA[0].dot(Coefs))**2 + (AA[1].dot(Coefs))**2 - return FF - - def get_TotFunc_FixCoefs(self, Deriv=0, DVect=tfd.BF2_DVect_DefR, Coefs=1., Test=True): - assert type(Coefs) in [int,float] or (isinstance(Coefs,np.ndarray) and Coefs.ndim==1 and Coefs.size==self._NFunc), "Arg Coefs must be a float or a (NF,) np.ndarray !" - return BF2D_get_TotFunc(self, Deriv=Deriv, DVect=DVect, Coefs=Coefs, Test=Test) - - def get_TotVal(self, Points, Deriv=0, DVect=tfd.BF2_DVect_DefR, Coefs=1., Test=True): - assert Deriv in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Gauss','D2-Mean','D2N2-Lapl','D2N2-Vect'], "Arg Deriv must be in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Gauss','D2-Mean','D2N2-Lapl','D2N2-Vect'] !" - if type(Coefs) in [int,float] or (isinstance(Coefs,np.ndarray) and Coefs.ndim==1): - Coefs = Coefs*np.ones((self._NFunc,)) - if Points.shape==2: - Points = np.array([Points[0,:],np.zeros((Points.shape[1],)), Points[1,:]]) - FF = self.get_TotFunc_FixPoints(Points, Deriv=Deriv, Test=Test) - if Coefs.ndim==1: - if Deriv in [1,2,'D1','D2']: - dvect = DVect(Points) - return FF(Coefs,dvect) - else: - return FF(Coefs) - else: - Nt = Coefs.shape[0] - Vals = np.empty((Nt,Points.shape[1])) - if Deriv in [1,2,'D1','D2']: - dvect = DVect(Points) - for ii in range(0,Nt): - Vals[ii,:] = FF(Coefs[ii,:], dvect) - else: - for ii in range(0,Nt): - Vals[ii,:] = FF(Coefs[ii,:]) - return Vals - - def get_Coefs(self,xx=None,yy=None, zz=None, ff=None, SubP=tfd.BF2Sub, SubMode=tfd.BF1SubMode, indFin=None, Test=True): # To be updated to take into account fraction of BF - assert not all([xx is None or yy is None, ff is None]), "You must provide either a function (ff) or sampled data (xx and yy) !" - assert indFin is None or (isnstance(indFin,np.ndarray) and indFin.dtype.name in ['bool','int32','int64','int']), "Arg indFin must be None or a np.naddary of bool or int !" - print self.Id.Name+" : Getting fit coefficients..." - if indFin is None: - indFin = np.arange(0,self.NFunc) - if indFin.dtype.name=='bool': - indFin = indFin.nonzero()[0] - - if not ff is None: - xx, yy, nx, ny = self.get_XYplot(SubP=SubP, SubMode=SubMode) # To update - xx, yy = xx.flatten(), yy.flatten() - zz = ff(RZ2Points(np.array([xx,yy]))) - else: - assert xx.shape==yy.shape==zz.shape, "Args xx, yy and zz must have same shape !" - xx, yy, zz = xx.flatten(), yy.flatten(), zz.flatten() - # Keep only points inside the Boundary - ind = self.Mesh.isInside(np.array([xx,yy])) - xx, yy, zz = xx[ind], yy[ind], zz[ind] - - AA, m = BF2D_get_Op(self, np.array([xx.flatten(),yy.flatten()]), Deriv=0, indFin=indFin, Test=Test) - Coefs, res, rank, sing = np.linalg.lstsq(AA,zz) - if rank < indFin.size: - xx1, yy1, nx1, ny1 = self.get_XYplot(SubP=SubP/2., SubMode=SubMode) - xx1, yy1 = xx1.flatten(), yy1.flatten() - ind = self._Mesh.isInside(np.array([xx1,yy1])) - xx1, yy1 = xx1[ind], yy1[ind] - zz1 = scpint.interp2d(xx, yy, zzz, kind='linear', bounds_error=False, fill_value=0)(xx1,yy1) - xx, yy, zz = np.concatenate((xx,xx1)), np.concatenate((yy,yy1)), np.concatenate((zz,zz1)) - AA, m = BF2D_get_Op(self, np.array([xx.flatten(),yy.flatten()]), Deriv=0, Test=Test) - Coefs, res, rank, sing = np.linalg.lstsq(AA,zz) - return Coefs, res - - def get_XYplot(self, SubP=tfd.BF2PlotSubP, SubMode=tfd.BF2PlotSubMode): - Xplot, Yplot = Calc_SumMeshGrid2D(self.Mesh._MeshR.Knots, self.Mesh._MeshZ.Knots, SubP=SubP, SubMode=SubMode, Test=True) - nx, ny = Xplot.size, Yplot.size - Xplot, Yplot = np.dot(np.ones((ny,1)),Xplot.reshape((1,nx))), np.dot(Yplot.reshape((ny,1)),np.ones((1,nx))) - return Xplot, Yplot, nx, ny - - def get_IntOp(self, Deriv=0, Mode=tfd.BF2IntMode, Sparse=tfd.L1IntOpSpa, SpaFormat=tfd.L1IntOpSpaFormat, Test=True): - print self.Id.Name+" : Getting integral operator "+str(Deriv) - return Calc_IntOp_BSpline2D(self, Deriv=Deriv, Mode=Mode, Sparse=Sparse, SpaFormat=SpaFormat, Test=Test) - - def get_IntVal(self, Deriv=0, Mode=tfd.BF2IntMode, Coefs=1., Test=True): - A, m = Calc_IntOp_BSpline2D(self, Deriv=Deriv, Mode=Mode, Sparse=True, Test=Test) - if type(Coefs) is float: - Coefs = Coefs*np.ones((self.NFunc,),dtype=float) - if Coefs.ndim==1: - if m==0: - Int = A.dot(Coefs) - elif m==1: - Int = Coefs.dot(A.dot(Coefs)) - elif m==2: - A = A[0]+A[1] - Int = Coefs.dot(A.dot(Coefs)) - else: - print 'Not coded yet !' - else: - Int = np.nan*np.ones((Coefs.shape[0],)) - if m==0: - for ii in range(0,Coefs.shape[0]): - Int[ii] = A.dot(Coefs[ii,:]) - elif m==1: - for ii in range(0,Coefs.shape[0]): - Int[ii] = Coefs[ii,:].dot(A.dot(Coefs[ii,:])) - elif m==2: - A = A[0]+A[1] - for ii in range(0,Coefs.shape[0]): - Int[ii] =Coefs[ii,:].dot(A.dot(Coefs[ii,:])) - else: - print 'Not coded yet !' - return Int - - def get_MinMax(self, Coefs=1., Ratio=0.05, SubP=0.004, SubP1=0.015, SubP2=0.001, TwoSteps=False, SubMode='abs', Deriv='D0', Test=True): # To be deprecated by get_Extrema() when implemented - return Get_MinMax(self, Coefs=Coefs, Ratio=Ratio, SubP=SubP, SubP1=SubP1, SubP2=SubP2, TwoSteps=TwoSteps, SubMode=SubMode, Deriv=Deriv, Test=Test) - - def get_Extrema(self, Coefs=1., Ratio=0.95, SubP=0.002, SubMode='abs', Deriv='D0', D1N2=True, D2N2=True): - return Get_Extrema(self, Coefs=Coefs, Ratio=Ratio, SubP=SubP, SubMode=SubMode, D1N2=D1N2, D2N2=D2N2) - - - def plot(self, ax='None', Coefs=1., Deriv=0, Elt='T', NC=tfd.BF2PlotNC, DVect=tfd.BF2_DVect_DefR, PlotMode='contourf', SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, Totdict=tfd.BF1Totd, LegDict=tfd.TorLegd, Test=True): - return Plot_BSpline2D(self, ax=ax, Elt=Elt, Deriv=Deriv, Coefs=Coefs, DVect=DVect, NC=NC, PlotMode=PlotMode, Name=self.Id.Name+' '+str(Deriv), SubP=SubP, SubMode=SubMode, Totdict=Totdict, LegDict=LegDict, Test=Test) - - def plot_fit(self, ax1='None', ax2='None', xx=None, yy=None, zz=None, ff=None, NC=tfd.BF2PlotNC, PlotMode='contourf', Name='', SubP=tfd.BF2Sub, SubMode=tfd.BF1SubMode, Totdict=tfd.BF1Totd, LegDict=tfd.TorLegd, Test=True): - Coefs, res = self.get_Coefs(xx=xx,yy=yy, zz=zz, ff=ff, SubP=SubP, SubMode=SubMode, Test=Test) - if xx is None: - xx, yy, nxg, nyg = self.get_XYplot(SubP=SubP, SubMode=SubMode) - zz = ff(RZ2Points(np.array([xx.flatten(),yy.flatten()]))) - zz = zz.reshape((xx.shape)) - else: - assert xx.ndim==2, "Args xx, yy and zz must be (N,M) plot-friendly !" - if Name=='': - Name = self.Id.Name - - Xplot, Yplot, nx, ny = self.get_XYplot(SubP=SubP, SubMode=SubMode) - PointsRZ = np.array([Xplot.flatten(),Yplot.flatten()]) - ind = self.Mesh.isInside(PointsRZ) - Val = self.get_TotVal(PointsRZ, Deriv=0, Coefs=Coefs, Test=True) - Val[~ind] = np.nan - Val = Val.reshape(Xplot.shape) - if PlotMode=='surf': - if ax1=='None' or ax2=='None': - ax1, ax2 = tfd.Plot_BSplineFit_DefAxes('3D') - ax1.plot_surface(xx,yy,zz, label='Model', **Totdict) - ax2.plot_surface(Xplot,Yplot,Val, label=Name, **Totdict) - else: - if ax1=='None' or ax2=='None': - ax1, ax2 = tfd.Plot_BSplineFit_DefAxes('2D') - if PlotMode=='contour': - ax1.contour(xx,yy,zz, NC, label='Model', **Totdict) - ax2.contour(Xplot,Yplot,Val, NC, label=Name, **Totdict) - elif PlotMode=='contourf': - ax1.contourf(xx,yy,zz, NC, label='Model', **Totdict) - ax2.contourf(Xplot,Yplot,Val, NC, label=Name, **Totdict) - if not LegDict is None: - ax1.legend(**LegDict) - ax2.legend(**LegDict) - ax2.set_title(r"$\chi^2 = "+str(res)+"$") - ax1.figure.canvas.draw() - return ax1, ax2 - - def plot_Ind(self, Ind=0, Elt='LSP', EltM='BMCK', ax='None', Coefs=1., NC=tfd.BF2PlotNC, PlotMode='contourf', SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, Totdict=tfd.BF2PlotTotd, - Cdict=tfd.M2Cd, Kdict=tfd.M2Kd, Bckdict=tfd.M2Bckd, Mshdict=tfd.M2Mshd, LegDict=tfd.TorLegd, Colorbar=True, Test=True): - assert type(Ind) in [int,list,np.ndarray], "Arg Ind must be a int, a list of int or a np.ndarray of int or booleans !" - if type(Ind) is int: - Ind = np.array([Ind],dtype=int) - elif type(Ind) is list: - Ind = np.array(tuple(Ind),dtype=int) - elif type(Ind) is np.ndarray: - assert (np.issubdtype(Ind.dtype,bool) and Ind.size==self._NFunc) or np.issubdtype(Ind.dtype,int), "Arg Ind must be a np.ndarray of boolenas with size==self.NFunc or a np.ndarray of int !" - if np.issubdtype(Ind.dtype,bool): - Ind = Ind.nonzero()[0] - NInd = Ind.size - if type(Coefs) is float: - Coefs = Coefs*np.ones((self._NFunc,)) - indC, indK = self._Func_Centsind[:,Ind].flatten().astype(int), self._Func_Knotsind[:,Ind].flatten().astype(int) - ax = self._Mesh.plot(indKnots=indK, indCents=indC, ax=ax, Elt=EltM, Cdict=Cdict, Kdict=Kdict, Bckdict=Bckdict, Mshdict=Mshdict, LegDict=LegDict, Test=Test) - ax = Plot_BSpline2D_Ind(self, Ind, ax=ax, Coefs=Coefs, Elt=Elt, NC=NC, PlotMode=PlotMode, Name=self._Id.Name, SubP=SubP, SubMode=SubMode, Totdict=Totdict, LegDict=LegDict, Colorbar=Colorbar, Test=Test) - return ax - - def save(self,SaveName=None,Path=None,Mode='npz'): - if Path is None: - Path = self.Id.SavePath - else: - assert type(Path) is str, "Arg Path must be a str !" - self._Id.SavePath = Path - if SaveName is None: - SaveName = self.Id.SaveName - else: - assert type(SaveName) is str, "Arg SaveName must be a str !" - self.Id.SaveName = SaveName - Ext = '.npz' if 'npz' in Mode else '.pck' - TFPF.save(self, Path+SaveName+Ext) - - - - - -############################################ -##### Computing functions -############################################ - - -def RZ2Points(PointsRZ, Theta=0.): - return np.array([PointsRZ[0,:]*np.cos(Theta), PointsRZ[0,:]*np.sin(Theta),PointsRZ[1,:]]) - -def Points2RZ(Points): - return np.array([np.sqrt(Points[0,:]**2+Points[1,:]**2),Points[2,:]]) - - -def Calc_BF1D_Weights(LFunc, Points, Test=True): - if Test: - assert type(LFunc) is list, "Arg LFunc must be a list of functions !" - assert isinstance(Points,np.ndarray) and Points.ndim==1, "Arg Points must be a (N,) np.ndarray !" - NFunc = len(LFunc) - Wgh = np.zeros((Points.size, NFunc)) - for ii in range(0,NFunc): - Wgh[:,ii] = LFunc[ii](Points) - return Wgh - -def Calc_BF2D_Weights(LFunc, PointsRZ, Test=True): - if Test: - assert type(LFunc) is list, "Arg LFunc must be a list of functions !" - assert isinstance(PointsRZ,np.ndarray) and PointsRZ.ndim==2, "Arg Points must be a (2,N) np.ndarray !" - NFunc = len(LFunc) - Wgh = np.zeros((PointsRZ.shape[1], NFunc)) - for ii in range(0,NFunc): - Wgh[:,ii] = LFunc[ii](PointsRZ) - return Wgh - - -def BF2D_get_Op(BF2, Points, Deriv=0, indFin=None, Test=True): # To be updated to take into account only fraction of BF - """ Return the operator to compute the desired quantity on NP points (to be multiplied by Coefs) Y = Op(Coefs) for NF basis functions - Input : - BF2 A BF2D instance - Points A (3,NP) np.ndarray indicating (X,Y,Z) cylindrical coordinates of points at which to evaluate desired quantity (automatically converted to (R,Z) coordinates) - Deriv A flag indicating the desired quantity in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Lapl','D2N2-Lapl'] - Test A bool Flag indicating whether inputs shall be tested for conformity - Output : - A The operator itself as a 2D or 3D numpy array - m Flag indicating the kind of operation necessary - = 0 Y = A.dot(C) (Y = AC, with A.shape=(NP,NF)) - = 1 Y = C.dot(A.dot(C)) (Y = tCAC, with A.shape=(NF,NP,NF)) - = 2 Y = sum( C.dot(A[:].dot(C)) ) (e.g.: Y = tCArC + tCAzC with Ar.shape==Az.shape=(NF,NP,NF), you can compute a scalar product with each component if necessary) - """ - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert isinstance(Points,np.ndarray) and Points.ndim==2 and Points.shape[0] in [2,3], "Arg Points must be a (2-3,NP) np.ndarray !" - assert Deriv in [0,1,2,'D0','D0N2','D1','D1N2','D2','D2N2'], "Arg Deriv must be in [0,1,2,'D0','D0N2','D1','D1N2','D2','D2N2'] !" - assert indFin is None or (isinstance(indFin,np.ndarray) and indFin.dtype.name in ['bool','int32','int64','int']), "Arg indFin must be None or a np.naddary of bool or int !" - - if indFin is None: - indFin = np.arange(0,BF2.NFunc) - if indFin.dtype.name=='bool': - indFin = indFin.nonzero()[0] - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - NF = indFin.size - NP = Points.shape[1] - if Points.shape[0]==3: - RZ = np.array([np.hypot(Points[0,:],Points[1,:]),Points[2,:]]) - else: - RZ = np.copy(Points) - - QuadR, QuadZ = BF2._get_quadPoints() - QuadR, QuadZ = QuadR[:,indFin], QuadZ[:,indFin] - if Deriv=='D0': - m = 0 - A = np.zeros((NP,NF)) - for ii in range(0,NF): - A[:,ii] = BF2._LFunc[indFin[ii]](RZ) - return A, m - elif Deriv=='D0N2': # Update in progress from here... - m = 1 - A = np.zeros((NF,NP,NF)) - for ii in range(0,NF): - Yii = BF2._LFunc[ii](RZ) - A[ii,:,ii] = Yii**2 - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - A[ii,:,Ind[jj]] = Yii*BF2._LFunc[Ind[jj]](RZ) - return A, m - elif Deriv=='D1' and BF2.Deg>=1: - m = 2 - Ar, Az = np.zeros((NP,NF)), np.zeros((NP,NF)) - for ii in range(0,NF): - Ar[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Az[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - return (Ar,Az), m - elif Deriv=='D1N2' and BF2.Deg>=1: - m = 2 - AR, AZ = np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)) - for ii in range(0,NF): - rii, zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Rii, Zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - AR[ii,:,ii] = (Rii*zii)**2 - AZ[ii,:,ii] = (rii*Zii)**2 - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - AR[ii,:,Ind[jj]] = Rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=1)[0][0](RZ[0,:]) * zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=0)[0][0](RZ[1,:]) - AZ[ii,:,Ind[jj]] = rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=0)[0][0](RZ[0,:]) * Zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=1)[0][0](RZ[1,:]) - return (AR,AZ), m - elif Deriv=='D2' and BF2.Deg>=2: - m = 2 - Arr, Azz, Arz = np.zeros((NP,NF)), np.zeros((NP,NF)), np.zeros((NP,NF)) - for ii in range(0,NF): - Arr[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=2)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Azz[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=2)[0][0](RZ[1,:]) - Arz[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - return (Arr,Azz,Arz), m - elif Deriv=='D2N2' and BF2.Deg>=2: - m = 2 - ARR, AZZ, ARZ, Arrzz = np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)) - for ii in range(0,NF): - rii, zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Rii, Zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - RRii, ZZii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=2)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=2)[0][0](RZ[1,:]) - ARR[ii,:,ii] = (RRii*zii)**2 - AZZ[ii,:,ii] = (rii*ZZii)**2 - ARZ[ii,:,ii] = (Rii*Zii)**2 - Arrzz[ii,:,ii] = RRii*ZZii - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - ARR[ii,:,Ind[jj]] = RRii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=2)[0][0](RZ[0,:]) * zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=0)[0][0](RZ[1,:]) - AZZ[ii,:,Ind[jj]] = rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=0)[0][0](RZ[0,:]) * ZZii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=2)[0][0](RZ[1,:]) - ARZ[ii,:,Ind[jj]] = Rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=1)[0][0](RZ[0,:]) * Zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=1)[0][0](RZ[1,:]) - return (ARR,AZZ,ARZ, Arrzz), m - - -def BF2D_get_TotFunc(BF2, Deriv=0, DVect=tfd.BF2_DVect_DefR, Coefs=1., Test=True): - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert type(Deriv) in [int,str], "Arg Deriv must be a int or a str !" - assert type(Coefs) is float or (isinstance(Coefs,np.ndarray) and Coefs.size==BF2.NFunc), "Arg Coefs must be a float or a np.ndarray !" - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - - if type(Coefs) is float: - Coefs = Coefs.np.ones((BF2.NFunc,)) - - NF = BF2.NFunc - QuadR, QuadZ = BF2._get_quadPoints() - if Deriv in [0,'D0']: - LF = BF2._LFunc - return lambda Points, Coefs=Coefs, LF=LF, NF=NF: np.sum(np.concatenate(tuple([Coefs[jj]*LF[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - elif Deriv=='D0N2': - LF = BF2._LFunc - return lambda Points, Coefs=Coefs, LF=LF, NF=NF: np.sum(np.concatenate(tuple([Coefs[jj]*LF[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0)**2 - - elif Dbis==1: - LDR = [] - LDZ = [] - for ii in range(0,NF): - LDR.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=1, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=0, Test=Test)[0](PointsRZ[1,:])) - LDZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=0, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=1, Test=Test)[0](PointsRZ[1,:])) - if Deriv=='D1': - def FTot(Points, Coefs=Coefs, DVect=DVect, NF=NF, LDR=LDR, LDZ=LDZ): - DVect = DVect(Points) - Theta = np.arctan2(Points[1,:],Points[0,:]) - eR = np.array([np.cos(Theta),np.sin(Theta),np.zeros((Theta.size,))]) - DVect = np.array([np.sum(DVect*eR,axis=0), DVect[2,:]]) - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0)*DVect[0,:] - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0)*DVect[1,:] - return ValR+ValZ - elif Deriv=='D1N2': - def FTot(Points, Coefs=Coefs, NF=NF, LDR=LDR, LDZ=LDZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return ValR**2+ValZ**2 - elif Deriv=='D1FI': - LF = BF2._LFunc - def FTot(Points, Coefs=Coefs, NF=NF, LF=LF, LDR=LDR, LDZ=LDZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - Val = np.sum(np.concatenate(tuple([Coefs[jj]*LF[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return (ValR**2+ValZ**2)/Val - - elif Dbis==2: - LDRR, LDZZ = [], [] - for ii in range(0,NF): - LDRR.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=2, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=0, Test=Test)[0](PointsRZ[1,:])) - LDZZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=0, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=2, Test=Test)[0](PointsRZ[1,:])) - if Deriv=='D2-Lapl': - def FTot(Points, Coefs=Coefs, NF=NF, LDRR=LDRR, LDZZ=LDZZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return ValR+ValZ - elif Deriv=='D2N2-Lapl': - def FTot(Points, Coefs=Coefs, NF=NF, LDRR=LDRR, LDZZ=LDZZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return (ValR+ValZ)**2 - else: - LDR, LDZ, LDRZ= [], [], [] - for ii in range(0,NF): - LDR.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=1, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=0, Test=Test)[0](PointsRZ[1,:])) - LDZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=0, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=1, Test=Test)[0](PointsRZ[1,:])) - LDRZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=1, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=1, Test=Test)[0](PointsRZ[1,:])) - if Deriv=='D2-Gauss': - def FTot(Points, Coefs=Coefs, NF=NF, LDR=LDR, LDZ=LDZ, LDRR=LDRR, LDZZ=LDZZ, LDRZ=LDRZ): - ValRR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValRZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDRZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return (ValRR*ValZZ-ValRZ**2)/(1. + ValR**2 + ValZ**2)**2 - elif Deriv=='D2-Mean': - def FTot(Points, Coefs=Coefs, NF=NF, LDR=LDR, LDZ=LDZ, LDRR=LDRR, LDZZ=LDZZ, LDRZ=LDRZ): - ValRR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValRZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDRZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return ((1.+ValR**2)*ValZZ - 2.*ValR*ValZ*ValRZ + (1.+ValZ**2)*ValRR)/(2.*(1. + ValR**2 + ValZ**2)**(1.5)) - - return FTot - - -def Calc_BF2D_Val(LFunc, Points, Coef=1., Test=True): - if Test: - assert type(LFunc) is list, "Arg LFunc must be a list of functions !" - assert isinstance(Points,np.ndarray) and (Points.shape[0]==2 or Points.shape[0]==3), "Arg Points must be a (2,N) or (3,N) np.ndarray !" - assert (type(Coef) is float and Coef==1.) or (isinstance(Coef,np.ndarray) and Coef.shape[0]==len(LFunc)), "Arg Coef must be a (BF2.NFunc,1) np.ndarray !" - - if Points.shape[0]==3: - R = np.sqrt(np.sum(Points[0:2,:]**2,axis=0,keepdims=False)) - Points = np.array([[R],[Points[2,:]]]) - - NFunc = len(LFunc) - Val = np.zeros((Points.shape[1],)) - Coef = Coef*np.ones((NFunc,1)) - for ii in range(0,NFunc): - Val = Val + Coef[ii]*LFunc[ii](Points) - - return Val - - - - - - - - - -def Calc_Integ_BF2(BF2, Coefs=1., Mode='Vol', Test=True): - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert Mode=='Vol' or Mode=='Surf', "Arg Mode must be 'Vol' or 'Surf' !" - assert type(Coefs) is float or (isinstance(Coefs,np.ndarray) and Coefs.size==BF2.NFunc), "Arg Coefs must be a (BF2.NFunc,) np.ndarray !" - assert BF2.Deg <= 3, "Arg BF2 should not have Degree > 3 !" - - if type(Coefs) is float: - Coefs = Coefs*np.ones((BF2.NFunc,)) - if Mode=='Surf': - if BF2.Deg==0: - Supp = BF2.get_Func_SuppRZ() - Int = np.sum(Coefs.flatten()*(Supp[1,:]-Supp[0,:])*(Supp[3,:]-Supp[2,:])) - elif BF2.Deg==1: - Supp = BF2.get_Func_SuppRZ() - Int = np.sum(Coefs.flatten()*0.25*(Supp[1,:]-Supp[0,:])*(Supp[3,:]-Supp[2,:])) - elif BF2.Deg==2: - QR, QZ = BF2._get_quadPoints() - IntR1 = (QR[1,:]-QR[0,:])**2/(3.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**2 -2.*QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[0,:]*(QR[1,:]-QR[2,:]))/(6*(QR[2,:]-QR[0,:])) - IntR22 = (-2.*QR[2,:]**2+QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[3,:]*(QR[2,:]-QR[1,:]))/(6.*(QR[3,:]-QR[1,:])) - IntR3 = (QR[3,:]-QR[2,:])**2/(3.*(QR[3,:]-QR[1,:])) - IntZ1 = (QZ[1,:]-QZ[0,:])**2/(3.*(QZ[2,:]-QZ[0,:])) - IntZ21 = (QZ[2,:]**2 -2*QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[0,:]*(QZ[1,:]-QZ[2,:]))/(6*(QZ[2,:]-QZ[0,:])) - IntZ22 = (-2.*QZ[2,:]**2+QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[3,:]*(QZ[2,:]-QZ[1,:]))/(6.*(QZ[3,:]-QZ[1,:])) - IntZ3 = (QZ[3,:]-QZ[2,:])**2/(3.*(QZ[3,:]-QZ[1,:])) - Int = np.sum(Coefs.flatten() * (IntR1+IntR21+IntR22+IntR3) * (IntZ1+IntZ21+IntZ22+IntZ3)) - elif BF2.Deg==3: - print "NOT CODED YET !" - - else: - if BF2.Deg==0: - Supp = BF2.get_Func_SuppRZ() - Int = np.sum( Coefs.flatten() * 2.*np.pi * 0.5*(Supp[1,:]**2-Supp[0,:]**2)*(Supp[3,:]-Supp[2,:])) - elif BF2.Deg==1: - Supp = BF2.get_Func_SuppRZ() - QuadR, QuadZ = BF2._get_quadPoints() - Int = np.sum( Coefs.flatten() * 2.*np.pi * 0.5*(QuadR[2,:]**2-QuadR[0,:]**2 + QuadR[1,:]*(QuadR[2,:]-QuadR[0,:]))*(Supp[3,:]-Supp[2,:])/6.) - elif BF2.Deg==2: - QR, QZ = BF2._get_quadPoints() - IntR1 = (3.*QR[1,:]**3+QR[0,:]**3 -5.*QR[0,:]*QR[1,:]**2+QR[0,:]**2*QR[1,:])/(12.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**3 -3.*QR[1,:]**3+QR[1,:]**2*QR[2,:]+QR[1,:]*QR[2,:]**2 -2.*QR[0,:]*QR[2,:]**2 -2.*QR[0,:]*QR[1,:]*QR[2,:] +4.*QR[0,:]*QR[1,:]**2)/(12.*(QR[2,:]-QR[0,:])) - IntR22 = ( -3.*QR[2,:]**3+QR[1,:]**3+QR[1,:]*QR[2,:]**2+QR[1,:]**2*QR[2,:]+4.*QR[2,:]**2*QR[3,:]-2.*QR[1,:]*QR[2,:]*QR[3,:]-2.*QR[1,:]**2*QR[3,:] )/(12.*(QR[3,:]-QR[1,:])) - IntR3 = ( QR[3,:]**3 +3.*QR[2,:]**3 -5.*QR[2,:]**2*QR[3,:]+QR[2,:]*QR[3,:]**2)/(12.*(QR[3,:]-QR[1,:])) - IntZ1 = (QZ[1,:]-QZ[0,:])**2/(3.*(QZ[2,:]-QZ[0,:])) - IntZ21 = (QZ[2,:]**2 -2*QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[0,:]*(QZ[1,:]-QZ[2,:]))/(6*(QZ[2,:]-QZ[0,:])) - IntZ22 = (-2.*QZ[2,:]**2+QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[3,:]*(QZ[2,:]-QZ[1,:]))/(6.*(QZ[3,:]-QZ[1,:])) - IntZ3 = (QZ[3,:]-QZ[2,:])**2/(3.*(QZ[3,:]-QZ[1,:])) - Int = np.sum(Coefs.flatten() * 2.*np.pi * (IntR1+IntR21+IntR22+IntR3) * (IntZ1+IntZ21+IntZ22+IntZ3)) - elif BF2.Deg==3: - print "NOT CODED YET !" - - return Int - - - - - - - -def Calc_IntOp_BSpline2D(BF2, Deriv=0, Mode='Vol', Sparse=tfd.L1IntOpSpa, SpaFormat=tfd.L1IntOpSpaFormat, Test=True): - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert Mode in ['Surf','Vol'], "Arg Mode must be in ['Surf','Vol'] !" - assert (type(Deriv) is int and Deriv<=BF2.Deg) or (type(Deriv) is str and Deriv in ['D0','D1','D2','D3','D0N2','D1N2','D2N2','D3N2','D1FI'] and int(Deriv[1])<=BF2.Deg), "Arg Deriv must be a int or a str !" - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - - if Deriv=='D0': - m = 0 - if BF2.Deg==0: - Supp = BF2._get_Func_SuppBounds() - if Mode=='Surf': - A = (Supp[1,:]-Supp[0,:]) * (Supp[3,:]-Supp[2,:]) - else: - A = 0.5*(Supp[1,:]**2-Supp[0,:]**2) * (Supp[3,:]-Supp[2,:]) - elif BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - if Mode=='Surf': - A = 0.25*(Supp[1,:]-Supp[0,:])*(Supp[3,:]-Supp[2,:]) - else: - QuadR, QuadZ = BF2._get_quadPoints() - A = 0.5*(QuadR[2,:]**2-QuadR[0,:]**2 + QuadR[1,:]*(QuadR[2,:]-QuadR[0,:])) * (Supp[3,:]-Supp[2,:])/6. - elif BF2.Deg==2: - QR, QZ = BF2._get_quadPoints() - - IntZ1 = (QZ[1,:]-QZ[0,:])**2/(3.*(QZ[2,:]-QZ[0,:])) - IntZ21 = (QZ[2,:]**2 -2*QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[0,:]*(QZ[1,:]-QZ[2,:]))/(6*(QZ[2,:]-QZ[0,:])) - IntZ22 = (-2.*QZ[2,:]**2+QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[3,:]*(QZ[2,:]-QZ[1,:]))/(6.*(QZ[3,:]-QZ[1,:])) - IntZ3 = (QZ[3,:]-QZ[2,:])**2/(3.*(QZ[3,:]-QZ[1,:])) - IntZ = IntZ1+IntZ21+IntZ22+IntZ3 - - if Mode=='Surf': - IntR1 = (QR[1,:]-QR[0,:])**2/(3.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**2 -2.*QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[0,:]*(QR[1,:]-QR[2,:]))/(6*(QR[2,:]-QR[0,:])) - IntR22 = (-2.*QR[2,:]**2+QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[3,:]*(QR[2,:]-QR[1,:]))/(6.*(QR[3,:]-QR[1,:])) - IntR3 = (QR[3,:]-QR[2,:])**2/(3.*(QR[3,:]-QR[1,:])) - else: - IntR1 = (3.*QR[1,:]**3+QR[0,:]**3 -5.*QR[0,:]*QR[1,:]**2+QR[0,:]**2*QR[1,:])/(12.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**3 -3.*QR[1,:]**3+QR[1,:]**2*QR[2,:]+QR[1,:]*QR[2,:]**2 -2.*QR[0,:]*QR[2,:]**2 -2.*QR[0,:]*QR[1,:]*QR[2,:] +4.*QR[0,:]*QR[1,:]**2)/(12.*(QR[2,:]-QR[0,:])) - IntR22 = ( -3.*QR[2,:]**3+QR[1,:]**3+QR[1,:]*QR[2,:]**2+QR[1,:]**2*QR[2,:]+4.*QR[2,:]**2*QR[3,:]-2.*QR[1,:]*QR[2,:]*QR[3,:]-2.*QR[1,:]**2*QR[3,:] )/(12.*(QR[3,:]-QR[1,:])) - IntR3 = ( QR[3,:]**3 +3.*QR[2,:]**3 -5.*QR[2,:]**2*QR[3,:]+QR[2,:]*QR[3,:]**2)/(12.*(QR[3,:]-QR[1,:])) - IntR = IntR1+IntR21+IntR22+IntR3 - A = IntR*IntZ - elif BF2.Deg==3: - print "NOT CODED YET !" - A = 0 - - elif Deriv=='D0N2': - m = 1 - if BF2.Deg==0: - Supp = BF2._get_Func_SuppBounds() - if Mode=='Surf': - A = scpsp.diags([(Supp[1,:]-Supp[0,:]) * (Supp[3,:]-Supp[2,:])],[0],shape=None,format=SpaFormat) - else: - A = scpsp.diags([0.5*(Supp[1,:]**2-Supp[0,:]**2) * (Supp[3,:]-Supp[2,:])],[0],shape=None,format=SpaFormat) - elif BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - if Mode=='Surf': - d0R, d0Z = (Supp[1,:]-Supp[0,:])/3., (Supp[3,:]-Supp[2,:])/3. - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intR = (kR[1]-kR[0])/6. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZ = (kZ[1]-kZ[0])/6. - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - else: - d0R, d0Z = (QR[2,:]**2-QR[0,:]**2 + 2.*QR[1,:]*(QR[2,:]-QR[0,:]))/12., (Supp[3,:]-Supp[2,:])/3. - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intR = (kR[1]**2-kR[0]**2)/12. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZ = (kZ[1]-kZ[0])/6. - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - A = scpsp.vstack(LL,format='csr') - elif BF2.Deg==2: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - if Mode=='Surf': - d0R21 = (QR[2,:]-QR[1,:])*(10.*QR[0,:]**2+6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2 - 5.*QR[0,:]*(3.*QR[1,:]+QR[2,:]))/(30.*(QR[2,:]-QR[0,:])**2) - d0R22 = (QR[2,:]-QR[1,:])*(10.*QR[3,:]**2+6.*QR[2,:]**2+3.*QR[1,:]*QR[2,:]+QR[1,:]**2 - 5.*QR[3,:]*(3.*QR[2,:]+QR[1,:]))/(30.*(QR[3,:]-QR[1,:])**2) - d0R23 = ( 3.*QR[1,:]**2 + 4.*QR[1,:]*QR[2,:] + 3.*QR[2,:]**2 - 5.*QR[0,:]*(QR[1,:]+QR[2,:]-2.*QR[3,:]) -5.*QR[3,:]*(QR[1,:]+QR[2,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (QR[1,:]-QR[0,:])**3/(5.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (QR[3,:]-QR[2,:])**3/(5.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intR = (QR[1,ii]-QR[0,ii])**3/(30.*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR = ( 6.*QR[1,ii]**2 - QR[0,ii]*(9.*QR[1,ii]+QR[2,ii]-10.*QR[3,ii]) + QR[2,ii]*(QR[2,ii]-4.*QR[3,ii]) +3.*QR[1,ii]*(QR[2,ii]-2.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) + ( QR[0,ii]**2 + 3.*QR[0,ii]*QR[1,ii] + 6.*QR[1,ii]**2 - 2.*QR[0,Ind[jj]]*(2.*QR[0,ii]+3.*QR[1,ii] - 5.*QR[2,ii]) - QR[0,ii]*QR[2,ii] -9.*QR[1,ii]*QR[2,ii] )*(QR[1,ii]-QR[0,ii])**2/(30.*(QR[0,Ind[jj]]-QR[2,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intR = (QR[3,ii]-QR[2,ii])**3/(30.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR = ( 6.*QR[2,ii]**2 - QR[1,ii]*(9.*QR[2,ii]+QR[3,ii]-10.*QR[3,Ind[jj]]) + QR[3,ii]*(QR[3,ii]-4.*QR[3,Ind[jj]]) +3.*QR[2,ii]*(QR[3,ii]-2.*QR[3,Ind[jj]]) )*(QR[3,ii]-QR[2,ii])**2/(30.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) + ( QR[1,ii]**2 + 3.*QR[1,ii]*QR[2,ii] + 6.*QR[2,ii]**2 - 2.*QR[0,ii]*(2.*QR[1,ii]+3.*QR[2,ii] - 5.*QR[3,ii]) - QR[1,ii]*QR[3,ii] -9.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[0,ii]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZ = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZ = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZ = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZ = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - A = scpsp.vstack(LL,format='csr') - - elif Mode=='Vol': - d0R21 = (10*QR[1,:]**3 + 6.*QR[1,:]**2*QR[2,:] + 3.*QR[1,:]*QR[2,:]**2 + QR[2,:]**3 + 5.*QR[0,:]**2*(3.*QR[1,:]+QR[2,:]) - 4.*QR[0,:]*(6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[2,:]-QR[0,:])**2) - d0R22 = (10*QR[2,:]**3 + 6.*QR[2,:]**2*QR[1,:] + 3.*QR[2,:]*QR[1,:]**2 + QR[1,:]**3 + 5.*QR[3,:]**2*(3.*QR[2,:]+QR[1,:]) - 4.*QR[3,:]*(6.*QR[2,:]**2+3.*QR[2,:]*QR[1,:]+QR[1,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[3,:]-QR[1,:])**2) - d0R23 = (2.*QR[1,:]**3 + QR[1,:]*QR[2,:]*(3.*QR[2,:]-4.*QR[3,:]) +(2.*QR[2,:]-3.*QR[3,:])*QR[2,:]**2 +3.*(QR[2,:]-QR[3,:])*QR[1,:]**2 + QR[0,:]*(-3.*QR[1,:]**2-4.*QR[1,:]*QR[2,:]-3.*QR[2,:]**2+5.*QR[1,:]*QR[3,:]+5.*QR[2,:]*QR[3,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[3,:]-QR[1,:])*(QR[2,:]-QR[0,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (5.*QR[1,:]+QR[0,:])*(QR[1,:]-QR[0,:])**3/(30.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (5.*QR[2,:]+QR[3,:])*(QR[3,:]-QR[2,:])**3/(30.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intR = (QR[1,ii]+QR[0,ii])*(QR[1,ii]-QR[0,ii])**3/(60.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR1A = ( -2.*QR[0,Ind[jj]]*QR[0,ii] + QR[0,ii]**2 - 3.*QR[0,Ind[jj]]*QR[1,ii] + 2.*QR[0,ii]*QR[1,ii] + 2.*QR[1,ii]**2 )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intR1B = - ( QR[0,ii]**2 + 2.*QR[1,ii]*(5.*QR[1,ii]-6.*QR[2,ii]) + QR[0,ii]*(4.*QR[1,ii]-3.*QR[2,ii]) )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2A = ( 10.*QR[1,ii]**2 + 4.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[0,ii]*(4.*QR[1,ii]+QR[2,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2B = - ( 2.*QR[1,ii]**2 + 2.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[1,ii]*QR[3,ii] -2.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR = intR1A + intR1B + intR2A + intR2B - - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intR = (QR[3,ii]+QR[2,ii])*(QR[3,ii]-QR[2,ii])**3/(60.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR1A = ( -2.*QR[0,ii]*QR[1,ii] + QR[1,ii]**2 - 3.*QR[0,ii]*QR[2,ii] + 2.*QR[1,ii]*QR[2,ii] + 2.*QR[2,ii]**2 )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR1B = - ( QR[1,ii]**2 + 2.*QR[2,ii]*(5.*QR[2,ii]-6.*QR[3,ii]) + QR[1,ii]*(4.*QR[2,ii]-3.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2A = ( 10.*QR[2,ii]**2 + 4.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[1,ii]*(4.*QR[2,ii]+QR[3,ii]) )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2B = - ( 2.*QR[2,ii]**2 + 2.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[2,ii]*QR[3,Ind[jj]] -2.*QR[3,ii]*QR[3,Ind[jj]] )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])*(QR[3,Ind[jj]]-QR[2,ii])) - intR = intR1A + intR1B + intR2A + intR2B - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZ = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZ = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZ = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZ = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - A = scpsp.vstack(LL,format='csr') - - elif Deriv=='D1N2': - m = 2 - if BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - - if Mode=='Surf': - d0R, d0Z = (Supp[1,:]-Supp[0,:])/3., (Supp[3,:]-Supp[2,:])/3. - d0DR, d0DZ = (QR[2,:]-QR[0,:])/((QR[2,:]-QR[1,:])*(QR[1,:]-QR[0,:])), (QZ[2,:]-QZ[0,:])/((QZ[2,:]-QZ[1,:])*(QZ[1,:]-QZ[0,:])) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDR = d0DR[ii] - intRDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intRDR = -1./(kR[1]-kR[0]) - intRDZ = (kR[1]-kR[0])/6. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZDR = (kZ[1]-kZ[0])/6. - intZDZ = -1./(kZ[1]-kZ[0]) - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - else: - d0R, d0Z = (QR[2,:]**2-QR[0,:]**2 + 2.*QR[1,:]*(QR[2,:]-QR[0,:]))/12., (Supp[3,:]-Supp[2,:])/3. - d0DR, d0DZ = 0.5*(QR[1,:]+QR[0,:])/(QR[1,:]-QR[0,:]) + 0.5*(QR[2,:]+QR[1,:])/(QR[2,:]-QR[1,:]), (QZ[2,:]-QZ[0,:])/((QZ[2,:]-QZ[1,:])*(QZ[1,:]-QZ[0,:])) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDR = d0DR[ii] - intRDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intRDR = -0.5*(kR[1]+kR[0])/(kR[1]-kR[0]) - intRDZ = (kR[1]**2-kR[0]**2)/12. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZDR = (kZ[1]-kZ[0])/6. - intZDZ = -1./(kZ[1]-kZ[0]) - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - AR, AZ = scpsp.vstack(LLR,format='csr'), scpsp.vstack(LLZ,format='csr') - A = (AR,AZ) - - elif BF2.Deg==2: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - if Mode=='Surf': - d0R21 = (QR[2,:]-QR[1,:])*(10.*QR[0,:]**2+6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2 - 5.*QR[0,:]*(3.*QR[1,:]+QR[2,:]))/(30.*(QR[2,:]-QR[0,:])**2) - d0R22 = (QR[2,:]-QR[1,:])*(10.*QR[3,:]**2+6.*QR[2,:]**2+3.*QR[1,:]*QR[2,:]+QR[1,:]**2 - 5.*QR[3,:]*(3.*QR[2,:]+QR[1,:]))/(30.*(QR[3,:]-QR[1,:])**2) - d0R23 = ( 3.*QR[1,:]**2 + 4.*QR[1,:]*QR[2,:] + 3.*QR[2,:]**2 - 5.*QR[0,:]*(QR[1,:]+QR[2,:]-2.*QR[3,:]) -5.*QR[3,:]*(QR[1,:]+QR[2,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (QR[1,:]-QR[0,:])**3/(5.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (QR[3,:]-QR[2,:])**3/(5.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DR = 4.*(QR[1,:]-QR[0,:])/(3.*(QR[2,:]-QR[0,:])**2) + 4.*( QR[0,:]**2 + QR[1,:]**2 + QR[2,:]**2 + (QR[2,:]-2.*QR[3,:])*QR[1,:] - QR[2,:]*QR[3,:] + QR[3,:]**2 + (-QR[1,:]-2.*QR[2,:]+QR[3,:])*QR[0,:] )*(QR[2,:]-QR[1,:])/(3.*(QR[2,:]-QR[0,:])**2*(QR[3,:]-QR[1,:])**2) + 4.*(QR[3,:]-QR[2,:])/(3.*(QR[3,:]-QR[1,:])**2) - d0DZ = 4.*(QZ[1,:]-QZ[0,:])/(3.*(QZ[2,:]-QZ[0,:])**2) + 4.*( QZ[0,:]**2 + QZ[1,:]**2 + QZ[2,:]**2 + (QZ[2,:]-2.*QZ[3,:])*QZ[1,:] - QZ[2,:]*QZ[3,:] + QZ[3,:]**2 + (-QZ[1,:]-2.*QZ[2,:]+QZ[3,:])*QZ[0,:] )*(QZ[2,:]-QZ[1,:])/(3.*(QZ[2,:]-QZ[0,:])**2*(QZ[3,:]-QZ[1,:])**2) + 4.*(QZ[3,:]-QZ[2,:])/(3.*(QZ[3,:]-QZ[1,:])**2) - - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDZ = d0R[ii] - intRDR = d0DR[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDZ = (QR[1,ii]-QR[0,ii])**3/(30.*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - intRDR = 2.*(QR[0,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intRDZ = ( 6.*QR[1,ii]**2 - QR[0,ii]*(9.*QR[1,ii]+QR[2,ii]-10.*QR[3,ii]) + QR[2,ii]*(QR[2,ii]-4.*QR[3,ii]) +3.*QR[1,ii]*(QR[2,ii]-2.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) + ( QR[0,ii]**2 + 3.*QR[0,ii]*QR[1,ii] + 6.*QR[1,ii]**2 - 2.*QR[0,Ind[jj]]*(2.*QR[0,ii]+3.*QR[1,ii] - 5.*QR[2,ii]) - QR[0,ii]*QR[2,ii] -9.*QR[1,ii]*QR[2,ii] )*(QR[1,ii]-QR[0,ii])**2/(30.*(QR[0,Ind[jj]]-QR[2,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - intRDR = 2.*(2.*QR[0,Ind[jj]]-QR[0,ii]-2.*QR[1,ii]+QR[2,ii])*(QR[1,ii]-QR[0,ii])/(3.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) + 2.*(QR[0,ii]-2.*QR[1,ii]-QR[2,ii]+2.*QR[3,ii])*(QR[2,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDZ = (QR[3,ii]-QR[2,ii])**3/(30.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - intRDR = 2.*(QR[2,ii]-QR[3,ii])/(3.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intRDZ = ( 6.*QR[2,ii]**2 - QR[1,ii]*(9.*QR[2,ii]+QR[3,ii]-10.*QR[3,Ind[jj]]) + QR[3,ii]*(QR[3,ii]-4.*QR[3,Ind[jj]]) +3.*QR[2,ii]*(QR[3,ii]-2.*QR[3,Ind[jj]]) )*(QR[3,ii]-QR[2,ii])**2/(30.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) + ( QR[1,ii]**2 + 3.*QR[1,ii]*QR[2,ii] + 6.*QR[2,ii]**2 - 2.*QR[0,ii]*(2.*QR[1,ii]+3.*QR[2,ii] - 5.*QR[3,ii]) - QR[1,ii]*QR[3,ii] -9.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[0,ii]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - intRDR = 2.*(2.*QR[0,ii]-QR[1,ii]-2.*QR[2,ii]+QR[3,ii])*(QR[2,ii]-QR[1,ii])/(3.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) + 2.*(QR[1,ii]-2.*QR[2,ii]-QR[3,ii]+2.*QR[3,Ind[jj]])*(QR[3,ii]-QR[2,ii])/(3.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDZ = 2.*(QZ[0,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[1,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - intZDZ = 2.*(2.*QZ[0,Ind[jj]]-QZ[0,ii]-2.*QZ[1,ii]+QZ[2,ii])*(QZ[1,ii]-QZ[0,ii])/(3.*(QZ[1,ii]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) + 2.*(QZ[0,ii]-2.*QZ[1,ii]-QZ[2,ii]+2.*QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDZ = 2.*(QZ[2,ii]-QZ[3,ii])/(3.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[2,ii])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDZ = 2.*(2.*QZ[0,ii]-QZ[1,ii]-2.*QZ[2,ii]+QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) + 2.*(QZ[1,ii]-2.*QZ[2,ii]-QZ[3,ii]+2.*QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[2,ii])/(3.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - elif Mode=='Vol': - d0R21 = (10*QR[1,:]**3 + 6.*QR[1,:]**2*QR[2,:] + 3.*QR[1,:]*QR[2,:]**2 + QR[2,:]**3 + 5.*QR[0,:]**2*(3.*QR[1,:]+QR[2,:]) - 4.*QR[0,:]*(6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[2,:]-QR[0,:])**2) - d0R22 = (10*QR[2,:]**3 + 6.*QR[2,:]**2*QR[1,:] + 3.*QR[2,:]*QR[1,:]**2 + QR[1,:]**3 + 5.*QR[3,:]**2*(3.*QR[2,:]+QR[1,:]) - 4.*QR[3,:]*(6.*QR[2,:]**2+3.*QR[2,:]*QR[1,:]+QR[1,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[3,:]-QR[1,:])**2) - d0R23 = (2.*QR[1,:]**3 + QR[1,:]*QR[2,:]*(3.*QR[2,:]-4.*QR[3,:]) +(2.*QR[2,:]-3.*QR[3,:])*QR[2,:]**2 +3.*(QR[2,:]-QR[3,:])*QR[1,:]**2 + QR[0,:]*(-3.*QR[1,:]**2-4.*QR[1,:]*QR[2,:]-3.*QR[2,:]**2+5.*QR[1,:]*QR[3,:]+5.*QR[2,:]*QR[3,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[3,:]-QR[1,:])*(QR[2,:]-QR[0,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (5.*QR[1,:]+QR[0,:])*(QR[1,:]-QR[0,:])**3/(30.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (5.*QR[2,:]+QR[3,:])*(QR[3,:]-QR[2,:])**3/(30.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DR = (QR[1,:]-QR[0,:])*(QR[0,:]+3.*QR[1,:])/(3.*(QR[2,:]-QR[0,:])**2) + ( (3.*QR[1,:]+QR[2,:])/(QR[2,:]-QR[0,:])**2 + (QR[1,:]+3.*QR[2,:])/(QR[3,:]-QR[1,:])**2 - 2.*(QR[1,:]+QR[2,:])/((QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) )*(QR[2,:]-QR[1,:])/3. + (QR[3,:]-QR[2,:])*(QR[3,:]+3.*QR[2,:])/(3.*(QR[3,:]-QR[1,:])**2) - d0DZ = 4.*(QZ[1,:]-QZ[0,:])/(3.*(QZ[2,:]-QZ[0,:])**2) + 4.*( QZ[0,:]**2 + QZ[1,:]**2 + QZ[2,:]**2 + (QZ[2,:]-2.*QZ[3,:])*QZ[1,:] - QZ[2,:]*QZ[3,:] + QZ[3,:]**2 + (-QZ[1,:]-2.*QZ[2,:]+QZ[3,:])*QZ[0,:] )*(QZ[2,:]-QZ[1,:])/(3.*(QZ[2,:]-QZ[0,:])**2*(QZ[3,:]-QZ[1,:])**2) + 4.*(QZ[3,:]-QZ[2,:])/(3.*(QZ[3,:]-QZ[1,:])**2) - - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDZ = d0R[ii] - intRDR = d0DR[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDZ = (QR[1,ii]+QR[0,ii])*(QR[1,ii]-QR[0,ii])**3/(60.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intRDR = (QR[0,ii]+QR[1,ii])*(QR[0,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR1A = ( -2.*QR[0,Ind[jj]]*QR[0,ii] + QR[0,ii]**2 - 3.*QR[0,Ind[jj]]*QR[1,ii] + 2.*QR[0,ii]*QR[1,ii] + 2.*QR[1,ii]**2 )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intR1B = - ( QR[0,ii]**2 + 2.*QR[1,ii]*(5.*QR[1,ii]-6.*QR[2,ii]) + QR[0,ii]*(4.*QR[1,ii]-3.*QR[2,ii]) )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2A = ( 10.*QR[1,ii]**2 + 4.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[0,ii]*(4.*QR[1,ii]+QR[2,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2B = - ( 2.*QR[1,ii]**2 + 2.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[1,ii]*QR[3,ii] -2.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intRDZ = intR1A + intR1B + intR2A + intR2B - intRDR = ( -QR[0,ii]**2 + (QR[0,ii]+3.*QR[1,ii])*QR[0,Ind[jj]] + (-3.*QR[1,ii]+QR[2,ii])*QR[1,ii] +(-2.*QR[1,ii]+QR[2,ii])*QR[0,ii] )*(QR[1,ii]-QR[0,ii])/(3.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) + ( -3.*QR[1,ii]**2 + (QR[1,ii]+QR[2,ii])*QR[0,ii] + (-QR[2,ii]+QR[3,ii])*QR[2,ii] + (-2.*QR[2,ii]+3.*QR[3,ii])*QR[1,ii] )*(QR[2,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDZ = (QR[3,ii]+QR[2,ii])*(QR[3,ii]-QR[2,ii])**3/(60.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - intRDR = (QR[2,ii]+QR[3,ii])*(QR[2,ii]-QR[3,ii])/(3.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR1A = ( -2.*QR[0,ii]*QR[1,ii] + QR[1,ii]**2 - 3.*QR[0,ii]*QR[2,ii] + 2.*QR[1,ii]*QR[2,ii] + 2.*QR[2,ii]**2 )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR1B = - ( QR[1,ii]**2 + 2.*QR[2,ii]*(5.*QR[2,ii]-6.*QR[3,ii]) + QR[1,ii]*(4.*QR[2,ii]-3.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2A = ( 10.*QR[2,ii]**2 + 4.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[1,ii]*(4.*QR[2,ii]+QR[3,ii]) )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2B = - ( 2.*QR[2,ii]**2 + 2.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[2,ii]*QR[3,Ind[jj]] -2.*QR[3,ii]*QR[3,Ind[jj]] )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])*(QR[3,Ind[jj]]-QR[2,ii])) - intRDZ = intR1A + intR1B + intR2A + intR2B - intRDR = ( -QR[1,ii]**2 + (QR[1,ii]+3.*QR[2,ii])*QR[0,ii] + (-3.*QR[2,ii]+QR[3,ii])*QR[2,ii] +(-2.*QR[2,ii]+QR[3,ii])*QR[1,ii] )*(QR[2,ii]-QR[1,ii])/(3.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) + ( -3.*QR[2,ii]**2 + (QR[2,ii]+QR[3,ii])*QR[1,ii] + (-QR[3,ii]+QR[3,Ind[jj]])*QR[3,ii] + (-2.*QR[3,ii]+3.*QR[3,Ind[jj]])*QR[2,ii] )*(QR[3,ii]-QR[2,ii])/(3.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDZ = 2.*(QZ[0,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[1,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - intZDZ = 2.*(2.*QZ[0,Ind[jj]]-QZ[0,ii]-2.*QZ[1,ii]+QZ[2,ii])*(QZ[1,ii]-QZ[0,ii])/(3.*(QZ[1,ii]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) + 2.*(QZ[0,ii]-2.*QZ[1,ii]-QZ[2,ii]+2.*QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDZ = 2.*(QZ[2,ii]-QZ[3,ii])/(3.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[2,ii])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDZ = 2.*(2.*QZ[0,ii]-QZ[1,ii]-2.*QZ[2,ii]+QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) + 2.*(QZ[1,ii]-2.*QZ[2,ii]-QZ[3,ii]+2.*QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[2,ii])/(3.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - AR, AZ = scpsp.vstack(LLR,format='csr'), scpsp.vstack(LLZ,format='csr') - A = (AR,AZ) - - - elif Deriv=='D1FI': - m = 3 - if BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - - - - - elif 'D2N2' in Deriv: - m = 2 - if BF2.Deg==2: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - - if Mode=='Surf': - d0R21 = (QR[2,:]-QR[1,:])*(10.*QR[0,:]**2+6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2 - 5.*QR[0,:]*(3.*QR[1,:]+QR[2,:]))/(30.*(QR[2,:]-QR[0,:])**2) - d0R22 = (QR[2,:]-QR[1,:])*(10.*QR[3,:]**2+6.*QR[2,:]**2+3.*QR[1,:]*QR[2,:]+QR[1,:]**2 - 5.*QR[3,:]*(3.*QR[2,:]+QR[1,:]))/(30.*(QR[3,:]-QR[1,:])**2) - d0R23 = ( 3.*QR[1,:]**2 + 4.*QR[1,:]*QR[2,:] + 3.*QR[2,:]**2 - 5.*QR[0,:]*(QR[1,:]+QR[2,:]-2.*QR[3,:]) -5.*QR[3,:]*(QR[1,:]+QR[2,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (QR[1,:]-QR[0,:])**3/(5.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (QR[3,:]-QR[2,:])**3/(5.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DDR = 4./((QR[1,:]-QR[0,:])*(QR[2,:]-QR[0,:])**2) + 4.*(QR[3,:]+QR[2,:]-QR[1,:]-QR[0,:])**2/((QR[2,:]-QR[1,:])*(QR[3,:]-QR[1,:])**2*(QR[2,:]-QR[0,:])**2) + 4./((QR[3,:]-QR[2,:])*(QR[3,:]-QR[1,:])**2) - d0DDZ = 4./((QZ[1,:]-QZ[0,:])*(QZ[2,:]-QZ[0,:])**2) + 4.*(QZ[3,:]+QZ[2,:]-QZ[1,:]-QZ[0,:])**2/((QZ[2,:]-QZ[1,:])*(QZ[3,:]-QZ[1,:])**2*(QZ[2,:]-QZ[0,:])**2) + 4./((QZ[3,:]-QZ[2,:])*(QZ[3,:]-QZ[1,:])**2) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDDR = d0DDR[ii] - intRDDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDDR = 4./((kR[1]-kR[0])*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - intRDDZ = (QR[1,ii]-QR[0,ii])**3/(30.*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intRDDR = -4.*(QR[2,ii]+QR[1,ii]-QR[1,Ind[jj]]-QR[0,Ind[jj]])/((QR[2,Ind[jj]]-QR[1,Ind[jj]])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - 4.*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[3,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])**2) - intRDDZ = ( 6.*QR[1,ii]**2 - QR[0,ii]*(9.*QR[1,ii]+QR[2,ii]-10.*QR[3,ii]) + QR[2,ii]*(QR[2,ii]-4.*QR[3,ii]) +3.*QR[1,ii]*(QR[2,ii]-2.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) + ( QR[0,ii]**2 + 3.*QR[0,ii]*QR[1,ii] + 6.*QR[1,ii]**2 - 2.*QR[0,Ind[jj]]*(2.*QR[0,ii]+3.*QR[1,ii] - 5.*QR[2,ii]) - QR[0,ii]*QR[2,ii] -9.*QR[1,ii]*QR[2,ii] )*(QR[1,ii]-QR[0,ii])**2/(30.*(QR[0,Ind[jj]]-QR[2,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDDR = 4./((kR[1]-kR[0])*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - intRDDZ = (QR[3,ii]-QR[2,ii])**3/(30.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intRDDR = -4.*(QR[3,Ind[jj]]+QR[2,Ind[jj]]-QR[2,ii]-QR[1,ii])/((QR[3,ii]-QR[2,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) - 4.*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) - intRDDZ = ( 6.*QR[2,ii]**2 - QR[1,ii]*(9.*QR[2,ii]+QR[3,ii]-10.*QR[3,Ind[jj]]) + QR[3,ii]*(QR[3,ii]-4.*QR[3,Ind[jj]]) +3.*QR[2,ii]*(QR[3,ii]-2.*QR[3,Ind[jj]]) )*(QR[3,ii]-QR[2,ii])**2/(30.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) + ( QR[1,ii]**2 + 3.*QR[1,ii]*QR[2,ii] + 6.*QR[2,ii]**2 - 2.*QR[0,ii]*(2.*QR[1,ii]+3.*QR[2,ii] - 5.*QR[3,ii]) - QR[1,ii]*QR[3,ii] -9.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[0,ii]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common knots..." - - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDDR = d0Z[ii] - intZDDZ = d0DDZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDDZ = -4.*(QZ[2,ii]+QZ[1,ii]-QZ[1,Ind[jj]]-QZ[0,Ind[jj]])/((QZ[2,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])**2) - intZDDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDDZ = -4.*(QZ[3,Ind[jj]]+QZ[2,Ind[jj]]-QZ[2,ii]-QZ[1,ii])/((QZ[3,ii]-QZ[2,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common knots..." - - llR[0,Ind[jj]] = intRDDR*intZDDR - llZ[0,Ind[jj]] = intRDDZ*intZDDZ - llR[0,ii] = d0DDR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DDZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - elif Mode=='Vol': - d0R21 = (10*QR[1,:]**3 + 6.*QR[1,:]**2*QR[2,:] + 3.*QR[1,:]*QR[2,:]**2 + QR[2,:]**3 + 5.*QR[0,:]**2*(3.*QR[1,:]+QR[2,:]) - 4.*QR[0,:]*(6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[2,:]-QR[0,:])**2) - d0R22 = (10*QR[2,:]**3 + 6.*QR[2,:]**2*QR[1,:] + 3.*QR[2,:]*QR[1,:]**2 + QR[1,:]**3 + 5.*QR[3,:]**2*(3.*QR[2,:]+QR[1,:]) - 4.*QR[3,:]*(6.*QR[2,:]**2+3.*QR[2,:]*QR[1,:]+QR[1,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[3,:]-QR[1,:])**2) - d0R23 = (2.*QR[1,:]**3 + QR[1,:]*QR[2,:]*(3.*QR[2,:]-4.*QR[3,:]) +(2.*QR[2,:]-3.*QR[3,:])*QR[2,:]**2 +3.*(QR[2,:]-QR[3,:])*QR[1,:]**2 + QR[0,:]*(-3.*QR[1,:]**2-4.*QR[1,:]*QR[2,:]-3.*QR[2,:]**2+5.*QR[1,:]*QR[3,:]+5.*QR[2,:]*QR[3,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[3,:]-QR[1,:])*(QR[2,:]-QR[0,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (5.*QR[1,:]+QR[0,:])*(QR[1,:]-QR[0,:])**3/(30.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (5.*QR[2,:]+QR[3,:])*(QR[3,:]-QR[2,:])**3/(30.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DDR = 2.*(QR[1,:]+QR[0,:])/((QR[1,:]-QR[0,:])*(QR[2,:]-QR[0,:])**2) + 2.*(QR[2,:]+QR[1,:])*(QR[3,:]+QR[2,:]-QR[1,:]-QR[0,:])**2/((QR[2,:]-QR[1,:])*(QR[3,:]-QR[1,:])**2*(QR[2,:]-QR[0,:])**2) + 2.*(QR[3,:]+QR[2,:])/((QR[3,:]-QR[2,:])*(QR[3,:]-QR[1,:])**2) - d0DDZ = 4./((QZ[1,:]-QZ[0,:])*(QZ[2,:]-QZ[0,:])**2) + 4.*(QZ[3,:]+QZ[2,:]-QZ[1,:]-QZ[0,:])**2/((QZ[2,:]-QZ[1,:])*(QZ[3,:]-QZ[1,:])**2*(QZ[2,:]-QZ[0,:])**2) + 4./((QZ[3,:]-QZ[2,:])*(QZ[3,:]-QZ[1,:])**2) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - Ind = np.asarray([int(xxx) for xxx in Ind], dtype=int) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDDR = d0DDR[ii] - intRDDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDDR = 2.*(kR[1]+kR[0])/((kR[1]-kR[0])*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - intRDDZ = (QR[1,ii]+QR[0,ii])*(QR[1,ii]-QR[0,ii])**3/(60.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR1A = ( -2.*QR[0,Ind[jj]]*QR[0,ii] + QR[0,ii]**2 - 3.*QR[0,Ind[jj]]*QR[1,ii] + 2.*QR[0,ii]*QR[1,ii] + 2.*QR[1,ii]**2 )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intR1B = - ( QR[0,ii]**2 + 2.*QR[1,ii]*(5.*QR[1,ii]-6.*QR[2,ii]) + QR[0,ii]*(4.*QR[1,ii]-3.*QR[2,ii]) )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2A = ( 10.*QR[1,ii]**2 + 4.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[0,ii]*(4.*QR[1,ii]+QR[2,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2B = - ( 2.*QR[1,ii]**2 + 2.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[1,ii]*QR[3,ii] -2.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intRDDZ = intR1A + intR1B + intR2A + intR2B - intRDDR = -2.*(QR[1,ii]+QR[0,ii])*(QR[2,ii]+QR[1,ii]-QR[0,ii]-QR[0,Ind[jj]])/((QR[1,ii]-QR[0,ii])*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - 2.*(QR[2,ii]+QR[1,ii])*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[3,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDDR = 2.*(kR[1]+kR[0])/((kR[1]-kR[0])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])*(QR[3,ii]-QR[1,ii])) - intRDDZ = (QR[3,ii]+QR[2,ii])*(QR[3,ii]-QR[2,ii])**3/(60.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR1A = ( -2.*QR[0,ii]*QR[1,ii] + QR[1,ii]**2 - 3.*QR[0,ii]*QR[2,ii] + 2.*QR[1,ii]*QR[2,ii] + 2.*QR[2,ii]**2 )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR1B = - ( QR[1,ii]**2 + 2.*QR[2,ii]*(5.*QR[2,ii]-6.*QR[3,ii]) + QR[1,ii]*(4.*QR[2,ii]-3.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2A = ( 10.*QR[2,ii]**2 + 4.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[1,ii]*(4.*QR[2,ii]+QR[3,ii]) )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2B = - ( 2.*QR[2,ii]**2 + 2.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[2,ii]*QR[3,Ind[jj]] -2.*QR[3,ii]*QR[3,Ind[jj]] )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])*(QR[3,Ind[jj]]-QR[2,ii])) - intRDDZ = intR1A + intR1B + intR2A + intR2B - intRDDR = -2.*(QR[2,ii]+QR[1,ii])*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) - 2.*(QR[3,ii]+QR[2,ii])*(QR[3,Ind[jj]]+QR[3,ii]-QR[2,ii]-QR[1,ii])/((QR[3,ii]-QR[2,ii])*(QR[3,Ind[jj]]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common knots..." - - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDDR = d0Z[ii] - intZDDZ = d0DDZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDDZ = -4.*(QZ[2,ii]+QZ[1,ii]-QZ[1,Ind[jj]]-QZ[0,Ind[jj]])/((QZ[2,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])**2) - intZDDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDDZ = -4.*(QZ[3,Ind[jj]]+QZ[2,Ind[jj]]-QZ[2,ii]-QZ[1,ii])/((QZ[3,ii]-QZ[2,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common knots..." - - llR[0,Ind[jj]] = intRDDR*intZDDR - llZ[0,Ind[jj]] = intRDDZ*intZDDZ - llR[0,ii] = d0DDR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DDZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - AR, AZ = scpsp.vstack(LLR,format='csr'), scpsp.vstack(LLZ,format='csr') - A = (AR,AZ) - - if not Sparse: - if m in [0,1]: - A = A.toarray() - elif m==2: - A = (A[0].toarray(),A[1].toarray()) - - return A, m - - - - - - - - - - - - - - - - - - - -def Calc_BF2D_DerivFunc(BF2, Deriv, Test=True): - if Test: - assert isinstance(BF2, BF2D), "Arg BF2 must be a MeshBase2D instance !" - assert type(Deriv) is int, "Arg Deriv must be a int !" - - KnR, KnZ = BF2._get_quadPoints() - if Deriv==1: - LFuncR, LFuncZ = [], [] - for ii in range(0,BF2.NFunc): - LFuncR.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=0, Test=False)[0](X[1,:])*BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=Deriv, Test=False)[0](X[0,:])) - LFuncZ.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=0, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=Deriv, Test=False)[0](X[1,:])) - return LFuncR, LFuncZ - elif Deriv==2: - # Formulas for Gauss and Mean curvature were found on http://en.wikipedia.org/wiki/Differential_geometry_of_surfaces - DRR, DRZ, DZZ = [], [], [] - for ii in range(0,BF2.NFunc): - DRR.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=Deriv, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=0, Test=False)[0](X[1,:])) - DRZ.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=1, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=1, Test=False)[0](X[1,:])) - DZZ.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=0, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=Deriv, Test=False)[0](X[1,:])) - return DRR, DRZ, DZZ - - - - -def Get_MinMax(BF2, Coefs=1., Ratio=0.05, SubP=0.004, SubP1=0.015, SubP2=0.001, TwoSteps=False, SubMode='abs', Deriv='D0', Margin=0.2, Test=True): - assert Ratio is None or (type(Ratio) is float and Ratio>0 and Ratio<1), "Arg Ratio must be None or a float in ]0;1[ !" - if TwoSteps: - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP1, SubMode='abs', Test=Test) - else: - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP, SubMode='abs', Test=Test) - nx, ny = X.size, Y.size - dS = np.mean(np.diff(X))*np.mean(np.diff(Y)) - Xplot, Yplot = np.tile(X,(ny,1)), np.tile(Y,(nx,1)).T - Points = np.array([Xplot.flatten(), Yplot.flatten()]) - Vals = BF2.get_TotVal(Points, Deriv=Deriv, Coefs=Coefs, Test=Test) - - def getminmaxRatioFloat(valsmax, valsmin, indmax, indmin, Ratio, Ptsmin, Ptsmax): - DV = valsmax[indmax]-valsmin[indmin] - imin, imax = valsmin<=valsmin[indmin]+Ratio*DV, valsmax>=valsmax[indmax]-Ratio*DV - PMin = np.array([np.sum(Ptsmin[0,imin]*valsmin[imin])/np.sum(valsmin[imin]), np.sum(Ptsmin[1,imin]*valsmin[imin])/np.sum(valsmin[imin])]) - PMax = np.array([np.sum(Ptsmax[0,imax]*valsmax[imax])/np.sum(valsmax[imax]), np.sum(Ptsmax[1,imax]*valsmax[imax])/np.sum(valsmax[imax])]) - VMin, VMax = np.mean(valsmin[imin]), np.mean(valsmax[imax]) - return PMin, PMax, VMin, VMax - - def get_XYgridFine(DXmin, DYmin, DXmax, DYmax, Margin, subp): - DXmin, DYmin = [DXmin[0]-Margin*(DXmin[1]-DXmin[0]), DXmin[1]+Margin*(DXmin[1]-DXmin[0])], [DYmin[0]-Margin*(DYmin[1]-DYmin[0]), DYmin[1]+Margin*(DYmin[1]-DYmin[0])] - DXmax, DYmax = [DXmax[0]-Margin*(DXmax[1]-DXmax[0]), DXmax[1]+Margin*(DXmax[1]-DXmax[0])], [DYmax[0]-Margin*(DYmax[1]-DYmax[0]), DYmax[1]+Margin*(DYmax[1]-DYmax[0])] - Nxmin, Nymin = (DXmin[1]-DXmin[0])/subp, (DYmin[1]-DYmin[0])/subp - Nxmax, Nymax = (DXmax[1]-DXmax[0])/subp, (DYmax[1]-DYmax[0])/subp - Xmin, Ymin = np.linspace(DXmin[0],DXmin[1], Nxmin), np.linspace(DYmin[0],DYmin[1], Nymin) - Xmax, Ymax = np.linspace(DXmax[0],DXmax[1], Nxmax), np.linspace(DYmax[0],DYmax[1], Nymax) - Ptsmin = np.array([np.tile(Xmin,(Nymin,1)).flatten(), np.tile(Ymin,(Nxmin,1)).T.flatten()]) - Ptsmax = np.array([np.tile(Xmax,(Nymax,1)).flatten(), np.tile(Ymax,(Nxmax,1)).T.flatten()]) - return Ptsmin, Ptsmax - - def get_minmaxFine(vals, indmaxi, indmini, coefs, Points=Points, ratio=0.02, SubP2=SubP2, Ratio=Ratio, Test=Test): - DV = vals[indmaxi]-vals[indmini] - imin, imax = vals<=vals[indmini]+ratio*DV, vals>=vals[indmaxi]-ratio*DV - xminmin, xminmax = np.min(Points[0,imin]), np.max(Points[0,imin]) - xmaxmin, xmaxmax = np.min(Points[0,imax]), np.max(Points[0,imax]) - yminmin, yminmax = np.min(Points[1,imin]), np.max(Points[1,imin]) - ymaxmin, ymaxmax = np.min(Points[1,imax]), np.max(Points[1,imax]) - Ptsmin, Ptsmax = get_XYgridFine([xminmin,xminmax], [yminmin,yminmax], [xmaxmin, xmaxmax], [ymaxmin, ymaxmax], Margin, SubP2) - valsmin, valsmax = BF2.get_TotVal(Ptsmin, Deriv=Deriv, Coefs=coefs, Test=Test), BF2.get_TotVal(Ptsmax, Deriv=Deriv, Coefs=coefs, Test=Test) - indmin, indmax = np.nanargmin(valsmin), np.nanargmax(valsmax) - if Ratio is None: - return Ptsmin[:,indmin], Ptsmax[:,indmax], valsmin[indmin], valsmax[indmax] - else: - return getminmaxRatioFloat(valsmax, valsmin, indmax, indmin, Ratio, Ptsmin, Ptsmax) - - if not hasattr(Coefs,'__getitem__') or Coefs.ndim==1: - indmin, indmax = np.nanargmin(Vals), np.nanargmax(Vals) - if TwoSteps: - PMin, PMax, VMin, VMax = get_minmaxFine(Vals, indmax, indmin, Coefs, Points=Points, ratio=0.02, SubP2=SubP2, Ratio=Ratio, Test=Test) - else: - if Ratio is None: - PMin, PMax = Points[:,indmin], Points[:,indmax] - VMin, VMax = Vals[indmin], Vals[indmax] - else: - PMin, PMax, VMin, VMax = getminmaxRatioFloat(Vals, Vals, indmax, indmin, Ratio, Points, Points) - Surf = (Vals >= Vals(np.nanargmax(Vals))*0.5).sum()*dS - else: - indmin, indmax = np.nanargmin(Vals,axis=1), np.nanargmax(Vals,axis=1) - if TwoSteps: - ratio = 0.02 if Ratio is None else Ratio+0.02 - mmin, mmax = np.nanmin(Vals,axis=1).max(), np.nanmax(Vals,axis=1).min() - DV = np.max(np.nanmax(Vals,axis=1)-np.nanmin(Vals,axis=1)) - assert mmin+ratio*DV <= mmax-ratio*DV, "Profile changes too much !" - imin, imax = np.any(Vals<=mmin+ratio*DV,axis=0), np.any(Vals>=mmax-ratio*DV,axis=0) - DXmin, DYmin = [Points[0,imin].min(), Points[0,imin].max()], [Points[1,imin].min(), Points[1,imin].max()] - DXmax, DYmax = [Points[0,imax].min(), Points[0,imax].max()], [Points[1,imax].min(), Points[1,imax].max()] - Ptsmin, Ptsmax = get_XYgridFine(DXmin, DYmin, DXmax, DYmax, Margin, SubP2) - Valsmin, Valsmax = BF2.get_TotVal(Ptsmin, Deriv=Deriv, Coefs=Coefs, Test=Test), BF2.get_TotVal(Ptsmax, Deriv=Deriv, Coefs=Coefs, Test=Test) - else: - Ptsmin, Ptsmax = Points, Points - Valsmin, Valsmax = Vals, Vals - indmin, indmax = np.nanargmin(Valsmin,axis=1), np.nanargmax(Valsmax,axis=1) - if Ratio is None: - PMin, PMax = Ptsmin[:,indmin].T, Ptsmax[:,indmax].T - VMin, VMax = np.nanmin(Valsmin,axis=1), np.nanmax(Valsmax,axis=1) - else: - Nt = Coefs.shape[0] - PMin, PMax = np.empty((Nt,2)), np.empty((Nt,2)) - VMin, VMax = np.empty((Nt,)), np.empty((Nt,)) - for ii in range(0,Nt): - PMin[ii,:], PMax[ii,:], VMin[ii], VMax[ii] = getminmaxRatioFloat(Valsmax[ii,:], Valsmin[ii,:], indmax[ii], indmin[ii], Ratio, Ptsmin, Ptsmax) - Surf = np.sum(Vals >= np.tile(np.nanmax(Vals,axis=1)*0.5,(Vals.shape[1],1)).T,axis=1)*dS - - return PMin, PMax, VMin, VMax, Surf - - - - - - - - -def Calc_GetRoots(BF2, Deriv=0., Coefs=1., Test=True): - if Test: - assert isinstance(BF2, BF2D), "Arg BF2 must be a BF2D instance !" - assert Deriv in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI'], "Arg Deriv must be in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI'] !" - if type(Deriv) is str: - intDeriv = int(Deriv[1]) - else: - intDeriv = Deriv - assert BF2.Deg > 0 and intDeriv0)) and C4.size==4: - Inds[ii] = True - A = C4[0]+C4[3] - C4[1]+C4[2] - B = C4[1]*Kts[1,1] - C4[3]*Kts[1,0] - C4[0]*Kts[1,1] + C4[2]*Kts[1,0] - C = C4[1]*Kts[0,0] - C4[3]*Kts[0,0] - C4[0]*Kts[0,1] + C4[2]*Kts[0,1] - D = Kts[0,1]*(C4[0]*Kts[1,1]-C4[2]*Kts[1,0]) - Kts[0,0]*(C4[1]*Kts[1,1]-C4[3]*Kts[1,0]) - if A==0.: - if C==0.: - if B==0.: - Shape[ii] = ['all',[]] if D==0. else ['',[]] # Else not possible - else: - Shape[ii] = ['x',[-D/B]] - else: - Shape[ii] = ['yx',[-B/C,-D/C]] - else: - if -C/A>Kts[0,1] or -C/A0)) and C9.size==9: - Inds[ii] = True - print " Not finished yet !" - - - - - if intDeriv==1: - if Deriv[1]=='D1N2': - if BF2.Deg==2: - for ii in range(0,NCents): - ind = BF2._Cents_Funcind[:,ii] - C9 = Coefs[np.unique(ind[~np.isnan(ind)]).astype(int)] - Kts = BF2.Mesh.Knots[:,np.unique(BF2.Mesh._Cents_Knotsind[:,ii])] - - #A0, B0 = - #A1, B1 = - #A2, B2 = - #alpha0, beta0, gam0 = - #alpha1, beta1, gam1 = - #alpha2, beta2, gam2 = - return Inds, Pts, Shape - - - - - - -############################################ -##### Plotting functions -############################################ - - - -def Plot_BF2D(BF2, Coef=1., ax='None',SubP=0.1, SubMode='Rel', Name='Tot', TotDict=Tot2Dict_Def): - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert ax=='None' or isinstance(ax,plt.Axes), "Arg ax must be a plt.Axes instance !" - assert type(Name) is str, "Arg Name must be a str !" - - assert type(TotDict) is dict, "Arg TotDict must be a dict !" - - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP, SubMode=SubMode, Test=True) - nx, ny = X.size, Y.size - Xplot, Yplot = np.dot(np.ones((ny,1)),X.reshape((1,nx))), np.dot(Y.reshape((ny,1)),np.ones((1,nx))) - Points = np.concatenate((Xplot.reshape((1,nx*ny)), Yplot.reshape((1,nx*ny))),axis=0) - Z = Calc_BF2D_Val(BF2.LFunc, Points, Coef=Coef, Test=True) - Zplot= Z.reshape((ny,nx)) - - if ax=='None': - ax = tfd.Plot_BSpline_DefAxes('2D') - ax.plot_surface(Xplot,Yplot,Zplot, label=Name, **TotDict) - - ax.figure.canvas.draw() - return ax - - - - -def Plot_BF2D_BFuncMesh(BF2, ind, Coef=1., ax1='None', ax2='None',SubP=0.25, SubMode='Rel', Name='', TotDict=Tot2Dict_Def): - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert type(ind) is int, "Arg ind must be a int !" - assert ax1=='None' or isinstance(ax1,plt.Axes), "Arg ax1 must be a plt.Axes instance !" - assert ax2=='None' or isinstance(ax2,plt.Axes), "Arg ax2 must be a plt.Axes instance !" - assert type(Name) is str, "Arg Name must be a str !" - assert type(TotDict) is dict, "Arg TotDict must be a dict !" - - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP, SubMode=SubMode, Test=True) - nx, ny = X.size, Y.size - Xplot, Yplot = np.dot(np.ones((ny,1)),X.reshape((1,nx))), np.dot(Y.reshape((ny,1)),np.ones((1,nx))) - Points = np.concatenate((Xplot.reshape((1,nx*ny)), Yplot.reshape((1,nx*ny))),axis=0) - Z = Calc_BF2D_Val([BF2.LFunc[ind]], Points, Coef=Coef, Test=True) - Zplot= Z.reshape((ny,nx)) - - if ax1=='None' or ax2=='None': - ax1, ax2 = tfd.Plot_BF2D_BFuncMesh_DefAxes() - - BF2.Mesh.plot(ax=ax1) - BF2.Mesh.plot_Cents(ax=ax1,Ind=BF2.Func_Centsind[:,ind], Knots=False) - BF2.Mesh.plot_Knots(ax=ax1,Ind=BF2.Func_Knotsind[:,ind], Cents=False) - - ax2.plot_surface(Xplot,Yplot,Zplot, label=Name, **TotDict) - ax1.figure.canvas.draw() - return ax1, ax2 - - -def Plot_BFunc_SuppMax_PolProj(BF2, ind, ax='None', Supp=True,PMax=True,SuppDict=SuppDict_Def, PMaxDict=PMaxDict_Def): - assert type(ind) is int, "Arg ind must be a int !" - assert type(Supp) is bool, "Arg Supp must be a bool !" - assert type(PMax) is bool, "Arg Supp must be a bool !" - assert type(SuppDict) is dict, "Arg SuppDict must be a dict !" - assert type(PMaxDict) is dict, "Arg SuppDict must be a dict !" - assert isinstance(ax,plt.Axes) or ax=='None', "Arg ax must be a plt.Axes instance !" - - - if ax=='None': - ax = tfd.Plot_BFunc_SuppMax_PolProj_DefAxes() - - if Supp: - RZsupp = BF2.get_Func_SuppRZ()[:,ind] - verts = [(RZsupp[0], RZsupp[2]), # left, bottom - (RZsupp[1], RZsupp[2]), # left, top - (RZsupp[1], RZsupp[3]), # right, top - (RZsupp[0], RZsupp[3]), # right, bottom - (RZsupp[0], RZsupp[2])] - - codes = [Path.MOVETO, - Path.LINETO, - Path.LINETO, - Path.LINETO, - Path.CLOSEPOLY] - - patch = patches.PathPatch(Path(verts, codes), **SuppDict) - ax.add_patch(patch) - if PMax: - PMax = BF2.Func_PMax[:,ind] - ax.plot(PMax[0],PMax[1], **PMaxDict) - - return ax - - - -""" -############################################################################### -############################################################################### - Testing ground -############################################################################### -""" -""" -Deg = 2 -KnotsMult1 = np.array([0.,1.,2.,3.,4.,5., 5., 5.]) -KnotsMult2 = np.array([0.,0.,1.,2.,3.,4.,5.]) -BS1 = BSpline(Deg,KnotsMult1)[0] -BS2 = BSpline(Deg,KnotsMult2)[0] -#ax = Plot_BSpline1D(KnotsMult1,BS1,ax='None',SubP=0.05,SubMode='Rel') -ax1, ax2 = Plot_BSpline2D(KnotsMult1, KnotsMult2, BS1, BS2, ax1=None, ax2='None',SubP=0.05,SubMode='Rel') -""" - diff --git a/tofu/mesh/_core.py b/tofu/mesh/_core.py deleted file mode 100644 index cefed8544..000000000 --- a/tofu/mesh/_core.py +++ /dev/null @@ -1,2661 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Aug 25 10:03:58 2014 - -@author: didiervezinet -""" - -import numpy as np -import matplotlib.pyplot as plt -from mpl_toolkits.mplot3d import Axes3D -import Polygon as plg -import scipy.sparse as scpsp -from matplotlib.path import Path -import matplotlib.patches as patches -from matplotlib.collections import PatchCollection as PcthColl -import datetime as dtm -import scipy.interpolate as scpinterp - -#from mayavi import mlab - - - -# ToFu-specific -import tofu.defaults as tfd -import tofu.pathfile as tfpf -from . import _bsplines_cy as _tfm_bs -from . import _compute as _tfm_c -from . import _plot as _tfm_p - - -__all__ = ['LinMesh','LinMesh_List','Mesh1D','Mesh2D','LBF1D'] - - - -""" -############################################################################### -############################################################################### - Default -############################################################################### -""" - -BS2Dict_Def = {'linewidth':0.,'rstride':1,'cstride':1, 'antialiased':False} -Tot2Dict_Def = {'color':(0.7,0.7,0.7),'linewidth':0.,'rstride':1,'cstride':1, 'antialiased':False} -SuppDict_Def = {'facecolor':(0.8,0.8,0.8), 'lw':0.} -PMaxDict_Def = {'color':'g', 'marker':'s', 'markersize':8, 'linestyle':'None', 'linewidth':1.} - - -""" -############################################################################### -############################################################################### - Mesh definitions -############################################################################### -""" - -############################################ -##### Helper functions -############################################ - - - -def LinMesh(X1,X2,Res1,Res2, DRes=tfd.L1DRes, Mode=tfd.L1Mode, Test=True): - """ - Create a linearly variable-size 1D mesh between between 2 points, with specified resolution (i.e. mesh size) in the neighbourhood of each point - - Inputs: - ------- - X1 float / np.float64 First point of the interval to be meshed - X2 float / np.float64 Last point of the interval to be meshed - Res1 float / np.float64 Mesh size to be achieved in the vicinity of X1 - Res2 float / np.float64 Mesh size to be achieved in the vicinity of X2 - DRes float / np.float64 Tolerable variation on the mesh size (i.e.: if abs(Res1-Res2)0., "Arg DRes must be a strictly positive float !" - assert Mode=='Larger' or Mode=='Both', "Arg Mode must be 'Larger' or 'Both' !" - Delta = abs(X2-X1) - Sum = Res1+Res2 - if Delta < Res2 or Delta < Res1: - xn = np.array([X1, X2]) - elif Delta < Sum: - xn = np.array([X1, X1*Res2/Sum + X2*Res1/Sum, X2]) - elif abs(Res2 - Res1) Res2: - Eps = 2.*Delta/(Res1*(N+1)) - Sum/Res1 - Res1 = Res1*(1+Eps) - else: - Eps = 2.*Delta/(Res2*(N+1)) - Sum/Res2 - Res2 = Res2*(1+Eps) - else: - Eps = 2.*Delta/((N+1)*Sum) - 1 - Res1, Res2 = Res1*(1+Eps), Res2*(1+Eps) - xn = X1 + Res1*n + (Res2-Res1)*n*(n-1)/(2*N) - return xn, float(Res1), float(Res2) - - -def LinMesh_List(KnotsL, ResL, DRes=tfd.L1DRes, Mode=tfd.L1Mode, Tol=tfd.L1Tol, Concat=True, Test=True): - """ - Create a linearly variable-size 1D mesh by concatenating several such meshes computed with LinMesh() from a list of adjacent intervals - - Inputs: - ------- - KnotsL list List of intervals (tuples or lists of len()==2) - ResL list List of associated resolution objectives (tuples or lists of len()==2) - DRes float / np.float64 Tolerable variation on the mesh size (see LinMesh()) - Mode str Flag indicating how the linear variation should be computed (see LinMesh()) - Tol float Tolerance on the final concatenated array (to decide whether points are different or identical) - Concat bool Flag indicating whether the final list of meshes should be concatenated into a unique array - Test bool Flag indicating whether the inputs should be tested for conformity - - Outputs: - -------- - X list / np.ndarray Final list of meshes or cancatenated array - Res list List of final acheived resolutions / mesh sizes - - """ - if Test: - assert type(KnotsL) is list and [len(K)==2 for K in KnotsL], "Arg KnotsL must be a list of intervals !" - assert type(ResL) is list and [len(R)==2 for R in ResL], "Arg ResL must be a list of resolutions !" - assert type(DRes) is float and DRes>0., "Arg DRes must be a strictly positive float !" - assert Mode=='Larger' or Mode=='Both', "Arg Mode must be 'Larger' or 'Both' !" - X, Res = [], [] - for ii in range(0,len(KnotsL)): - x, res1, res2 = LinMesh(float(KnotsL[ii][0]), float(KnotsL[ii][1]), float(ResL[ii][0]), float(ResL[ii][1]), DRes=DRes, Mode=Mode, Test=True) - X.append(x) - Res.append((res1,res2)) - if Concat: - X = np.unique(np.concatenate(tuple(X))) - dX = np.diff(X) - indout = (dX <= Tol).nonzero()[0] - X = np.delete(X,indout) - return X, Res - - - - -############################################ -##### Objects definitions -############################################ - - -class Mesh1D(object): - """ A class defining a 1D mesh (knot vector, with associated lengths, centers and correspondace between them, as well as plotting routines) - - Inputs: - ------- - Knots iterable The knots of the mesh - Id None or str or tfpf.ID A name or tfpf.ID class, for identification - Type None or str The type of Mesh1D object (default: None) - Exp None or str The experiment to which this object relates (e.g.: "ITER", "AUG", "JET"...) - shot None or int A shot number from which this object can be used (i.e.: in case of changing geometry) - dtime None or dtm.datetime A time reference to be used to identify this particular instance (used for debugging mostly), default: None - dtimeIn bool Flag indicating whether dtime should be included in the SaveName (used for debugging mostly), default: False - SavePath None or str Absolute path where the object would be saved if necessary - """ - - def __init__(self, Id, Knots, Type=None, Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - - self._Done = False - self._set_Id(Id, Type=Type, Exp=Exp, shot=shot, dtime=dtime, dtimeIn=dtimeIn, SavePath=SavePath) - self._set_Knots(Knots) - self._Done = True - - - @property - def Id(self): - "" "Return the Id """ - return self._Id - @property - def Knots(self): - """ Return the knots """ - return self._Knots - @property - def NKnots(self): - return self._NKnots - @property - def Cents(self): - """ Return the centers of the mesh """ - return self._Cents - @property - def NCents(self): - """ Return the centers of the mesh """ - return self._NCents - @property - def Bary(self): - """ Return the barycenter """ - return self._Bary - @property - def Lengths(self): - """ Return the vector of length of each mesh element """ - return self._Lengths - @property - def Length(self): - """ Return the total length of the Mesh """ - return self._Length - - #@property - #def Cents_Knotsind(self): - # """ Return the indices of all knots surrounding each center """ - # return self._Cents_Knotsind - #@property - #def Knots_Centsind(self): - # """ Return the indices of all centers surrounding each knot """ - # return self._Knots_Centsind - - - def _check_inputs(self, Id=None, Knots=None, Type=None, Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - _Mesh1D_check_inputs(Id=Id, Knots=Knots, Type=Type, Exp=Exp, shot=shot, dtime=dtime, dtimeIn=dtimeIn, SavePath=SavePath) - - def _set_Id(self, Id, Type=None, Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - if self._Done: - Out = tfpf._get_FromItself(self.Id,{'Type':Type, 'Exp':Exp, 'shot':shot, 'dtime':dtime, '_dtimeIn':dtimeIn, 'SavePath':SavePath}) - Type, Exp, shot, dtime, dtimeIn, SavePath = Out['Type'], Out['Exp'], Out['shot'], Out['dtime'], Out['dtimeIn'], Out['SavePath'] - tfpf._check_NotNone({'Id':Id}) - self._check_inputs(Id=Id) - if type(Id) is str: - Exp = 'Test' if Exp is None else Exp - tfpf._check_NotNone({'Exp':Exp, 'dtimeIn':dtimeIn}) - self._check_inputs(Type=Type, Exp=Exp, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - Id = tfpf.ID('Mesh1D', Id, Type=Type, Exp=Exp, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._Id = Id - - def _set_Knots(self, Knots): - """ Set the knots and computes all subsequent attributes """ - tfpf._check_NotNone({'Knots':Knots}) - self._check_inputs(Knots=Knots) - self._NKnots, self._Knots, self._NCents, self._Cents, self._Lengths, self._Length, self._Bary, self._Cents_Knotsind, self._Knots_Centsind = _tfm_c._Mesh1D_set_Knots(Knots) - - def sample(self, Sub=tfd.BF1Sub, SubMode=tfd.BF1SubMode, Test=True): - """ Return a sampling of Mesh using the provided Sub resolution in 'rel' (relative to the size of each mesh element) or 'abs' mode (in distance unit), useful for plotting basis functions on the mesh """ - xx = _tfm_c._Mesh1D_sample(self.Knots, Sub=Sub, SubMode=SubMode, Test=True) - return xx - - - # plotting routines - def plot(self, y=0., Elt='KCN', ax=None, Kdict=tfd.M1Kd, Cdict=tfd.M1Cd, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True): - """ Return a plt.Axes instance to the plot of Mesh1D """ - return _tfm_p.Mesh1D_Plot(self._Knots, y=y, Elt=Elt, Leg=self._Id.NameLTX, ax=ax, Kdict=Kdict, Cdict=Cdict, LegDict=LegDict, draw=draw, a4=a4, Test=Test) - - def plot_Res(self, ax=None, Dict=tfd.M1Resd, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True): - """ Return a plt.Axes instance to the plot of the resolution of Mesh1D """ - return _tfm_p.Mesh1D_Plot_Res(self._Knots, Leg=self._Id.NameLTX, ax=ax, Dict=Dict, LegDict=LegDict, draw=draw, a4=a4, Test=Test) - - # Saving routine - def save(self, SaveName=None, Path=None, Mode='npz'): - """ - Save the object in folder Name, under file name SaveName, using specified mode - - Inputs: - ------ - SaveName str The name to be used to for the saved file, if None (recommended) uses Ves.Id.SaveName (default: None) - Path str Path specifying where to save the file, if None (recommended) uses Ves.Id.SavePath (default: None) - Mode str Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, may cause retro-compatibility issues with later versions) - """ - tfpf.Save_Generic(self, SaveName=SaveName, Path=Path, Mode=Mode) - - -def _Mesh1D_check_inputs(Id=None, Knots=None, Type=None, Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - if Id is not None: - assert type(Id) in [str,tfpf.ID], "Arg Id must be a str or a tfpf.ID object !" - if Knots is not None: - assert hasattr(Knots,'__iter__') and np.asarray(Knots).ndim==1 and np.all(Knots==np.unique(Knots)) and not np.any(np.isnan(Knots)), "Arg Knots must be an iterable of increasing non-NaN knots coordinates !" - assert Type is None, "Arg Type must be None for a 1D mesh and LBF !" - if not Exp is None: - assert Exp in tfd.AllowedExp, "Ar Exp must be in "+str(tfd.AllowedExp)+" !" - Ints = [shot] - if any([not aa is None for aa in Ints]): - assert all([aa is None or type(aa) is int for aa in Ints]), "Args [shot] must be int !" - strs = [SavePath] - if any([not aa is None for aa in strs]): - assert all([aa is None or type(aa) is str for aa in strs]), "Args [SavePath] must all be str !" - if not dtime is None: - assert type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !" - bools = [dtimeIn] - if any([not aa is None for aa in bools]): - assert all([aa is None or type(aa) is bool for aa in bools]), " Args [dtimeIn] must all be bool !" - - - - - - - - -class Mesh2D(object): - """ A class defining a 2D mesh (knot vector, with associated surfaces, centers and correspondace between them, as well as plotting routines) - - Inputs: - ------- - Id None or str or tfpf.ID A name or tfpf.ID class, for identification - Knots iterable or Mesh2D An iterable of len()==2, containing either 2 Mesh1D instances or 2 iterables of knots, or a Mesh2D instance, of which only some elements (indicated by ind) are to be kept - ind iterable An iterable - Type None or str The type of Mesh1D object (default: None) - Exp None or str The experiment to which this object relates (e.g.: "ITER", "AUG", "JET"...) - shot None or int A shot number from which this object can be used (i.e.: in case of changing geometry) - dtime None or dtm.datetime A time reference to be used to identify this particular instance (used for debugging mostly), default: None - dtimeIn bool Flag indicating whether dtime should be included in the SaveName (used for debugging mostly), default: False - SavePath None or str Absolute path where the object would be saved if necessary - """ - - def __init__(self, Id, Knots, ind=None, Type='Tor', Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - - self._Done = False - self._set_Id(Id, Type=Type, Exp=Exp, shot=shot, dtime=dtime, dtimeIn=dtimeIn, SavePath=SavePath) - self._set_Knots(Knots, ind=ind) - self._Done = True - - @property - def Id(self): - return self._Id - @property - def Type(self): - return self.Id.Type - @property - def Knots(self): - return self._Knots - @property - def NKnots(self): - return self._NKnots - @property - def Cents(self): - return self._Cents - @property - def NCents(self): - return self._NCents - @property - def MeshX1(self): - return self._MeshX1 - @property - def MeshX2(self): - return self._MeshX2 - @property - def SubMesh(self): - return self._SubMesh - @property - def BaryS(self): - return self._BaryS - @property - def Surfs(self): - return self._Surfs - @property - def Surf(self): - return self._Surf - @property - def VolAngs(self): - return self._VolAngs - @property - def VolAng(self): - return self._VolAng - @property - def BaryV(self): - return self._BaryV - @property - def CentsV(self): - return self._CentsV - - - def _check_inputs(self, Id=None, Knots=None, ind=None, Type=None, Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - _Mesh2D_check_inputs(Id=Id, Knots=Knots, ind=ind, Type=Type, Exp=Exp, shot=shot, dtime=dtime, dtimeIn=dtimeIn, SavePath=SavePath) - - def _set_Id(self, Id, Type=None, Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - if self._Done: - Out = tfpf._get_FromItself(self.Id,{'Type':Type, 'Exp':Exp, 'shot':shot, 'dtime':dtime, '_dtimeIn':dtimeIn, 'SavePath':SavePath}) - Type, Exp, shot, dtime, dtimeIn, SavePath = Out['Type'], Out['Exp'], Out['shot'], Out['dtime'], Out['dtimeIn'], Out['SavePath'] - tfpf._check_NotNone({'Id':Id}) - self._check_inputs(Id=Id) - if type(Id) is str: - Exp = 'Test' if Exp is None else Exp - tfpf._check_NotNone({'Exp':Exp, 'dtimeIn':dtimeIn}) - self._check_inputs(Type=Type, Exp=Exp, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - Id = tfpf.ID('Mesh2D', Id, Type=Type, Exp=Exp, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._Id = Id - - def _set_Knots(self, Knots, ind=None): - tfpf._check_NotNone({'Knots':Knots}) - self._check_inputs(Knots=Knots, ind=ind) - if ind is None: - self._MeshX1 = Knots[0] if type(Knots[0]) is Mesh1D else Mesh1D(self.Id.Name+'_MeshX1', np.asarray(Knots[0])) - self._MeshX2 = Knots[1] if type(Knots[1]) is Mesh1D else Mesh1D(self.Id.Name+'_MeshX2', np.asarray(Knots[1])) - self._Knots = np.array([np.tile(self.MeshX1.Knots,(1,self.MeshX2.NKnots)).flatten(), np.tile(self.MeshX2.Knots,(self.MeshX1.NKnots,1)).T.flatten()]) - self._Cents = np.array([np.tile(self.MeshX1.Cents,(1,self.MeshX2.NCents)).flatten(), np.tile(self.MeshX2.Cents,(self.MeshX1.NCents,1)).T.flatten()]) - else: - # ind should refer to the centers of 'Knots', which should be a Mesh2D object - ind = np.asarray(ind) - ind = ind.nonzero()[0] if ind.dtype.name is 'bool' else ind - self._Cents = Knots._Cents[:,ind] - indKnots = np.unique(Knots._Cents_Knotsind[:,ind].flatten()) - self._Knots = Knots.Knots[:,indKnots] - self._MeshX1 = Mesh1D(self.Id.Name+'_MeshX1',np.unique(self.Knots[0,:])) - self._MeshX2 = Mesh1D(self.Id.Name+'_MeshX2',np.unique(self.Knots[1,:])) - self._NCents = self.Cents.shape[1] - self._NKnots = self.Knots.shape[1] - self._set_Attribs() - - def _set_Attribs(self): - self._set_Cents_Knotsind() - self._set_Knots_Centsind() - self._set_SurfVolBary() - self._set_BoundPoly() - self._SubMesh = {} - - def _set_Cents_Knotsind(self): - self._Cents_Knotsind = _tfm_c._Mesh2D_set_Cents_Knotsind(self.NCents, self.MeshX1.Knots, self.MeshX2.Knots, self.Cents, self.Knots) - - def _set_Knots_Centsind(self): - self._Knots_Centsind = _tfm_c._Mesh2D_set_Knots_Centsind(self.NKnots, self.MeshX1.Cents, self.MeshX2.Cents, self.Knots, self.Cents, self.NCents) - - def _set_SurfVolBary(self): - self._Surfs, self._Surf, self._VolAngs, self._VolAng, self._BaryS, self._BaryV, self._CentsV = _tfm_c._Mesh2D_set_SurfVolBary(self.Knots, self._Cents_Knotsind, self.Cents, VType=self.Id.Type) - - def _set_BoundPoly(self): - self._BoundPoly = _tfm_c._Mesh2D_set_BoundPoly(self.Knots, self._Cents_Knotsind, self.NCents) - - def _get_SubMeshInPolygon(self, Poly, InMode='Cents', NLim=1, Id=None, Out='Mesh2D'): - """ Get the indices (int or bool) of the Cents which lie inside the input Poly (InMode='Cents') or of the Cents of which at least NLim Knots lie inside the input Poly (InMode='Knots'), can also return Mesh2D object """ - assert Out in ['Mesh2D', int, bool], "Arg Out must be in ['Mesh2D', int, bool] !" - indIn = _tfm_c._Mesh2D_get_SubMeshPolygon(self.Cents, self.Knots, self._Cents_Knotsind, Poly, InMode=InMode, NLim=NLim) - if Out=='Mesh2D': - Id = self.Id.Name+'_SubMesh' if Id is None else Id - indIn = Mesh2D(Id, self, ind=indIn, Type=self.Id.Type, Exp=self.Exp, shot=self.shot, SavePath=self.SavePath, dtime=self.dtime, dtimeIn=self.dtimeIn) - indIn.Id.set_USRdict({'SubMeshPoly':Poly}) - else: - indIn = indIn if Out==bool else indIn.nonzero()[0] - return indIn - - def add_SubMesh(self, Name, ind=None, Poly=None, InMode='Cents', NLim=1): - """ - Add a submesh, defined by the indices of some centers or by the elements lying inside a polygon - - Inputs: - ------- - Name str The name to be given to the created submesh - ind None / Indices of the mesh elements to be used for creating the submesh - Poly None / Polygon inside which the elements should lie to belong to the submesh - InMode str Flag indicating how to determine whether an element lies inside the polygon, by its center ('Cents') or knots ('Knots') - NLim int If InMode=='Knots', number of knots that must lie inside the polygon for the mesh element to be considered inside too - - The created submesh is added to the self.SubMesh dictionary under the key Name - """ - assert not (ind is None) == (Poly is None), "Either ind or Poly must be None !" - assert Name is None or type(Name) is str, "Arg name must be str !" - if ind is not None: - ind = np.asarray(ind) if hasattr(ind,'__getitem__') else np.asarray([ind]) - assert ind.ndim==1 and ind.dtype.name in ['bool','int64'], "Arg ind must be an index or a iterable of indices in int or bool format !" - if ind.dtype.name=='int64': - iind = np.zeros((self.NCents,),dtype=bool) - iind[ind] = True - ind = iind - assert ind.size==self.NCents and ind.dtype.name=='bool', "Arg ind must be an array of bool of size==self.NCents !" - else: - ind = self._get_SubMeshInPolygon(Poly, InMode='Cents', Out=bool) - Name = r"Sub{0:02.0f}".format(len(self.SubMesh.keys())) if Name is None else Name - Sub = {'Name':Name, 'ind':ind, 'Mesh2D':Mesh2D(Name, self, ind=ind, Type=self.Id.Type, Exp=self.Id.Exp, shot=self.Id.shot, SavePath=self.Id.SavePath, dtime=self.Id.dtime, dtimeIn=self.Id._dtimeIn)} - self._SubMesh[Name] = Sub - - def _get_CentBckg(self): - return _tfm_c._Mesh2D_get_CentBckg(self.MeshX1.NCents, self.MeshX2.NCents, self.MeshX1.Cents, self.MeshX2.Cents, self.Cents, self.NCents) - - def _get_KnotsBckg(self): - """ Return the knots of the background full rectangular mesh, and the indices of those background knots which belong to the mesh """ - return _tfm_c._Mesh2D_get_KnotsBckg(self.MeshX1.NKnots, self.MeshX2.NKnots, self.MeshX1.Knots, self.MeshX2.Knots, self.Knots, self.NKnots) - - def isInside(self, Pts2D): - """ Return a 1d bool array indicating which points (in (R,Z) or (Y,Z) coordinates) are inside the mesh support (i.e. inside the bounding polygon) """ - return _tfm_c._Mesh2D_isInside(Pts2D, self._BoundPoly) - - - def sample(self, Sub=tfd.BF2Sub, SubMode=tfd.BF2SubMode, Test=True): - """ Return a sampling of Mesh using the provided Sub resolution in 'rel' (relative to the size of each mesh element) or 'abs' mode (in distance unit), useful for plotting basis functions on the mesh """ - Pts = _tfm_c._Mesh2D_sample(self.Knots, Sub=Sub, SubMode=SubMode, BoundPoly=self._BoundPoly, Test=Test) - return Pts - - - - def plot(self, ax=None, Elt='MBgKCBsBv', indKnots=None, indCents=None, SubMesh=None, Bckdict=tfd.M2Bckd, Mshdict=tfd.M2Mshd, Kdict=tfd.M2Kd, Cdict=tfd.M2Cd, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True): - """ - Plot the mesh - - Inputs: - ------- - ax None / plt.Axes Axes to be used for plotting, if None a new figure with axes is created - Elt str Flag specifying which elements to plot, each capital letter corresponds to an element - 'M': the mesh itself - 'Bg': the background mesh on which it lies (if this mesh was extracted from a larger mesh) - 'K': some specific knots of the mesh (identified by kwdarg indKnots) - 'C': some specific centers of the mesh (identified by kwdarg indCents) - 'Bs': plot the surfacic center of mass - 'Bv': plot the volumic center of mass - indKnots None / str / iterable Flag indicating which knots to plot specifically, None, 'all' or those indicated by the int indices in a list/tuple/array - indCents None / str / iterable Flag indicating which centers to plot specifically, None, 'all' or those indicated by the int indices in a list/tuple/array - SubMesh None / str Flag indicating which submesh to plot, if any (provide the str key) - Bckdict dict Dictionary of properties used for the background mesh, if plotted (fed to plt.plot()) - Mshdict dict Dictionary of properties used for the mesh, if plotted (fed to plt.plot()) - Kdict dict Dictionary of properties used for the knots, if plotted (fed to plt.plot()) - Cdict dict Dictionary of properties used for the centers, if plotted (fed to plt.plot()) - LegDict dict Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None - draw bool Flag indicating whether the fig.canvas.draw() shall be called automatically - a4 bool Flag indicating whether the figure should be plotted in a4 dimensions for printing - Test bool Flag indicating whether the inputs should be tested for conformity - - Outputs: - -------- - ax plt.Axes - - """ - ax = _tfm_p.Mesh2D_Plot(self, ax=ax, Elt=Elt, indKnots=indKnots, indCents=indCents, SubMesh=SubMesh, Bckdict=Bckdict, Mshdict=Mshdict, Kdict=Kdict, Cdict=Cdict, LegDict=LegDict, draw=draw, a4=a4, Test=Test) - return ax - - - def plot_Res(self, ax1=None, ax2=None, ax3=None, axcb=None, Elt='MBgS', SubMesh=None, Leg=None, Bckdict=tfd.M2Bckd, Mshdict=tfd.M2Mshd, LegDict=tfd.M2Legd, draw=True, a4=False, Test=True): - """ - Plot the resolution of the mesh - - Inputs: - ------- - ax1 None or plt.Axes Axes to be used for plotting the mesh, if None a new figure with axes is created - ax2 None or plt.Axes Axes to be used for plotting the , if None a new figure with axes is created - ax3 None or plt.Axes Axes to be used for plotting the, if None a new figure with axes is created - axcb None or plt.Axes Axes to be used for the colorbar of surfaces, if None a new figure with axes is created - Elt str Flag specifying which elements to plot, each capital letter corresponds to an element - 'M': the mesh itself - 'Bg': the background mesh on which it lies (if this mesh was extracted from a larger mesh) - 'S': the surface of each mesh element (color-coded) - SubMesh None or str Flag indicating which submesh to plot, if any (provide the str key) - Leg None or str String to be used as legend - Bckdict dict Dictionary of properties used for the background mesh, if plotted (fed to plt.plot()) - Mshdict dict Dictionary of properties used for the mesh, if plotted (fed to plt.plot()) - LegDict dict Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None - draw bool Flag indicating whether the fig.canvas.draw() shall be called automatically - a4 bool Flag indicating whether the figure should be plotted in a4 dimensions for printing - Test bool Flag indicating whether the inputs should be tested for conformity - - - Outputs: - -------- - ax1 plt.Axes - ax2 plt.Axes - ax3 plt.Axes - axcb plt.Axes - - """ - ax1, ax2, ax3, axcb = _tfm_p.Mesh2D_Plot_Res(self, ax1=ax1, ax2=ax2, ax3=ax3, axcb=axcb, Elt=Elt, SubMesh=SubMesh, Leg=Leg, Bckdict=Bckdict, Mshdict=Mshdict, LegDict=LegDict, draw=draw, a4=a4, Test=Test) - return ax1, ax2, ax3, axcb - - def save(self, SaveName=None, Path=None, Mode='npz'): - """ - Save the object in folder Name, under file name SaveName, using specified mode - - Inputs: - ------ - SaveName str The name to be used to for the saved file, if None (recommended) uses Ves.Id.SaveName (default: None) - Path str Path specifying where to save the file, if None (recommended) uses Ves.Id.SavePath (default: None) - Mode str Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, may cause retro-compatibility issues with later versions) - """ - tfpf.Save_Generic(self, SaveName=SaveName, Path=Path, Mode=Mode) - - - -def _Mesh2D_check_inputs(Id=None, Knots=None, ind=None, Type=None, Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - if Id is not None: - assert type(Id) in [str,tfpf.ID], "Arg Id must be a str or a tfpf.ID object !" - if Knots is not None: - assert type(Knots) is Mesh2D or (hasattr(Knots,'__iter__') and len(Knots)==2), "Arg Knots must be an iterable of 2 Knots vectors or 2 Mesh1D objects, or a Mesh2D object !" - if type(Knots) is not Mesh2D: - assert all([type(kk) is Mesh1D or (hasattr(kk,'__iter__') and np.asarray(kk).ndim==1 and np.all(kk==np.unique(kk)) and not np.any(np.isnan(kk))) for kk in Knots]), "Each element of Knots must be Mesh1D or knot vector !" - if not ind is None: - assert type(Knots) is Mesh2D, "Arg Knots must be a Mesh2D instance when ind is not None !" - assert hasattr(ind,'__iter__') and np.asarray(ind).ndim==1 and np.asarray(ind).dtype.name in ['bool',int,'int32','int64'], "Arg ind must be an iterable of bool or int indices !" - if np.asarray(ind).dtype.name is 'bool': - assert len(ind)==Knots.NCents, "Arg ind must be of len()==Knots.Cents if indices of type bool !" - if np.asarray(ind).dtype.name in [int,'int32','int64']: - assert max(ind)0: - for ii in range(0,self.NFunc): - ind = self._Cents_Funcind[:,self._Func_Centsind[:,ii]].flatten() - ind = np.unique(ind[~np.isnan(ind)]) - ind = np.delete(ind,(ind==ii).nonzero()[0]) - indF[:ind.size,ii] = ind.astype(int) - return indF - - def get_TotFunc(self, Deriv=0, Coefs=1., thr=1.e-8, thrmode='rel', Abs=True, Test=True): - """ - Return the function or list of functions ff such that ff(Pts) give the total value of the basis functions for each time step provided in Coefs - - Inputs: - ------- - Deriv int / str Flag indicating which quantity should be computed - 0 / 'D0': The function itself - 1 / 'D1': Its first derivative - 2 / 'D2': Its first derivative - 3 / 'D3': Its first derivative - 'D0N2': Its squared norm - 'D0ME': Its entropy - 'D1N2': The squared norm of its first derivative - 'D1FI': Its Fisher information - 'D2N2': The squared norm of its second derivative - 'D3N2': The squared norm of its third derivative - Coefs float / np.ndarray Values of the coefficients to be used for each basis function, common to all if float, if 2-dim the first dimension should be the number of time steps - thr None / float If provided, value used as a lower threshold to the function value for computing non-linear diverging quantities such as 'D0ME' or 'D1FI' - thrmode str Flag indicating whether the provided thr value shall be considered as an absolute value ('abs') or relative to the maximum of the funcion ('rel') - Abs bool Flag indicating whether the absolute value (True) of the function should be considered for computing 'D0ME' and 'D1FI' - Test bool Flag indicating whether the inputs should be tested for conformity - - Outputs: - -------- - Func callable / list Function issuing the required quantity for any provided points, list of such if several time steps were provided - - """ - return _tfm_bs.BSpline_TotFunc(self.Deg, self.Mesh.Knots, Deriv=Deriv, Coefs=Coefs, thr=thr, thrmode=thrmode, Abs=Abs, Test=Test) - - def get_TotVal(self, Pts, Deriv=0, Coefs=1., thr=1.e-8, thrmode='rel', Test=True): - """ - Return the total value the required quantity computed using the provided coefficients at provided points - - Inputs: (see self.get_TotFunc() for documentation of common inputs) - ------- - Pts np.ndarray 1-dim array of pts coordinates where the quantity should be evaluated - - Outputs: - -------- - Val np.ndarray 1 or 2-dim array of evaluated values (2-dim if the provided coefficients were also 2-dim, i.e.: if they spanned several time steps) - - """ - TF = _tfm_bs.BSpline_TotFunc(self.Deg, self.Mesh.Knots, Deriv=Deriv, Coefs=Coefs, thr=thr, thrmode=thrmode, Test=Test) - Val = np.vstack([ff(Pts) for ff in TF]) if type(TF) is list else TF(Pts) - return Val - - def get_Coefs(self, xx=None, yy=None, ff=None, Sub=tfd.BF1Sub, SubMode=tfd.BF1SubMode, Test=True): - """ - Return the coefficients and residue obtained by a lest square fit of the basis functions to the provided data data or function - - Inputs: - ------- - xx None / np.ndarray If provided, the points at which the data is provided, 1-dim - yy None / np.ndarray If provided, the data provided at points xx, 1-dim - ff None / callable If provided, the function to be used for the fit (xx will be computed from a sampling of the underlying mesh, using parameters Sub and SubMode, and yy=ff(xx)) - Sub None / float Needed if ff is used instead of (xx,yy), resolution to be used for the sampling of the mesh, fed to self.Mesh.sample() - SubMode None / str Flag indcating whether Sub should be understood as an absolute distance ('abs') or a fracion of each mesh element ('rel') - Test bool Flag indicating whether the inputs should be tested for conformity - - Outputs: - -------- - Coefs np.ndarray Array of coefficients (1-dim) found by least-square fit - res Residue of the fit (from np.linalg.lstsq()) - - """ - Coefs, res = _tfm_c._LBF1D_get_Coefs(self.LFunc, self.NFunc, self.Mesh.Knots, xx=xx, yy=yy, ff=ff, Sub=Sub, SubMode=SubMode, Test=Test) - return Coefs, res - - def get_IntOp(self, Deriv=0, Method=None, Mode='Vol', Sparse=tfd.L1IntOpSpa, SpaFormat=tfd.L1IntOpSpaFormat, N=None, Test=True): - """ - Return the matrix operator necessary for computing the chosen integral, only possible for linear or quadratic functionals like derivatives or squared norm of derivatives - - Inputs: - ------- - Deriv int / str Flag indicating which integral operator is to be computed, notice that since exact derivations are used (i.e.: no discretization), you can only access a derivative <= degree of the functions - 0 or 'D0': integral of the function - 1 or 'D1': integral of the first derivative - 2 or 'D2': integral of the second derivative - 3 or 'D3': integral of the third derivative - 'D0N2': integral of the squared norm of the function - 'D1N2': integral of the squared norm of the first derivative - 'D2N2': integral of the squared norm of the second derivative - 'D3N2': integral of the squared norm of the third derivative - Method None / str Flag indicating the method to be used for computing the operator, if None switches to 'exact' whenever possible - 'exact': uses pre-derived exact analytical formulas (prefered because faster and more accurate) - 'quad': uses Gauss-Legendre quadrature formulas (exact too if the good number of points, but slower, implemented to prepare for CAID and non-linear operators) - Mode str Flag indicating whether the integral shall be computed assuming as is or by multiplying by the abscissa prior to integration - 'Surf': Normal integration - 'Vol': The integrand is multiplied by x prioir to integration, useful later for volume integrals for 2D toiroidal geometries - Sparse bool Flag indicting whether the operator should be returned as a scipy sparse matrix - SpaFormat str Flag indicating which format to use for the operator if it is to be returned as a scipy sparse matrix, in ['dia','bsr','coo','csc','csr'] - N None / int If int provided, forces the number of quadrature points to N, if None N is computed automatically - Test bool Flag indicating whether the inputs should be tested for conformity - - Outputs: - -------- - A np.ndarray / scipy.sparse.spmatrix Operator - m int Flag indicating how to get the integral from the operator, if coefs is the vector of coefficients of the basis functions - 0: integral = A.dot(coefs) or np.sum(A*coefs) - 1: integral = coefs.dot(A.dot(coefs)) - """ - return _tfm_bs.Calc_1D_LinIntOp(Knots=self.Mesh.Knots, Deg=self.Deg, Deriv=Deriv, Method=Method, Mode=Mode, LFunc=self.LFunc, quad_pts=None, quad_w=None, quad_aa=None, Sparse=Sparse, SpaFormat=SpaFormat, N=N, Test=Test) - - - def get_IntQuadPts(self, Deriv=0, Mode='Vol', N=None, Test=True): # To be finished - """ - Return the Gauss-Legendre quadrature points and weights for computing the desired integral - - Inputs: - ------- - Deriv int / str Flag indicating which integral operator is to be computed, notice that since exact derivations are used (i.e.: no discretization), you can only access a derivative <= degree of the functions - 0 or 'D0': integral of the function - 1 or 'D1': integral of the first derivative - 2 or 'D2': integral of the second derivative - 3 or 'D3': integral of the third derivative - 'D0N2': integral of the squared norm of the function - 'D1N2': integral of the squared norm of the first derivative - 'D2N2': integral of the squared norm of the second derivative - 'D3N2': integral of the squared norm of the third derivative - Mode str Flag indicating whether the integral shall be computed assuming as is or by multiplying by the abscissa prior to integration - 'Surf': Normal integration - 'Vol': The integrand is multiplied by x prioir to integration, useful later for volume integrals for 2D toiroidal geometries - N None / int If int provided, forces the number of quadrature points to N, if None N is computed automatically - Test bool Flag indicating whether the inputs should be tested for conformity - - Outputs: - -------- - pts np.ndarray 2D array of shape (N,NKnots-1) of points coordinates in each mesh element, where N is the number of points per mesh element and NKnots-1 is the number of mesh elements - w np.ndarray 2D array of weights associated to each point, same shape as pts - A np.ndarray 1D array of rescaling coefficients (i.e.: (b-a)/2) to multiply to the sum in each mesh element - N int Number of points per mesh element (i.e.: = pts.shape[0]) - - - """ - intDeriv = Deriv if type(Deriv) is int else int(Deriv[1]) - return _tfm_bs.get_IntQuadPts(self.Knots, self.Deg, Deriv, intDeriv, Mode=Mode, N=N) - - - def get_IntVal(self, Coefs=1., Deriv=0, Method=None, Mode='Vol', Abs=True, thr=1.e-8, thrmode='rel', N=None, Test=True): # To be finished - """ - Return the value of the desired integral (chosen from Deriv in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D2N2','D3N2'] for linear functionals and ['D0ME','D1FI'] for non-linear ones), with the provided coefficients - - Inputs: - ------- - Coefs float / np.ndarray - Deriv int / str Flag indicating which integral operator is to be computed (see doc of self.IntOp() for details) - Method None / str Flag indicating the method to be used for computing the operator, if None switches to 'exact' whenever possible (see doc of self.IntOp() for details) - Mode str Flag indicating whether the integral shall be computed assuming as is or by multiplying by the abscissa prior to integration (see doc of self.IntOp() for details) - Abs bool Flag indicating whether the absolute value (True) of the function should be considered for computing 'D0ME' and 'D1FI' - thr None / float If provided, value used as a lower threshold to the function value for computing non-linear diverging quantities such as 'D0ME' or 'D1FI' - thrmode str Flag indicating whether the provided thr value shall be considered as an absolute value ('abs') or relative to the maximum of the funcion ('rel') - N None / int If int provided, forces the number of quadrature points to N, if None N is computed automatically - Test bool Flag indicating whether the inputs should be tested for conformity - - Outputs: - -------- - Int float / np.ndarray The computed integral or array of integral values if a 2D array of Coefs was provided (each line corresponding to a time step) - - """ - return _tfm_c.get_IntVal(Coefs=Coefs, Knots=self.Mesh.Knots, Deg=self.Deg, Deriv=Deriv, LFunc=self.LFunc, LFunc_Mode=self._LFunc_Mode, Method=Method, Mode=Mode, N=N, Test=Test) - - - def plot(self, ax='None', Coefs=1., Deriv=0, Elt='TL', Sub=tfd.BF1Sub, SubMode=tfd.BF1SubMode, LFdict=tfd.BF1Fd, Totdict=tfd.BF1Totd, LegDict=tfd.TorLegd, Test=True): - """ - - """ - if type(Coefs) is float: - Coefs = Coefs*np.ones((self.NFunc,)) - if 'T' in Elt: - TotF = BSpline_get_TotFunc(self.Deg, self.Mesh.Knots, Deriv=Deriv, Coefs=Coefs, Test=Test) - else: - TotF = None - if (type(Deriv) is int or Deriv in ['D0','D1','D2','D3']) and 'L' in Elt: - if not type(Deriv) is int: - Deriv = int(Deriv[1]) - LF1 = BSplineDeriv(self.Deg, self.Mesh.Knots, Deriv=Deriv, Test=Test) - LF = [lambda x,Coefs=Coefs,ii=ii: Coefs[ii]*LF1[ii](x) for ii in range(0,len(LF1))] - else: - LF = None - return Plot_BSpline1D(self.Mesh.Knots, TotF, LF, ax=ax, Elt=Elt, Name=self.Id.Name+' '+str(Deriv), Sub=Sub, SubMode=SubMode, LFdict=LFdict, Totdict=Totdict, LegDict=LegDict, Test=Test) - - def plot_Ind(self, ax='None', Ind=0, Coefs=1., Elt='LCK', y=0., Sub=tfd.BF1Sub, SubMode=tfd.BF1SubMode, LFdict=tfd.BF1Fd, Kdict=tfd.M2Kd, Cdict=tfd.M2Cd, LegDict=tfd.TorLegd, Test=True): - """ - - """ - assert type(Ind) in [int,list,np.ndarray], "Arg Ind must be a int, a list of int or a np.ndarray of int or booleans !" - if type(Ind) is int: - Ind = [Ind] - NInd = len(Ind) - elif type(Ind) is list: - NInd = len(Ind) - elif type(Ind) is np.ndarray: - assert (np.issubdtype(Ind.dtype,bool) and Ind.size==self.NFunc) or np.issubdtype(Ind.dtype,int), "Arg Ind must be a np.ndarray of boolenas with size==self.NFunc or a np.ndarray of int !" - NInd = Ind.size - - if type(Coefs) is float: - Coefs = Coefs*np.ones((self.NFunc,)) - if 'L' in Elt: - LF1 = BSplineDeriv(self.Deg, self.Mesh.Knots, Deriv=0, Test=Test) - LF = [lambda x,Coefs=Coefs,ii=ii: Coefs[Ind[ii]]*LF1[Ind[ii]](x) for ii in range(0,NInd)] - ax = Plot_BSpline1D(self.Mesh.Knots, None, LF, ax=ax, Elt=Elt, Name=self.Id.Name, Sub=Sub, SubMode=SubMode, LFdict=LFdict, LegDict=LegDict, Test=Test) - if 'C' in Elt or 'K' in Elt: - Cents = self.Mesh.Cents[self.Func_Centsind[:,Ind]].flatten() - Knots = self.Mesh.Knots[self.Func_Knotsind[:,Ind]].flatten() - ax = Plot_Mesh1D(Knots, Cents=Cents, y=y, Elt=Elt, Name=self.Id.NameLTX, ax=ax, Kdict=Kdict, Cdict=Cdict, LegDict=LegDict, Test=Test) - return ax - - def save(self,SaveName=None,Path=None,Mode='npz'): - """ - Save the object in folder Name, under file name SaveName, using specified mode - - Inputs: - ------ - SaveName str The name to be used to for the saved file, if None (recommended) uses Ves.Id.SaveName (default: None) - Path str Path specifying where to save the file, if None (recommended) uses Ves.Id.SavePath (default: None) - Mode str Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, may cause retro-compatibility issues with later versions) - """ - tfpf.Save_Generic(self, SaveName=SaveName, Path=Path, Mode=Mode) - - - -def _LBF1D_check_inputs(Id=None, MeshKnts=None, Deg=None, Type=None, Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - if Id is not None: - assert type(Id) in [str,tfpf.ID], "Arg Id must be a str or a tfpf.ID object !" - if MeshKnts is not None: - assert type(MeshKnts) is Mesh1D or (hasattr(MeshKnts,'__iter__') and np.asarray(MeshKnts).ndim==1 and np.asarray(MeshKnts).dtype.name=='float64'), "Arg MeshKnts must be Mesh1D object, or a 1-dim iterable of floats (knots) !" - if not Deg is None: - assert type(Deg) is int and Deg in [0,1,2,3], "Arg Knots must be a Mesh2D instance when ind is not None !" - assert Type is None, "Arg Type must be None for a 1D mesh and LBF !" - if not Exp is None: - assert Exp in tfd.AllowedExp, "Ar Exp must be in "+str(tfd.AllowedExp)+" !" - Ints = [shot] - if any([not aa is None for aa in Ints]): - assert all([aa is None or type(aa) is int for aa in Ints]), "Args [shot] must be int !" - strs = [SavePath] - if any([not aa is None for aa in strs]): - assert all([aa is None or type(aa) is str for aa in strs]), "Args [SavePath] must all be str !" - if not dtime is None: - assert type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !" - bools = [dtimeIn] - if any([not aa is None for aa in bools]): - assert all([aa is None or type(aa) is bool for aa in bools]), " Args [dtimeIn] must all be bool !" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -class BF2D(object): - - def __init__(self, Id, Mesh, Deg, dtime=None): - self.set_Id(Id,Deg=Deg, dtime=dtime) - self.set_Mesh(Mesh,Deg=Deg) - - @property - def Id(self): - return self._Id - @property - def Mesh(self): - return self._Mesh - @Mesh.setter - def Mesh(self,Val): - self.set_Mesh(Val) - @property - def Deg(self): - return self._Deg - @Deg.setter - def Deg(self,Val): - self.set_BF(Deg=Val) - @property - def NFunc(self): - return self._NFunc - - @property - def Surf(self): - indin = np.any(~np.isnan(self._Cents_Funcind),axis=0) - return np.sum(self.Mesh._Surfs[indin]) - - def set_Id(self,Id,Deg=Deg, dtime=None): - assert type(Id) is str or isinstance(Id,tfpf.ID), "Arg Id should be string or an tfpf.ID instance !" - if type(Id) is str: - Id = tfpf.ID('BF2D',Id+'_D{0:01.0f}'.format(Deg), dtime=dtime) - self._Id = Id - - def set_Mesh(self,Mesh,Deg=None): - assert isinstance(Mesh,Mesh2D), "Arg Mesh must be a Mesh2D instance !" - self._Mesh = Mesh - self.set_BF(Deg=Deg) - - def set_BF(self,Deg=None): - assert Deg is None or type(Deg) is int, "Arg Deg must be a int !" - if not Deg is None: - self._Deg = Deg - BSR, RF_Kind, RF_Cind, RK_Find, RC_Find, RMaxPos = BSpline_LFunc(self._Deg, self._Mesh._MeshR._Knots) - BSZ, ZF_Kind, ZF_Cind, ZK_Find, ZC_Find, ZMaxPos = BSpline_LFunc(self._Deg, self._Mesh._MeshZ._Knots) - nBR, nBZ = len(BSR), len(BSZ) - Func, F_Kind, F_Cind, F_MaxPos = [], [], [], [] - - CentBckg, indCentBckInMesh, NumCentBck = self._Mesh._get_CentBckg() - NCperF, NKperF = (self._Deg+1)**2, (self._Deg+2)**2 - for ii in range(0,nBZ): - for jj in range(0,nBR): - inds = ZF_Cind[:,ii].reshape((ZF_Cind.shape[0],1))*self._Mesh._MeshR._NCents + RF_Cind[:,jj] - if np.all(indCentBckInMesh[inds]): - Func.append(lambda RZ, ii=ii,jj=jj: BSR[jj](RZ[0,:])*BSZ[ii](RZ[1,:])) - F_Cind.append(NumCentBck[inds].reshape(NCperF,1).astype(int)) - F_Kind.append(np.unique(self._Mesh._Cents_Knotsind[:,F_Cind[-1][:,0]]).reshape(NKperF,1)) - F_MaxPos.append(np.array([[RMaxPos[jj]],[ZMaxPos[ii]]])) - self._LFunc = Func - self._NFunc = len(Func) - self._Func_Knotsind = np.concatenate(tuple(F_Kind),axis=1) - self._Func_Centsind = np.concatenate(tuple(F_Cind),axis=1) - self._Func_MaxPos = np.concatenate(tuple(F_MaxPos),axis=1) - self._Cents_Funcind = self._get_Cents_Funcind(Init=True) - self._Knots_Funcind = self._get_Knots_Funcind(Init=True) - self._Func_InterFunc = self._get_Func_InterFunc(Init=True) - - def _get_Cents_Funcind(self,Init=True): # To be updated with ability to select fraction of BF - Cent_indFunc = np.nan*np.ones(((self._Deg+1)**2,self._Mesh._NCents)) - for ii in range(0,self._Mesh._NCents): - inds = np.any(self._Func_Centsind==ii,axis=0) - Cent_indFunc[:inds.sum(),ii] = inds.nonzero()[0] - return Cent_indFunc - - def _get_Knots_Funcind(self,Init=True): # To be updated with ability to select fraction of BF - Knots_indFunc = np.nan*np.ones(((self._Deg+2)**2,self._Mesh._NKnots)) - for ii in range(0,self._Mesh._NKnots): - inds = np.any(self._Func_Knotsind==ii,axis=0) - Knots_indFunc[:inds.sum(),ii] = inds.nonzero()[0] - return Knots_indFunc - - def _get_Func_InterFunc(self,Init=True): # To be updated with ability to select fraction of BF - Func_InterFunc = np.nan*np.ones(((2*self._Deg+1)**2-1,self._NFunc)) - for ii in range(0,self.NFunc): - ind = self._Cents_Funcind[:,self._Func_Centsind[:,ii]].flatten() - ind = np.unique(ind[~np.isnan(ind)]) - ind = np.delete(ind,(ind==ii).nonzero()[0]) - Func_InterFunc[:ind.size,ii] = ind.astype(int) - return Func_InterFunc - - def _get_Func_InterFunc(self, Init=False, indFin=None): # To be updated with ability to select fraction of BF - assert indFin is None or (isnstance(indFin,np.ndarray) and indFin.dtype.name in ['bool','int32','int64','int']), "Arg indFin must be None or a np.naddary of bool or int !" - if indFin is None and not Init: - return self._Func_InterFunc - elif indFin is None: - indFin = np.arange(0,self._NFunc) - if indFin.dtype.name=='bool': - indFin = indFin.nonzero()[0] - NF = indFin.size - Func_InterFunc = np.nan*np.ones(((2*self._Deg+1)**2-1,NF)) # Update in progress from here... - for ii in range(0,NF): - ind = self._Cents_Funcind[:,self._Func_Centsind[:,ii]].flatten() - ind = np.unique(ind[~np.isnan(ind)]) - ind = np.delete(ind,(ind==ii).nonzero()[0]) - Func_InterFunc[:ind.size,ii] = ind.astype(int) - return Func_InterFunc - - def _get_quadPoints(self): - R = self._Mesh._Knots[0,self._Func_Knotsind] - Z = self._Mesh._Knots[1,self._Func_Knotsind] - QuadR, QuadZ = np.zeros((self._Deg+2,self._NFunc)), np.zeros((self._Deg+2,self._NFunc)) - for ii in range(0,self._NFunc): - QuadR[:,ii] = np.unique(R[:,ii]) - QuadZ[:,ii] = np.unique(Z[:,ii]) - return QuadR, QuadZ - - def _get_Func_SuppBounds(self): - Func_SuppRZ = np.nan*np.ones((4,self._NFunc)) - RKnots = self._Mesh._Knots[0,self._Func_Knotsind] - ZKnots = self._Mesh._Knots[1,self._Func_Knotsind] - Func_SuppRZ = np.concatenate((RKnots.min(axis=0,keepdims=True), np.max(RKnots,axis=0,keepdims=True), np.min(ZKnots,axis=0,keepdims=True), np.max(ZKnots,axis=0,keepdims=True)),axis=0) - return Func_SuppRZ - - def _get_Func_Supps(self): - R = self._Mesh._Knots[0,self._Func_Knotsind] - Z = self._Mesh._Knots[1,self._Func_Knotsind] - R = np.array([np.min(R,axis=0),np.max(R,axis=0)]) - Z = np.array([np.min(Z,axis=0),np.max(Z,axis=0)]) - return [np.array([[R[0,ii],R[1,ii],R[1,ii],R[0,ii],R[0,ii]],[Z[0,ii],Z[0,ii],Z[1,ii],Z[1,ii],Z[0,ii]]]) for ii in range(0,self._NFunc)] - - def get_SubBFPolygon_indin(self, Poly, NLim=3, Out=bool): - assert Out in [bool,int], "Arg Out must be in [bool,int] !" - indMeshout = ~self.Mesh.get_SubMeshPolygon(Poly, NLim=NLim, Out=bool) - indFout = self._Cents_Funcind[:,indMeshout] - indFout = np.unique(indFout[~np.isnan(indFout)]).astype(int) - indF = np.ones((self.NFunc,),dtype=bool) - indF[indFout] = False - if Out==int: - indF = indF.nonzero()[0] - return indF - - def get_SubBFPolygonind(self, Poly=None, NLim=3, indFin=None): - assert indFin is None or (isinstance(indFin,np.ndarray) and indFin.dtype.name in ['bool','int','int32','int64']), "Arg indFin must be None or a np.ndarray of bool or int !" - assert (not indFin is None and Poly is None) or (indFin is None and isinstance(Poly,np.ndarray) and Poly.ndim==2 and Poly.shape[0]==2), "If arg indFin is None, arg Poly must be a 2D np.ndarray instance !" - if indFin is None: - indFin = self.get_SubBFPolygon_indin(Poly, NLim=NLim, Out=int) - if indFin.dtype.name=='bool': - indFin = indFin.nonzero()[0] - IndMin = np.unique(self._Func_Centsind[:,indFin].flatten()) - Id, IdM = self.Id, self.Mesh.Id - Id._Name, IdM._Name = Id._Name+'_SubBF', Id._Name+'_SubMesh' - M = Mesh2D(IdM, self.Mesh, IndMin) - return BF2D(Id, M, self.Deg, self.Id.dtime) - - def get_TotFunc_FixPoints(self, Points, Deriv=0, Test=True): - assert Deriv in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Gauss','D2-Mean','D2N2-Lapl','D2N2-Vect'], "Arg Deriv must be in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Gauss','D2-Mean','D2N2-Lapl','D2N2-Vect'] !" - if Deriv in [0,'D0']: - AA, m = BF2D_get_Op(self, Points, Deriv=Deriv, Test=Test) - def FF(Coefs,AA=AA): - return AA.dot(Coefs) - elif Deriv in [1,2,'D1','D2']: - AA, m = BF2D_get_Op(self, Points, Deriv=Deriv, Test=Test) - def FF(Coefs, DVect,AA=AA): - dvR = np.hypot(DVect[0,:],DVect[1,:]) - return dvR*AA[0].dot(Coefs) + DVect[2,:]*AA[1].dot(Coefs) - elif Deriv == 'D0N2': - try: - AA, m = BF2D_get_Op(self, Points, Deriv=Deriv, Test=Test) - def FF(Coefs,AA=AA): - return Coefs.dot(AA.dot(Coefs)) - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv=0, Test=Test) - def FF(Coefs,AA=AA): - return AA.dot(Coefs)*AA.dot(Coefs) - elif Deriv=='D2-Gauss': - try: - AA, m = BF2D_get_Op(self, Points, Deriv=2, Test=Test) - BB, n = BF2D_get_Op(self, Points, Deriv='D2N2', Test=Test) - CC, n = BF2D_get_Op(self, Points, Deriv='D1N2', Test=Test) - AA, BB, CC = (AA[0],AA[1]), BB[2], CC[0]+CC[1] - def FF(Coefs, AA=AA, BB=BB, CC=CC): - return (AA[0].dot(Coefs) * AA[1].dot(Coefs) - Coefs.dot(BB.dot(Coefs))) / (1. + Coefs.dot(CC.dot(Coefs)))**2 - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv=2, Test=Test) - BB, n = BF2D_get_Op(self, Points, Deriv=1, Test=Test) - def FF(Coefs, AA=AA, BB=BB): - return (AA[0].dot(Coefs) * AA[1].dot(Coefs) - (AA[2].dot(Coefs))**2) / (1. + (BB[0].dot(Coefs))**2+(BB[1].dot(Coefs))**2)**2 - elif Deriv=='D2-Mean': - try: - AA, m = BF2D_get_Op(self, Points, Deriv=1, Test=Test) - BB, n = BF2D_get_Op(self, Points, Deriv='D1N2', Test=Test) - CC, p = BF2D_get_Op(self, Points, Deriv=2, Test=Test) - CC = (CC[0],CC[1],CC[2]) - def FF(Coefs,AA=AA,BB=BB,CC=CC): - return ( (1.+Coefs.dot(BB[0].dot(Coefs)))*CC[1].dot(Coefs) - 2.*AA[0].dot(Coefs)*AA[1].dot(Coefs)*CC[2].dot(Coefs) + (1.+Coefs.dot(BB[1].dot(Coefs)))*CC[0].dot(Coefs) ) / (2.*(1. + Coefs.dot((BB[0]+BB[1]).dot(Coefs)))**1.5) - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv=2, Test=Test) - BB, n = BF2D_get_Op(self, Points, Deriv=1, Test=Test) - def FF(Coefs,AA=AA,BB=BB): - return ( (1.+(BB[0].dot(Coefs))**2)*AA[1].dot(Coefs) - 2.*BB[0].dot(Coefs)*BB[1].dot(Coefs)*AA[2].dot(Coefs) + (1.+(BB[1].dot(Coefs))**2)*AA[0].dot(Coefs) ) / (2.*(1. + BB[0].dot(Coefs)**2+(BB[1].dot(Coefs))**2)**1.5) - else: - if 'D1' in Deriv: - try: - AA, m = BF2D_get_Op(self, Points, Deriv='D1N2', Test=Test) - AA = AA[0]+AA[1] - if Deriv=='D1N2': - def FF(Coefs,AA=AA): - return Coefs.dot(AA.dot(Coefs)) - elif Deriv=='D1FI': - B, n = BF2D_get_Op(self, Points, Deriv='D0', Test=Test) - def FF(Coefs,AA=AA,B=B): - return Coefs.dot(AA.dot(Coefs))/B.dot(Coefs) - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv='D1', Test=Test) - if Deriv=='D1N2': - def FF(Coefs,AA=AA): - return (AA[0].dot(Coefs))**2 + (AA[1].dot(Coefs))**2 - elif Deriv=='D1FI': - B, n = BF2D_get_Op(self, Points, Deriv='D0', Test=Test) - def FF(Coefs,AA=AA,B=B): - return ((AA[0].dot(Coefs))**2 + (AA[1].dot(Coefs))**2)/B.dot(Coefs) - elif 'D2' in Deriv: - try: - AA, m = BF2D_get_Op(self, Points, Deriv='D2N2', Test=Test) - if Deriv=='D2N2-Lapl': - AA, B = AA[0]+AA[1], AA[3] - def FF(Coefs,AA=AA,B=B): - return Coefs.dot(AA.dot(Coefs)) + 2.*B.dot(Coefs) - elif Deriv=='D2N2-Vect': - AA = AA[0]+AA[1] - def FF(Coefs,AA=AA): - return Coefs.dot(AA.dot(Coefs)) - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv='D2', Test=Test) - AA = (AA[0],AA[1]) - if Deriv=='D2N2-Lapl': - def FF(Coefs,AA=AA): - return (AA[0].dot(Coefs))**2 + (AA[1].dot(Coefs))**2 + 2.*AA[0].dot(Coefs)*AA[1].dot(Coefs) - elif Deriv=='D2N2-Vect': - AA = (AA[0],AA[1]) - def FF(Coefs,AA=AA): - return (AA[0].dot(Coefs))**2 + (AA[1].dot(Coefs))**2 - return FF - - def get_TotFunc_FixCoefs(self, Deriv=0, DVect=tfd.BF2_DVect_DefR, Coefs=1., Test=True): - assert type(Coefs) in [int,float] or (isinstance(Coefs,np.ndarray) and Coefs.ndim==1 and Coefs.size==self._NFunc), "Arg Coefs must be a float or a (NF,) np.ndarray !" - return BF2D_get_TotFunc(self, Deriv=Deriv, DVect=DVect, Coefs=Coefs, Test=Test) - - def get_TotVal(self, Points, Deriv=0, DVect=tfd.BF2_DVect_DefR, Coefs=1., Test=True): - assert Deriv in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Gauss','D2-Mean','D2N2-Lapl','D2N2-Vect'], "Arg Deriv must be in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Gauss','D2-Mean','D2N2-Lapl','D2N2-Vect'] !" - if type(Coefs) in [int,float] or (isinstance(Coefs,np.ndarray) and Coefs.ndim==1): - Coefs = Coefs*np.ones((self._NFunc,)) - if Points.shape==2: - Points = np.array([Points[0,:],np.zeros((Points.shape[1],)), Points[1,:]]) - FF = self.get_TotFunc_FixPoints(Points, Deriv=Deriv, Test=Test) - if Coefs.ndim==1: - if Deriv in [1,2,'D1','D2']: - dvect = DVect(Points) - return FF(Coefs,dvect) - else: - return FF(Coefs) - else: - Nt = Coefs.shape[0] - Vals = np.empty((Nt,Points.shape[1])) - if Deriv in [1,2,'D1','D2']: - dvect = DVect(Points) - for ii in range(0,Nt): - Vals[ii,:] = FF(Coefs[ii,:], dvect) - else: - for ii in range(0,Nt): - Vals[ii,:] = FF(Coefs[ii,:]) - return Vals - - def get_Coefs(self,xx=None,yy=None, zz=None, ff=None, SubP=tfd.BF2Sub, SubMode=tfd.BF1SubMode, indFin=None, Test=True): # To be updated to take into account fraction of BF - assert not all([xx is None or yy is None, ff is None]), "You must provide either a function (ff) or sampled data (xx and yy) !" - assert indFin is None or (isnstance(indFin,np.ndarray) and indFin.dtype.name in ['bool','int32','int64','int']), "Arg indFin must be None or a np.naddary of bool or int !" - print self.Id.Name+" : Getting fit coefficients..." - if indFin is None: - indFin = np.arange(0,self.NFunc) - if indFin.dtype.name=='bool': - indFin = indFin.nonzero()[0] - - if not ff is None: - xx, yy, nx, ny = self.get_XYplot(SubP=SubP, SubMode=SubMode) # To update - xx, yy = xx.flatten(), yy.flatten() - zz = ff(RZ2Points(np.array([xx,yy]))) - else: - assert xx.shape==yy.shape==zz.shape, "Args xx, yy and zz must have same shape !" - xx, yy, zz = xx.flatten(), yy.flatten(), zz.flatten() - # Keep only points inside the Boundary - ind = self.Mesh.isInside(np.array([xx,yy])) - xx, yy, zz = xx[ind], yy[ind], zz[ind] - - AA, m = BF2D_get_Op(self, np.array([xx.flatten(),yy.flatten()]), Deriv=0, indFin=indFin, Test=Test) - Coefs, res, rank, sing = np.linalg.lstsq(AA,zz) - if rank < indFin.size: - xx1, yy1, nx1, ny1 = self.get_XYplot(SubP=SubP/2., SubMode=SubMode) - xx1, yy1 = xx1.flatten(), yy1.flatten() - ind = self._Mesh.isInside(np.array([xx1,yy1])) - xx1, yy1 = xx1[ind], yy1[ind] - zz1 = scpint.interp2d(xx, yy, zzz, kind='linear', bounds_error=False, fill_value=0)(xx1,yy1) - xx, yy, zz = np.concatenate((xx,xx1)), np.concatenate((yy,yy1)), np.concatenate((zz,zz1)) - AA, m = BF2D_get_Op(self, np.array([xx.flatten(),yy.flatten()]), Deriv=0, Test=Test) - Coefs, res, rank, sing = np.linalg.lstsq(AA,zz) - return Coefs, res - - def get_XYplot(self, SubP=tfd.BF2PlotSubP, SubMode=tfd.BF2PlotSubMode): - Xplot, Yplot = Calc_SumMeshGrid2D(self.Mesh._MeshR.Knots, self.Mesh._MeshZ.Knots, SubP=SubP, SubMode=SubMode, Test=True) - nx, ny = Xplot.size, Yplot.size - Xplot, Yplot = np.dot(np.ones((ny,1)),Xplot.reshape((1,nx))), np.dot(Yplot.reshape((ny,1)),np.ones((1,nx))) - return Xplot, Yplot, nx, ny - - def get_IntOp(self, Deriv=0, Mode=tfd.BF2IntMode, Sparse=tfd.L1IntOpSpa, SpaFormat=tfd.L1IntOpSpaFormat, Test=True): - print self.Id.Name+" : Getting integral operator "+str(Deriv) - return Calc_IntOp_BSpline2D(self, Deriv=Deriv, Mode=Mode, Sparse=Sparse, SpaFormat=SpaFormat, Test=Test) - - def get_IntVal(self, Deriv=0, Mode=tfd.BF2IntMode, Coefs=1., Test=True): - A, m = Calc_IntOp_BSpline2D(self, Deriv=Deriv, Mode=Mode, Sparse=True, Test=Test) - if type(Coefs) is float: - Coefs = Coefs*np.ones((self.NFunc,),dtype=float) - if Coefs.ndim==1: - if m==0: - Int = A.dot(Coefs) - elif m==1: - Int = Coefs.dot(A.dot(Coefs)) - elif m==2: - A = A[0]+A[1] - Int = Coefs.dot(A.dot(Coefs)) - else: - print 'Not coded yet !' - else: - Int = np.nan*np.ones((Coefs.shape[0],)) - if m==0: - for ii in range(0,Coefs.shape[0]): - Int[ii] = A.dot(Coefs[ii,:]) - elif m==1: - for ii in range(0,Coefs.shape[0]): - Int[ii] = Coefs[ii,:].dot(A.dot(Coefs[ii,:])) - elif m==2: - A = A[0]+A[1] - for ii in range(0,Coefs.shape[0]): - Int[ii] =Coefs[ii,:].dot(A.dot(Coefs[ii,:])) - else: - print 'Not coded yet !' - return Int - - def get_MinMax(self, Coefs=1., Ratio=0.05, SubP=0.004, SubP1=0.015, SubP2=0.001, TwoSteps=False, SubMode='abs', Deriv='D0', Test=True): # To be deprecated by get_Extrema() when implemented - return Get_MinMax(self, Coefs=Coefs, Ratio=Ratio, SubP=SubP, SubP1=SubP1, SubP2=SubP2, TwoSteps=TwoSteps, SubMode=SubMode, Deriv=Deriv, Test=Test) - - def get_Extrema(self, Coefs=1., Ratio=0.95, SubP=0.002, SubMode='abs', Deriv='D0', D1N2=True, D2N2=True): - return Get_Extrema(self, Coefs=Coefs, Ratio=Ratio, SubP=SubP, SubMode=SubMode, D1N2=D1N2, D2N2=D2N2) - - - def plot(self, ax='None', Coefs=1., Deriv=0, Elt='T', NC=tfd.BF2PlotNC, DVect=tfd.BF2_DVect_DefR, PlotMode='contourf', SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, Totdict=tfd.BF1Totd, LegDict=tfd.TorLegd, Test=True): - return Plot_BSpline2D(self, ax=ax, Elt=Elt, Deriv=Deriv, Coefs=Coefs, DVect=DVect, NC=NC, PlotMode=PlotMode, Name=self.Id.Name+' '+str(Deriv), SubP=SubP, SubMode=SubMode, Totdict=Totdict, LegDict=LegDict, Test=Test) - - def plot_fit(self, ax1='None', ax2='None', xx=None, yy=None, zz=None, ff=None, NC=tfd.BF2PlotNC, PlotMode='contourf', Name='', SubP=tfd.BF2Sub, SubMode=tfd.BF1SubMode, Totdict=tfd.BF1Totd, LegDict=tfd.TorLegd, Test=True): - Coefs, res = self.get_Coefs(xx=xx,yy=yy, zz=zz, ff=ff, SubP=SubP, SubMode=SubMode, Test=Test) - if xx is None: - xx, yy, nxg, nyg = self.get_XYplot(SubP=SubP, SubMode=SubMode) - zz = ff(RZ2Points(np.array([xx.flatten(),yy.flatten()]))) - zz = zz.reshape((xx.shape)) - else: - assert xx.ndim==2, "Args xx, yy and zz must be (N,M) plot-friendly !" - if Name=='': - Name = self.Id.Name - - Xplot, Yplot, nx, ny = self.get_XYplot(SubP=SubP, SubMode=SubMode) - PointsRZ = np.array([Xplot.flatten(),Yplot.flatten()]) - ind = self.Mesh.isInside(PointsRZ) - Val = self.get_TotVal(PointsRZ, Deriv=0, Coefs=Coefs, Test=True) - Val[~ind] = np.nan - Val = Val.reshape(Xplot.shape) - if PlotMode=='surf': - if ax1=='None' or ax2=='None': - ax1, ax2 = tfd.Plot_BSplineFit_DefAxes('3D') - ax1.plot_surface(xx,yy,zz, label='Model', **Totdict) - ax2.plot_surface(Xplot,Yplot,Val, label=Name, **Totdict) - else: - if ax1=='None' or ax2=='None': - ax1, ax2 = tfd.Plot_BSplineFit_DefAxes('2D') - if PlotMode=='contour': - ax1.contour(xx,yy,zz, NC, label='Model', **Totdict) - ax2.contour(Xplot,Yplot,Val, NC, label=Name, **Totdict) - elif PlotMode=='contourf': - ax1.contourf(xx,yy,zz, NC, label='Model', **Totdict) - ax2.contourf(Xplot,Yplot,Val, NC, label=Name, **Totdict) - if not LegDict is None: - ax1.legend(**LegDict) - ax2.legend(**LegDict) - ax2.set_title(r"$\chi^2 = "+str(res)+"$") - ax1.figure.canvas.draw() - return ax1, ax2 - - def plot_Ind(self, Ind=0, Elt='LSP', EltM='BMCK', ax='None', Coefs=1., NC=tfd.BF2PlotNC, PlotMode='contourf', SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, Totdict=tfd.BF2PlotTotd, - Cdict=tfd.M2Cd, Kdict=tfd.M2Kd, Bckdict=tfd.M2Bckd, Mshdict=tfd.M2Mshd, LegDict=tfd.TorLegd, Colorbar=True, Test=True): - assert type(Ind) in [int,list,np.ndarray], "Arg Ind must be a int, a list of int or a np.ndarray of int or booleans !" - if type(Ind) is int: - Ind = np.array([Ind],dtype=int) - elif type(Ind) is list: - Ind = np.array(tuple(Ind),dtype=int) - elif type(Ind) is np.ndarray: - assert (np.issubdtype(Ind.dtype,bool) and Ind.size==self._NFunc) or np.issubdtype(Ind.dtype,int), "Arg Ind must be a np.ndarray of boolenas with size==self.NFunc or a np.ndarray of int !" - if np.issubdtype(Ind.dtype,bool): - Ind = Ind.nonzero()[0] - NInd = Ind.size - if type(Coefs) is float: - Coefs = Coefs*np.ones((self._NFunc,)) - indC, indK = self._Func_Centsind[:,Ind].flatten().astype(int), self._Func_Knotsind[:,Ind].flatten().astype(int) - ax = self._Mesh.plot(indKnots=indK, indCents=indC, ax=ax, Elt=EltM, Cdict=Cdict, Kdict=Kdict, Bckdict=Bckdict, Mshdict=Mshdict, LegDict=LegDict, Test=Test) - ax = Plot_BSpline2D_Ind(self, Ind, ax=ax, Coefs=Coefs, Elt=Elt, NC=NC, PlotMode=PlotMode, Name=self._Id.Name, SubP=SubP, SubMode=SubMode, Totdict=Totdict, LegDict=LegDict, Colorbar=Colorbar, Test=Test) - return ax - - def save(self,SaveName=None,Path=None,Mode='npz'): - if Path is None: - Path = self.Id.SavePath - else: - assert type(Path) is str, "Arg Path must be a str !" - self._Id.SavePath = Path - if SaveName is None: - SaveName = self.Id.SaveName - else: - assert type(SaveName) is str, "Arg SaveName must be a str !" - self.Id.SaveName = SaveName - Ext = '.npz' if 'npz' in Mode else '.pck' - tfpf.save(self, Path+SaveName+Ext) - - - - - -############################################ -##### Computing functions -############################################ - - -def RZ2Points(PointsRZ, Theta=0.): - return np.array([PointsRZ[0,:]*np.cos(Theta), PointsRZ[0,:]*np.sin(Theta),PointsRZ[1,:]]) - -def Points2RZ(Points): - return np.array([np.sqrt(Points[0,:]**2+Points[1,:]**2),Points[2,:]]) - - -def Calc_BF1D_Weights(LFunc, Points, Test=True): - if Test: - assert type(LFunc) is list, "Arg LFunc must be a list of functions !" - assert isinstance(Points,np.ndarray) and Points.ndim==1, "Arg Points must be a (N,) np.ndarray !" - NFunc = len(LFunc) - Wgh = np.zeros((Points.size, NFunc)) - for ii in range(0,NFunc): - Wgh[:,ii] = LFunc[ii](Points) - return Wgh - -def Calc_BF2D_Weights(LFunc, PointsRZ, Test=True): - if Test: - assert type(LFunc) is list, "Arg LFunc must be a list of functions !" - assert isinstance(PointsRZ,np.ndarray) and PointsRZ.ndim==2, "Arg Points must be a (2,N) np.ndarray !" - NFunc = len(LFunc) - Wgh = np.zeros((PointsRZ.shape[1], NFunc)) - for ii in range(0,NFunc): - Wgh[:,ii] = LFunc[ii](PointsRZ) - return Wgh - - -def BF2D_get_Op(BF2, Points, Deriv=0, indFin=None, Test=True): # To be updated to take into account only fraction of BF - """ Return the operator to compute the desired quantity on NP points (to be multiplied by Coefs) Y = Op(Coefs) for NF basis functions - Input : - BF2 A BF2D instance - Points A (3,NP) np.ndarray indicating (X,Y,Z) cylindrical coordinates of points at which to evaluate desired quantity (automatically converted to (R,Z) coordinates) - Deriv A flag indicating the desired quantity in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Lapl','D2N2-Lapl'] - Test A bool Flag indicating whether inputs shall be tested for conformity - Output : - A The operator itself as a 2D or 3D numpy array - m Flag indicating the kind of operation necessary - = 0 Y = A.dot(C) (Y = AC, with A.shape=(NP,NF)) - = 1 Y = C.dot(A.dot(C)) (Y = tCAC, with A.shape=(NF,NP,NF)) - = 2 Y = sum( C.dot(A[:].dot(C)) ) (e.g.: Y = tCArC + tCAzC with Ar.shape==Az.shape=(NF,NP,NF), you can compute a scalar product with each component if necessary) - """ - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert isinstance(Points,np.ndarray) and Points.ndim==2 and Points.shape[0] in [2,3], "Arg Points must be a (2-3,NP) np.ndarray !" - assert Deriv in [0,1,2,'D0','D0N2','D1','D1N2','D2','D2N2'], "Arg Deriv must be in [0,1,2,'D0','D0N2','D1','D1N2','D2','D2N2'] !" - assert indFin is None or (isinstance(indFin,np.ndarray) and indFin.dtype.name in ['bool','int32','int64','int']), "Arg indFin must be None or a np.naddary of bool or int !" - - if indFin is None: - indFin = np.arange(0,BF2.NFunc) - if indFin.dtype.name=='bool': - indFin = indFin.nonzero()[0] - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - NF = indFin.size - NP = Points.shape[1] - if Points.shape[0]==3: - RZ = np.array([np.hypot(Points[0,:],Points[1,:]),Points[2,:]]) - else: - RZ = np.copy(Points) - - QuadR, QuadZ = BF2._get_quadPoints() - QuadR, QuadZ = QuadR[:,indFin], QuadZ[:,indFin] - if Deriv=='D0': - m = 0 - A = np.zeros((NP,NF)) - for ii in range(0,NF): - A[:,ii] = BF2._LFunc[indFin[ii]](RZ) - return A, m - elif Deriv=='D0N2': # Update in progress from here... - m = 1 - A = np.zeros((NF,NP,NF)) - for ii in range(0,NF): - Yii = BF2._LFunc[ii](RZ) - A[ii,:,ii] = Yii**2 - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - A[ii,:,Ind[jj]] = Yii*BF2._LFunc[Ind[jj]](RZ) - return A, m - elif Deriv=='D1' and BF2.Deg>=1: - m = 2 - Ar, Az = np.zeros((NP,NF)), np.zeros((NP,NF)) - for ii in range(0,NF): - Ar[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Az[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - return (Ar,Az), m - elif Deriv=='D1N2' and BF2.Deg>=1: - m = 2 - AR, AZ = np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)) - for ii in range(0,NF): - rii, zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Rii, Zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - AR[ii,:,ii] = (Rii*zii)**2 - AZ[ii,:,ii] = (rii*Zii)**2 - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - AR[ii,:,Ind[jj]] = Rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=1)[0][0](RZ[0,:]) * zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=0)[0][0](RZ[1,:]) - AZ[ii,:,Ind[jj]] = rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=0)[0][0](RZ[0,:]) * Zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=1)[0][0](RZ[1,:]) - return (AR,AZ), m - elif Deriv=='D2' and BF2.Deg>=2: - m = 2 - Arr, Azz, Arz = np.zeros((NP,NF)), np.zeros((NP,NF)), np.zeros((NP,NF)) - for ii in range(0,NF): - Arr[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=2)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Azz[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=2)[0][0](RZ[1,:]) - Arz[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - return (Arr,Azz,Arz), m - elif Deriv=='D2N2' and BF2.Deg>=2: - m = 2 - ARR, AZZ, ARZ, Arrzz = np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)) - for ii in range(0,NF): - rii, zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Rii, Zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - RRii, ZZii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=2)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=2)[0][0](RZ[1,:]) - ARR[ii,:,ii] = (RRii*zii)**2 - AZZ[ii,:,ii] = (rii*ZZii)**2 - ARZ[ii,:,ii] = (Rii*Zii)**2 - Arrzz[ii,:,ii] = RRii*ZZii - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - ARR[ii,:,Ind[jj]] = RRii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=2)[0][0](RZ[0,:]) * zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=0)[0][0](RZ[1,:]) - AZZ[ii,:,Ind[jj]] = rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=0)[0][0](RZ[0,:]) * ZZii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=2)[0][0](RZ[1,:]) - ARZ[ii,:,Ind[jj]] = Rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=1)[0][0](RZ[0,:]) * Zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=1)[0][0](RZ[1,:]) - return (ARR,AZZ,ARZ, Arrzz), m - - -def BF2D_get_TotFunc(BF2, Deriv=0, DVect=tfd.BF2_DVect_DefR, Coefs=1., Test=True): - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert type(Deriv) in [int,str], "Arg Deriv must be a int or a str !" - assert type(Coefs) is float or (isinstance(Coefs,np.ndarray) and Coefs.size==BF2.NFunc), "Arg Coefs must be a float or a np.ndarray !" - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - - if type(Coefs) is float: - Coefs = Coefs.np.ones((BF2.NFunc,)) - - NF = BF2.NFunc - QuadR, QuadZ = BF2._get_quadPoints() - if Deriv in [0,'D0']: - LF = BF2._LFunc - return lambda Points, Coefs=Coefs, LF=LF, NF=NF: np.sum(np.concatenate(tuple([Coefs[jj]*LF[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - elif Deriv=='D0N2': - LF = BF2._LFunc - return lambda Points, Coefs=Coefs, LF=LF, NF=NF: np.sum(np.concatenate(tuple([Coefs[jj]*LF[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0)**2 - - elif Dbis==1: - LDR = [] - LDZ = [] - for ii in range(0,NF): - LDR.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=1, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=0, Test=Test)[0](PointsRZ[1,:])) - LDZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=0, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=1, Test=Test)[0](PointsRZ[1,:])) - if Deriv=='D1': - def FTot(Points, Coefs=Coefs, DVect=DVect, NF=NF, LDR=LDR, LDZ=LDZ): - DVect = DVect(Points) - Theta = np.arctan2(Points[1,:],Points[0,:]) - eR = np.array([np.cos(Theta),np.sin(Theta),np.zeros((Theta.size,))]) - DVect = np.array([np.sum(DVect*eR,axis=0), DVect[2,:]]) - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0)*DVect[0,:] - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0)*DVect[1,:] - return ValR+ValZ - elif Deriv=='D1N2': - def FTot(Points, Coefs=Coefs, NF=NF, LDR=LDR, LDZ=LDZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return ValR**2+ValZ**2 - elif Deriv=='D1FI': - LF = BF2._LFunc - def FTot(Points, Coefs=Coefs, NF=NF, LF=LF, LDR=LDR, LDZ=LDZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - Val = np.sum(np.concatenate(tuple([Coefs[jj]*LF[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return (ValR**2+ValZ**2)/Val - - elif Dbis==2: - LDRR, LDZZ = [], [] - for ii in range(0,NF): - LDRR.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=2, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=0, Test=Test)[0](PointsRZ[1,:])) - LDZZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=0, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=2, Test=Test)[0](PointsRZ[1,:])) - if Deriv=='D2-Lapl': - def FTot(Points, Coefs=Coefs, NF=NF, LDRR=LDRR, LDZZ=LDZZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return ValR+ValZ - elif Deriv=='D2N2-Lapl': - def FTot(Points, Coefs=Coefs, NF=NF, LDRR=LDRR, LDZZ=LDZZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return (ValR+ValZ)**2 - else: - LDR, LDZ, LDRZ= [], [], [] - for ii in range(0,NF): - LDR.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=1, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=0, Test=Test)[0](PointsRZ[1,:])) - LDZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=0, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=1, Test=Test)[0](PointsRZ[1,:])) - LDRZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=1, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=1, Test=Test)[0](PointsRZ[1,:])) - if Deriv=='D2-Gauss': - def FTot(Points, Coefs=Coefs, NF=NF, LDR=LDR, LDZ=LDZ, LDRR=LDRR, LDZZ=LDZZ, LDRZ=LDRZ): - ValRR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValRZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDRZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return (ValRR*ValZZ-ValRZ**2)/(1. + ValR**2 + ValZ**2)**2 - elif Deriv=='D2-Mean': - def FTot(Points, Coefs=Coefs, NF=NF, LDR=LDR, LDZ=LDZ, LDRR=LDRR, LDZZ=LDZZ, LDRZ=LDRZ): - ValRR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValRZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDRZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return ((1.+ValR**2)*ValZZ - 2.*ValR*ValZ*ValRZ + (1.+ValZ**2)*ValRR)/(2.*(1. + ValR**2 + ValZ**2)**(1.5)) - - return FTot - - -def Calc_BF2D_Val(LFunc, Points, Coef=1., Test=True): - if Test: - assert type(LFunc) is list, "Arg LFunc must be a list of functions !" - assert isinstance(Points,np.ndarray) and (Points.shape[0]==2 or Points.shape[0]==3), "Arg Points must be a (2,N) or (3,N) np.ndarray !" - assert (type(Coef) is float and Coef==1.) or (isinstance(Coef,np.ndarray) and Coef.shape[0]==len(LFunc)), "Arg Coef must be a (BF2.NFunc,1) np.ndarray !" - - if Points.shape[0]==3: - R = np.sqrt(np.sum(Points[0:2,:]**2,axis=0,keepdims=False)) - Points = np.array([[R],[Points[2,:]]]) - - NFunc = len(LFunc) - Val = np.zeros((Points.shape[1],)) - Coef = Coef*np.ones((NFunc,1)) - for ii in range(0,NFunc): - Val = Val + Coef[ii]*LFunc[ii](Points) - - return Val - - - - - - - - - -def Calc_Integ_BF2(BF2, Coefs=1., Mode='Vol', Test=True): - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert Mode=='Vol' or Mode=='Surf', "Arg Mode must be 'Vol' or 'Surf' !" - assert type(Coefs) is float or (isinstance(Coefs,np.ndarray) and Coefs.size==BF2.NFunc), "Arg Coefs must be a (BF2.NFunc,) np.ndarray !" - assert BF2.Deg <= 3, "Arg BF2 should not have Degree > 3 !" - - if type(Coefs) is float: - Coefs = Coefs*np.ones((BF2.NFunc,)) - if Mode=='Surf': - if BF2.Deg==0: - Supp = BF2.get_Func_SuppRZ() - Int = np.sum(Coefs.flatten()*(Supp[1,:]-Supp[0,:])*(Supp[3,:]-Supp[2,:])) - elif BF2.Deg==1: - Supp = BF2.get_Func_SuppRZ() - Int = np.sum(Coefs.flatten()*0.25*(Supp[1,:]-Supp[0,:])*(Supp[3,:]-Supp[2,:])) - elif BF2.Deg==2: - QR, QZ = BF2._get_quadPoints() - IntR1 = (QR[1,:]-QR[0,:])**2/(3.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**2 -2.*QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[0,:]*(QR[1,:]-QR[2,:]))/(6*(QR[2,:]-QR[0,:])) - IntR22 = (-2.*QR[2,:]**2+QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[3,:]*(QR[2,:]-QR[1,:]))/(6.*(QR[3,:]-QR[1,:])) - IntR3 = (QR[3,:]-QR[2,:])**2/(3.*(QR[3,:]-QR[1,:])) - IntZ1 = (QZ[1,:]-QZ[0,:])**2/(3.*(QZ[2,:]-QZ[0,:])) - IntZ21 = (QZ[2,:]**2 -2*QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[0,:]*(QZ[1,:]-QZ[2,:]))/(6*(QZ[2,:]-QZ[0,:])) - IntZ22 = (-2.*QZ[2,:]**2+QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[3,:]*(QZ[2,:]-QZ[1,:]))/(6.*(QZ[3,:]-QZ[1,:])) - IntZ3 = (QZ[3,:]-QZ[2,:])**2/(3.*(QZ[3,:]-QZ[1,:])) - Int = np.sum(Coefs.flatten() * (IntR1+IntR21+IntR22+IntR3) * (IntZ1+IntZ21+IntZ22+IntZ3)) - elif BF2.Deg==3: - print "NOT CODED YET !" - - else: - if BF2.Deg==0: - Supp = BF2.get_Func_SuppRZ() - Int = np.sum( Coefs.flatten() * 2.*np.pi * 0.5*(Supp[1,:]**2-Supp[0,:]**2)*(Supp[3,:]-Supp[2,:])) - elif BF2.Deg==1: - Supp = BF2.get_Func_SuppRZ() - QuadR, QuadZ = BF2._get_quadPoints() - Int = np.sum( Coefs.flatten() * 2.*np.pi * 0.5*(QuadR[2,:]**2-QuadR[0,:]**2 + QuadR[1,:]*(QuadR[2,:]-QuadR[0,:]))*(Supp[3,:]-Supp[2,:])/6.) - elif BF2.Deg==2: - QR, QZ = BF2._get_quadPoints() - IntR1 = (3.*QR[1,:]**3+QR[0,:]**3 -5.*QR[0,:]*QR[1,:]**2+QR[0,:]**2*QR[1,:])/(12.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**3 -3.*QR[1,:]**3+QR[1,:]**2*QR[2,:]+QR[1,:]*QR[2,:]**2 -2.*QR[0,:]*QR[2,:]**2 -2.*QR[0,:]*QR[1,:]*QR[2,:] +4.*QR[0,:]*QR[1,:]**2)/(12.*(QR[2,:]-QR[0,:])) - IntR22 = ( -3.*QR[2,:]**3+QR[1,:]**3+QR[1,:]*QR[2,:]**2+QR[1,:]**2*QR[2,:]+4.*QR[2,:]**2*QR[3,:]-2.*QR[1,:]*QR[2,:]*QR[3,:]-2.*QR[1,:]**2*QR[3,:] )/(12.*(QR[3,:]-QR[1,:])) - IntR3 = ( QR[3,:]**3 +3.*QR[2,:]**3 -5.*QR[2,:]**2*QR[3,:]+QR[2,:]*QR[3,:]**2)/(12.*(QR[3,:]-QR[1,:])) - IntZ1 = (QZ[1,:]-QZ[0,:])**2/(3.*(QZ[2,:]-QZ[0,:])) - IntZ21 = (QZ[2,:]**2 -2*QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[0,:]*(QZ[1,:]-QZ[2,:]))/(6*(QZ[2,:]-QZ[0,:])) - IntZ22 = (-2.*QZ[2,:]**2+QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[3,:]*(QZ[2,:]-QZ[1,:]))/(6.*(QZ[3,:]-QZ[1,:])) - IntZ3 = (QZ[3,:]-QZ[2,:])**2/(3.*(QZ[3,:]-QZ[1,:])) - Int = np.sum(Coefs.flatten() * 2.*np.pi * (IntR1+IntR21+IntR22+IntR3) * (IntZ1+IntZ21+IntZ22+IntZ3)) - elif BF2.Deg==3: - print "NOT CODED YET !" - - return Int - - - - - - - -def Calc_IntOp_BSpline2D(BF2, Deriv=0, Mode='Vol', Sparse=tfd.L1IntOpSpa, SpaFormat=tfd.L1IntOpSpaFormat, Test=True): - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert Mode in ['Surf','Vol'], "Arg Mode must be in ['Surf','Vol'] !" - assert (type(Deriv) is int and Deriv<=BF2.Deg) or (type(Deriv) is str and Deriv in ['D0','D1','D2','D3','D0N2','D1N2','D2N2','D3N2','D1FI'] and int(Deriv[1])<=BF2.Deg), "Arg Deriv must be a int or a str !" - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - - if Deriv=='D0': - m = 0 - if BF2.Deg==0: - Supp = BF2._get_Func_SuppBounds() - if Mode=='Surf': - A = (Supp[1,:]-Supp[0,:]) * (Supp[3,:]-Supp[2,:]) - else: - A = 0.5*(Supp[1,:]**2-Supp[0,:]**2) * (Supp[3,:]-Supp[2,:]) - elif BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - if Mode=='Surf': - A = 0.25*(Supp[1,:]-Supp[0,:])*(Supp[3,:]-Supp[2,:]) - else: - QuadR, QuadZ = BF2._get_quadPoints() - A = 0.5*(QuadR[2,:]**2-QuadR[0,:]**2 + QuadR[1,:]*(QuadR[2,:]-QuadR[0,:])) * (Supp[3,:]-Supp[2,:])/6. - elif BF2.Deg==2: - QR, QZ = BF2._get_quadPoints() - - IntZ1 = (QZ[1,:]-QZ[0,:])**2/(3.*(QZ[2,:]-QZ[0,:])) - IntZ21 = (QZ[2,:]**2 -2*QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[0,:]*(QZ[1,:]-QZ[2,:]))/(6*(QZ[2,:]-QZ[0,:])) - IntZ22 = (-2.*QZ[2,:]**2+QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[3,:]*(QZ[2,:]-QZ[1,:]))/(6.*(QZ[3,:]-QZ[1,:])) - IntZ3 = (QZ[3,:]-QZ[2,:])**2/(3.*(QZ[3,:]-QZ[1,:])) - IntZ = IntZ1+IntZ21+IntZ22+IntZ3 - - if Mode=='Surf': - IntR1 = (QR[1,:]-QR[0,:])**2/(3.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**2 -2.*QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[0,:]*(QR[1,:]-QR[2,:]))/(6*(QR[2,:]-QR[0,:])) - IntR22 = (-2.*QR[2,:]**2+QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[3,:]*(QR[2,:]-QR[1,:]))/(6.*(QR[3,:]-QR[1,:])) - IntR3 = (QR[3,:]-QR[2,:])**2/(3.*(QR[3,:]-QR[1,:])) - else: - IntR1 = (3.*QR[1,:]**3+QR[0,:]**3 -5.*QR[0,:]*QR[1,:]**2+QR[0,:]**2*QR[1,:])/(12.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**3 -3.*QR[1,:]**3+QR[1,:]**2*QR[2,:]+QR[1,:]*QR[2,:]**2 -2.*QR[0,:]*QR[2,:]**2 -2.*QR[0,:]*QR[1,:]*QR[2,:] +4.*QR[0,:]*QR[1,:]**2)/(12.*(QR[2,:]-QR[0,:])) - IntR22 = ( -3.*QR[2,:]**3+QR[1,:]**3+QR[1,:]*QR[2,:]**2+QR[1,:]**2*QR[2,:]+4.*QR[2,:]**2*QR[3,:]-2.*QR[1,:]*QR[2,:]*QR[3,:]-2.*QR[1,:]**2*QR[3,:] )/(12.*(QR[3,:]-QR[1,:])) - IntR3 = ( QR[3,:]**3 +3.*QR[2,:]**3 -5.*QR[2,:]**2*QR[3,:]+QR[2,:]*QR[3,:]**2)/(12.*(QR[3,:]-QR[1,:])) - IntR = IntR1+IntR21+IntR22+IntR3 - A = IntR*IntZ - elif BF2.Deg==3: - print "NOT CODED YET !" - A = 0 - - elif Deriv=='D0N2': - m = 1 - if BF2.Deg==0: - Supp = BF2._get_Func_SuppBounds() - if Mode=='Surf': - A = scpsp.diags([(Supp[1,:]-Supp[0,:]) * (Supp[3,:]-Supp[2,:])],[0],shape=None,format=SpaFormat) - else: - A = scpsp.diags([0.5*(Supp[1,:]**2-Supp[0,:]**2) * (Supp[3,:]-Supp[2,:])],[0],shape=None,format=SpaFormat) - elif BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - if Mode=='Surf': - d0R, d0Z = (Supp[1,:]-Supp[0,:])/3., (Supp[3,:]-Supp[2,:])/3. - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intR = (kR[1]-kR[0])/6. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZ = (kZ[1]-kZ[0])/6. - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - else: - d0R, d0Z = (QR[2,:]**2-QR[0,:]**2 + 2.*QR[1,:]*(QR[2,:]-QR[0,:]))/12., (Supp[3,:]-Supp[2,:])/3. - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intR = (kR[1]**2-kR[0]**2)/12. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZ = (kZ[1]-kZ[0])/6. - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - A = scpsp.vstack(LL,format='csr') - elif BF2.Deg==2: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - if Mode=='Surf': - d0R21 = (QR[2,:]-QR[1,:])*(10.*QR[0,:]**2+6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2 - 5.*QR[0,:]*(3.*QR[1,:]+QR[2,:]))/(30.*(QR[2,:]-QR[0,:])**2) - d0R22 = (QR[2,:]-QR[1,:])*(10.*QR[3,:]**2+6.*QR[2,:]**2+3.*QR[1,:]*QR[2,:]+QR[1,:]**2 - 5.*QR[3,:]*(3.*QR[2,:]+QR[1,:]))/(30.*(QR[3,:]-QR[1,:])**2) - d0R23 = ( 3.*QR[1,:]**2 + 4.*QR[1,:]*QR[2,:] + 3.*QR[2,:]**2 - 5.*QR[0,:]*(QR[1,:]+QR[2,:]-2.*QR[3,:]) -5.*QR[3,:]*(QR[1,:]+QR[2,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (QR[1,:]-QR[0,:])**3/(5.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (QR[3,:]-QR[2,:])**3/(5.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intR = (QR[1,ii]-QR[0,ii])**3/(30.*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR = ( 6.*QR[1,ii]**2 - QR[0,ii]*(9.*QR[1,ii]+QR[2,ii]-10.*QR[3,ii]) + QR[2,ii]*(QR[2,ii]-4.*QR[3,ii]) +3.*QR[1,ii]*(QR[2,ii]-2.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) + ( QR[0,ii]**2 + 3.*QR[0,ii]*QR[1,ii] + 6.*QR[1,ii]**2 - 2.*QR[0,Ind[jj]]*(2.*QR[0,ii]+3.*QR[1,ii] - 5.*QR[2,ii]) - QR[0,ii]*QR[2,ii] -9.*QR[1,ii]*QR[2,ii] )*(QR[1,ii]-QR[0,ii])**2/(30.*(QR[0,Ind[jj]]-QR[2,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intR = (QR[3,ii]-QR[2,ii])**3/(30.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR = ( 6.*QR[2,ii]**2 - QR[1,ii]*(9.*QR[2,ii]+QR[3,ii]-10.*QR[3,Ind[jj]]) + QR[3,ii]*(QR[3,ii]-4.*QR[3,Ind[jj]]) +3.*QR[2,ii]*(QR[3,ii]-2.*QR[3,Ind[jj]]) )*(QR[3,ii]-QR[2,ii])**2/(30.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) + ( QR[1,ii]**2 + 3.*QR[1,ii]*QR[2,ii] + 6.*QR[2,ii]**2 - 2.*QR[0,ii]*(2.*QR[1,ii]+3.*QR[2,ii] - 5.*QR[3,ii]) - QR[1,ii]*QR[3,ii] -9.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[0,ii]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZ = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZ = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZ = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZ = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - A = scpsp.vstack(LL,format='csr') - - elif Mode=='Vol': - d0R21 = (10*QR[1,:]**3 + 6.*QR[1,:]**2*QR[2,:] + 3.*QR[1,:]*QR[2,:]**2 + QR[2,:]**3 + 5.*QR[0,:]**2*(3.*QR[1,:]+QR[2,:]) - 4.*QR[0,:]*(6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[2,:]-QR[0,:])**2) - d0R22 = (10*QR[2,:]**3 + 6.*QR[2,:]**2*QR[1,:] + 3.*QR[2,:]*QR[1,:]**2 + QR[1,:]**3 + 5.*QR[3,:]**2*(3.*QR[2,:]+QR[1,:]) - 4.*QR[3,:]*(6.*QR[2,:]**2+3.*QR[2,:]*QR[1,:]+QR[1,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[3,:]-QR[1,:])**2) - d0R23 = (2.*QR[1,:]**3 + QR[1,:]*QR[2,:]*(3.*QR[2,:]-4.*QR[3,:]) +(2.*QR[2,:]-3.*QR[3,:])*QR[2,:]**2 +3.*(QR[2,:]-QR[3,:])*QR[1,:]**2 + QR[0,:]*(-3.*QR[1,:]**2-4.*QR[1,:]*QR[2,:]-3.*QR[2,:]**2+5.*QR[1,:]*QR[3,:]+5.*QR[2,:]*QR[3,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[3,:]-QR[1,:])*(QR[2,:]-QR[0,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (5.*QR[1,:]+QR[0,:])*(QR[1,:]-QR[0,:])**3/(30.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (5.*QR[2,:]+QR[3,:])*(QR[3,:]-QR[2,:])**3/(30.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intR = (QR[1,ii]+QR[0,ii])*(QR[1,ii]-QR[0,ii])**3/(60.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR1A = ( -2.*QR[0,Ind[jj]]*QR[0,ii] + QR[0,ii]**2 - 3.*QR[0,Ind[jj]]*QR[1,ii] + 2.*QR[0,ii]*QR[1,ii] + 2.*QR[1,ii]**2 )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intR1B = - ( QR[0,ii]**2 + 2.*QR[1,ii]*(5.*QR[1,ii]-6.*QR[2,ii]) + QR[0,ii]*(4.*QR[1,ii]-3.*QR[2,ii]) )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2A = ( 10.*QR[1,ii]**2 + 4.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[0,ii]*(4.*QR[1,ii]+QR[2,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2B = - ( 2.*QR[1,ii]**2 + 2.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[1,ii]*QR[3,ii] -2.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR = intR1A + intR1B + intR2A + intR2B - - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intR = (QR[3,ii]+QR[2,ii])*(QR[3,ii]-QR[2,ii])**3/(60.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR1A = ( -2.*QR[0,ii]*QR[1,ii] + QR[1,ii]**2 - 3.*QR[0,ii]*QR[2,ii] + 2.*QR[1,ii]*QR[2,ii] + 2.*QR[2,ii]**2 )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR1B = - ( QR[1,ii]**2 + 2.*QR[2,ii]*(5.*QR[2,ii]-6.*QR[3,ii]) + QR[1,ii]*(4.*QR[2,ii]-3.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2A = ( 10.*QR[2,ii]**2 + 4.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[1,ii]*(4.*QR[2,ii]+QR[3,ii]) )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2B = - ( 2.*QR[2,ii]**2 + 2.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[2,ii]*QR[3,Ind[jj]] -2.*QR[3,ii]*QR[3,Ind[jj]] )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])*(QR[3,Ind[jj]]-QR[2,ii])) - intR = intR1A + intR1B + intR2A + intR2B - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZ = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZ = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZ = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZ = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - A = scpsp.vstack(LL,format='csr') - - elif Deriv=='D1N2': - m = 2 - if BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - - if Mode=='Surf': - d0R, d0Z = (Supp[1,:]-Supp[0,:])/3., (Supp[3,:]-Supp[2,:])/3. - d0DR, d0DZ = (QR[2,:]-QR[0,:])/((QR[2,:]-QR[1,:])*(QR[1,:]-QR[0,:])), (QZ[2,:]-QZ[0,:])/((QZ[2,:]-QZ[1,:])*(QZ[1,:]-QZ[0,:])) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDR = d0DR[ii] - intRDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intRDR = -1./(kR[1]-kR[0]) - intRDZ = (kR[1]-kR[0])/6. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZDR = (kZ[1]-kZ[0])/6. - intZDZ = -1./(kZ[1]-kZ[0]) - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - else: - d0R, d0Z = (QR[2,:]**2-QR[0,:]**2 + 2.*QR[1,:]*(QR[2,:]-QR[0,:]))/12., (Supp[3,:]-Supp[2,:])/3. - d0DR, d0DZ = 0.5*(QR[1,:]+QR[0,:])/(QR[1,:]-QR[0,:]) + 0.5*(QR[2,:]+QR[1,:])/(QR[2,:]-QR[1,:]), (QZ[2,:]-QZ[0,:])/((QZ[2,:]-QZ[1,:])*(QZ[1,:]-QZ[0,:])) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDR = d0DR[ii] - intRDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intRDR = -0.5*(kR[1]+kR[0])/(kR[1]-kR[0]) - intRDZ = (kR[1]**2-kR[0]**2)/12. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZDR = (kZ[1]-kZ[0])/6. - intZDZ = -1./(kZ[1]-kZ[0]) - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - AR, AZ = scpsp.vstack(LLR,format='csr'), scpsp.vstack(LLZ,format='csr') - A = (AR,AZ) - - elif BF2.Deg==2: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - if Mode=='Surf': - d0R21 = (QR[2,:]-QR[1,:])*(10.*QR[0,:]**2+6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2 - 5.*QR[0,:]*(3.*QR[1,:]+QR[2,:]))/(30.*(QR[2,:]-QR[0,:])**2) - d0R22 = (QR[2,:]-QR[1,:])*(10.*QR[3,:]**2+6.*QR[2,:]**2+3.*QR[1,:]*QR[2,:]+QR[1,:]**2 - 5.*QR[3,:]*(3.*QR[2,:]+QR[1,:]))/(30.*(QR[3,:]-QR[1,:])**2) - d0R23 = ( 3.*QR[1,:]**2 + 4.*QR[1,:]*QR[2,:] + 3.*QR[2,:]**2 - 5.*QR[0,:]*(QR[1,:]+QR[2,:]-2.*QR[3,:]) -5.*QR[3,:]*(QR[1,:]+QR[2,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (QR[1,:]-QR[0,:])**3/(5.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (QR[3,:]-QR[2,:])**3/(5.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DR = 4.*(QR[1,:]-QR[0,:])/(3.*(QR[2,:]-QR[0,:])**2) + 4.*( QR[0,:]**2 + QR[1,:]**2 + QR[2,:]**2 + (QR[2,:]-2.*QR[3,:])*QR[1,:] - QR[2,:]*QR[3,:] + QR[3,:]**2 + (-QR[1,:]-2.*QR[2,:]+QR[3,:])*QR[0,:] )*(QR[2,:]-QR[1,:])/(3.*(QR[2,:]-QR[0,:])**2*(QR[3,:]-QR[1,:])**2) + 4.*(QR[3,:]-QR[2,:])/(3.*(QR[3,:]-QR[1,:])**2) - d0DZ = 4.*(QZ[1,:]-QZ[0,:])/(3.*(QZ[2,:]-QZ[0,:])**2) + 4.*( QZ[0,:]**2 + QZ[1,:]**2 + QZ[2,:]**2 + (QZ[2,:]-2.*QZ[3,:])*QZ[1,:] - QZ[2,:]*QZ[3,:] + QZ[3,:]**2 + (-QZ[1,:]-2.*QZ[2,:]+QZ[3,:])*QZ[0,:] )*(QZ[2,:]-QZ[1,:])/(3.*(QZ[2,:]-QZ[0,:])**2*(QZ[3,:]-QZ[1,:])**2) + 4.*(QZ[3,:]-QZ[2,:])/(3.*(QZ[3,:]-QZ[1,:])**2) - - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDZ = d0R[ii] - intRDR = d0DR[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDZ = (QR[1,ii]-QR[0,ii])**3/(30.*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - intRDR = 2.*(QR[0,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intRDZ = ( 6.*QR[1,ii]**2 - QR[0,ii]*(9.*QR[1,ii]+QR[2,ii]-10.*QR[3,ii]) + QR[2,ii]*(QR[2,ii]-4.*QR[3,ii]) +3.*QR[1,ii]*(QR[2,ii]-2.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) + ( QR[0,ii]**2 + 3.*QR[0,ii]*QR[1,ii] + 6.*QR[1,ii]**2 - 2.*QR[0,Ind[jj]]*(2.*QR[0,ii]+3.*QR[1,ii] - 5.*QR[2,ii]) - QR[0,ii]*QR[2,ii] -9.*QR[1,ii]*QR[2,ii] )*(QR[1,ii]-QR[0,ii])**2/(30.*(QR[0,Ind[jj]]-QR[2,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - intRDR = 2.*(2.*QR[0,Ind[jj]]-QR[0,ii]-2.*QR[1,ii]+QR[2,ii])*(QR[1,ii]-QR[0,ii])/(3.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) + 2.*(QR[0,ii]-2.*QR[1,ii]-QR[2,ii]+2.*QR[3,ii])*(QR[2,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDZ = (QR[3,ii]-QR[2,ii])**3/(30.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - intRDR = 2.*(QR[2,ii]-QR[3,ii])/(3.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intRDZ = ( 6.*QR[2,ii]**2 - QR[1,ii]*(9.*QR[2,ii]+QR[3,ii]-10.*QR[3,Ind[jj]]) + QR[3,ii]*(QR[3,ii]-4.*QR[3,Ind[jj]]) +3.*QR[2,ii]*(QR[3,ii]-2.*QR[3,Ind[jj]]) )*(QR[3,ii]-QR[2,ii])**2/(30.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) + ( QR[1,ii]**2 + 3.*QR[1,ii]*QR[2,ii] + 6.*QR[2,ii]**2 - 2.*QR[0,ii]*(2.*QR[1,ii]+3.*QR[2,ii] - 5.*QR[3,ii]) - QR[1,ii]*QR[3,ii] -9.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[0,ii]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - intRDR = 2.*(2.*QR[0,ii]-QR[1,ii]-2.*QR[2,ii]+QR[3,ii])*(QR[2,ii]-QR[1,ii])/(3.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) + 2.*(QR[1,ii]-2.*QR[2,ii]-QR[3,ii]+2.*QR[3,Ind[jj]])*(QR[3,ii]-QR[2,ii])/(3.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDZ = 2.*(QZ[0,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[1,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - intZDZ = 2.*(2.*QZ[0,Ind[jj]]-QZ[0,ii]-2.*QZ[1,ii]+QZ[2,ii])*(QZ[1,ii]-QZ[0,ii])/(3.*(QZ[1,ii]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) + 2.*(QZ[0,ii]-2.*QZ[1,ii]-QZ[2,ii]+2.*QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDZ = 2.*(QZ[2,ii]-QZ[3,ii])/(3.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[2,ii])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDZ = 2.*(2.*QZ[0,ii]-QZ[1,ii]-2.*QZ[2,ii]+QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) + 2.*(QZ[1,ii]-2.*QZ[2,ii]-QZ[3,ii]+2.*QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[2,ii])/(3.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - elif Mode=='Vol': - d0R21 = (10*QR[1,:]**3 + 6.*QR[1,:]**2*QR[2,:] + 3.*QR[1,:]*QR[2,:]**2 + QR[2,:]**3 + 5.*QR[0,:]**2*(3.*QR[1,:]+QR[2,:]) - 4.*QR[0,:]*(6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[2,:]-QR[0,:])**2) - d0R22 = (10*QR[2,:]**3 + 6.*QR[2,:]**2*QR[1,:] + 3.*QR[2,:]*QR[1,:]**2 + QR[1,:]**3 + 5.*QR[3,:]**2*(3.*QR[2,:]+QR[1,:]) - 4.*QR[3,:]*(6.*QR[2,:]**2+3.*QR[2,:]*QR[1,:]+QR[1,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[3,:]-QR[1,:])**2) - d0R23 = (2.*QR[1,:]**3 + QR[1,:]*QR[2,:]*(3.*QR[2,:]-4.*QR[3,:]) +(2.*QR[2,:]-3.*QR[3,:])*QR[2,:]**2 +3.*(QR[2,:]-QR[3,:])*QR[1,:]**2 + QR[0,:]*(-3.*QR[1,:]**2-4.*QR[1,:]*QR[2,:]-3.*QR[2,:]**2+5.*QR[1,:]*QR[3,:]+5.*QR[2,:]*QR[3,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[3,:]-QR[1,:])*(QR[2,:]-QR[0,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (5.*QR[1,:]+QR[0,:])*(QR[1,:]-QR[0,:])**3/(30.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (5.*QR[2,:]+QR[3,:])*(QR[3,:]-QR[2,:])**3/(30.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DR = (QR[1,:]-QR[0,:])*(QR[0,:]+3.*QR[1,:])/(3.*(QR[2,:]-QR[0,:])**2) + ( (3.*QR[1,:]+QR[2,:])/(QR[2,:]-QR[0,:])**2 + (QR[1,:]+3.*QR[2,:])/(QR[3,:]-QR[1,:])**2 - 2.*(QR[1,:]+QR[2,:])/((QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) )*(QR[2,:]-QR[1,:])/3. + (QR[3,:]-QR[2,:])*(QR[3,:]+3.*QR[2,:])/(3.*(QR[3,:]-QR[1,:])**2) - d0DZ = 4.*(QZ[1,:]-QZ[0,:])/(3.*(QZ[2,:]-QZ[0,:])**2) + 4.*( QZ[0,:]**2 + QZ[1,:]**2 + QZ[2,:]**2 + (QZ[2,:]-2.*QZ[3,:])*QZ[1,:] - QZ[2,:]*QZ[3,:] + QZ[3,:]**2 + (-QZ[1,:]-2.*QZ[2,:]+QZ[3,:])*QZ[0,:] )*(QZ[2,:]-QZ[1,:])/(3.*(QZ[2,:]-QZ[0,:])**2*(QZ[3,:]-QZ[1,:])**2) + 4.*(QZ[3,:]-QZ[2,:])/(3.*(QZ[3,:]-QZ[1,:])**2) - - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDZ = d0R[ii] - intRDR = d0DR[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDZ = (QR[1,ii]+QR[0,ii])*(QR[1,ii]-QR[0,ii])**3/(60.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intRDR = (QR[0,ii]+QR[1,ii])*(QR[0,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR1A = ( -2.*QR[0,Ind[jj]]*QR[0,ii] + QR[0,ii]**2 - 3.*QR[0,Ind[jj]]*QR[1,ii] + 2.*QR[0,ii]*QR[1,ii] + 2.*QR[1,ii]**2 )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intR1B = - ( QR[0,ii]**2 + 2.*QR[1,ii]*(5.*QR[1,ii]-6.*QR[2,ii]) + QR[0,ii]*(4.*QR[1,ii]-3.*QR[2,ii]) )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2A = ( 10.*QR[1,ii]**2 + 4.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[0,ii]*(4.*QR[1,ii]+QR[2,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2B = - ( 2.*QR[1,ii]**2 + 2.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[1,ii]*QR[3,ii] -2.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intRDZ = intR1A + intR1B + intR2A + intR2B - intRDR = ( -QR[0,ii]**2 + (QR[0,ii]+3.*QR[1,ii])*QR[0,Ind[jj]] + (-3.*QR[1,ii]+QR[2,ii])*QR[1,ii] +(-2.*QR[1,ii]+QR[2,ii])*QR[0,ii] )*(QR[1,ii]-QR[0,ii])/(3.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) + ( -3.*QR[1,ii]**2 + (QR[1,ii]+QR[2,ii])*QR[0,ii] + (-QR[2,ii]+QR[3,ii])*QR[2,ii] + (-2.*QR[2,ii]+3.*QR[3,ii])*QR[1,ii] )*(QR[2,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDZ = (QR[3,ii]+QR[2,ii])*(QR[3,ii]-QR[2,ii])**3/(60.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - intRDR = (QR[2,ii]+QR[3,ii])*(QR[2,ii]-QR[3,ii])/(3.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR1A = ( -2.*QR[0,ii]*QR[1,ii] + QR[1,ii]**2 - 3.*QR[0,ii]*QR[2,ii] + 2.*QR[1,ii]*QR[2,ii] + 2.*QR[2,ii]**2 )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR1B = - ( QR[1,ii]**2 + 2.*QR[2,ii]*(5.*QR[2,ii]-6.*QR[3,ii]) + QR[1,ii]*(4.*QR[2,ii]-3.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2A = ( 10.*QR[2,ii]**2 + 4.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[1,ii]*(4.*QR[2,ii]+QR[3,ii]) )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2B = - ( 2.*QR[2,ii]**2 + 2.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[2,ii]*QR[3,Ind[jj]] -2.*QR[3,ii]*QR[3,Ind[jj]] )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])*(QR[3,Ind[jj]]-QR[2,ii])) - intRDZ = intR1A + intR1B + intR2A + intR2B - intRDR = ( -QR[1,ii]**2 + (QR[1,ii]+3.*QR[2,ii])*QR[0,ii] + (-3.*QR[2,ii]+QR[3,ii])*QR[2,ii] +(-2.*QR[2,ii]+QR[3,ii])*QR[1,ii] )*(QR[2,ii]-QR[1,ii])/(3.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) + ( -3.*QR[2,ii]**2 + (QR[2,ii]+QR[3,ii])*QR[1,ii] + (-QR[3,ii]+QR[3,Ind[jj]])*QR[3,ii] + (-2.*QR[3,ii]+3.*QR[3,Ind[jj]])*QR[2,ii] )*(QR[3,ii]-QR[2,ii])/(3.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDZ = 2.*(QZ[0,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[1,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - intZDZ = 2.*(2.*QZ[0,Ind[jj]]-QZ[0,ii]-2.*QZ[1,ii]+QZ[2,ii])*(QZ[1,ii]-QZ[0,ii])/(3.*(QZ[1,ii]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) + 2.*(QZ[0,ii]-2.*QZ[1,ii]-QZ[2,ii]+2.*QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDZ = 2.*(QZ[2,ii]-QZ[3,ii])/(3.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[2,ii])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDZ = 2.*(2.*QZ[0,ii]-QZ[1,ii]-2.*QZ[2,ii]+QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) + 2.*(QZ[1,ii]-2.*QZ[2,ii]-QZ[3,ii]+2.*QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[2,ii])/(3.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - AR, AZ = scpsp.vstack(LLR,format='csr'), scpsp.vstack(LLZ,format='csr') - A = (AR,AZ) - - - elif Deriv=='D1FI': - m = 3 - if BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - - - - - elif 'D2N2' in Deriv: - m = 2 - if BF2.Deg==2: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - - if Mode=='Surf': - d0R21 = (QR[2,:]-QR[1,:])*(10.*QR[0,:]**2+6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2 - 5.*QR[0,:]*(3.*QR[1,:]+QR[2,:]))/(30.*(QR[2,:]-QR[0,:])**2) - d0R22 = (QR[2,:]-QR[1,:])*(10.*QR[3,:]**2+6.*QR[2,:]**2+3.*QR[1,:]*QR[2,:]+QR[1,:]**2 - 5.*QR[3,:]*(3.*QR[2,:]+QR[1,:]))/(30.*(QR[3,:]-QR[1,:])**2) - d0R23 = ( 3.*QR[1,:]**2 + 4.*QR[1,:]*QR[2,:] + 3.*QR[2,:]**2 - 5.*QR[0,:]*(QR[1,:]+QR[2,:]-2.*QR[3,:]) -5.*QR[3,:]*(QR[1,:]+QR[2,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (QR[1,:]-QR[0,:])**3/(5.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (QR[3,:]-QR[2,:])**3/(5.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DDR = 4./((QR[1,:]-QR[0,:])*(QR[2,:]-QR[0,:])**2) + 4.*(QR[3,:]+QR[2,:]-QR[1,:]-QR[0,:])**2/((QR[2,:]-QR[1,:])*(QR[3,:]-QR[1,:])**2*(QR[2,:]-QR[0,:])**2) + 4./((QR[3,:]-QR[2,:])*(QR[3,:]-QR[1,:])**2) - d0DDZ = 4./((QZ[1,:]-QZ[0,:])*(QZ[2,:]-QZ[0,:])**2) + 4.*(QZ[3,:]+QZ[2,:]-QZ[1,:]-QZ[0,:])**2/((QZ[2,:]-QZ[1,:])*(QZ[3,:]-QZ[1,:])**2*(QZ[2,:]-QZ[0,:])**2) + 4./((QZ[3,:]-QZ[2,:])*(QZ[3,:]-QZ[1,:])**2) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDDR = d0DDR[ii] - intRDDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDDR = 4./((kR[1]-kR[0])*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - intRDDZ = (QR[1,ii]-QR[0,ii])**3/(30.*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intRDDR = -4.*(QR[2,ii]+QR[1,ii]-QR[1,Ind[jj]]-QR[0,Ind[jj]])/((QR[2,Ind[jj]]-QR[1,Ind[jj]])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - 4.*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[3,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])**2) - intRDDZ = ( 6.*QR[1,ii]**2 - QR[0,ii]*(9.*QR[1,ii]+QR[2,ii]-10.*QR[3,ii]) + QR[2,ii]*(QR[2,ii]-4.*QR[3,ii]) +3.*QR[1,ii]*(QR[2,ii]-2.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) + ( QR[0,ii]**2 + 3.*QR[0,ii]*QR[1,ii] + 6.*QR[1,ii]**2 - 2.*QR[0,Ind[jj]]*(2.*QR[0,ii]+3.*QR[1,ii] - 5.*QR[2,ii]) - QR[0,ii]*QR[2,ii] -9.*QR[1,ii]*QR[2,ii] )*(QR[1,ii]-QR[0,ii])**2/(30.*(QR[0,Ind[jj]]-QR[2,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDDR = 4./((kR[1]-kR[0])*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - intRDDZ = (QR[3,ii]-QR[2,ii])**3/(30.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intRDDR = -4.*(QR[3,Ind[jj]]+QR[2,Ind[jj]]-QR[2,ii]-QR[1,ii])/((QR[3,ii]-QR[2,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) - 4.*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) - intRDDZ = ( 6.*QR[2,ii]**2 - QR[1,ii]*(9.*QR[2,ii]+QR[3,ii]-10.*QR[3,Ind[jj]]) + QR[3,ii]*(QR[3,ii]-4.*QR[3,Ind[jj]]) +3.*QR[2,ii]*(QR[3,ii]-2.*QR[3,Ind[jj]]) )*(QR[3,ii]-QR[2,ii])**2/(30.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) + ( QR[1,ii]**2 + 3.*QR[1,ii]*QR[2,ii] + 6.*QR[2,ii]**2 - 2.*QR[0,ii]*(2.*QR[1,ii]+3.*QR[2,ii] - 5.*QR[3,ii]) - QR[1,ii]*QR[3,ii] -9.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[0,ii]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common knots..." - - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDDR = d0Z[ii] - intZDDZ = d0DDZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDDZ = -4.*(QZ[2,ii]+QZ[1,ii]-QZ[1,Ind[jj]]-QZ[0,Ind[jj]])/((QZ[2,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])**2) - intZDDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDDZ = -4.*(QZ[3,Ind[jj]]+QZ[2,Ind[jj]]-QZ[2,ii]-QZ[1,ii])/((QZ[3,ii]-QZ[2,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common knots..." - - llR[0,Ind[jj]] = intRDDR*intZDDR - llZ[0,Ind[jj]] = intRDDZ*intZDDZ - llR[0,ii] = d0DDR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DDZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - elif Mode=='Vol': - d0R21 = (10*QR[1,:]**3 + 6.*QR[1,:]**2*QR[2,:] + 3.*QR[1,:]*QR[2,:]**2 + QR[2,:]**3 + 5.*QR[0,:]**2*(3.*QR[1,:]+QR[2,:]) - 4.*QR[0,:]*(6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[2,:]-QR[0,:])**2) - d0R22 = (10*QR[2,:]**3 + 6.*QR[2,:]**2*QR[1,:] + 3.*QR[2,:]*QR[1,:]**2 + QR[1,:]**3 + 5.*QR[3,:]**2*(3.*QR[2,:]+QR[1,:]) - 4.*QR[3,:]*(6.*QR[2,:]**2+3.*QR[2,:]*QR[1,:]+QR[1,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[3,:]-QR[1,:])**2) - d0R23 = (2.*QR[1,:]**3 + QR[1,:]*QR[2,:]*(3.*QR[2,:]-4.*QR[3,:]) +(2.*QR[2,:]-3.*QR[3,:])*QR[2,:]**2 +3.*(QR[2,:]-QR[3,:])*QR[1,:]**2 + QR[0,:]*(-3.*QR[1,:]**2-4.*QR[1,:]*QR[2,:]-3.*QR[2,:]**2+5.*QR[1,:]*QR[3,:]+5.*QR[2,:]*QR[3,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[3,:]-QR[1,:])*(QR[2,:]-QR[0,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (5.*QR[1,:]+QR[0,:])*(QR[1,:]-QR[0,:])**3/(30.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (5.*QR[2,:]+QR[3,:])*(QR[3,:]-QR[2,:])**3/(30.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DDR = 2.*(QR[1,:]+QR[0,:])/((QR[1,:]-QR[0,:])*(QR[2,:]-QR[0,:])**2) + 2.*(QR[2,:]+QR[1,:])*(QR[3,:]+QR[2,:]-QR[1,:]-QR[0,:])**2/((QR[2,:]-QR[1,:])*(QR[3,:]-QR[1,:])**2*(QR[2,:]-QR[0,:])**2) + 2.*(QR[3,:]+QR[2,:])/((QR[3,:]-QR[2,:])*(QR[3,:]-QR[1,:])**2) - d0DDZ = 4./((QZ[1,:]-QZ[0,:])*(QZ[2,:]-QZ[0,:])**2) + 4.*(QZ[3,:]+QZ[2,:]-QZ[1,:]-QZ[0,:])**2/((QZ[2,:]-QZ[1,:])*(QZ[3,:]-QZ[1,:])**2*(QZ[2,:]-QZ[0,:])**2) + 4./((QZ[3,:]-QZ[2,:])*(QZ[3,:]-QZ[1,:])**2) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - Ind = np.asarray([int(xxx) for xxx in Ind], dtype=int) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDDR = d0DDR[ii] - intRDDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDDR = 2.*(kR[1]+kR[0])/((kR[1]-kR[0])*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - intRDDZ = (QR[1,ii]+QR[0,ii])*(QR[1,ii]-QR[0,ii])**3/(60.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR1A = ( -2.*QR[0,Ind[jj]]*QR[0,ii] + QR[0,ii]**2 - 3.*QR[0,Ind[jj]]*QR[1,ii] + 2.*QR[0,ii]*QR[1,ii] + 2.*QR[1,ii]**2 )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intR1B = - ( QR[0,ii]**2 + 2.*QR[1,ii]*(5.*QR[1,ii]-6.*QR[2,ii]) + QR[0,ii]*(4.*QR[1,ii]-3.*QR[2,ii]) )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2A = ( 10.*QR[1,ii]**2 + 4.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[0,ii]*(4.*QR[1,ii]+QR[2,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2B = - ( 2.*QR[1,ii]**2 + 2.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[1,ii]*QR[3,ii] -2.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intRDDZ = intR1A + intR1B + intR2A + intR2B - intRDDR = -2.*(QR[1,ii]+QR[0,ii])*(QR[2,ii]+QR[1,ii]-QR[0,ii]-QR[0,Ind[jj]])/((QR[1,ii]-QR[0,ii])*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - 2.*(QR[2,ii]+QR[1,ii])*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[3,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDDR = 2.*(kR[1]+kR[0])/((kR[1]-kR[0])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])*(QR[3,ii]-QR[1,ii])) - intRDDZ = (QR[3,ii]+QR[2,ii])*(QR[3,ii]-QR[2,ii])**3/(60.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR1A = ( -2.*QR[0,ii]*QR[1,ii] + QR[1,ii]**2 - 3.*QR[0,ii]*QR[2,ii] + 2.*QR[1,ii]*QR[2,ii] + 2.*QR[2,ii]**2 )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR1B = - ( QR[1,ii]**2 + 2.*QR[2,ii]*(5.*QR[2,ii]-6.*QR[3,ii]) + QR[1,ii]*(4.*QR[2,ii]-3.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2A = ( 10.*QR[2,ii]**2 + 4.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[1,ii]*(4.*QR[2,ii]+QR[3,ii]) )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2B = - ( 2.*QR[2,ii]**2 + 2.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[2,ii]*QR[3,Ind[jj]] -2.*QR[3,ii]*QR[3,Ind[jj]] )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])*(QR[3,Ind[jj]]-QR[2,ii])) - intRDDZ = intR1A + intR1B + intR2A + intR2B - intRDDR = -2.*(QR[2,ii]+QR[1,ii])*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) - 2.*(QR[3,ii]+QR[2,ii])*(QR[3,Ind[jj]]+QR[3,ii]-QR[2,ii]-QR[1,ii])/((QR[3,ii]-QR[2,ii])*(QR[3,Ind[jj]]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common knots..." - - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDDR = d0Z[ii] - intZDDZ = d0DDZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDDZ = -4.*(QZ[2,ii]+QZ[1,ii]-QZ[1,Ind[jj]]-QZ[0,Ind[jj]])/((QZ[2,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])**2) - intZDDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDDZ = -4.*(QZ[3,Ind[jj]]+QZ[2,Ind[jj]]-QZ[2,ii]-QZ[1,ii])/((QZ[3,ii]-QZ[2,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common knots..." - - llR[0,Ind[jj]] = intRDDR*intZDDR - llZ[0,Ind[jj]] = intRDDZ*intZDDZ - llR[0,ii] = d0DDR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DDZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - AR, AZ = scpsp.vstack(LLR,format='csr'), scpsp.vstack(LLZ,format='csr') - A = (AR,AZ) - - if not Sparse: - if m in [0,1]: - A = A.toarray() - elif m==2: - A = (A[0].toarray(),A[1].toarray()) - - return A, m - - - - - - - - - - - - - - - - - - - -def Calc_BF2D_DerivFunc(BF2, Deriv, Test=True): - if Test: - assert isinstance(BF2, BF2D), "Arg BF2 must be a MeshBase2D instance !" - assert type(Deriv) is int, "Arg Deriv must be a int !" - - KnR, KnZ = BF2._get_quadPoints() - if Deriv==1: - LFuncR, LFuncZ = [], [] - for ii in range(0,BF2.NFunc): - LFuncR.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=0, Test=False)[0](X[1,:])*BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=Deriv, Test=False)[0](X[0,:])) - LFuncZ.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=0, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=Deriv, Test=False)[0](X[1,:])) - return LFuncR, LFuncZ - elif Deriv==2: - # Formulas for Gauss and Mean curvature were found on http://en.wikipedia.org/wiki/Differential_geometry_of_surfaces - DRR, DRZ, DZZ = [], [], [] - for ii in range(0,BF2.NFunc): - DRR.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=Deriv, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=0, Test=False)[0](X[1,:])) - DRZ.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=1, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=1, Test=False)[0](X[1,:])) - DZZ.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=0, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=Deriv, Test=False)[0](X[1,:])) - return DRR, DRZ, DZZ - - - - -def Get_MinMax(BF2, Coefs=1., Ratio=0.05, SubP=0.004, SubP1=0.015, SubP2=0.001, TwoSteps=False, SubMode='abs', Deriv='D0', Margin=0.2, Test=True): - assert Ratio is None or (type(Ratio) is float and Ratio>0 and Ratio<1), "Arg Ratio must be None or a float in ]0;1[ !" - if TwoSteps: - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP1, SubMode='abs', Test=Test) - else: - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP, SubMode='abs', Test=Test) - nx, ny = X.size, Y.size - dS = np.mean(np.diff(X))*np.mean(np.diff(Y)) - Xplot, Yplot = np.tile(X,(ny,1)), np.tile(Y,(nx,1)).T - Points = np.array([Xplot.flatten(), Yplot.flatten()]) - Vals = BF2.get_TotVal(Points, Deriv=Deriv, Coefs=Coefs, Test=Test) - - def getminmaxRatioFloat(valsmax, valsmin, indmax, indmin, Ratio, Ptsmin, Ptsmax): - DV = valsmax[indmax]-valsmin[indmin] - imin, imax = valsmin<=valsmin[indmin]+Ratio*DV, valsmax>=valsmax[indmax]-Ratio*DV - PMin = np.array([np.sum(Ptsmin[0,imin]*valsmin[imin])/np.sum(valsmin[imin]), np.sum(Ptsmin[1,imin]*valsmin[imin])/np.sum(valsmin[imin])]) - PMax = np.array([np.sum(Ptsmax[0,imax]*valsmax[imax])/np.sum(valsmax[imax]), np.sum(Ptsmax[1,imax]*valsmax[imax])/np.sum(valsmax[imax])]) - VMin, VMax = np.mean(valsmin[imin]), np.mean(valsmax[imax]) - return PMin, PMax, VMin, VMax - - def get_XYgridFine(DXmin, DYmin, DXmax, DYmax, Margin, subp): - DXmin, DYmin = [DXmin[0]-Margin*(DXmin[1]-DXmin[0]), DXmin[1]+Margin*(DXmin[1]-DXmin[0])], [DYmin[0]-Margin*(DYmin[1]-DYmin[0]), DYmin[1]+Margin*(DYmin[1]-DYmin[0])] - DXmax, DYmax = [DXmax[0]-Margin*(DXmax[1]-DXmax[0]), DXmax[1]+Margin*(DXmax[1]-DXmax[0])], [DYmax[0]-Margin*(DYmax[1]-DYmax[0]), DYmax[1]+Margin*(DYmax[1]-DYmax[0])] - Nxmin, Nymin = (DXmin[1]-DXmin[0])/subp, (DYmin[1]-DYmin[0])/subp - Nxmax, Nymax = (DXmax[1]-DXmax[0])/subp, (DYmax[1]-DYmax[0])/subp - Xmin, Ymin = np.linspace(DXmin[0],DXmin[1], Nxmin), np.linspace(DYmin[0],DYmin[1], Nymin) - Xmax, Ymax = np.linspace(DXmax[0],DXmax[1], Nxmax), np.linspace(DYmax[0],DYmax[1], Nymax) - Ptsmin = np.array([np.tile(Xmin,(Nymin,1)).flatten(), np.tile(Ymin,(Nxmin,1)).T.flatten()]) - Ptsmax = np.array([np.tile(Xmax,(Nymax,1)).flatten(), np.tile(Ymax,(Nxmax,1)).T.flatten()]) - return Ptsmin, Ptsmax - - def get_minmaxFine(vals, indmaxi, indmini, coefs, Points=Points, ratio=0.02, SubP2=SubP2, Ratio=Ratio, Test=Test): - DV = vals[indmaxi]-vals[indmini] - imin, imax = vals<=vals[indmini]+ratio*DV, vals>=vals[indmaxi]-ratio*DV - xminmin, xminmax = np.min(Points[0,imin]), np.max(Points[0,imin]) - xmaxmin, xmaxmax = np.min(Points[0,imax]), np.max(Points[0,imax]) - yminmin, yminmax = np.min(Points[1,imin]), np.max(Points[1,imin]) - ymaxmin, ymaxmax = np.min(Points[1,imax]), np.max(Points[1,imax]) - Ptsmin, Ptsmax = get_XYgridFine([xminmin,xminmax], [yminmin,yminmax], [xmaxmin, xmaxmax], [ymaxmin, ymaxmax], Margin, SubP2) - valsmin, valsmax = BF2.get_TotVal(Ptsmin, Deriv=Deriv, Coefs=coefs, Test=Test), BF2.get_TotVal(Ptsmax, Deriv=Deriv, Coefs=coefs, Test=Test) - indmin, indmax = np.nanargmin(valsmin), np.nanargmax(valsmax) - if Ratio is None: - return Ptsmin[:,indmin], Ptsmax[:,indmax], valsmin[indmin], valsmax[indmax] - else: - return getminmaxRatioFloat(valsmax, valsmin, indmax, indmin, Ratio, Ptsmin, Ptsmax) - - if not hasattr(Coefs,'__getitem__') or Coefs.ndim==1: - indmin, indmax = np.nanargmin(Vals), np.nanargmax(Vals) - if TwoSteps: - PMin, PMax, VMin, VMax = get_minmaxFine(Vals, indmax, indmin, Coefs, Points=Points, ratio=0.02, SubP2=SubP2, Ratio=Ratio, Test=Test) - else: - if Ratio is None: - PMin, PMax = Points[:,indmin], Points[:,indmax] - VMin, VMax = Vals[indmin], Vals[indmax] - else: - PMin, PMax, VMin, VMax = getminmaxRatioFloat(Vals, Vals, indmax, indmin, Ratio, Points, Points) - Surf = (Vals >= Vals(np.nanargmax(Vals))*0.5).sum()*dS - else: - indmin, indmax = np.nanargmin(Vals,axis=1), np.nanargmax(Vals,axis=1) - if TwoSteps: - ratio = 0.02 if Ratio is None else Ratio+0.02 - mmin, mmax = np.nanmin(Vals,axis=1).max(), np.nanmax(Vals,axis=1).min() - DV = np.max(np.nanmax(Vals,axis=1)-np.nanmin(Vals,axis=1)) - assert mmin+ratio*DV <= mmax-ratio*DV, "Profile changes too much !" - imin, imax = np.any(Vals<=mmin+ratio*DV,axis=0), np.any(Vals>=mmax-ratio*DV,axis=0) - DXmin, DYmin = [Points[0,imin].min(), Points[0,imin].max()], [Points[1,imin].min(), Points[1,imin].max()] - DXmax, DYmax = [Points[0,imax].min(), Points[0,imax].max()], [Points[1,imax].min(), Points[1,imax].max()] - Ptsmin, Ptsmax = get_XYgridFine(DXmin, DYmin, DXmax, DYmax, Margin, SubP2) - Valsmin, Valsmax = BF2.get_TotVal(Ptsmin, Deriv=Deriv, Coefs=Coefs, Test=Test), BF2.get_TotVal(Ptsmax, Deriv=Deriv, Coefs=Coefs, Test=Test) - else: - Ptsmin, Ptsmax = Points, Points - Valsmin, Valsmax = Vals, Vals - indmin, indmax = np.nanargmin(Valsmin,axis=1), np.nanargmax(Valsmax,axis=1) - if Ratio is None: - PMin, PMax = Ptsmin[:,indmin].T, Ptsmax[:,indmax].T - VMin, VMax = np.nanmin(Valsmin,axis=1), np.nanmax(Valsmax,axis=1) - else: - Nt = Coefs.shape[0] - PMin, PMax = np.empty((Nt,2)), np.empty((Nt,2)) - VMin, VMax = np.empty((Nt,)), np.empty((Nt,)) - for ii in range(0,Nt): - PMin[ii,:], PMax[ii,:], VMin[ii], VMax[ii] = getminmaxRatioFloat(Valsmax[ii,:], Valsmin[ii,:], indmax[ii], indmin[ii], Ratio, Ptsmin, Ptsmax) - Surf = np.sum(Vals >= np.tile(np.nanmax(Vals,axis=1)*0.5,(Vals.shape[1],1)).T,axis=1)*dS - - return PMin, PMax, VMin, VMax, Surf - - - - - - - - -def Calc_GetRoots(BF2, Deriv=0., Coefs=1., Test=True): - if Test: - assert isinstance(BF2, BF2D), "Arg BF2 must be a BF2D instance !" - assert Deriv in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI'], "Arg Deriv must be in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI'] !" - if type(Deriv) is str: - intDeriv = int(Deriv[1]) - else: - intDeriv = Deriv - assert BF2.Deg > 0 and intDeriv0)) and C4.size==4: - Inds[ii] = True - A = C4[0]+C4[3] - C4[1]+C4[2] - B = C4[1]*Kts[1,1] - C4[3]*Kts[1,0] - C4[0]*Kts[1,1] + C4[2]*Kts[1,0] - C = C4[1]*Kts[0,0] - C4[3]*Kts[0,0] - C4[0]*Kts[0,1] + C4[2]*Kts[0,1] - D = Kts[0,1]*(C4[0]*Kts[1,1]-C4[2]*Kts[1,0]) - Kts[0,0]*(C4[1]*Kts[1,1]-C4[3]*Kts[1,0]) - if A==0.: - if C==0.: - if B==0.: - Shape[ii] = ['all',[]] if D==0. else ['',[]] # Else not possible - else: - Shape[ii] = ['x',[-D/B]] - else: - Shape[ii] = ['yx',[-B/C,-D/C]] - else: - if -C/A>Kts[0,1] or -C/A0)) and C9.size==9: - Inds[ii] = True - print " Not finished yet !" - - - - - if intDeriv==1: - if Deriv[1]=='D1N2': - if BF2.Deg==2: - for ii in range(0,NCents): - ind = BF2._Cents_Funcind[:,ii] - C9 = Coefs[np.unique(ind[~np.isnan(ind)]).astype(int)] - Kts = BF2.Mesh.Knots[:,np.unique(BF2.Mesh._Cents_Knotsind[:,ii])] - - #A0, B0 = - #A1, B1 = - #A2, B2 = - #alpha0, beta0, gam0 = - #alpha1, beta1, gam1 = - #alpha2, beta2, gam2 = - return Inds, Pts, Shape - - - - - - -############################################ -##### Plotting functions -############################################ - - - -def Plot_BF2D(BF2, Coef=1., ax='None',SubP=0.1, SubMode='Rel', Name='Tot', TotDict=Tot2Dict_Def): - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert ax=='None' or isinstance(ax,plt.Axes), "Arg ax must be a plt.Axes instance !" - assert type(Name) is str, "Arg Name must be a str !" - - assert type(TotDict) is dict, "Arg TotDict must be a dict !" - - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP, SubMode=SubMode, Test=True) - nx, ny = X.size, Y.size - Xplot, Yplot = np.dot(np.ones((ny,1)),X.reshape((1,nx))), np.dot(Y.reshape((ny,1)),np.ones((1,nx))) - Points = np.concatenate((Xplot.reshape((1,nx*ny)), Yplot.reshape((1,nx*ny))),axis=0) - Z = Calc_BF2D_Val(BF2.LFunc, Points, Coef=Coef, Test=True) - Zplot= Z.reshape((ny,nx)) - - if ax=='None': - ax = tfd.Plot_BSpline_DefAxes('2D') - ax.plot_surface(Xplot,Yplot,Zplot, label=Name, **TotDict) - - ax.figure.canvas.draw() - return ax - - - - -def Plot_BF2D_BFuncMesh(BF2, ind, Coef=1., ax1='None', ax2='None',SubP=0.25, SubMode='Rel', Name='', TotDict=Tot2Dict_Def): - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert type(ind) is int, "Arg ind must be a int !" - assert ax1=='None' or isinstance(ax1,plt.Axes), "Arg ax1 must be a plt.Axes instance !" - assert ax2=='None' or isinstance(ax2,plt.Axes), "Arg ax2 must be a plt.Axes instance !" - assert type(Name) is str, "Arg Name must be a str !" - assert type(TotDict) is dict, "Arg TotDict must be a dict !" - - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP, SubMode=SubMode, Test=True) - nx, ny = X.size, Y.size - Xplot, Yplot = np.dot(np.ones((ny,1)),X.reshape((1,nx))), np.dot(Y.reshape((ny,1)),np.ones((1,nx))) - Points = np.concatenate((Xplot.reshape((1,nx*ny)), Yplot.reshape((1,nx*ny))),axis=0) - Z = Calc_BF2D_Val([BF2.LFunc[ind]], Points, Coef=Coef, Test=True) - Zplot= Z.reshape((ny,nx)) - - if ax1=='None' or ax2=='None': - ax1, ax2 = tfd.Plot_BF2D_BFuncMesh_DefAxes() - - BF2.Mesh.plot(ax=ax1) - BF2.Mesh.plot_Cents(ax=ax1,Ind=BF2.Func_Centsind[:,ind], Knots=False) - BF2.Mesh.plot_Knots(ax=ax1,Ind=BF2.Func_Knotsind[:,ind], Cents=False) - - ax2.plot_surface(Xplot,Yplot,Zplot, label=Name, **TotDict) - ax1.figure.canvas.draw() - return ax1, ax2 - - -def Plot_BFunc_SuppMax_PolProj(BF2, ind, ax='None', Supp=True,PMax=True,SuppDict=SuppDict_Def, PMaxDict=PMaxDict_Def): - assert type(ind) is int, "Arg ind must be a int !" - assert type(Supp) is bool, "Arg Supp must be a bool !" - assert type(PMax) is bool, "Arg Supp must be a bool !" - assert type(SuppDict) is dict, "Arg SuppDict must be a dict !" - assert type(PMaxDict) is dict, "Arg SuppDict must be a dict !" - assert isinstance(ax,plt.Axes) or ax=='None', "Arg ax must be a plt.Axes instance !" - - - if ax=='None': - ax = tfd.Plot_BFunc_SuppMax_PolProj_DefAxes() - - if Supp: - RZsupp = BF2.get_Func_SuppRZ()[:,ind] - verts = [(RZsupp[0], RZsupp[2]), # left, bottom - (RZsupp[1], RZsupp[2]), # left, top - (RZsupp[1], RZsupp[3]), # right, top - (RZsupp[0], RZsupp[3]), # right, bottom - (RZsupp[0], RZsupp[2])] - - codes = [Path.MOVETO, - Path.LINETO, - Path.LINETO, - Path.LINETO, - Path.CLOSEPOLY] - - patch = patches.PathPatch(Path(verts, codes), **SuppDict) - ax.add_patch(patch) - if PMax: - PMax = BF2.Func_PMax[:,ind] - ax.plot(PMax[0],PMax[1], **PMaxDict) - - return ax - - - -""" -############################################################################### -############################################################################### - Testing ground -############################################################################### -""" -""" -Deg = 2 -KnotsMult1 = np.array([0.,1.,2.,3.,4.,5., 5., 5.]) -KnotsMult2 = np.array([0.,0.,1.,2.,3.,4.,5.]) -BS1 = BSpline(Deg,KnotsMult1)[0] -BS2 = BSpline(Deg,KnotsMult2)[0] -#ax = Plot_BSpline1D(KnotsMult1,BS1,ax='None',SubP=0.05,SubMode='Rel') -ax1, ax2 = Plot_BSpline2D(KnotsMult1, KnotsMult2, BS1, BS2, ax1=None, ax2='None',SubP=0.05,SubMode='Rel') -""" - diff --git a/tofu/mesh/_plot.py b/tofu/mesh/_plot.py deleted file mode 100644 index f331fd4b8..000000000 --- a/tofu/mesh/_plot.py +++ /dev/null @@ -1,2314 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Aug 25 10:03:58 2014 - -@author: didiervezinet -""" - -import numpy as np -import matplotlib.pyplot as plt -from mpl_toolkits.mplot3d import Axes3D -import Polygon as plg -import scipy.sparse as scpsp -from matplotlib.path import Path -import matplotlib.patches as patches -from matplotlib.collections import PatchCollection as PcthColl -import datetime as dtm -import scipy.interpolate as scpinterp - - -# ToFu-specific -import tofu.defaults as tfd -import tofu.pathfile as TFPF -#import tofu_Mesh as TFM - - -#from mayavi import mlab - -""" -############################################################################### -############################################################################### - Mesh1D and Mesh2D -############################################################################### -""" - -BS2Dict_Def = {'linewidth':0.,'rstride':1,'cstride':1, 'antialiased':False} -Tot2Dict_Def = {'color':(0.7,0.7,0.7),'linewidth':0.,'rstride':1,'cstride':1, 'antialiased':False} -SuppDict_Def = {'facecolor':(0.8,0.8,0.8), 'lw':0.} -PMaxDict_Def = {'color':'g', 'marker':'s', 'markersize':8, 'linestyle':'None', 'linewidth':1.} - - - -############################################ -##### Plotting functions -############################################ - -def Mesh1D_Plot(Knots, Cents=None, y=0., Leg=None, Elt='KCN', ax=None, Kdict=tfd.M1Kd, Cdict=tfd.M1Cd, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True): - if Test: - assert isinstance(Knots,np.ndarray) and Knots.ndim==1, "Arg Knots must be a 1-dim np.ndarray !" - assert type(y) is float, "Arg y must be a float !" - assert type(Leg) is str, "Arg Leg must be a str !" - assert ax is None or isinstance(ax,plt.Axes), "Arg ax must be a plt.Axes instance !" - assert type(Kdict) is dict, "Arg Kdict must be a dict !" - assert type(Cdict) is dict, "Arg Cdict must be a dict !" - assert type(Elt) is str, "Arg Elt must be a str !" - - if ax is None: - ax = tfd.Plot_Mesh1D_DefAxes(a4=a4) - if 'K' in Elt: - ax.plot(Knots, y*np.ones(Knots.shape),label=Leg + ' Knots', **Kdict) - if 'C' in Elt: - if Cents is None: - Cents = (Knots[:-1]+Knots[1:])/2. - ax.plot(Cents, y*np.ones(Cents.shape), label=Leg + ' Cents', **Cdict) - if 'N' in Elt: - YLim = ax.get_ylim() - DY = YLim[1]-YLim[0] - for ii in range(Cents.size): - ax.annotate(str(ii),xy=(Cents[ii], y), xycoords='data', xytext=(Cents[ii], y+0.04*DY), textcoords='data', ha='center', va='bottom') - Delta = np.abs(np.max(Knots)-np.min(Knots)) - ax.set_xlim([np.min(Knots)-0.02*Delta, np.max(Knots)+0.02*Delta]) - ax.set_yticks([]) - if not LegDict is None: - ax.legend(**LegDict) - if draw: - ax.figure.canvas.draw() - return ax - -def Mesh1D_Plot_Res(Knots, Leg=None, ax=None, Dict=tfd.M1Resd, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True): - if Test: - assert isinstance(Knots,np.ndarray) and Knots.ndim==1, "Arg Knots must be a 1-dim np.ndarray !" - assert type(Leg) is str, "Arg Leg must be a str !" - assert ax is None or isinstance(ax,plt.Axes), "Arg ax must be a plt.Axes instance !" - assert type(Dict) is dict, "Arg dict must be a dict !" - - if ax is None: - ax = tfd.Plot_Res_Mesh1D_DefAxes(a4=a4) - Res = np.diff(Knots) - Eps = np.min(Res)/1000. - ResX = np.array([Knots[:-1]+Eps, Knots[1:]-Eps]).T - ResY = np.array([Res,Res]).T - ax.plot(ResX.flatten(), ResY.flatten(), label=Leg+' Res', **Dict) - if not LegDict is None: - ax.legend(**LegDict) - if draw: - ax.figure.canvas.draw() - return ax - - -def Mesh2D_Plot(M2, ax=None, Leg=None, Elt='MBgKCBsBv', indKnots=None, indCents=None, SubMesh=None, - Bckdict=tfd.M2Bckd, Mshdict=tfd.M2Mshd, Kdict=tfd.M2Kd, Cdict=tfd.M2Cd, LegDict=tfd.TorLegd, - draw=True, a4=False, Test=True): - - if Test: - assert M2.Id.Cls=='Mesh2D', "Arg M2 must be a Mesh2D instance !" - assert ax is None or isinstance(ax,plt.Axes), "Arg ax must be a plt.Axes instance !" - assert all([type(dd) is dict for dd in [Bckdict,Mshdict,Kdict,Cdict]]), "Arg Bckdict,Mshdict,Kdict,Cdict must be dict !" - assert type(LegDict) is dict or LegDict is None, "Arg LegDict must be a dict !" - assert type(Elt) is str, "Arg Elt must be a str !" - - if not SubMesh is None: - M2 = M2._SubMesh[SubMesh]['Mesh2D'] - - # Preparing - if indKnots is None: - indKnots = np.zeros((M2.NKnots,),dtype=bool) - elif indKnots=='all': - indKnots = np.ones((M2.NKnots,),dtype=bool) - elif hasattr(indKnots,'__getitem__') and all(type(ii) in [int,np.int64] for ii in indKnots): - indKnots = np.asarray(indKnots) - ind = np.zeros((M2.NKnots,),dtype=bool) - ind[indKnots] = True - indKnots = ind - else: - assert isinstance(indKnots,np.ndarray) and indKnots.dtype == bool, "Arg indKnots must be None, 'all' or a list/tuple/np.ndarray of int indices or a np.ndarray of bool !" - - if indCents is None: - indCents = np.zeros((M2.NCents,),dtype=bool) - elif indCents=='all': - indCents = np.ones((M2.NCents,),dtype=bool) - elif hasattr(indCents,'__getitem__') and all(type(ii) in [int,np.int64] for ii in indCents): - indCents = np.asarray(indCents) - ind = np.zeros((M2.NCents,),dtype=bool) - ind[indCents] = True - indCents = ind - else: - assert isinstance(indCents,np.ndarray) and indCents.dtype == bool, "Arg indCents must be None, 'all' or a list/tuple/np.ndarray of int indices or a np.ndarray of bool !" - indKnotsEx = np.zeros((M2.NKnots,),dtype=bool) - indKnotsEx[np.unique(M2._Cents_Knotsind[:,indCents])] = True - indCentsEx = np.zeros((M2.NCents,),dtype=bool) - indtemp = np.unique(M2._Knots_Centsind[:,indKnots]) - indCentsEx[indtemp[indtemp>=0]] = True - - # Plotting - Leg = M2.Id.NameLTX if Leg is None else Leg - if ax is None: - ax = tfd.Plot_Mesh2D_DefAxes(VType=M2.Type, a4=a4) - - NR, NZ = M2.MeshX1.NKnots, M2.MeshX2.NKnots - if 'Bg' in Elt: - Rmin, Rmax = M2.MeshX1.Knots.min(), M2.MeshX1.Knots.max() - Zmin, Zmax = M2.MeshX2.Knots.min(), M2.MeshX2.Knots.max() - RH = np.tile(np.array([Rmin,Rmax,np.nan]),(NZ)) - ZH = np.concatenate((np.tile(M2.MeshX2.Knots,(2,1)),np.nan*np.ones((1,NZ))),axis=0).T.flatten() - RV = np.concatenate((np.tile(M2.MeshX1.Knots,(2,1)),np.nan*np.ones((1,NR))),axis=0).T.flatten() - ZV = np.tile(np.array([Zmin,Zmax,np.nan]),(NR)) - RB, ZB = np.concatenate((RH,RV)), np.concatenate((ZH,ZV)) - ax.plot(RB, ZB, label=Leg+' Background', **Bckdict) - - if 'M' in Elt: - ROR = np.concatenate((np.tile(M2.MeshX1.Knots,(2,1)),np.nan*np.ones((1,NR))),axis=0).T.flatten() - ZOR = np.nan*np.ones((3,NR)) - for ii in range(0,NR): - indK = M2.Knots[0,:] == M2.MeshX1.Knots[ii] - ZOR[0,ii] = M2.Knots[1,indK].min() - ZOR[1,ii] = M2.Knots[1,indK].max() - ZOR = ZOR.T.flatten() - ZOZ = np.concatenate((np.tile(M2.MeshX2.Knots,(2,1)),np.nan*np.ones((1,NZ))),axis=0).T.flatten() - ROZ = np.nan*np.ones((3,NZ)) - for ii in range(0,NZ): - indK = M2.Knots[1,:] == M2.MeshX2.Knots[ii] - ROZ[0,ii] = M2.Knots[0,indK].min() - ROZ[1,ii] = M2.Knots[0,indK].max() - ROZ = ROZ.T.flatten() - RO, ZO = np.concatenate((ROR,ROZ)), np.concatenate((ZOR,ZOZ)) - ax.plot(RO, ZO, label=Leg+' Mesh', **Mshdict) - - if 'K' in Elt: - if not indKnots is None and np.any(indKnots): - ll = ax.plot(M2.Knots[0,indKnots], M2.Knots[1,indKnots], label=Leg+' Knots', **Kdict) - if not indKnotsEx is None and np.any(indKnotsEx): - kd = Kdict.copy() - kd['alpha'] = 0.2 - ax.plot(M2.Knots[0,indKnotsEx], M2.Knots[1,indKnotsEx], label=Leg+' Knots of Cents', **kd) - if 'C' in Elt: - if not indCents is None and np.any(indCents): - ax.plot(M2.Cents[0,indCents], M2.Cents[1,indCents], label=Leg+' Cents', **Cdict) - if not indCentsEx is None and np.any(indCentsEx): - cd = Cdict.copy() - cd['alpha'] = 0.2 - ax.plot(M2.Cents[0,indCentsEx], M2.Cents[1,indCentsEx], label=Leg+' Cents of Knots', **cd) - if 'Bs' in Elt: - ax.plot(M2.BaryS[0],M2.BaryS[1], ls='None', lw=0., marker='o', c='k', label=Leg+' BaryS') - if 'Bv' in Elt and M2.Id.Type=='Tor': - ax.plot(M2.BaryV[0],M2.BaryV[1], ls='None', lw=0., marker='.', c='k', label=Leg+' BaryV') - - - if not LegDict is None: - ax.legend(**LegDict) - if draw: - ax.figure.canvas.draw() - return ax - - -def Mesh2D_Plot_Res(M2, ax1=None, ax2=None, ax3=None, axcb=None, Leg=None, Elt='MBgS', SubMesh=None, Bckdict=tfd.M2Bckd, Mshdict=tfd.M2Mshd, Sdict=tfd.M2Sd, LegDict=tfd.M2Legd, draw=True, a4=False, Test=True): - if Test: - assert M2.Id.Cls=='Mesh2D', "Arg M2 must be a Mesh2D instance !" - assert all([ax is None or isinstance(ax,plt.Axes) for ax in [ax1,ax2,ax3,axcb]]), "Arg ax1,ax2,ax3,axcb must be a plt.Axes instance !" - assert all([type(dd) is dict for dd in [Bckdict,Mshdict]]), "Args Bckdict, Mshdict must be dict !" - assert type(LegDict) is dict or LegDict is None, "Arg LegDict must be a dict !" - assert type(Elt) is str, "Arg Elt must be a str !" - assert not ('S' in Elt and 'V' in Elt), "Cannot plot simultaneously the surface and the volume !" - - if not SubMesh is None: - M2 = M2._SubMesh[SubMesh]['Mesh2D'] - - if Leg is None: - Leg = M2.Id.NameLTX - - if None in [ax1,ax2,ax3,axcb]: - ax1, ax2, ax3, axcb = tfd.Plot_Res_Mesh2D_DefAxes(a4=a4, VType=M2.Id.Type) - - if 'M' in Elt or 'B' in Elt: - ax1 = Mesh2D_Plot(M2, ax=ax1, Leg=Leg, Elt=Elt, Bckdict=Bckdict, Mshdict=Mshdict, LegDict=None, draw=False, a4=False, Test=False) - - # Plotting surface resolution - if 'S' in Elt or 'V' in Elt: - assert not (M2.Id.Type=='Lin' and 'V' in Elt), "Cannot plot VolAng if not a 'Tor' Type !" - patch = [] - quant = M2.Surfs*1e4 if 'S' in Elt else M2.VolAngs*1e6 - ylab = r"S ($cm^2$)" if 'S' in Elt else r"VolAng ($cm^3/sr$)" - for ii in range(0,M2.NCents): - Rk = np.unique(M2.Knots[0,M2._Cents_Knotsind[:,ii]]) - Zk = np.unique(M2.Knots[1,M2._Cents_Knotsind[:,ii]]) - patch.append(patches.Polygon(np.array([[Rk[0], Zk[0]], [Rk[1], Zk[0]], [Rk[1], Zk[1]], [Rk[0], Zk[1]]]), True)) - ppp = PcthColl(patch, **Sdict) - ppp.set_array(quant) - CNb = ax1.add_collection(ppp) - cbar = plt.colorbar(CNb, cax=axcb) - axcb.set_ylabel(ylab) - - # Plotting 1D resolution - ResRB, ResRM = np.diff(M2.MeshX1.Knots), np.diff(np.unique(M2.Knots[0,:])) - ResZB, ResZM = np.diff(M2.MeshX2.Knots), np.diff(np.unique(M2.Knots[1,:])) - Eps = min(np.min(ResRB),np.min(ResZB))/1000. - - ResRXB = np.array([M2.MeshX1.Knots[:-1]+Eps, M2.MeshX1.Knots[1:]-Eps]).T - ResZXB = np.array([M2.MeshX2.Knots[:-1]+Eps, M2.MeshX2.Knots[1:]-Eps]).T - ResRYB = np.array([ResRB,ResRB]).T - ResZYB = np.array([ResZB,ResZB]).T - - ResRXM = np.array([np.unique(M2.Knots[0,:])[:-1]+Eps, np.unique(M2.Knots[0,:])[1:]-Eps]).T - ResZXM = np.array([np.unique(M2.Knots[1,:])[:-1]+Eps, np.unique(M2.Knots[1,:])[1:]-Eps]).T - ResRYM = np.array([ResRM,ResRM]).T - ResZYM = np.array([ResZM,ResZM]).T - - ax2.plot(ResZYB.flatten(), ResZXB.flatten(), label=Leg+' Z-Res Bckgrd', **Bckdict) - ax2.plot(ResZYM.flatten(), ResZXM.flatten(), label=Leg+' Z-Res Mesh', **Mshdict) - ax3.plot(ResRXB.flatten(), ResRYB.flatten(), label=Leg+' R-Res Bckgrd', **Bckdict) - ax3.plot(ResRXM.flatten(), ResRYM.flatten(), label=Leg+' R-Res Mesh', **Mshdict) - ax1.figure.canvas.draw() - ax2.set_ylim(ax1.get_ylim()) - ax3.set_xlim(ax1.get_xlim()) - if not LegDict is None: - ax1.legend(**LegDict) - if draw: - ax1.figure.canvas.draw() - return ax1, ax2, ax3, axcb - - - - - - - - - - - - - - - - - - - - - - - - -""" -############################################################################### -############################################################################### - B-spline definitions -############################################################################### -""" - - -############################################ -##### Plotting functions -############################################ - - -def Plot_BSpline1D(Knots, FTot, LF, Elt='TL', ax='None', Name='', SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, LFdict=tfd.BF1Fd, Totdict=tfd.BF1Totd, LegDict=tfd.TorLegd, Test=True): - if Test: - assert ax=='None' or isinstance(ax,plt.Axes), "Arg ax must be a plt.Axes instance !" - assert type(Elt) is str, "Arg Elt must be a str !" - assert hasattr(FTot, '__call__') or FTot is None, "Arg FTot must be a function !" - assert (type(LF) is list and all([hasattr(ff,'__call__') for ff in LF])) or LF is None, "Arg BS must be a list of functions !" - assert type(LFdict) is dict, "Arg LFdict must be a dict !" - assert type(Totdict) is dict, "Arg Totdict must be a dict !" - - X = Calc_SumMeshGrid1D(Knots, SubP=SubP, SubMode=SubMode, Test=Test) - if ax=='None': - ax = tfd.Plot_BSpline_DefAxes('1D') - - if 'L' in Elt and not LF is None: - NBS = len(LF) - nx = X.size - Xplot = np.dot(np.ones((NBS,1)),X.reshape((1,nx))) - Y = np.nan*np.ones((NBS,nx)) - for ii in range(0,NBS): - Y[ii,:] = LF[ii](X) - ax.plot(Xplot.T, Y.T, **LFdict) - if 'T' in Elt and not FTot is None: - ax.plot(X, FTot(X), label=Name+' Tot', **Totdict) - - ax.set_xlim(np.min(X),np.max(X)) - if not LegDict is None: - ax.legend(**LegDict) - ax.figure.canvas.draw() - return ax - - - -def Plot_BSpline2D(BF2, ax='None', Elt='T', Deriv=0, Coefs=1., DVect=tfd.BF2_DVect_DefR, NC=tfd.BF2PlotNC, PlotMode=tfd.BF2PlotMode, SubP=tfd.BF2PlotSubP, SubMode=tfd.BF2PlotSubMode, Name='Tot', Totdict=tfd.BF2PlotTotd, LegDict=tfd.TorLegd, Test=True): - if Test: - assert ax=='None' or isinstance(ax,plt.Axes), "Arg ax must be a plt.Axes instance !" - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert type(Totdict) is dict, "Arg Totdict must be a dict !" - assert type(PlotMode) is str and PlotMode in ['contour','contourf','surf'], "Arg PlotMode must be in ['contour','contourf','surf'] !" - if type(Coefs) in [int,float]: - Coefs = Coefs*np.array((BF2._NFunc),dtype=float) - - Xplot, Yplot, nx, ny = BF2.get_XYplot(SubP=SubP, SubMode=SubMode) - PointsRZ = np.array([Xplot.flatten(),Yplot.flatten()]) - ind = BF2.Mesh.isInside(PointsRZ) - - Val = BF2.get_TotVal(PointsRZ,Deriv=Deriv,Coefs=Coefs,DVect=DVect, Test=Test) - Val[~ind] = np.nan - Val = Val.reshape(Xplot.shape) - - if PlotMode=='surf': - if ax=='None': - ax = tfd.Plot_BSpline_DefAxes('3D') - if 'T' in Elt: - ax.plot_surface(Xplot,Yplot,Val, label=Name, **Totdict) - else: - if ax=='None': - ax = tfd.Plot_BSpline_DefAxes('2D') - if PlotMode=='contour': - if 'T' in Elt: - ax.contour(Xplot,Yplot,Val, NC, label=Name, **Totdict) - elif PlotMode=='contourf': - if 'T' in Elt: - CC = ax.contourf(Xplot,Yplot,Val, NC, label=Name, **Totdict) - plt.colorbar(CC) - if not LegDict is None: - ax.legend(**LegDict) - ax.figure.canvas.draw() - return ax - - -def Plot_BSpline2D_Ind(BF2, Ind, ax='None', Elt='LPS', Coefs=1., NC=tfd.BF2PlotNC, PlotMode=tfd.BF2PlotMode, SubP=tfd.BF2PlotSubP, SubMode=tfd.BF2PlotSubMode, Name='Tot', Totdict=tfd.BF2PlotTotd, Sdict=tfd.BF2PlotIndSd, Pdict=tfd.BF2PlotIndPd, LegDict=tfd.TorLegd, Colorbar=True, Test=True): - if Test: - assert ax=='None' or isinstance(ax,plt.Axes), "Arg ax must be a plt.Axes instance !" - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert type(Totdict) is dict, "Arg Totdict must be a dict !" - assert type(PlotMode) is str and PlotMode in ['contour','contourf'], "Arg PlotMode must be in ['contour','contourf'] !" - - if type(Coefs) is float: - Coefs = Coefs*np.ones((BF2.NFunc,)) - - NInd = Ind.size - if ax=='None': - ax = tfd.Plot_BSpline_DefAxes('2D') - - if 'L' in Elt or 'S' in Elt: - Poly = BF2._get_Func_Supps() - Poly = [plg.Polygon(Poly[ii].T) for ii in Ind] - for ii in range(1,Ind.size): - Poly[0] = Poly[0] + Poly[ii] - Poly = Poly[0] - NPoly = len(Poly) - - if 'S' in Elt: # Plot support - NPoly = len(Poly) - patch = [patches.Polygon(np.array(Poly.contour(ii)), True) for ii in range(0,NPoly)] - ppp = PcthColl(patch, **Sdict) - ax.add_collection(ppp) - - if 'P' in Elt: # Plot Points of max value - PP = BF2._Func_MaxPos[:,Ind] - ax.plot(PP[0,:],PP[1,:], label=Name+' PMax', **Pdict) - - if 'L' in Elt: # Plot local value as contour or contourf - Hull = np.concatenate(tuple([np.array(Poly.contour(ii)) for ii in range(0,NPoly)]),axis=0) - MinR, MaxR = np.min(Hull[:,0]), np.max(Hull[:,0]) - MinZ, MaxZ = np.min(Hull[:,1]), np.max(Hull[:,1]) - - indKR = np.logical_and(BF2._Mesh._MeshR._Knots>=MinR,BF2._Mesh._MeshR._Knots<=MaxR) - indKZ = np.logical_and(BF2._Mesh._MeshZ._Knots>=MinZ,BF2._Mesh._MeshZ._Knots<=MaxZ) - KnotsR, KnotsZ = BF2._Mesh._MeshR._Knots[indKR], BF2._Mesh._MeshZ._Knots[indKZ] - Xplot, Yplot = Calc_SumMeshGrid2D(KnotsR, KnotsZ, SubP=SubP, SubMode=SubMode, Test=True) - nx, ny = Xplot.size, Yplot.size - Xplot, Yplot = np.dot(np.ones((ny,1)),Xplot.reshape((1,nx))), np.dot(Yplot.reshape((ny,1)),np.ones((1,nx))) - PointsRZ = np.array([Xplot.flatten(),Yplot.flatten()]) - - Val = np.sum(np.concatenate(tuple([Coefs[Ind[ii]]*BF2._LFunc[Ind[ii]](PointsRZ).reshape((1,PointsRZ.shape[1])) for ii in range(0,NInd)]),axis=0),axis=0) - indIn = np.array([Poly.isInside(PointsRZ[0,jj],PointsRZ[1,jj]) for jj in range(0,PointsRZ.shape[1])], dtype=bool) - Val[~indIn] = np.nan - Val = Val.reshape(Xplot.shape) - if PlotMode=='contour': - cc = ax.contour(Xplot,Yplot,Val, NC, label=Name, **Totdict) - elif PlotMode=='contourf': - cc = ax.contourf(Xplot,Yplot,Val, NC, label=Name, **Totdict) - if Colorbar: - plt.colorbar(cc,ax=ax,orientation='vertical', anchor=(0.,0.), panchor=(1.,0.), shrink=0.65) - - if not LegDict is None: - ax.legend(**LegDict) - ax.figure.canvas.draw() - return ax - - - -""" - -def Plot_BSpline2D_mlab(KnotsMultX, KnotsMultY, BSX, BSY, ax1='None', ax2='None',SubP=0.1, SubMode='Rel', BSDict=BS2Dict_Def, TotDict=Tot2Dict_Def): - assert isinstance(KnotsMultX,np.ndarray) and KnotsMultX.ndim==1, "Arg KnotsMultX must be a 1-dim np.ndarray !" - assert isinstance(KnotsMultY,np.ndarray) and KnotsMultY.ndim==1, "Arg KnotsMultY must be a 1-dim np.ndarray !" - assert ax1=='None' or isinstance(ax1,plt.Axes), "Arg ax1 must be a plt.Axes instance !" - assert ax2=='None' or isinstance(ax2,plt.Axes), "Arg ax2 must be a plt.Axes instance !" - assert type(SubP) is float, "Arg SubP must be a float !" - assert SubMode=='Rel' or SubMode=='Abs', "Arg SubMode must be 'Rel' or 'Abs' !" - assert type(BSX) is list, "Arg BSX must be a list of functions !" - assert type(BSY) is list, "Arg BSY must be a list of functions !" - assert type(BSDict) is dict, "Arg BSDict must be a dict !" - assert type(TotDict) is dict, "Arg TotDict must be a dict !" - - NBSX, NBSY = len(BSX), len(BSY) - NBS = NBSX*NBSY - KnotsUniqX, KnotsUniqY = np.unique(KnotsMultX), np.unique(KnotsMultY) - nKnotsX, nKnotsY = KnotsUniqX.size, KnotsUniqY.size - X, Y = KnotsUniqX, KnotsUniqY - - if SubMode=='Abs': - subX, subY = int(round((X[-1]-X[0])/SubP)), int(round((Y[-1]-Y[0])/SubP)) - X = np.linspace(X[0],X[-1],subX,endpoint=True) - Y = np.linspace(Y[0],Y[-1],subY,endpoint=True) - else: - X, Y = X.reshape((1,nKnotsX)), Y.reshape((1,nKnotsY)) - X, Y = np.concatenate((X[:,:-1],X[:,1:]),axis=0), np.concatenate((Y[:,:-1],Y[:,1:]),axis=0) - sub = int(round(1./SubP)) - dd = np.delete(np.linspace(0,1,sub,endpoint=False),0) - Xtemp = np.dot(np.ones((sub-1,1)),X[0:1,:]) + np.dot(dd.reshape((sub-1,1)), np.diff(X,axis=0)) - Ytemp = np.dot(np.ones((sub-1,1)),Y[0:1,:]) + np.dot(dd.reshape((sub-1,1)), np.diff(Y,axis=0)) - X, Y = np.concatenate((X[0:1,:],Xtemp,X[1:2,:]),axis=0), np.concatenate((Y[0:1,:],Ytemp,Y[1:2,:]),axis=0) - X, Y = np.unique(X.T.flatten()), np.unique(Y.T.flatten()) - nx, ny = X.size, Y.size - Xplot, Yplot = np.dot(np.ones((ny,1)),X.reshape((1,nx))), np.dot(Y.reshape((ny,1)),np.ones((1,nx))) - - Z = np.nan*np.ones((ny,nx,NBS)) - for ii in range(0,NBSX): - for jj in range(0,NBSY): - Z[:,:,(ii-1)*NBSX+jj] = BSX[ii](Xplot)*BSY[jj](Yplot) - - if ax1=='None' or ax2=='None': - f = Plot_BSpline_2Dmlab_DefFig() - - for ii in range(0,NBS): - ax1.plot_surface(Xplot,Yplot,Z[:,:,ii], **BSDict) - - ax2.plot_surface(Xplot,Yplot,np.sum(Z,axis=2), label='Tot', **TotDict) - f.draw() - return ax1, ax2 -""" - - -""" -############################################################################### -############################################################################### - MeshBase Objects and properties -############################################################################### -""" - - -class BF1D(object): - def __init__(self, Id, Mesh, Deg, dtime=None): - self.set_Id(Id,Deg=Deg, dtime=dtime) - self.set_Mesh(Mesh,Deg=Deg) - - @property - def Mesh(self): - """Return the knots""" - return self._Mesh - @Mesh.setter - def Mesh(self,Val): - """Set a new Knot vector and recompute all subsequent attributes""" - self.set_Mesh(Val) - @property - def Deg(self): - return self._Deg - @Deg.setter - def Deg(self,Val): - self.set_BF(Deg=Val) - - # Read-only attributes - @property - def Id(self): - """Return the Id""" - return self._Id - - def set_Id(self,Id,Deg=Deg, dtime=None): - assert type(Id) is str or isinstance(Id,TFPF.ID), "Arg Id should be string or an TFPF.ID instance !" - if type(Id) is str: - Id = TFPF.ID('BF1D',Id+'_D{0:01.0f}'.format(Deg), dtime=dtime) - self._Id = Id - - def set_Mesh(self,Mesh,Deg=None): - assert isinstance(Mesh,Mesh1D), "Arg Mesh must be a Mesh1D instance !" - self._Mesh = Mesh - self.set_BF(Deg=Deg) - - def set_BF(self,Deg=None): - assert Deg is None or (type(Deg) is int and Deg>=0 and Deg<=2), "Arg Deg must be a int with Deg>=0 and Deg<=2 !" - if not Deg is None: - self._Deg = Deg - self._LFunc, self._Func_Knotsind, self._Func_Centsind, self._Knots_Funcind, self._Cents_Funcind, self._Func_MaxPos = BSpline_LFunc(self._Deg, self._Mesh._Knots) - #self._LFunc, self._Func_Knotsind, indlK, self._Func_PMax = BSpline(self._Deg, self._Mesh._Knots) - self._NFunc = len(self._LFunc) - - def _get_Func_Supps(self): - Knots = self._Mesh._Knots[self._Func_Knotsind] - return np.array([Knots.min(axis=0),Knots.max(axis=0)]) - - def _get_Func_InterFunc(self): - if self._Deg==0: - return np.empty((0,)) - indF = np.empty((2*self._Deg+1,self._NFunc)) - return indF - - def get_TotFunc(self, Deriv=0, Coefs=1., Test=True): - return BSpline_TotFunc(self._Deg, self._Knots, Deriv=Deriv, Coefs=Coefs, Test=Test) - - def get_TotVal(self, Points, Deriv=0, Coefs=1., Test=True): - TF = BSpline_get_TotFunc(self.Deg, self.Mesh.Knots, Deriv=Deriv, Coefs=Coefs, Test=Test) - return Val - - def get_Funcs(self, Deriv=0, Test=True): - return BSpline_LFunc(self._Deg, self._Mesh._Knots, Deriv=Deriv, Test=Test) - - def get_Coefs(self,xx=None,yy=None,ff=None, SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, Test=True): - assert not all([xx is None or yy is None, ff is None]), "You must provide either a function (ff) or sampled data (xx and yy) !" - - if not ff is None: - xx = Calc_SumMeshGrid1D(self.Mesh.Knots, SubP=SubP, SubMode=SubMode, Test=Test) - yy = ff(xx) - - # Keep only points inside the Boundary - ind = np.logical_and(xx>=np.min(self.Mesh.Knots), xx<=np.max(self.Mesh.Knots)) - xx, yy = xx[ind], yy[ind] - - A = Calc_BF1D_Weights(self.LFunc, xx, Test=False) - Coefs, res, rank, sing = np.linalg.lstsq(A,yy) - if rank < self.NFunc: - xx1 = Calc_SumMeshGrid1D(self.Mesh.Knots, SubP=SubP, SubMode=SubMode, Test=Test) - yy1 = scpinterp.interp1d(xx, yy, kind='linear', bounds_error=False, fill_value=0., assume_sorted=True)(xx1) - xx, yy = np.concatenate((xx,xx1)), np.concatenate((yy,yy1)) - xx, ind = np.unique(xx, return_index=True) - yy = yy[ind] - A = Calc_BF1D_Weights(self.LFunc, xx, Test=False) - Coefs, res, rank, sing = np.linalg.lstsq(A,yy) - return Coefs, res - - def get_IntOp(self, Deriv=0, Sparse=tfd.L1IntOpSpa, SpaFormat=tfd.L1IntOpSpaFormat, Test=True): - return Calc_IntOp_BSpline(self.Mesh.Knots, self.Deg, Deriv=Deriv, Sparse=Sparse, SpaFormat=SpaFormat, Test=Test) - - def get_IntVal(self, Deriv=0, Coefs=1., Test=True): - A, m = Calc_IntOp_BSpline(self.Mesh.Knots, self.Deg, Deriv=Deriv, Sparse=True, Test=Test) - if type(Coefs) is float: - Coefs = Coefs*np.ones((self.NFunc,)) - if m==0: - Int = A.dot(Coefs) - elif m==1: - Int = Coefs.dot(A.dot(Coefs)) - else: - print 'Not coded yet !' - return Int - - def plot(self, ax='None', Coefs=1., Deriv=0, Elt='TL', SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, LFdict=tfd.BF1Fd, Totdict=tfd.BF1Totd, LegDict=tfd.TorLegd, Test=True): - if type(Coefs) is float: - Coefs = Coefs*np.ones((self.NFunc,)) - if 'T' in Elt: - TotF = BSpline_get_TotFunc(self.Deg, self.Mesh.Knots, Deriv=Deriv, Coefs=Coefs, Test=Test) - else: - TotF = None - if (type(Deriv) is int or Deriv in ['D0','D1','D2','D3']) and 'L' in Elt: - if not type(Deriv) is int: - Deriv = int(Deriv[1]) - LF1 = BSplineDeriv(self.Deg, self.Mesh.Knots, Deriv=Deriv, Test=Test) - LF = [lambda x,Coefs=Coefs,ii=ii: Coefs[ii]*LF1[ii](x) for ii in range(0,len(LF1))] - else: - LF = None - return Plot_BSpline1D(self.Mesh.Knots, TotF, LF, ax=ax, Elt=Elt, Name=self.Id.Name+' '+str(Deriv), SubP=SubP, SubMode=SubMode, LFdict=LFdict, Totdict=Totdict, LegDict=LegDict, Test=Test) - - def plot_Ind(self, ax='None', Ind=0, Coefs=1., Elt='LCK', y=0., SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, LFdict=tfd.BF1Fd, Kdict=tfd.M2Kd, Cdict=tfd.M2Cd, LegDict=tfd.TorLegd, Test=True): - assert type(Ind) in [int,list,np.ndarray], "Arg Ind must be a int, a list of int or a np.ndarray of int or booleans !" - if type(Ind) is int: - Ind = [Ind] - NInd = len(Ind) - elif type(Ind) is list: - NInd = len(Ind) - elif type(Ind) is np.ndarray: - assert (np.issubdtype(Ind.dtype,bool) and Ind.size==self.NFunc) or np.issubdtype(Ind.dtype,int), "Arg Ind must be a np.ndarray of boolenas with size==self.NFunc or a np.ndarray of int !" - NInd = Ind.size - - if type(Coefs) is float: - Coefs = Coefs*np.ones((self.NFunc,)) - if 'L' in Elt: - LF1 = BSplineDeriv(self.Deg, self.Mesh.Knots, Deriv=0, Test=Test) - LF = [lambda x,Coefs=Coefs,ii=ii: Coefs[Ind[ii]]*LF1[Ind[ii]](x) for ii in range(0,NInd)] - ax = Plot_BSpline1D(self.Mesh.Knots, None, LF, ax=ax, Elt=Elt, Name=self.Id.Name, SubP=SubP, SubMode=SubMode, LFdict=LFdict, LegDict=LegDict, Test=Test) - if 'C' in Elt or 'K' in Elt: - Cents = self.Mesh.Cents[self.Func_Centsind[:,Ind]].flatten() - Knots = self.Mesh.Knots[self.Func_Knotsind[:,Ind]].flatten() - ax = Plot_Mesh1D(Knots, Cents=Cents, y=y, Elt=Elt, Name=self.Id.NameLTX, ax=ax, Kdict=Kdict, Cdict=Cdict, LegDict=LegDict, Test=Test) - return ax - - def save(self,SaveName=None,Path=None,Mode='npz'): - if Path is None: - Path = self.Id.SavePath - else: - assert type(Path) is str, "Arg Path must be a str !" - self._Id.SavePath = Path - if SaveName is None: - SaveName = self.Id.SaveName - else: - assert type(SaveName) is str, "Arg SaveName must be a str !" - self.Id.SaveName = SaveName - Ext = '.npz' if 'npz' in Mode else '.pck' - TFPF.save(self, Path+SaveName+Ext) - - - -class BF2D(object): - - def __init__(self, Id, Mesh, Deg, dtime=None): - self.set_Id(Id,Deg=Deg, dtime=dtime) - self.set_Mesh(Mesh,Deg=Deg) - - @property - def Id(self): - return self._Id - @property - def Mesh(self): - return self._Mesh - @Mesh.setter - def Mesh(self,Val): - self.set_Mesh(Val) - @property - def Deg(self): - return self._Deg - @Deg.setter - def Deg(self,Val): - self.set_BF(Deg=Val) - @property - def NFunc(self): - return self._NFunc - - @property - def Surf(self): - indin = np.any(~np.isnan(self._Cents_Funcind),axis=0) - return np.sum(self.Mesh._Surfs[indin]) - - def set_Id(self,Id,Deg=Deg, dtime=None): - assert type(Id) is str or isinstance(Id,TFPF.ID), "Arg Id should be string or an TFPF.ID instance !" - if type(Id) is str: - Id = TFPF.ID('BF2D',Id+'_D{0:01.0f}'.format(Deg), dtime=dtime) - self._Id = Id - - def set_Mesh(self,Mesh,Deg=None): - assert isinstance(Mesh,Mesh2D), "Arg Mesh must be a Mesh2D instance !" - self._Mesh = Mesh - self.set_BF(Deg=Deg) - - def set_BF(self,Deg=None): - assert Deg is None or type(Deg) is int, "Arg Deg must be a int !" - if not Deg is None: - self._Deg = Deg - BSR, RF_Kind, RF_Cind, RK_Find, RC_Find, RMaxPos = BSpline_LFunc(self._Deg, self._Mesh._MeshR._Knots) - BSZ, ZF_Kind, ZF_Cind, ZK_Find, ZC_Find, ZMaxPos = BSpline_LFunc(self._Deg, self._Mesh._MeshZ._Knots) - nBR, nBZ = len(BSR), len(BSZ) - Func, F_Kind, F_Cind, F_MaxPos = [], [], [], [] - - CentBckg, indCentBckInMesh, NumCentBck = self._Mesh._get_CentBckg() - NCperF, NKperF = (self._Deg+1)**2, (self._Deg+2)**2 - for ii in range(0,nBZ): - for jj in range(0,nBR): - inds = ZF_Cind[:,ii].reshape((ZF_Cind.shape[0],1))*self._Mesh._MeshR._NCents + RF_Cind[:,jj] - if np.all(indCentBckInMesh[inds]): - Func.append(lambda RZ, ii=ii,jj=jj: BSR[jj](RZ[0,:])*BSZ[ii](RZ[1,:])) - F_Cind.append(NumCentBck[inds].reshape(NCperF,1).astype(int)) - F_Kind.append(np.unique(self._Mesh._Cents_Knotsind[:,F_Cind[-1][:,0]]).reshape(NKperF,1)) - F_MaxPos.append(np.array([[RMaxPos[jj]],[ZMaxPos[ii]]])) - self._LFunc = Func - self._NFunc = len(Func) - self._Func_Knotsind = np.concatenate(tuple(F_Kind),axis=1) - self._Func_Centsind = np.concatenate(tuple(F_Cind),axis=1) - self._Func_MaxPos = np.concatenate(tuple(F_MaxPos),axis=1) - self._Cents_Funcind = self._get_Cents_Funcind(Init=True) - self._Knots_Funcind = self._get_Knots_Funcind(Init=True) - self._Func_InterFunc = self._get_Func_InterFunc(Init=True) - - def _get_Cents_Funcind(self,Init=True): # To be updated with ability to select fraction of BF - Cent_indFunc = np.nan*np.ones(((self._Deg+1)**2,self._Mesh._NCents)) - for ii in range(0,self._Mesh._NCents): - inds = np.any(self._Func_Centsind==ii,axis=0) - Cent_indFunc[:inds.sum(),ii] = inds.nonzero()[0] - return Cent_indFunc - - def _get_Knots_Funcind(self,Init=True): # To be updated with ability to select fraction of BF - Knots_indFunc = np.nan*np.ones(((self._Deg+2)**2,self._Mesh._NKnots)) - for ii in range(0,self._Mesh._NKnots): - inds = np.any(self._Func_Knotsind==ii,axis=0) - Knots_indFunc[:inds.sum(),ii] = inds.nonzero()[0] - return Knots_indFunc - - def _get_Func_InterFunc(self,Init=True): # To be updated with ability to select fraction of BF - Func_InterFunc = np.nan*np.ones(((2*self._Deg+1)**2-1,self._NFunc)) - for ii in range(0,self.NFunc): - ind = self._Cents_Funcind[:,self._Func_Centsind[:,ii]].flatten() - ind = np.unique(ind[~np.isnan(ind)]) - ind = np.delete(ind,(ind==ii).nonzero()[0]) - Func_InterFunc[:ind.size,ii] = ind.astype(int) - return Func_InterFunc - - def _get_Func_InterFunc(self, Init=False, indFin=None): # To be updated with ability to select fraction of BF - assert indFin is None or (isnstance(indFin,np.ndarray) and indFin.dtype.name in ['bool','int32','int64','int']), "Arg indFin must be None or a np.naddary of bool or int !" - if indFin is None and not Init: - return self._Func_InterFunc - elif indFin is None: - indFin = np.arange(0,self._NFunc) - if indFin.dtype.name=='bool': - indFin = indFin.nonzero()[0] - NF = indFin.size - Func_InterFunc = np.nan*np.ones(((2*self._Deg+1)**2-1,NF)) # Update in progress from here... - for ii in range(0,NF): - ind = self._Cents_Funcind[:,self._Func_Centsind[:,ii]].flatten() - ind = np.unique(ind[~np.isnan(ind)]) - ind = np.delete(ind,(ind==ii).nonzero()[0]) - Func_InterFunc[:ind.size,ii] = ind.astype(int) - return Func_InterFunc - - def _get_quadPoints(self): - R = self._Mesh._Knots[0,self._Func_Knotsind] - Z = self._Mesh._Knots[1,self._Func_Knotsind] - QuadR, QuadZ = np.zeros((self._Deg+2,self._NFunc)), np.zeros((self._Deg+2,self._NFunc)) - for ii in range(0,self._NFunc): - QuadR[:,ii] = np.unique(R[:,ii]) - QuadZ[:,ii] = np.unique(Z[:,ii]) - return QuadR, QuadZ - - def _get_Func_SuppBounds(self): - Func_SuppRZ = np.nan*np.ones((4,self._NFunc)) - RKnots = self._Mesh._Knots[0,self._Func_Knotsind] - ZKnots = self._Mesh._Knots[1,self._Func_Knotsind] - Func_SuppRZ = np.concatenate((RKnots.min(axis=0,keepdims=True), np.max(RKnots,axis=0,keepdims=True), np.min(ZKnots,axis=0,keepdims=True), np.max(ZKnots,axis=0,keepdims=True)),axis=0) - return Func_SuppRZ - - def _get_Func_Supps(self): - R = self._Mesh._Knots[0,self._Func_Knotsind] - Z = self._Mesh._Knots[1,self._Func_Knotsind] - R = np.array([np.min(R,axis=0),np.max(R,axis=0)]) - Z = np.array([np.min(Z,axis=0),np.max(Z,axis=0)]) - return [np.array([[R[0,ii],R[1,ii],R[1,ii],R[0,ii],R[0,ii]],[Z[0,ii],Z[0,ii],Z[1,ii],Z[1,ii],Z[0,ii]]]) for ii in range(0,self._NFunc)] - - def get_SubBFPolygon_indin(self, Poly, NLim=3, Out=bool): - assert Out in [bool,int], "Arg Out must be in [bool,int] !" - indMeshout = ~self.Mesh.get_SubMeshPolygon(Poly, NLim=NLim, Out=bool) - indFout = self._Cents_Funcind[:,indMeshout] - indFout = np.unique(indFout[~np.isnan(indFout)]).astype(int) - indF = np.ones((self.NFunc,),dtype=bool) - indF[indFout] = False - if Out==int: - indF = indF.nonzero()[0] - return indF - - def get_SubBFPolygonind(self, Poly=None, NLim=3, indFin=None): - assert indFin is None or (isinstance(indFin,np.ndarray) and indFin.dtype.name in ['bool','int','int32','int64']), "Arg indFin must be None or a np.ndarray of bool or int !" - assert (not indFin is None and Poly is None) or (indFin is None and isinstance(Poly,np.ndarray) and Poly.ndim==2 and Poly.shape[0]==2), "If arg indFin is None, arg Poly must be a 2D np.ndarray instance !" - if indFin is None: - indFin = self.get_SubBFPolygon_indin(Poly, NLim=NLim, Out=int) - if indFin.dtype.name=='bool': - indFin = indFin.nonzero()[0] - IndMin = np.unique(self._Func_Centsind[:,indFin].flatten()) - Id, IdM = self.Id, self.Mesh.Id - Id._Name, IdM._Name = Id._Name+'_SubBF', Id._Name+'_SubMesh' - M = Mesh2D(IdM, self.Mesh, IndMin) - return BF2D(Id, M, self.Deg, self.Id.dtime) - - def get_TotFunc_FixPoints(self, Points, Deriv=0, Test=True): - assert Deriv in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Gauss','D2-Mean','D2N2-Lapl','D2N2-Vect'], "Arg Deriv must be in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Gauss','D2-Mean','D2N2-Lapl','D2N2-Vect'] !" - if Deriv in [0,'D0']: - AA, m = BF2D_get_Op(self, Points, Deriv=Deriv, Test=Test) - def FF(Coefs,AA=AA): - return AA.dot(Coefs) - elif Deriv in [1,2,'D1','D2']: - AA, m = BF2D_get_Op(self, Points, Deriv=Deriv, Test=Test) - def FF(Coefs, DVect,AA=AA): - dvR = np.hypot(DVect[0,:],DVect[1,:]) - return dvR*AA[0].dot(Coefs) + DVect[2,:]*AA[1].dot(Coefs) - elif Deriv == 'D0N2': - try: - AA, m = BF2D_get_Op(self, Points, Deriv=Deriv, Test=Test) - def FF(Coefs,AA=AA): - return Coefs.dot(AA.dot(Coefs)) - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv=0, Test=Test) - def FF(Coefs,AA=AA): - return AA.dot(Coefs)*AA.dot(Coefs) - elif Deriv=='D2-Gauss': - try: - AA, m = BF2D_get_Op(self, Points, Deriv=2, Test=Test) - BB, n = BF2D_get_Op(self, Points, Deriv='D2N2', Test=Test) - CC, n = BF2D_get_Op(self, Points, Deriv='D1N2', Test=Test) - AA, BB, CC = (AA[0],AA[1]), BB[2], CC[0]+CC[1] - def FF(Coefs, AA=AA, BB=BB, CC=CC): - return (AA[0].dot(Coefs) * AA[1].dot(Coefs) - Coefs.dot(BB.dot(Coefs))) / (1. + Coefs.dot(CC.dot(Coefs)))**2 - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv=2, Test=Test) - BB, n = BF2D_get_Op(self, Points, Deriv=1, Test=Test) - def FF(Coefs, AA=AA, BB=BB): - return (AA[0].dot(Coefs) * AA[1].dot(Coefs) - (AA[2].dot(Coefs))**2) / (1. + (BB[0].dot(Coefs))**2+(BB[1].dot(Coefs))**2)**2 - elif Deriv=='D2-Mean': - try: - AA, m = BF2D_get_Op(self, Points, Deriv=1, Test=Test) - BB, n = BF2D_get_Op(self, Points, Deriv='D1N2', Test=Test) - CC, p = BF2D_get_Op(self, Points, Deriv=2, Test=Test) - CC = (CC[0],CC[1],CC[2]) - def FF(Coefs,AA=AA,BB=BB,CC=CC): - return ( (1.+Coefs.dot(BB[0].dot(Coefs)))*CC[1].dot(Coefs) - 2.*AA[0].dot(Coefs)*AA[1].dot(Coefs)*CC[2].dot(Coefs) + (1.+Coefs.dot(BB[1].dot(Coefs)))*CC[0].dot(Coefs) ) / (2.*(1. + Coefs.dot((BB[0]+BB[1]).dot(Coefs)))**1.5) - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv=2, Test=Test) - BB, n = BF2D_get_Op(self, Points, Deriv=1, Test=Test) - def FF(Coefs,AA=AA,BB=BB): - return ( (1.+(BB[0].dot(Coefs))**2)*AA[1].dot(Coefs) - 2.*BB[0].dot(Coefs)*BB[1].dot(Coefs)*AA[2].dot(Coefs) + (1.+(BB[1].dot(Coefs))**2)*AA[0].dot(Coefs) ) / (2.*(1. + BB[0].dot(Coefs)**2+(BB[1].dot(Coefs))**2)**1.5) - else: - if 'D1' in Deriv: - try: - AA, m = BF2D_get_Op(self, Points, Deriv='D1N2', Test=Test) - AA = AA[0]+AA[1] - if Deriv=='D1N2': - def FF(Coefs,AA=AA): - return Coefs.dot(AA.dot(Coefs)) - elif Deriv=='D1FI': - B, n = BF2D_get_Op(self, Points, Deriv='D0', Test=Test) - def FF(Coefs,AA=AA,B=B): - return Coefs.dot(AA.dot(Coefs))/B.dot(Coefs) - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv='D1', Test=Test) - if Deriv=='D1N2': - def FF(Coefs,AA=AA): - return (AA[0].dot(Coefs))**2 + (AA[1].dot(Coefs))**2 - elif Deriv=='D1FI': - B, n = BF2D_get_Op(self, Points, Deriv='D0', Test=Test) - def FF(Coefs,AA=AA,B=B): - return ((AA[0].dot(Coefs))**2 + (AA[1].dot(Coefs))**2)/B.dot(Coefs) - elif 'D2' in Deriv: - try: - AA, m = BF2D_get_Op(self, Points, Deriv='D2N2', Test=Test) - if Deriv=='D2N2-Lapl': - AA, B = AA[0]+AA[1], AA[3] - def FF(Coefs,AA=AA,B=B): - return Coefs.dot(AA.dot(Coefs)) + 2.*B.dot(Coefs) - elif Deriv=='D2N2-Vect': - AA = AA[0]+AA[1] - def FF(Coefs,AA=AA): - return Coefs.dot(AA.dot(Coefs)) - except MemoryError: - AA, m = BF2D_get_Op(self, Points, Deriv='D2', Test=Test) - AA = (AA[0],AA[1]) - if Deriv=='D2N2-Lapl': - def FF(Coefs,AA=AA): - return (AA[0].dot(Coefs))**2 + (AA[1].dot(Coefs))**2 + 2.*AA[0].dot(Coefs)*AA[1].dot(Coefs) - elif Deriv=='D2N2-Vect': - AA = (AA[0],AA[1]) - def FF(Coefs,AA=AA): - return (AA[0].dot(Coefs))**2 + (AA[1].dot(Coefs))**2 - return FF - - def get_TotFunc_FixCoefs(self, Deriv=0, DVect=tfd.BF2_DVect_DefR, Coefs=1., Test=True): - assert type(Coefs) in [int,float] or (isinstance(Coefs,np.ndarray) and Coefs.ndim==1 and Coefs.size==self._NFunc), "Arg Coefs must be a float or a (NF,) np.ndarray !" - return BF2D_get_TotFunc(self, Deriv=Deriv, DVect=DVect, Coefs=Coefs, Test=Test) - - def get_TotVal(self, Points, Deriv=0, DVect=tfd.BF2_DVect_DefR, Coefs=1., Test=True): - assert Deriv in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Gauss','D2-Mean','D2N2-Lapl','D2N2-Vect'], "Arg Deriv must be in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Gauss','D2-Mean','D2N2-Lapl','D2N2-Vect'] !" - if type(Coefs) in [int,float] or (isinstance(Coefs,np.ndarray) and Coefs.ndim==1): - Coefs = Coefs*np.ones((self._NFunc,)) - if Points.shape==2: - Points = np.array([Points[0,:],np.zeros((Points.shape[1],)), Points[1,:]]) - FF = self.get_TotFunc_FixPoints(Points, Deriv=Deriv, Test=Test) - if Coefs.ndim==1: - if Deriv in [1,2,'D1','D2']: - dvect = DVect(Points) - return FF(Coefs,dvect) - else: - return FF(Coefs) - else: - Nt = Coefs.shape[0] - Vals = np.empty((Nt,Points.shape[1])) - if Deriv in [1,2,'D1','D2']: - dvect = DVect(Points) - for ii in range(0,Nt): - Vals[ii,:] = FF(Coefs[ii,:], dvect) - else: - for ii in range(0,Nt): - Vals[ii,:] = FF(Coefs[ii,:]) - return Vals - - def get_Coefs(self,xx=None,yy=None, zz=None, ff=None, SubP=tfd.BF2Sub, SubMode=tfd.BF1SubMode, indFin=None, Test=True): # To be updated to take into account fraction of BF - assert not all([xx is None or yy is None, ff is None]), "You must provide either a function (ff) or sampled data (xx and yy) !" - assert indFin is None or (isnstance(indFin,np.ndarray) and indFin.dtype.name in ['bool','int32','int64','int']), "Arg indFin must be None or a np.naddary of bool or int !" - print self.Id.Name+" : Getting fit coefficients..." - if indFin is None: - indFin = np.arange(0,self.NFunc) - if indFin.dtype.name=='bool': - indFin = indFin.nonzero()[0] - - if not ff is None: - xx, yy, nx, ny = self.get_XYplot(SubP=SubP, SubMode=SubMode) # To update - xx, yy = xx.flatten(), yy.flatten() - zz = ff(RZ2Points(np.array([xx,yy]))) - else: - assert xx.shape==yy.shape==zz.shape, "Args xx, yy and zz must have same shape !" - xx, yy, zz = xx.flatten(), yy.flatten(), zz.flatten() - # Keep only points inside the Boundary - ind = self.Mesh.isInside(np.array([xx,yy])) - xx, yy, zz = xx[ind], yy[ind], zz[ind] - - AA, m = BF2D_get_Op(self, np.array([xx.flatten(),yy.flatten()]), Deriv=0, indFin=indFin, Test=Test) - Coefs, res, rank, sing = np.linalg.lstsq(AA,zz) - if rank < indFin.size: - xx1, yy1, nx1, ny1 = self.get_XYplot(SubP=SubP/2., SubMode=SubMode) - xx1, yy1 = xx1.flatten(), yy1.flatten() - ind = self._Mesh.isInside(np.array([xx1,yy1])) - xx1, yy1 = xx1[ind], yy1[ind] - zz1 = scpint.interp2d(xx, yy, zzz, kind='linear', bounds_error=False, fill_value=0)(xx1,yy1) - xx, yy, zz = np.concatenate((xx,xx1)), np.concatenate((yy,yy1)), np.concatenate((zz,zz1)) - AA, m = BF2D_get_Op(self, np.array([xx.flatten(),yy.flatten()]), Deriv=0, Test=Test) - Coefs, res, rank, sing = np.linalg.lstsq(AA,zz) - return Coefs, res - - def get_XYplot(self, SubP=tfd.BF2PlotSubP, SubMode=tfd.BF2PlotSubMode): - Xplot, Yplot = Calc_SumMeshGrid2D(self.Mesh._MeshR.Knots, self.Mesh._MeshZ.Knots, SubP=SubP, SubMode=SubMode, Test=True) - nx, ny = Xplot.size, Yplot.size - Xplot, Yplot = np.dot(np.ones((ny,1)),Xplot.reshape((1,nx))), np.dot(Yplot.reshape((ny,1)),np.ones((1,nx))) - return Xplot, Yplot, nx, ny - - def get_IntOp(self, Deriv=0, Mode=tfd.BF2IntMode, Sparse=tfd.L1IntOpSpa, SpaFormat=tfd.L1IntOpSpaFormat, Test=True): - print self.Id.Name+" : Getting integral operator "+str(Deriv) - return Calc_IntOp_BSpline2D(self, Deriv=Deriv, Mode=Mode, Sparse=Sparse, SpaFormat=SpaFormat, Test=Test) - - def get_IntVal(self, Deriv=0, Mode=tfd.BF2IntMode, Coefs=1., Test=True): - A, m = Calc_IntOp_BSpline2D(self, Deriv=Deriv, Mode=Mode, Sparse=True, Test=Test) - if type(Coefs) is float: - Coefs = Coefs*np.ones((self.NFunc,),dtype=float) - if Coefs.ndim==1: - if m==0: - Int = A.dot(Coefs) - elif m==1: - Int = Coefs.dot(A.dot(Coefs)) - elif m==2: - A = A[0]+A[1] - Int = Coefs.dot(A.dot(Coefs)) - else: - print 'Not coded yet !' - else: - Int = np.nan*np.ones((Coefs.shape[0],)) - if m==0: - for ii in range(0,Coefs.shape[0]): - Int[ii] = A.dot(Coefs[ii,:]) - elif m==1: - for ii in range(0,Coefs.shape[0]): - Int[ii] = Coefs[ii,:].dot(A.dot(Coefs[ii,:])) - elif m==2: - A = A[0]+A[1] - for ii in range(0,Coefs.shape[0]): - Int[ii] =Coefs[ii,:].dot(A.dot(Coefs[ii,:])) - else: - print 'Not coded yet !' - return Int - - def get_MinMax(self, Coefs=1., Ratio=0.05, SubP=0.004, SubP1=0.015, SubP2=0.001, TwoSteps=False, SubMode='abs', Deriv='D0', Test=True): # To be deprecated by get_Extrema() when implemented - return Get_MinMax(self, Coefs=Coefs, Ratio=Ratio, SubP=SubP, SubP1=SubP1, SubP2=SubP2, TwoSteps=TwoSteps, SubMode=SubMode, Deriv=Deriv, Test=Test) - - def get_Extrema(self, Coefs=1., Ratio=0.95, SubP=0.002, SubMode='abs', Deriv='D0', D1N2=True, D2N2=True): - return Get_Extrema(self, Coefs=Coefs, Ratio=Ratio, SubP=SubP, SubMode=SubMode, D1N2=D1N2, D2N2=D2N2) - - - def plot(self, ax='None', Coefs=1., Deriv=0, Elt='T', NC=tfd.BF2PlotNC, DVect=tfd.BF2_DVect_DefR, PlotMode='contourf', SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, Totdict=tfd.BF1Totd, LegDict=tfd.TorLegd, Test=True): - return Plot_BSpline2D(self, ax=ax, Elt=Elt, Deriv=Deriv, Coefs=Coefs, DVect=DVect, NC=NC, PlotMode=PlotMode, Name=self.Id.Name+' '+str(Deriv), SubP=SubP, SubMode=SubMode, Totdict=Totdict, LegDict=LegDict, Test=Test) - - def plot_fit(self, ax1='None', ax2='None', xx=None, yy=None, zz=None, ff=None, NC=tfd.BF2PlotNC, PlotMode='contourf', Name='', SubP=tfd.BF2Sub, SubMode=tfd.BF1SubMode, Totdict=tfd.BF1Totd, LegDict=tfd.TorLegd, Test=True): - Coefs, res = self.get_Coefs(xx=xx,yy=yy, zz=zz, ff=ff, SubP=SubP, SubMode=SubMode, Test=Test) - if xx is None: - xx, yy, nxg, nyg = self.get_XYplot(SubP=SubP, SubMode=SubMode) - zz = ff(RZ2Points(np.array([xx.flatten(),yy.flatten()]))) - zz = zz.reshape((xx.shape)) - else: - assert xx.ndim==2, "Args xx, yy and zz must be (N,M) plot-friendly !" - if Name=='': - Name = self.Id.Name - - Xplot, Yplot, nx, ny = self.get_XYplot(SubP=SubP, SubMode=SubMode) - PointsRZ = np.array([Xplot.flatten(),Yplot.flatten()]) - ind = self.Mesh.isInside(PointsRZ) - Val = self.get_TotVal(PointsRZ, Deriv=0, Coefs=Coefs, Test=True) - Val[~ind] = np.nan - Val = Val.reshape(Xplot.shape) - if PlotMode=='surf': - if ax1=='None' or ax2=='None': - ax1, ax2 = tfd.Plot_BSplineFit_DefAxes('3D') - ax1.plot_surface(xx,yy,zz, label='Model', **Totdict) - ax2.plot_surface(Xplot,Yplot,Val, label=Name, **Totdict) - else: - if ax1=='None' or ax2=='None': - ax1, ax2 = tfd.Plot_BSplineFit_DefAxes('2D') - if PlotMode=='contour': - ax1.contour(xx,yy,zz, NC, label='Model', **Totdict) - ax2.contour(Xplot,Yplot,Val, NC, label=Name, **Totdict) - elif PlotMode=='contourf': - ax1.contourf(xx,yy,zz, NC, label='Model', **Totdict) - ax2.contourf(Xplot,Yplot,Val, NC, label=Name, **Totdict) - if not LegDict is None: - ax1.legend(**LegDict) - ax2.legend(**LegDict) - ax2.set_title(r"$\chi^2 = "+str(res)+"$") - ax1.figure.canvas.draw() - return ax1, ax2 - - def plot_Ind(self, Ind=0, Elt='LSP', EltM='BMCK', ax='None', Coefs=1., NC=tfd.BF2PlotNC, PlotMode='contourf', SubP=tfd.BF1Sub, SubMode=tfd.BF1SubMode, Totdict=tfd.BF2PlotTotd, - Cdict=tfd.M2Cd, Kdict=tfd.M2Kd, Bckdict=tfd.M2Bckd, Mshdict=tfd.M2Mshd, LegDict=tfd.TorLegd, Colorbar=True, Test=True): - assert type(Ind) in [int,list,np.ndarray], "Arg Ind must be a int, a list of int or a np.ndarray of int or booleans !" - if type(Ind) is int: - Ind = np.array([Ind],dtype=int) - elif type(Ind) is list: - Ind = np.array(tuple(Ind),dtype=int) - elif type(Ind) is np.ndarray: - assert (np.issubdtype(Ind.dtype,bool) and Ind.size==self._NFunc) or np.issubdtype(Ind.dtype,int), "Arg Ind must be a np.ndarray of boolenas with size==self.NFunc or a np.ndarray of int !" - if np.issubdtype(Ind.dtype,bool): - Ind = Ind.nonzero()[0] - NInd = Ind.size - if type(Coefs) is float: - Coefs = Coefs*np.ones((self._NFunc,)) - indC, indK = self._Func_Centsind[:,Ind].flatten().astype(int), self._Func_Knotsind[:,Ind].flatten().astype(int) - ax = self._Mesh.plot(indKnots=indK, indCents=indC, ax=ax, Elt=EltM, Cdict=Cdict, Kdict=Kdict, Bckdict=Bckdict, Mshdict=Mshdict, LegDict=LegDict, Test=Test) - ax = Plot_BSpline2D_Ind(self, Ind, ax=ax, Coefs=Coefs, Elt=Elt, NC=NC, PlotMode=PlotMode, Name=self._Id.Name, SubP=SubP, SubMode=SubMode, Totdict=Totdict, LegDict=LegDict, Colorbar=Colorbar, Test=Test) - return ax - - def save(self,SaveName=None,Path=None,Mode='npz'): - if Path is None: - Path = self.Id.SavePath - else: - assert type(Path) is str, "Arg Path must be a str !" - self._Id.SavePath = Path - if SaveName is None: - SaveName = self.Id.SaveName - else: - assert type(SaveName) is str, "Arg SaveName must be a str !" - self.Id.SaveName = SaveName - Ext = '.npz' if 'npz' in Mode else '.pck' - TFPF.save(self, Path+SaveName+Ext) - - - - - -############################################ -##### Computing functions -############################################ - - -def RZ2Points(PointsRZ, Theta=0.): - return np.array([PointsRZ[0,:]*np.cos(Theta), PointsRZ[0,:]*np.sin(Theta),PointsRZ[1,:]]) - -def Points2RZ(Points): - return np.array([np.sqrt(Points[0,:]**2+Points[1,:]**2),Points[2,:]]) - - -def Calc_BF1D_Weights(LFunc, Points, Test=True): - if Test: - assert type(LFunc) is list, "Arg LFunc must be a list of functions !" - assert isinstance(Points,np.ndarray) and Points.ndim==1, "Arg Points must be a (N,) np.ndarray !" - NFunc = len(LFunc) - Wgh = np.zeros((Points.size, NFunc)) - for ii in range(0,NFunc): - Wgh[:,ii] = LFunc[ii](Points) - return Wgh - -def Calc_BF2D_Weights(LFunc, PointsRZ, Test=True): - if Test: - assert type(LFunc) is list, "Arg LFunc must be a list of functions !" - assert isinstance(PointsRZ,np.ndarray) and PointsRZ.ndim==2, "Arg Points must be a (2,N) np.ndarray !" - NFunc = len(LFunc) - Wgh = np.zeros((PointsRZ.shape[1], NFunc)) - for ii in range(0,NFunc): - Wgh[:,ii] = LFunc[ii](PointsRZ) - return Wgh - - -def BF2D_get_Op(BF2, Points, Deriv=0, indFin=None, Test=True): # To be updated to take into account only fraction of BF - """ Return the operator to compute the desired quantity on NP points (to be multiplied by Coefs) Y = Op(Coefs) for NF basis functions - Input : - BF2 A BF2D instance - Points A (3,NP) np.ndarray indicating (X,Y,Z) cylindrical coordinates of points at which to evaluate desired quantity (automatically converted to (R,Z) coordinates) - Deriv A flag indicating the desired quantity in [0,1,2,'D0','D0N2','D1','D1N2','D1FI','D2','D2-Lapl','D2N2-Lapl'] - Test A bool Flag indicating whether inputs shall be tested for conformity - Output : - A The operator itself as a 2D or 3D numpy array - m Flag indicating the kind of operation necessary - = 0 Y = A.dot(C) (Y = AC, with A.shape=(NP,NF)) - = 1 Y = C.dot(A.dot(C)) (Y = tCAC, with A.shape=(NF,NP,NF)) - = 2 Y = sum( C.dot(A[:].dot(C)) ) (e.g.: Y = tCArC + tCAzC with Ar.shape==Az.shape=(NF,NP,NF), you can compute a scalar product with each component if necessary) - """ - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert isinstance(Points,np.ndarray) and Points.ndim==2 and Points.shape[0] in [2,3], "Arg Points must be a (2-3,NP) np.ndarray !" - assert Deriv in [0,1,2,'D0','D0N2','D1','D1N2','D2','D2N2'], "Arg Deriv must be in [0,1,2,'D0','D0N2','D1','D1N2','D2','D2N2'] !" - assert indFin is None or (isinstance(indFin,np.ndarray) and indFin.dtype.name in ['bool','int32','int64','int']), "Arg indFin must be None or a np.naddary of bool or int !" - - if indFin is None: - indFin = np.arange(0,BF2.NFunc) - if indFin.dtype.name=='bool': - indFin = indFin.nonzero()[0] - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - NF = indFin.size - NP = Points.shape[1] - if Points.shape[0]==3: - RZ = np.array([np.hypot(Points[0,:],Points[1,:]),Points[2,:]]) - else: - RZ = np.copy(Points) - - QuadR, QuadZ = BF2._get_quadPoints() - QuadR, QuadZ = QuadR[:,indFin], QuadZ[:,indFin] - if Deriv=='D0': - m = 0 - A = np.zeros((NP,NF)) - for ii in range(0,NF): - A[:,ii] = BF2._LFunc[indFin[ii]](RZ) - return A, m - elif Deriv=='D0N2': # Update in progress from here... - m = 1 - A = np.zeros((NF,NP,NF)) - for ii in range(0,NF): - Yii = BF2._LFunc[ii](RZ) - A[ii,:,ii] = Yii**2 - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - A[ii,:,Ind[jj]] = Yii*BF2._LFunc[Ind[jj]](RZ) - return A, m - elif Deriv=='D1' and BF2.Deg>=1: - m = 2 - Ar, Az = np.zeros((NP,NF)), np.zeros((NP,NF)) - for ii in range(0,NF): - Ar[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Az[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - return (Ar,Az), m - elif Deriv=='D1N2' and BF2.Deg>=1: - m = 2 - AR, AZ = np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)) - for ii in range(0,NF): - rii, zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Rii, Zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - AR[ii,:,ii] = (Rii*zii)**2 - AZ[ii,:,ii] = (rii*Zii)**2 - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - AR[ii,:,Ind[jj]] = Rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=1)[0][0](RZ[0,:]) * zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=0)[0][0](RZ[1,:]) - AZ[ii,:,Ind[jj]] = rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=0)[0][0](RZ[0,:]) * Zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=1)[0][0](RZ[1,:]) - return (AR,AZ), m - elif Deriv=='D2' and BF2.Deg>=2: - m = 2 - Arr, Azz, Arz = np.zeros((NP,NF)), np.zeros((NP,NF)), np.zeros((NP,NF)) - for ii in range(0,NF): - Arr[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=2)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Azz[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=2)[0][0](RZ[1,:]) - Arz[:,ii] = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:])*BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - return (Arr,Azz,Arz), m - elif Deriv=='D2N2' and BF2.Deg>=2: - m = 2 - ARR, AZZ, ARZ, Arrzz = np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)), np.zeros((NF,NP,NF)) - for ii in range(0,NF): - rii, zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=0)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=0)[0][0](RZ[1,:]) - Rii, Zii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=1)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=1)[0][0](RZ[1,:]) - RRii, ZZii = BSpline_LFunc(BF2.Deg, QuadR[:,ii], Deriv=2)[0][0](RZ[0,:]), BSpline_LFunc(BF2.Deg, QuadZ[:,ii], Deriv=2)[0][0](RZ[1,:]) - ARR[ii,:,ii] = (RRii*zii)**2 - AZZ[ii,:,ii] = (rii*ZZii)**2 - ARZ[ii,:,ii] = (Rii*Zii)**2 - Arrzz[ii,:,ii] = RRii*ZZii - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - ARR[ii,:,Ind[jj]] = RRii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=2)[0][0](RZ[0,:]) * zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=0)[0][0](RZ[1,:]) - AZZ[ii,:,Ind[jj]] = rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=0)[0][0](RZ[0,:]) * ZZii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=2)[0][0](RZ[1,:]) - ARZ[ii,:,Ind[jj]] = Rii * BSpline_LFunc(BF2.Deg,QuadR[:,Ind[jj]],Deriv=1)[0][0](RZ[0,:]) * Zii * BSpline_LFunc(BF2.Deg,QuadZ[:,Ind[jj]],Deriv=1)[0][0](RZ[1,:]) - return (ARR,AZZ,ARZ, Arrzz), m - - -def BF2D_get_TotFunc(BF2, Deriv=0, DVect=tfd.BF2_DVect_DefR, Coefs=1., Test=True): - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert type(Deriv) in [int,str], "Arg Deriv must be a int or a str !" - assert type(Coefs) is float or (isinstance(Coefs,np.ndarray) and Coefs.size==BF2.NFunc), "Arg Coefs must be a float or a np.ndarray !" - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - - if type(Coefs) is float: - Coefs = Coefs.np.ones((BF2.NFunc,)) - - NF = BF2.NFunc - QuadR, QuadZ = BF2._get_quadPoints() - if Deriv in [0,'D0']: - LF = BF2._LFunc - return lambda Points, Coefs=Coefs, LF=LF, NF=NF: np.sum(np.concatenate(tuple([Coefs[jj]*LF[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - elif Deriv=='D0N2': - LF = BF2._LFunc - return lambda Points, Coefs=Coefs, LF=LF, NF=NF: np.sum(np.concatenate(tuple([Coefs[jj]*LF[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0)**2 - - elif Dbis==1: - LDR = [] - LDZ = [] - for ii in range(0,NF): - LDR.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=1, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=0, Test=Test)[0](PointsRZ[1,:])) - LDZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=0, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=1, Test=Test)[0](PointsRZ[1,:])) - if Deriv=='D1': - def FTot(Points, Coefs=Coefs, DVect=DVect, NF=NF, LDR=LDR, LDZ=LDZ): - DVect = DVect(Points) - Theta = np.arctan2(Points[1,:],Points[0,:]) - eR = np.array([np.cos(Theta),np.sin(Theta),np.zeros((Theta.size,))]) - DVect = np.array([np.sum(DVect*eR,axis=0), DVect[2,:]]) - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0)*DVect[0,:] - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0)*DVect[1,:] - return ValR+ValZ - elif Deriv=='D1N2': - def FTot(Points, Coefs=Coefs, NF=NF, LDR=LDR, LDZ=LDZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return ValR**2+ValZ**2 - elif Deriv=='D1FI': - LF = BF2._LFunc - def FTot(Points, Coefs=Coefs, NF=NF, LF=LF, LDR=LDR, LDZ=LDZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - Val = np.sum(np.concatenate(tuple([Coefs[jj]*LF[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return (ValR**2+ValZ**2)/Val - - elif Dbis==2: - LDRR, LDZZ = [], [] - for ii in range(0,NF): - LDRR.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=2, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=0, Test=Test)[0](PointsRZ[1,:])) - LDZZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=0, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=2, Test=Test)[0](PointsRZ[1,:])) - if Deriv=='D2-Lapl': - def FTot(Points, Coefs=Coefs, NF=NF, LDRR=LDRR, LDZZ=LDZZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return ValR+ValZ - elif Deriv=='D2N2-Lapl': - def FTot(Points, Coefs=Coefs, NF=NF, LDRR=LDRR, LDZZ=LDZZ): - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return (ValR+ValZ)**2 - else: - LDR, LDZ, LDRZ= [], [], [] - for ii in range(0,NF): - LDR.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=1, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=0, Test=Test)[0](PointsRZ[1,:])) - LDZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=0, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=1, Test=Test)[0](PointsRZ[1,:])) - LDRZ.append(lambda PointsRZ, ii=ii: BSplineDeriv(BF2.Deg, QuadR[:,ii], Deriv=1, Test=Test)[0](PointsRZ[0,:])*BSplineDeriv(BF2.Deg, QuadZ[:,ii], Deriv=1, Test=Test)[0](PointsRZ[1,:])) - if Deriv=='D2-Gauss': - def FTot(Points, Coefs=Coefs, NF=NF, LDR=LDR, LDZ=LDZ, LDRR=LDRR, LDZZ=LDZZ, LDRZ=LDRZ): - ValRR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValRZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDRZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return (ValRR*ValZZ-ValRZ**2)/(1. + ValR**2 + ValZ**2)**2 - elif Deriv=='D2-Mean': - def FTot(Points, Coefs=Coefs, NF=NF, LDR=LDR, LDZ=LDZ, LDRR=LDRR, LDZZ=LDZZ, LDRZ=LDRZ): - ValRR = np.sum(np.concatenate(tuple([Coefs[jj]*LDRR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValRZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDRZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValR = np.sum(np.concatenate(tuple([Coefs[jj]*LDR[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - ValZ = np.sum(np.concatenate(tuple([Coefs[jj]*LDZ[jj](Points2RZ(Points)).reshape((1,Points.shape[1])) for jj in range(0,NF)]),axis=0), axis=0) - return ((1.+ValR**2)*ValZZ - 2.*ValR*ValZ*ValRZ + (1.+ValZ**2)*ValRR)/(2.*(1. + ValR**2 + ValZ**2)**(1.5)) - - return FTot - - -def Calc_BF2D_Val(LFunc, Points, Coef=1., Test=True): - if Test: - assert type(LFunc) is list, "Arg LFunc must be a list of functions !" - assert isinstance(Points,np.ndarray) and (Points.shape[0]==2 or Points.shape[0]==3), "Arg Points must be a (2,N) or (3,N) np.ndarray !" - assert (type(Coef) is float and Coef==1.) or (isinstance(Coef,np.ndarray) and Coef.shape[0]==len(LFunc)), "Arg Coef must be a (BF2.NFunc,1) np.ndarray !" - - if Points.shape[0]==3: - R = np.sqrt(np.sum(Points[0:2,:]**2,axis=0,keepdims=False)) - Points = np.array([[R],[Points[2,:]]]) - - NFunc = len(LFunc) - Val = np.zeros((Points.shape[1],)) - Coef = Coef*np.ones((NFunc,1)) - for ii in range(0,NFunc): - Val = Val + Coef[ii]*LFunc[ii](Points) - - return Val - - - - - - - - - -def Calc_Integ_BF2(BF2, Coefs=1., Mode='Vol', Test=True): - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert Mode=='Vol' or Mode=='Surf', "Arg Mode must be 'Vol' or 'Surf' !" - assert type(Coefs) is float or (isinstance(Coefs,np.ndarray) and Coefs.size==BF2.NFunc), "Arg Coefs must be a (BF2.NFunc,) np.ndarray !" - assert BF2.Deg <= 3, "Arg BF2 should not have Degree > 3 !" - - if type(Coefs) is float: - Coefs = Coefs*np.ones((BF2.NFunc,)) - if Mode=='Surf': - if BF2.Deg==0: - Supp = BF2.get_Func_SuppRZ() - Int = np.sum(Coefs.flatten()*(Supp[1,:]-Supp[0,:])*(Supp[3,:]-Supp[2,:])) - elif BF2.Deg==1: - Supp = BF2.get_Func_SuppRZ() - Int = np.sum(Coefs.flatten()*0.25*(Supp[1,:]-Supp[0,:])*(Supp[3,:]-Supp[2,:])) - elif BF2.Deg==2: - QR, QZ = BF2._get_quadPoints() - IntR1 = (QR[1,:]-QR[0,:])**2/(3.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**2 -2.*QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[0,:]*(QR[1,:]-QR[2,:]))/(6*(QR[2,:]-QR[0,:])) - IntR22 = (-2.*QR[2,:]**2+QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[3,:]*(QR[2,:]-QR[1,:]))/(6.*(QR[3,:]-QR[1,:])) - IntR3 = (QR[3,:]-QR[2,:])**2/(3.*(QR[3,:]-QR[1,:])) - IntZ1 = (QZ[1,:]-QZ[0,:])**2/(3.*(QZ[2,:]-QZ[0,:])) - IntZ21 = (QZ[2,:]**2 -2*QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[0,:]*(QZ[1,:]-QZ[2,:]))/(6*(QZ[2,:]-QZ[0,:])) - IntZ22 = (-2.*QZ[2,:]**2+QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[3,:]*(QZ[2,:]-QZ[1,:]))/(6.*(QZ[3,:]-QZ[1,:])) - IntZ3 = (QZ[3,:]-QZ[2,:])**2/(3.*(QZ[3,:]-QZ[1,:])) - Int = np.sum(Coefs.flatten() * (IntR1+IntR21+IntR22+IntR3) * (IntZ1+IntZ21+IntZ22+IntZ3)) - elif BF2.Deg==3: - print "NOT CODED YET !" - - else: - if BF2.Deg==0: - Supp = BF2.get_Func_SuppRZ() - Int = np.sum( Coefs.flatten() * 2.*np.pi * 0.5*(Supp[1,:]**2-Supp[0,:]**2)*(Supp[3,:]-Supp[2,:])) - elif BF2.Deg==1: - Supp = BF2.get_Func_SuppRZ() - QuadR, QuadZ = BF2._get_quadPoints() - Int = np.sum( Coefs.flatten() * 2.*np.pi * 0.5*(QuadR[2,:]**2-QuadR[0,:]**2 + QuadR[1,:]*(QuadR[2,:]-QuadR[0,:]))*(Supp[3,:]-Supp[2,:])/6.) - elif BF2.Deg==2: - QR, QZ = BF2._get_quadPoints() - IntR1 = (3.*QR[1,:]**3+QR[0,:]**3 -5.*QR[0,:]*QR[1,:]**2+QR[0,:]**2*QR[1,:])/(12.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**3 -3.*QR[1,:]**3+QR[1,:]**2*QR[2,:]+QR[1,:]*QR[2,:]**2 -2.*QR[0,:]*QR[2,:]**2 -2.*QR[0,:]*QR[1,:]*QR[2,:] +4.*QR[0,:]*QR[1,:]**2)/(12.*(QR[2,:]-QR[0,:])) - IntR22 = ( -3.*QR[2,:]**3+QR[1,:]**3+QR[1,:]*QR[2,:]**2+QR[1,:]**2*QR[2,:]+4.*QR[2,:]**2*QR[3,:]-2.*QR[1,:]*QR[2,:]*QR[3,:]-2.*QR[1,:]**2*QR[3,:] )/(12.*(QR[3,:]-QR[1,:])) - IntR3 = ( QR[3,:]**3 +3.*QR[2,:]**3 -5.*QR[2,:]**2*QR[3,:]+QR[2,:]*QR[3,:]**2)/(12.*(QR[3,:]-QR[1,:])) - IntZ1 = (QZ[1,:]-QZ[0,:])**2/(3.*(QZ[2,:]-QZ[0,:])) - IntZ21 = (QZ[2,:]**2 -2*QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[0,:]*(QZ[1,:]-QZ[2,:]))/(6*(QZ[2,:]-QZ[0,:])) - IntZ22 = (-2.*QZ[2,:]**2+QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[3,:]*(QZ[2,:]-QZ[1,:]))/(6.*(QZ[3,:]-QZ[1,:])) - IntZ3 = (QZ[3,:]-QZ[2,:])**2/(3.*(QZ[3,:]-QZ[1,:])) - Int = np.sum(Coefs.flatten() * 2.*np.pi * (IntR1+IntR21+IntR22+IntR3) * (IntZ1+IntZ21+IntZ22+IntZ3)) - elif BF2.Deg==3: - print "NOT CODED YET !" - - return Int - - - - - - - -def Calc_IntOp_BSpline2D(BF2, Deriv=0, Mode='Vol', Sparse=tfd.L1IntOpSpa, SpaFormat=tfd.L1IntOpSpaFormat, Test=True): - if Test: - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert Mode in ['Surf','Vol'], "Arg Mode must be in ['Surf','Vol'] !" - assert (type(Deriv) is int and Deriv<=BF2.Deg) or (type(Deriv) is str and Deriv in ['D0','D1','D2','D3','D0N2','D1N2','D2N2','D3N2','D1FI'] and int(Deriv[1])<=BF2.Deg), "Arg Deriv must be a int or a str !" - - if type(Deriv) is int: - Dbis = Deriv - Deriv = 'D'+str(Dbis) - else: - Dbis = int(Deriv[1]) - - if Deriv=='D0': - m = 0 - if BF2.Deg==0: - Supp = BF2._get_Func_SuppBounds() - if Mode=='Surf': - A = (Supp[1,:]-Supp[0,:]) * (Supp[3,:]-Supp[2,:]) - else: - A = 0.5*(Supp[1,:]**2-Supp[0,:]**2) * (Supp[3,:]-Supp[2,:]) - elif BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - if Mode=='Surf': - A = 0.25*(Supp[1,:]-Supp[0,:])*(Supp[3,:]-Supp[2,:]) - else: - QuadR, QuadZ = BF2._get_quadPoints() - A = 0.5*(QuadR[2,:]**2-QuadR[0,:]**2 + QuadR[1,:]*(QuadR[2,:]-QuadR[0,:])) * (Supp[3,:]-Supp[2,:])/6. - elif BF2.Deg==2: - QR, QZ = BF2._get_quadPoints() - - IntZ1 = (QZ[1,:]-QZ[0,:])**2/(3.*(QZ[2,:]-QZ[0,:])) - IntZ21 = (QZ[2,:]**2 -2*QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[0,:]*(QZ[1,:]-QZ[2,:]))/(6*(QZ[2,:]-QZ[0,:])) - IntZ22 = (-2.*QZ[2,:]**2+QZ[1,:]**2+QZ[1,:]*QZ[2,:]+3.*QZ[3,:]*(QZ[2,:]-QZ[1,:]))/(6.*(QZ[3,:]-QZ[1,:])) - IntZ3 = (QZ[3,:]-QZ[2,:])**2/(3.*(QZ[3,:]-QZ[1,:])) - IntZ = IntZ1+IntZ21+IntZ22+IntZ3 - - if Mode=='Surf': - IntR1 = (QR[1,:]-QR[0,:])**2/(3.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**2 -2.*QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[0,:]*(QR[1,:]-QR[2,:]))/(6*(QR[2,:]-QR[0,:])) - IntR22 = (-2.*QR[2,:]**2+QR[1,:]**2+QR[1,:]*QR[2,:]+3.*QR[3,:]*(QR[2,:]-QR[1,:]))/(6.*(QR[3,:]-QR[1,:])) - IntR3 = (QR[3,:]-QR[2,:])**2/(3.*(QR[3,:]-QR[1,:])) - else: - IntR1 = (3.*QR[1,:]**3+QR[0,:]**3 -5.*QR[0,:]*QR[1,:]**2+QR[0,:]**2*QR[1,:])/(12.*(QR[2,:]-QR[0,:])) - IntR21 = (QR[2,:]**3 -3.*QR[1,:]**3+QR[1,:]**2*QR[2,:]+QR[1,:]*QR[2,:]**2 -2.*QR[0,:]*QR[2,:]**2 -2.*QR[0,:]*QR[1,:]*QR[2,:] +4.*QR[0,:]*QR[1,:]**2)/(12.*(QR[2,:]-QR[0,:])) - IntR22 = ( -3.*QR[2,:]**3+QR[1,:]**3+QR[1,:]*QR[2,:]**2+QR[1,:]**2*QR[2,:]+4.*QR[2,:]**2*QR[3,:]-2.*QR[1,:]*QR[2,:]*QR[3,:]-2.*QR[1,:]**2*QR[3,:] )/(12.*(QR[3,:]-QR[1,:])) - IntR3 = ( QR[3,:]**3 +3.*QR[2,:]**3 -5.*QR[2,:]**2*QR[3,:]+QR[2,:]*QR[3,:]**2)/(12.*(QR[3,:]-QR[1,:])) - IntR = IntR1+IntR21+IntR22+IntR3 - A = IntR*IntZ - elif BF2.Deg==3: - print "NOT CODED YET !" - A = 0 - - elif Deriv=='D0N2': - m = 1 - if BF2.Deg==0: - Supp = BF2._get_Func_SuppBounds() - if Mode=='Surf': - A = scpsp.diags([(Supp[1,:]-Supp[0,:]) * (Supp[3,:]-Supp[2,:])],[0],shape=None,format=SpaFormat) - else: - A = scpsp.diags([0.5*(Supp[1,:]**2-Supp[0,:]**2) * (Supp[3,:]-Supp[2,:])],[0],shape=None,format=SpaFormat) - elif BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - if Mode=='Surf': - d0R, d0Z = (Supp[1,:]-Supp[0,:])/3., (Supp[3,:]-Supp[2,:])/3. - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intR = (kR[1]-kR[0])/6. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZ = (kZ[1]-kZ[0])/6. - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - else: - d0R, d0Z = (QR[2,:]**2-QR[0,:]**2 + 2.*QR[1,:]*(QR[2,:]-QR[0,:]))/12., (Supp[3,:]-Supp[2,:])/3. - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intR = (kR[1]**2-kR[0]**2)/12. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZ = (kZ[1]-kZ[0])/6. - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - A = scpsp.vstack(LL,format='csr') - elif BF2.Deg==2: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - if Mode=='Surf': - d0R21 = (QR[2,:]-QR[1,:])*(10.*QR[0,:]**2+6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2 - 5.*QR[0,:]*(3.*QR[1,:]+QR[2,:]))/(30.*(QR[2,:]-QR[0,:])**2) - d0R22 = (QR[2,:]-QR[1,:])*(10.*QR[3,:]**2+6.*QR[2,:]**2+3.*QR[1,:]*QR[2,:]+QR[1,:]**2 - 5.*QR[3,:]*(3.*QR[2,:]+QR[1,:]))/(30.*(QR[3,:]-QR[1,:])**2) - d0R23 = ( 3.*QR[1,:]**2 + 4.*QR[1,:]*QR[2,:] + 3.*QR[2,:]**2 - 5.*QR[0,:]*(QR[1,:]+QR[2,:]-2.*QR[3,:]) -5.*QR[3,:]*(QR[1,:]+QR[2,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (QR[1,:]-QR[0,:])**3/(5.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (QR[3,:]-QR[2,:])**3/(5.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intR = (QR[1,ii]-QR[0,ii])**3/(30.*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR = ( 6.*QR[1,ii]**2 - QR[0,ii]*(9.*QR[1,ii]+QR[2,ii]-10.*QR[3,ii]) + QR[2,ii]*(QR[2,ii]-4.*QR[3,ii]) +3.*QR[1,ii]*(QR[2,ii]-2.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) + ( QR[0,ii]**2 + 3.*QR[0,ii]*QR[1,ii] + 6.*QR[1,ii]**2 - 2.*QR[0,Ind[jj]]*(2.*QR[0,ii]+3.*QR[1,ii] - 5.*QR[2,ii]) - QR[0,ii]*QR[2,ii] -9.*QR[1,ii]*QR[2,ii] )*(QR[1,ii]-QR[0,ii])**2/(30.*(QR[0,Ind[jj]]-QR[2,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intR = (QR[3,ii]-QR[2,ii])**3/(30.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR = ( 6.*QR[2,ii]**2 - QR[1,ii]*(9.*QR[2,ii]+QR[3,ii]-10.*QR[3,Ind[jj]]) + QR[3,ii]*(QR[3,ii]-4.*QR[3,Ind[jj]]) +3.*QR[2,ii]*(QR[3,ii]-2.*QR[3,Ind[jj]]) )*(QR[3,ii]-QR[2,ii])**2/(30.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) + ( QR[1,ii]**2 + 3.*QR[1,ii]*QR[2,ii] + 6.*QR[2,ii]**2 - 2.*QR[0,ii]*(2.*QR[1,ii]+3.*QR[2,ii] - 5.*QR[3,ii]) - QR[1,ii]*QR[3,ii] -9.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[0,ii]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZ = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZ = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZ = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZ = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - A = scpsp.vstack(LL,format='csr') - - elif Mode=='Vol': - d0R21 = (10*QR[1,:]**3 + 6.*QR[1,:]**2*QR[2,:] + 3.*QR[1,:]*QR[2,:]**2 + QR[2,:]**3 + 5.*QR[0,:]**2*(3.*QR[1,:]+QR[2,:]) - 4.*QR[0,:]*(6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[2,:]-QR[0,:])**2) - d0R22 = (10*QR[2,:]**3 + 6.*QR[2,:]**2*QR[1,:] + 3.*QR[2,:]*QR[1,:]**2 + QR[1,:]**3 + 5.*QR[3,:]**2*(3.*QR[2,:]+QR[1,:]) - 4.*QR[3,:]*(6.*QR[2,:]**2+3.*QR[2,:]*QR[1,:]+QR[1,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[3,:]-QR[1,:])**2) - d0R23 = (2.*QR[1,:]**3 + QR[1,:]*QR[2,:]*(3.*QR[2,:]-4.*QR[3,:]) +(2.*QR[2,:]-3.*QR[3,:])*QR[2,:]**2 +3.*(QR[2,:]-QR[3,:])*QR[1,:]**2 + QR[0,:]*(-3.*QR[1,:]**2-4.*QR[1,:]*QR[2,:]-3.*QR[2,:]**2+5.*QR[1,:]*QR[3,:]+5.*QR[2,:]*QR[3,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[3,:]-QR[1,:])*(QR[2,:]-QR[0,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (5.*QR[1,:]+QR[0,:])*(QR[1,:]-QR[0,:])**3/(30.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (5.*QR[2,:]+QR[3,:])*(QR[3,:]-QR[2,:])**3/(30.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - LL = [] - for ii in range(0,BF2.NFunc): - ll = np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intR = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intR = (QR[1,ii]+QR[0,ii])*(QR[1,ii]-QR[0,ii])**3/(60.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR1A = ( -2.*QR[0,Ind[jj]]*QR[0,ii] + QR[0,ii]**2 - 3.*QR[0,Ind[jj]]*QR[1,ii] + 2.*QR[0,ii]*QR[1,ii] + 2.*QR[1,ii]**2 )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intR1B = - ( QR[0,ii]**2 + 2.*QR[1,ii]*(5.*QR[1,ii]-6.*QR[2,ii]) + QR[0,ii]*(4.*QR[1,ii]-3.*QR[2,ii]) )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2A = ( 10.*QR[1,ii]**2 + 4.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[0,ii]*(4.*QR[1,ii]+QR[2,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2B = - ( 2.*QR[1,ii]**2 + 2.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[1,ii]*QR[3,ii] -2.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR = intR1A + intR1B + intR2A + intR2B - - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intR = (QR[3,ii]+QR[2,ii])*(QR[3,ii]-QR[2,ii])**3/(60.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR1A = ( -2.*QR[0,ii]*QR[1,ii] + QR[1,ii]**2 - 3.*QR[0,ii]*QR[2,ii] + 2.*QR[1,ii]*QR[2,ii] + 2.*QR[2,ii]**2 )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR1B = - ( QR[1,ii]**2 + 2.*QR[2,ii]*(5.*QR[2,ii]-6.*QR[3,ii]) + QR[1,ii]*(4.*QR[2,ii]-3.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2A = ( 10.*QR[2,ii]**2 + 4.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[1,ii]*(4.*QR[2,ii]+QR[3,ii]) )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2B = - ( 2.*QR[2,ii]**2 + 2.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[2,ii]*QR[3,Ind[jj]] -2.*QR[3,ii]*QR[3,Ind[jj]] )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])*(QR[3,Ind[jj]]-QR[2,ii])) - intR = intR1A + intR1B + intR2A + intR2B - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZ = d0Z[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZ = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZ = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZ = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZ = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - ll[0,Ind[jj]] = intR*intZ - ll[0,ii] = d0R[ii]*d0Z[ii] - LL.append(scpsp.coo_matrix(ll)) - A = scpsp.vstack(LL,format='csr') - - elif Deriv=='D1N2': - m = 2 - if BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - - if Mode=='Surf': - d0R, d0Z = (Supp[1,:]-Supp[0,:])/3., (Supp[3,:]-Supp[2,:])/3. - d0DR, d0DZ = (QR[2,:]-QR[0,:])/((QR[2,:]-QR[1,:])*(QR[1,:]-QR[0,:])), (QZ[2,:]-QZ[0,:])/((QZ[2,:]-QZ[1,:])*(QZ[1,:]-QZ[0,:])) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDR = d0DR[ii] - intRDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intRDR = -1./(kR[1]-kR[0]) - intRDZ = (kR[1]-kR[0])/6. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZDR = (kZ[1]-kZ[0])/6. - intZDZ = -1./(kZ[1]-kZ[0]) - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - else: - d0R, d0Z = (QR[2,:]**2-QR[0,:]**2 + 2.*QR[1,:]*(QR[2,:]-QR[0,:]))/12., (Supp[3,:]-Supp[2,:])/3. - d0DR, d0DZ = 0.5*(QR[1,:]+QR[0,:])/(QR[1,:]-QR[0,:]) + 0.5*(QR[2,:]+QR[1,:])/(QR[2,:]-QR[1,:]), (QZ[2,:]-QZ[0,:])/((QZ[2,:]-QZ[1,:])*(QZ[1,:]-QZ[0,:])) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDR = d0DR[ii] - intRDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - intRDR = -0.5*(kR[1]+kR[0])/(kR[1]-kR[0]) - intRDZ = (kR[1]**2-kR[0]**2)/12. - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - intZDR = (kZ[1]-kZ[0])/6. - intZDZ = -1./(kZ[1]-kZ[0]) - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - AR, AZ = scpsp.vstack(LLR,format='csr'), scpsp.vstack(LLZ,format='csr') - A = (AR,AZ) - - elif BF2.Deg==2: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - if Mode=='Surf': - d0R21 = (QR[2,:]-QR[1,:])*(10.*QR[0,:]**2+6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2 - 5.*QR[0,:]*(3.*QR[1,:]+QR[2,:]))/(30.*(QR[2,:]-QR[0,:])**2) - d0R22 = (QR[2,:]-QR[1,:])*(10.*QR[3,:]**2+6.*QR[2,:]**2+3.*QR[1,:]*QR[2,:]+QR[1,:]**2 - 5.*QR[3,:]*(3.*QR[2,:]+QR[1,:]))/(30.*(QR[3,:]-QR[1,:])**2) - d0R23 = ( 3.*QR[1,:]**2 + 4.*QR[1,:]*QR[2,:] + 3.*QR[2,:]**2 - 5.*QR[0,:]*(QR[1,:]+QR[2,:]-2.*QR[3,:]) -5.*QR[3,:]*(QR[1,:]+QR[2,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (QR[1,:]-QR[0,:])**3/(5.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (QR[3,:]-QR[2,:])**3/(5.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DR = 4.*(QR[1,:]-QR[0,:])/(3.*(QR[2,:]-QR[0,:])**2) + 4.*( QR[0,:]**2 + QR[1,:]**2 + QR[2,:]**2 + (QR[2,:]-2.*QR[3,:])*QR[1,:] - QR[2,:]*QR[3,:] + QR[3,:]**2 + (-QR[1,:]-2.*QR[2,:]+QR[3,:])*QR[0,:] )*(QR[2,:]-QR[1,:])/(3.*(QR[2,:]-QR[0,:])**2*(QR[3,:]-QR[1,:])**2) + 4.*(QR[3,:]-QR[2,:])/(3.*(QR[3,:]-QR[1,:])**2) - d0DZ = 4.*(QZ[1,:]-QZ[0,:])/(3.*(QZ[2,:]-QZ[0,:])**2) + 4.*( QZ[0,:]**2 + QZ[1,:]**2 + QZ[2,:]**2 + (QZ[2,:]-2.*QZ[3,:])*QZ[1,:] - QZ[2,:]*QZ[3,:] + QZ[3,:]**2 + (-QZ[1,:]-2.*QZ[2,:]+QZ[3,:])*QZ[0,:] )*(QZ[2,:]-QZ[1,:])/(3.*(QZ[2,:]-QZ[0,:])**2*(QZ[3,:]-QZ[1,:])**2) + 4.*(QZ[3,:]-QZ[2,:])/(3.*(QZ[3,:]-QZ[1,:])**2) - - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDZ = d0R[ii] - intRDR = d0DR[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDZ = (QR[1,ii]-QR[0,ii])**3/(30.*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - intRDR = 2.*(QR[0,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intRDZ = ( 6.*QR[1,ii]**2 - QR[0,ii]*(9.*QR[1,ii]+QR[2,ii]-10.*QR[3,ii]) + QR[2,ii]*(QR[2,ii]-4.*QR[3,ii]) +3.*QR[1,ii]*(QR[2,ii]-2.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) + ( QR[0,ii]**2 + 3.*QR[0,ii]*QR[1,ii] + 6.*QR[1,ii]**2 - 2.*QR[0,Ind[jj]]*(2.*QR[0,ii]+3.*QR[1,ii] - 5.*QR[2,ii]) - QR[0,ii]*QR[2,ii] -9.*QR[1,ii]*QR[2,ii] )*(QR[1,ii]-QR[0,ii])**2/(30.*(QR[0,Ind[jj]]-QR[2,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - intRDR = 2.*(2.*QR[0,Ind[jj]]-QR[0,ii]-2.*QR[1,ii]+QR[2,ii])*(QR[1,ii]-QR[0,ii])/(3.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) + 2.*(QR[0,ii]-2.*QR[1,ii]-QR[2,ii]+2.*QR[3,ii])*(QR[2,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDZ = (QR[3,ii]-QR[2,ii])**3/(30.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - intRDR = 2.*(QR[2,ii]-QR[3,ii])/(3.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intRDZ = ( 6.*QR[2,ii]**2 - QR[1,ii]*(9.*QR[2,ii]+QR[3,ii]-10.*QR[3,Ind[jj]]) + QR[3,ii]*(QR[3,ii]-4.*QR[3,Ind[jj]]) +3.*QR[2,ii]*(QR[3,ii]-2.*QR[3,Ind[jj]]) )*(QR[3,ii]-QR[2,ii])**2/(30.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) + ( QR[1,ii]**2 + 3.*QR[1,ii]*QR[2,ii] + 6.*QR[2,ii]**2 - 2.*QR[0,ii]*(2.*QR[1,ii]+3.*QR[2,ii] - 5.*QR[3,ii]) - QR[1,ii]*QR[3,ii] -9.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[0,ii]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - intRDR = 2.*(2.*QR[0,ii]-QR[1,ii]-2.*QR[2,ii]+QR[3,ii])*(QR[2,ii]-QR[1,ii])/(3.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) + 2.*(QR[1,ii]-2.*QR[2,ii]-QR[3,ii]+2.*QR[3,Ind[jj]])*(QR[3,ii]-QR[2,ii])/(3.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDZ = 2.*(QZ[0,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[1,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - intZDZ = 2.*(2.*QZ[0,Ind[jj]]-QZ[0,ii]-2.*QZ[1,ii]+QZ[2,ii])*(QZ[1,ii]-QZ[0,ii])/(3.*(QZ[1,ii]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) + 2.*(QZ[0,ii]-2.*QZ[1,ii]-QZ[2,ii]+2.*QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDZ = 2.*(QZ[2,ii]-QZ[3,ii])/(3.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[2,ii])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDZ = 2.*(2.*QZ[0,ii]-QZ[1,ii]-2.*QZ[2,ii]+QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) + 2.*(QZ[1,ii]-2.*QZ[2,ii]-QZ[3,ii]+2.*QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[2,ii])/(3.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - elif Mode=='Vol': - d0R21 = (10*QR[1,:]**3 + 6.*QR[1,:]**2*QR[2,:] + 3.*QR[1,:]*QR[2,:]**2 + QR[2,:]**3 + 5.*QR[0,:]**2*(3.*QR[1,:]+QR[2,:]) - 4.*QR[0,:]*(6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[2,:]-QR[0,:])**2) - d0R22 = (10*QR[2,:]**3 + 6.*QR[2,:]**2*QR[1,:] + 3.*QR[2,:]*QR[1,:]**2 + QR[1,:]**3 + 5.*QR[3,:]**2*(3.*QR[2,:]+QR[1,:]) - 4.*QR[3,:]*(6.*QR[2,:]**2+3.*QR[2,:]*QR[1,:]+QR[1,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[3,:]-QR[1,:])**2) - d0R23 = (2.*QR[1,:]**3 + QR[1,:]*QR[2,:]*(3.*QR[2,:]-4.*QR[3,:]) +(2.*QR[2,:]-3.*QR[3,:])*QR[2,:]**2 +3.*(QR[2,:]-QR[3,:])*QR[1,:]**2 + QR[0,:]*(-3.*QR[1,:]**2-4.*QR[1,:]*QR[2,:]-3.*QR[2,:]**2+5.*QR[1,:]*QR[3,:]+5.*QR[2,:]*QR[3,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[3,:]-QR[1,:])*(QR[2,:]-QR[0,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (5.*QR[1,:]+QR[0,:])*(QR[1,:]-QR[0,:])**3/(30.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (5.*QR[2,:]+QR[3,:])*(QR[3,:]-QR[2,:])**3/(30.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DR = (QR[1,:]-QR[0,:])*(QR[0,:]+3.*QR[1,:])/(3.*(QR[2,:]-QR[0,:])**2) + ( (3.*QR[1,:]+QR[2,:])/(QR[2,:]-QR[0,:])**2 + (QR[1,:]+3.*QR[2,:])/(QR[3,:]-QR[1,:])**2 - 2.*(QR[1,:]+QR[2,:])/((QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) )*(QR[2,:]-QR[1,:])/3. + (QR[3,:]-QR[2,:])*(QR[3,:]+3.*QR[2,:])/(3.*(QR[3,:]-QR[1,:])**2) - d0DZ = 4.*(QZ[1,:]-QZ[0,:])/(3.*(QZ[2,:]-QZ[0,:])**2) + 4.*( QZ[0,:]**2 + QZ[1,:]**2 + QZ[2,:]**2 + (QZ[2,:]-2.*QZ[3,:])*QZ[1,:] - QZ[2,:]*QZ[3,:] + QZ[3,:]**2 + (-QZ[1,:]-2.*QZ[2,:]+QZ[3,:])*QZ[0,:] )*(QZ[2,:]-QZ[1,:])/(3.*(QZ[2,:]-QZ[0,:])**2*(QZ[3,:]-QZ[1,:])**2) + 4.*(QZ[3,:]-QZ[2,:])/(3.*(QZ[3,:]-QZ[1,:])**2) - - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDZ = d0R[ii] - intRDR = d0DR[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDZ = (QR[1,ii]+QR[0,ii])*(QR[1,ii]-QR[0,ii])**3/(60.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intRDR = (QR[0,ii]+QR[1,ii])*(QR[0,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR1A = ( -2.*QR[0,Ind[jj]]*QR[0,ii] + QR[0,ii]**2 - 3.*QR[0,Ind[jj]]*QR[1,ii] + 2.*QR[0,ii]*QR[1,ii] + 2.*QR[1,ii]**2 )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intR1B = - ( QR[0,ii]**2 + 2.*QR[1,ii]*(5.*QR[1,ii]-6.*QR[2,ii]) + QR[0,ii]*(4.*QR[1,ii]-3.*QR[2,ii]) )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2A = ( 10.*QR[1,ii]**2 + 4.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[0,ii]*(4.*QR[1,ii]+QR[2,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2B = - ( 2.*QR[1,ii]**2 + 2.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[1,ii]*QR[3,ii] -2.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intRDZ = intR1A + intR1B + intR2A + intR2B - intRDR = ( -QR[0,ii]**2 + (QR[0,ii]+3.*QR[1,ii])*QR[0,Ind[jj]] + (-3.*QR[1,ii]+QR[2,ii])*QR[1,ii] +(-2.*QR[1,ii]+QR[2,ii])*QR[0,ii] )*(QR[1,ii]-QR[0,ii])/(3.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) + ( -3.*QR[1,ii]**2 + (QR[1,ii]+QR[2,ii])*QR[0,ii] + (-QR[2,ii]+QR[3,ii])*QR[2,ii] + (-2.*QR[2,ii]+3.*QR[3,ii])*QR[1,ii] )*(QR[2,ii]-QR[1,ii])/(3.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDZ = (QR[3,ii]+QR[2,ii])*(QR[3,ii]-QR[2,ii])**3/(60.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - intRDR = (QR[2,ii]+QR[3,ii])*(QR[2,ii]-QR[3,ii])/(3.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR1A = ( -2.*QR[0,ii]*QR[1,ii] + QR[1,ii]**2 - 3.*QR[0,ii]*QR[2,ii] + 2.*QR[1,ii]*QR[2,ii] + 2.*QR[2,ii]**2 )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR1B = - ( QR[1,ii]**2 + 2.*QR[2,ii]*(5.*QR[2,ii]-6.*QR[3,ii]) + QR[1,ii]*(4.*QR[2,ii]-3.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2A = ( 10.*QR[2,ii]**2 + 4.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[1,ii]*(4.*QR[2,ii]+QR[3,ii]) )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2B = - ( 2.*QR[2,ii]**2 + 2.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[2,ii]*QR[3,Ind[jj]] -2.*QR[3,ii]*QR[3,Ind[jj]] )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])*(QR[3,Ind[jj]]-QR[2,ii])) - intRDZ = intR1A + intR1B + intR2A + intR2B - intRDR = ( -QR[1,ii]**2 + (QR[1,ii]+3.*QR[2,ii])*QR[0,ii] + (-3.*QR[2,ii]+QR[3,ii])*QR[2,ii] +(-2.*QR[2,ii]+QR[3,ii])*QR[1,ii] )*(QR[2,ii]-QR[1,ii])/(3.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) + ( -3.*QR[2,ii]**2 + (QR[2,ii]+QR[3,ii])*QR[1,ii] + (-QR[3,ii]+QR[3,Ind[jj]])*QR[3,ii] + (-2.*QR[3,ii]+3.*QR[3,Ind[jj]])*QR[2,ii] )*(QR[3,ii]-QR[2,ii])/(3.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common R knots..." - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDR = d0Z[ii] - intZDZ = d0DZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDZ = 2.*(QZ[0,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[1,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - intZDZ = 2.*(2.*QZ[0,Ind[jj]]-QZ[0,ii]-2.*QZ[1,ii]+QZ[2,ii])*(QZ[1,ii]-QZ[0,ii])/(3.*(QZ[1,ii]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) + 2.*(QZ[0,ii]-2.*QZ[1,ii]-QZ[2,ii]+2.*QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDZ = 2.*(QZ[2,ii]-QZ[3,ii])/(3.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[2,ii])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDZ = 2.*(2.*QZ[0,ii]-QZ[1,ii]-2.*QZ[2,ii]+QZ[3,ii])*(QZ[2,ii]-QZ[1,ii])/(3.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) + 2.*(QZ[1,ii]-2.*QZ[2,ii]-QZ[3,ii]+2.*QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[2,ii])/(3.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common Z knots..." - - llR[0,Ind[jj]] = intRDR*intZDR - llZ[0,Ind[jj]] = intRDZ*intZDZ - llR[0,ii] = d0DR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - AR, AZ = scpsp.vstack(LLR,format='csr'), scpsp.vstack(LLZ,format='csr') - A = (AR,AZ) - - - elif Deriv=='D1FI': - m = 3 - if BF2.Deg==1: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - - - - - elif 'D2N2' in Deriv: - m = 2 - if BF2.Deg==2: - Supp = BF2._get_Func_SuppBounds() - QR, QZ = BF2._get_quadPoints() - LLR, LLZ = [], [] - - if Mode=='Surf': - d0R21 = (QR[2,:]-QR[1,:])*(10.*QR[0,:]**2+6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2 - 5.*QR[0,:]*(3.*QR[1,:]+QR[2,:]))/(30.*(QR[2,:]-QR[0,:])**2) - d0R22 = (QR[2,:]-QR[1,:])*(10.*QR[3,:]**2+6.*QR[2,:]**2+3.*QR[1,:]*QR[2,:]+QR[1,:]**2 - 5.*QR[3,:]*(3.*QR[2,:]+QR[1,:]))/(30.*(QR[3,:]-QR[1,:])**2) - d0R23 = ( 3.*QR[1,:]**2 + 4.*QR[1,:]*QR[2,:] + 3.*QR[2,:]**2 - 5.*QR[0,:]*(QR[1,:]+QR[2,:]-2.*QR[3,:]) -5.*QR[3,:]*(QR[1,:]+QR[2,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[2,:]-QR[0,:])*(QR[3,:]-QR[1,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (QR[1,:]-QR[0,:])**3/(5.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (QR[3,:]-QR[2,:])**3/(5.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DDR = 4./((QR[1,:]-QR[0,:])*(QR[2,:]-QR[0,:])**2) + 4.*(QR[3,:]+QR[2,:]-QR[1,:]-QR[0,:])**2/((QR[2,:]-QR[1,:])*(QR[3,:]-QR[1,:])**2*(QR[2,:]-QR[0,:])**2) + 4./((QR[3,:]-QR[2,:])*(QR[3,:]-QR[1,:])**2) - d0DDZ = 4./((QZ[1,:]-QZ[0,:])*(QZ[2,:]-QZ[0,:])**2) + 4.*(QZ[3,:]+QZ[2,:]-QZ[1,:]-QZ[0,:])**2/((QZ[2,:]-QZ[1,:])*(QZ[3,:]-QZ[1,:])**2*(QZ[2,:]-QZ[0,:])**2) + 4./((QZ[3,:]-QZ[2,:])*(QZ[3,:]-QZ[1,:])**2) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDDR = d0DDR[ii] - intRDDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDDR = 4./((kR[1]-kR[0])*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - intRDDZ = (QR[1,ii]-QR[0,ii])**3/(30.*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intRDDR = -4.*(QR[2,ii]+QR[1,ii]-QR[1,Ind[jj]]-QR[0,Ind[jj]])/((QR[2,Ind[jj]]-QR[1,Ind[jj]])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - 4.*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[3,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])**2) - intRDDZ = ( 6.*QR[1,ii]**2 - QR[0,ii]*(9.*QR[1,ii]+QR[2,ii]-10.*QR[3,ii]) + QR[2,ii]*(QR[2,ii]-4.*QR[3,ii]) +3.*QR[1,ii]*(QR[2,ii]-2.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[1,ii]-QR[3,ii])*(QR[2,ii]-QR[0,ii])**2) + ( QR[0,ii]**2 + 3.*QR[0,ii]*QR[1,ii] + 6.*QR[1,ii]**2 - 2.*QR[0,Ind[jj]]*(2.*QR[0,ii]+3.*QR[1,ii] - 5.*QR[2,ii]) - QR[0,ii]*QR[2,ii] -9.*QR[1,ii]*QR[2,ii] )*(QR[1,ii]-QR[0,ii])**2/(30.*(QR[0,Ind[jj]]-QR[2,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDDR = 4./((kR[1]-kR[0])*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - intRDDZ = (QR[3,ii]-QR[2,ii])**3/(30.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intRDDR = -4.*(QR[3,Ind[jj]]+QR[2,Ind[jj]]-QR[2,ii]-QR[1,ii])/((QR[3,ii]-QR[2,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) - 4.*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) - intRDDZ = ( 6.*QR[2,ii]**2 - QR[1,ii]*(9.*QR[2,ii]+QR[3,ii]-10.*QR[3,Ind[jj]]) + QR[3,ii]*(QR[3,ii]-4.*QR[3,Ind[jj]]) +3.*QR[2,ii]*(QR[3,ii]-2.*QR[3,Ind[jj]]) )*(QR[3,ii]-QR[2,ii])**2/(30.*(QR[2,ii]-QR[3,Ind[jj]])*(QR[3,ii]-QR[1,ii])**2) + ( QR[1,ii]**2 + 3.*QR[1,ii]*QR[2,ii] + 6.*QR[2,ii]**2 - 2.*QR[0,ii]*(2.*QR[1,ii]+3.*QR[2,ii] - 5.*QR[3,ii]) - QR[1,ii]*QR[3,ii] -9.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(30.*(QR[0,ii]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common knots..." - - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDDR = d0Z[ii] - intZDDZ = d0DDZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDDZ = -4.*(QZ[2,ii]+QZ[1,ii]-QZ[1,Ind[jj]]-QZ[0,Ind[jj]])/((QZ[2,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])**2) - intZDDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDDZ = -4.*(QZ[3,Ind[jj]]+QZ[2,Ind[jj]]-QZ[2,ii]-QZ[1,ii])/((QZ[3,ii]-QZ[2,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common knots..." - - llR[0,Ind[jj]] = intRDDR*intZDDR - llZ[0,Ind[jj]] = intRDDZ*intZDDZ - llR[0,ii] = d0DDR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DDZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - elif Mode=='Vol': - d0R21 = (10*QR[1,:]**3 + 6.*QR[1,:]**2*QR[2,:] + 3.*QR[1,:]*QR[2,:]**2 + QR[2,:]**3 + 5.*QR[0,:]**2*(3.*QR[1,:]+QR[2,:]) - 4.*QR[0,:]*(6.*QR[1,:]**2+3.*QR[1,:]*QR[2,:]+QR[2,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[2,:]-QR[0,:])**2) - d0R22 = (10*QR[2,:]**3 + 6.*QR[2,:]**2*QR[1,:] + 3.*QR[2,:]*QR[1,:]**2 + QR[1,:]**3 + 5.*QR[3,:]**2*(3.*QR[2,:]+QR[1,:]) - 4.*QR[3,:]*(6.*QR[2,:]**2+3.*QR[2,:]*QR[1,:]+QR[1,:]**2))*(QR[2,:]-QR[1,:])/(60.*(QR[3,:]-QR[1,:])**2) - d0R23 = (2.*QR[1,:]**3 + QR[1,:]*QR[2,:]*(3.*QR[2,:]-4.*QR[3,:]) +(2.*QR[2,:]-3.*QR[3,:])*QR[2,:]**2 +3.*(QR[2,:]-QR[3,:])*QR[1,:]**2 + QR[0,:]*(-3.*QR[1,:]**2-4.*QR[1,:]*QR[2,:]-3.*QR[2,:]**2+5.*QR[1,:]*QR[3,:]+5.*QR[2,:]*QR[3,:]) )*(QR[1,:]-QR[2,:])/(60.*(QR[3,:]-QR[1,:])*(QR[2,:]-QR[0,:])) - d0Z21 = (QZ[2,:]-QZ[1,:])*(10.*QZ[0,:]**2+6.*QZ[1,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[2,:]**2 - 5.*QZ[0,:]*(3.*QZ[1,:]+QZ[2,:]))/(30.*(QZ[2,:]-QZ[0,:])**2) - d0Z22 = (QZ[2,:]-QZ[1,:])*(10.*QZ[3,:]**2+6.*QZ[2,:]**2+3.*QZ[1,:]*QZ[2,:]+QZ[1,:]**2 - 5.*QZ[3,:]*(3.*QZ[2,:]+QZ[1,:]))/(30.*(QZ[3,:]-QZ[1,:])**2) - d0Z23 = ( 3.*QZ[1,:]**2 + 4.*QZ[1,:]*QZ[2,:] + 3.*QZ[2,:]**2 - 5.*QZ[0,:]*(QZ[1,:]+QZ[2,:]-2.*QZ[3,:]) -5.*QZ[3,:]*(QZ[1,:]+QZ[2,:]) )*(QZ[1,:]-QZ[2,:])/(60.*(QZ[2,:]-QZ[0,:])*(QZ[3,:]-QZ[1,:])) - d0R = (5.*QR[1,:]+QR[0,:])*(QR[1,:]-QR[0,:])**3/(30.*(QR[2,:]-QR[0,:])**2) + d0R21 + d0R22 + 2.*d0R23 + (5.*QR[2,:]+QR[3,:])*(QR[3,:]-QR[2,:])**3/(30.*(QR[3,:]-QR[1,:])**2) - d0Z = (QZ[1,:]-QZ[0,:])**3/(5.*(QZ[2,:]-QZ[0,:])**2) + d0Z21 + d0Z22 + 2.*d0Z23 + (QZ[3,:]-QZ[2,:])**3/(5.*(QZ[3,:]-QZ[1,:])**2) - - d0DDR = 2.*(QR[1,:]+QR[0,:])/((QR[1,:]-QR[0,:])*(QR[2,:]-QR[0,:])**2) + 2.*(QR[2,:]+QR[1,:])*(QR[3,:]+QR[2,:]-QR[1,:]-QR[0,:])**2/((QR[2,:]-QR[1,:])*(QR[3,:]-QR[1,:])**2*(QR[2,:]-QR[0,:])**2) + 2.*(QR[3,:]+QR[2,:])/((QR[3,:]-QR[2,:])*(QR[3,:]-QR[1,:])**2) - d0DDZ = 4./((QZ[1,:]-QZ[0,:])*(QZ[2,:]-QZ[0,:])**2) + 4.*(QZ[3,:]+QZ[2,:]-QZ[1,:]-QZ[0,:])**2/((QZ[2,:]-QZ[1,:])*(QZ[3,:]-QZ[1,:])**2*(QZ[2,:]-QZ[0,:])**2) + 4./((QZ[3,:]-QZ[2,:])*(QZ[3,:]-QZ[1,:])**2) - for ii in range(0,BF2.NFunc): - llR,llZ = np.zeros((1,BF2.NFunc)), np.zeros((1,BF2.NFunc)) - Ind = BF2._Func_InterFunc[:,ii] - Ind = np.unique(Ind[~np.isnan(Ind)]) - Ind = np.asarray([int(xxx) for xxx in Ind], dtype=int) - for jj in range(0,Ind.size): - if np.all(QR[:,Ind[jj]]==QR[:,ii]): - intRDDR = d0DDR[ii] - intRDDZ = d0R[ii] - else: - kR = np.intersect1d(QR[:,Ind[jj]], QR[:,ii], assume_unique=True) - if kR.size==2 and np.all(kR==QR[0:2,ii]): - intRDDR = 2.*(kR[1]+kR[0])/((kR[1]-kR[0])*(QR[2,ii]-QR[0,ii])*(QR[3,Ind[jj]]-QR[1,Ind[jj]])) - intRDDZ = (QR[1,ii]+QR[0,ii])*(QR[1,ii]-QR[0,ii])**3/(60.*(QR[1,ii]-QR[1,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - elif kR.size==3 and np.all(kR==QR[0:3,ii]): - intR1A = ( -2.*QR[0,Ind[jj]]*QR[0,ii] + QR[0,ii]**2 - 3.*QR[0,Ind[jj]]*QR[1,ii] + 2.*QR[0,ii]*QR[1,ii] + 2.*QR[1,ii]**2 )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])) - intR1B = - ( QR[0,ii]**2 + 2.*QR[1,ii]*(5.*QR[1,ii]-6.*QR[2,ii]) + QR[0,ii]*(4.*QR[1,ii]-3.*QR[2,ii]) )*(QR[1,ii]-QR[0,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2A = ( 10.*QR[1,ii]**2 + 4.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[0,ii]*(4.*QR[1,ii]+QR[2,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])**2) - intR2B = - ( 2.*QR[1,ii]**2 + 2.*QR[1,ii]*QR[2,ii] + QR[2,ii]**2 - 3.*QR[1,ii]*QR[3,ii] -2.*QR[2,ii]*QR[3,ii] )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intRDDZ = intR1A + intR1B + intR2A + intR2B - intRDDR = -2.*(QR[1,ii]+QR[0,ii])*(QR[2,ii]+QR[1,ii]-QR[0,ii]-QR[0,Ind[jj]])/((QR[1,ii]-QR[0,ii])*(QR[1,ii]-QR[0,Ind[jj]])*(QR[2,ii]-QR[0,ii])**2) - 2.*(QR[2,ii]+QR[1,ii])*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[3,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])**2) - elif kR.size==2 and np.all(kR==QR[-2:,ii]): - intRDDR = 2.*(kR[1]+kR[0])/((kR[1]-kR[0])*(QR[2,Ind[jj]]-QR[0,Ind[jj]])*(QR[3,ii]-QR[1,ii])) - intRDDZ = (QR[3,ii]+QR[2,ii])*(QR[3,ii]-QR[2,ii])**3/(60.*(QR[3,ii]-QR[1,ii])*(QR[2,Ind[jj]]-QR[2,ii])) - elif kR.size==3 and np.all(kR==QR[-3:,ii]): - intR1A = ( -2.*QR[0,ii]*QR[1,ii] + QR[1,ii]**2 - 3.*QR[0,ii]*QR[2,ii] + 2.*QR[1,ii]*QR[2,ii] + 2.*QR[2,ii]**2 )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])) - intR1B = - ( QR[1,ii]**2 + 2.*QR[2,ii]*(5.*QR[2,ii]-6.*QR[3,ii]) + QR[1,ii]*(4.*QR[2,ii]-3.*QR[3,ii]) )*(QR[2,ii]-QR[1,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2A = ( 10.*QR[2,ii]**2 + 4.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[1,ii]*(4.*QR[2,ii]+QR[3,ii]) )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])**2) - intR2B = - ( 2.*QR[2,ii]**2 + 2.*QR[2,ii]*QR[3,ii] + QR[3,ii]**2 - 3.*QR[2,ii]*QR[3,Ind[jj]] -2.*QR[3,ii]*QR[3,Ind[jj]] )*(QR[3,ii]-QR[2,ii])**2/(60.*(QR[3,ii]-QR[1,ii])*(QR[3,Ind[jj]]-QR[2,ii])) - intRDDZ = intR1A + intR1B + intR2A + intR2B - intRDDR = -2.*(QR[2,ii]+QR[1,ii])*(QR[3,ii]+QR[2,ii]-QR[1,ii]-QR[0,ii])/((QR[2,ii]-QR[1,ii])*(QR[2,ii]-QR[0,ii])*(QR[3,ii]-QR[1,ii])**2) - 2.*(QR[3,ii]+QR[2,ii])*(QR[3,Ind[jj]]+QR[3,ii]-QR[2,ii]-QR[1,ii])/((QR[3,ii]-QR[2,ii])*(QR[3,Ind[jj]]-QR[2,ii])*(QR[3,ii]-QR[1,ii])**2) - else: - assert np.all(kR==QR[0:3,ii]), "Something wrong with common knots..." - - if np.all(QZ[:,Ind[jj]]==QZ[:,ii]): - intZDDR = d0Z[ii] - intZDDZ = d0DDZ[ii] - else: - kZ = np.intersect1d(QZ[:,Ind[jj]], QZ[:,ii], assume_unique=True) - if kZ.size==2 and np.all(kZ==QZ[0:2,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - intZDDR = (QZ[1,ii]-QZ[0,ii])**3/(30.*(QZ[2,ii]-QZ[0,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[0:3,ii]): - intZDDZ = -4.*(QZ[2,ii]+QZ[1,ii]-QZ[1,Ind[jj]]-QZ[0,Ind[jj]])/((QZ[2,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])**2) - intZDDR = ( 6.*QZ[1,ii]**2 - QZ[0,ii]*(9.*QZ[1,ii]+QZ[2,ii]-10.*QZ[3,ii]) + QZ[2,ii]*(QZ[2,ii]-4.*QZ[3,ii]) +3.*QZ[1,ii]*(QZ[2,ii]-2.*QZ[3,ii]) )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[1,ii]-QZ[3,ii])*(QZ[2,ii]-QZ[0,ii])**2) + ( QZ[0,ii]**2 + 3.*QZ[0,ii]*QZ[1,ii] + 6.*QZ[1,ii]**2 - 2.*QZ[0,Ind[jj]]*(2.*QZ[0,ii]+3.*QZ[1,ii] - 5.*QZ[2,ii]) - QZ[0,ii]*QZ[2,ii] -9.*QZ[1,ii]*QZ[2,ii] )*(QZ[1,ii]-QZ[0,ii])**2/(30.*(QZ[0,Ind[jj]]-QZ[2,Ind[jj]])*(QZ[2,ii]-QZ[0,ii])**2) - elif kZ.size==2 and np.all(kZ==QZ[-2:,ii]): - intZDDZ = 4./((kZ[1]-kZ[0])*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - intZDDR = (QZ[3,ii]-QZ[2,ii])**3/(30.*(QZ[3,ii]-QZ[1,ii])*(QZ[2,Ind[jj]]-QZ[0,Ind[jj]])) - elif kZ.size==3 and np.all(kZ==QZ[-3:,ii]): - intZDDZ = -4.*(QZ[3,Ind[jj]]+QZ[2,Ind[jj]]-QZ[2,ii]-QZ[1,ii])/((QZ[3,ii]-QZ[2,ii])*(QZ[3,Ind[jj]]-QZ[1,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) - 4.*(QZ[3,ii]+QZ[2,ii]-QZ[1,ii]-QZ[0,ii])/((QZ[2,ii]-QZ[1,ii])*(QZ[2,ii]-QZ[0,ii])*(QZ[3,ii]-QZ[1,ii])**2) - intZDDR = ( 6.*QZ[2,ii]**2 - QZ[1,ii]*(9.*QZ[2,ii]+QZ[3,ii]-10.*QZ[3,Ind[jj]]) + QZ[3,ii]*(QZ[3,ii]-4.*QZ[3,Ind[jj]]) +3.*QZ[2,ii]*(QZ[3,ii]-2.*QZ[3,Ind[jj]]) )*(QZ[3,ii]-QZ[2,ii])**2/(30.*(QZ[2,ii]-QZ[3,Ind[jj]])*(QZ[3,ii]-QZ[1,ii])**2) + ( QZ[1,ii]**2 + 3.*QZ[1,ii]*QZ[2,ii] + 6.*QZ[2,ii]**2 - 2.*QZ[0,ii]*(2.*QZ[1,ii]+3.*QZ[2,ii] - 5.*QZ[3,ii]) - QZ[1,ii]*QZ[3,ii] -9.*QZ[2,ii]*QZ[3,ii] )*(QZ[2,ii]-QZ[1,ii])**2/(30.*(QZ[0,ii]-QZ[2,ii])*(QZ[3,ii]-QZ[1,ii])**2) - else: - assert np.all(kZ==QZ[0:3,ii]), "Something wrong with common knots..." - - llR[0,Ind[jj]] = intRDDR*intZDDR - llZ[0,Ind[jj]] = intRDDZ*intZDDZ - llR[0,ii] = d0DDR[ii]*d0Z[ii] - llZ[0,ii] = d0R[ii]*d0DDZ[ii] - LLR.append(scpsp.coo_matrix(llR)) - LLZ.append(scpsp.coo_matrix(llZ)) - - AR, AZ = scpsp.vstack(LLR,format='csr'), scpsp.vstack(LLZ,format='csr') - A = (AR,AZ) - - if not Sparse: - if m in [0,1]: - A = A.toarray() - elif m==2: - A = (A[0].toarray(),A[1].toarray()) - - return A, m - - - - - - - - - - - - - - - - - - - -def Calc_BF2D_DerivFunc(BF2, Deriv, Test=True): - if Test: - assert isinstance(BF2, BF2D), "Arg BF2 must be a MeshBase2D instance !" - assert type(Deriv) is int, "Arg Deriv must be a int !" - - KnR, KnZ = BF2._get_quadPoints() - if Deriv==1: - LFuncR, LFuncZ = [], [] - for ii in range(0,BF2.NFunc): - LFuncR.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=0, Test=False)[0](X[1,:])*BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=Deriv, Test=False)[0](X[0,:])) - LFuncZ.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=0, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=Deriv, Test=False)[0](X[1,:])) - return LFuncR, LFuncZ - elif Deriv==2: - # Formulas for Gauss and Mean curvature were found on http://en.wikipedia.org/wiki/Differential_geometry_of_surfaces - DRR, DRZ, DZZ = [], [], [] - for ii in range(0,BF2.NFunc): - DRR.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=Deriv, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=0, Test=False)[0](X[1,:])) - DRZ.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=1, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=1, Test=False)[0](X[1,:])) - DZZ.append(lambda X, ii=ii: BSplineDeriv(BF2.Deg, KnR[:,ii], Deriv=0, Test=False)[0](X[0,:])*BSplineDeriv(BF2.Deg, KnZ[:,ii], Deriv=Deriv, Test=False)[0](X[1,:])) - return DRR, DRZ, DZZ - - - - -def Get_MinMax(BF2, Coefs=1., Ratio=0.05, SubP=0.004, SubP1=0.015, SubP2=0.001, TwoSteps=False, SubMode='abs', Deriv='D0', Margin=0.2, Test=True): - assert Ratio is None or (type(Ratio) is float and Ratio>0 and Ratio<1), "Arg Ratio must be None or a float in ]0;1[ !" - if TwoSteps: - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP1, SubMode='abs', Test=Test) - else: - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP, SubMode='abs', Test=Test) - nx, ny = X.size, Y.size - dS = np.mean(np.diff(X))*np.mean(np.diff(Y)) - Xplot, Yplot = np.tile(X,(ny,1)), np.tile(Y,(nx,1)).T - Points = np.array([Xplot.flatten(), Yplot.flatten()]) - Vals = BF2.get_TotVal(Points, Deriv=Deriv, Coefs=Coefs, Test=Test) - - def getminmaxRatioFloat(valsmax, valsmin, indmax, indmin, Ratio, Ptsmin, Ptsmax): - DV = valsmax[indmax]-valsmin[indmin] - imin, imax = valsmin<=valsmin[indmin]+Ratio*DV, valsmax>=valsmax[indmax]-Ratio*DV - PMin = np.array([np.sum(Ptsmin[0,imin]*valsmin[imin])/np.sum(valsmin[imin]), np.sum(Ptsmin[1,imin]*valsmin[imin])/np.sum(valsmin[imin])]) - PMax = np.array([np.sum(Ptsmax[0,imax]*valsmax[imax])/np.sum(valsmax[imax]), np.sum(Ptsmax[1,imax]*valsmax[imax])/np.sum(valsmax[imax])]) - VMin, VMax = np.mean(valsmin[imin]), np.mean(valsmax[imax]) - return PMin, PMax, VMin, VMax - - def get_XYgridFine(DXmin, DYmin, DXmax, DYmax, Margin, subp): - DXmin, DYmin = [DXmin[0]-Margin*(DXmin[1]-DXmin[0]), DXmin[1]+Margin*(DXmin[1]-DXmin[0])], [DYmin[0]-Margin*(DYmin[1]-DYmin[0]), DYmin[1]+Margin*(DYmin[1]-DYmin[0])] - DXmax, DYmax = [DXmax[0]-Margin*(DXmax[1]-DXmax[0]), DXmax[1]+Margin*(DXmax[1]-DXmax[0])], [DYmax[0]-Margin*(DYmax[1]-DYmax[0]), DYmax[1]+Margin*(DYmax[1]-DYmax[0])] - Nxmin, Nymin = (DXmin[1]-DXmin[0])/subp, (DYmin[1]-DYmin[0])/subp - Nxmax, Nymax = (DXmax[1]-DXmax[0])/subp, (DYmax[1]-DYmax[0])/subp - Xmin, Ymin = np.linspace(DXmin[0],DXmin[1], Nxmin), np.linspace(DYmin[0],DYmin[1], Nymin) - Xmax, Ymax = np.linspace(DXmax[0],DXmax[1], Nxmax), np.linspace(DYmax[0],DYmax[1], Nymax) - Ptsmin = np.array([np.tile(Xmin,(Nymin,1)).flatten(), np.tile(Ymin,(Nxmin,1)).T.flatten()]) - Ptsmax = np.array([np.tile(Xmax,(Nymax,1)).flatten(), np.tile(Ymax,(Nxmax,1)).T.flatten()]) - return Ptsmin, Ptsmax - - def get_minmaxFine(vals, indmaxi, indmini, coefs, Points=Points, ratio=0.02, SubP2=SubP2, Ratio=Ratio, Test=Test): - DV = vals[indmaxi]-vals[indmini] - imin, imax = vals<=vals[indmini]+ratio*DV, vals>=vals[indmaxi]-ratio*DV - xminmin, xminmax = np.min(Points[0,imin]), np.max(Points[0,imin]) - xmaxmin, xmaxmax = np.min(Points[0,imax]), np.max(Points[0,imax]) - yminmin, yminmax = np.min(Points[1,imin]), np.max(Points[1,imin]) - ymaxmin, ymaxmax = np.min(Points[1,imax]), np.max(Points[1,imax]) - Ptsmin, Ptsmax = get_XYgridFine([xminmin,xminmax], [yminmin,yminmax], [xmaxmin, xmaxmax], [ymaxmin, ymaxmax], Margin, SubP2) - valsmin, valsmax = BF2.get_TotVal(Ptsmin, Deriv=Deriv, Coefs=coefs, Test=Test), BF2.get_TotVal(Ptsmax, Deriv=Deriv, Coefs=coefs, Test=Test) - indmin, indmax = np.nanargmin(valsmin), np.nanargmax(valsmax) - if Ratio is None: - return Ptsmin[:,indmin], Ptsmax[:,indmax], valsmin[indmin], valsmax[indmax] - else: - return getminmaxRatioFloat(valsmax, valsmin, indmax, indmin, Ratio, Ptsmin, Ptsmax) - - if not hasattr(Coefs,'__getitem__') or Coefs.ndim==1: - indmin, indmax = np.nanargmin(Vals), np.nanargmax(Vals) - if TwoSteps: - PMin, PMax, VMin, VMax = get_minmaxFine(Vals, indmax, indmin, Coefs, Points=Points, ratio=0.02, SubP2=SubP2, Ratio=Ratio, Test=Test) - else: - if Ratio is None: - PMin, PMax = Points[:,indmin], Points[:,indmax] - VMin, VMax = Vals[indmin], Vals[indmax] - else: - PMin, PMax, VMin, VMax = getminmaxRatioFloat(Vals, Vals, indmax, indmin, Ratio, Points, Points) - Surf = (Vals >= Vals(np.nanargmax(Vals))*0.5).sum()*dS - else: - indmin, indmax = np.nanargmin(Vals,axis=1), np.nanargmax(Vals,axis=1) - if TwoSteps: - ratio = 0.02 if Ratio is None else Ratio+0.02 - mmin, mmax = np.nanmin(Vals,axis=1).max(), np.nanmax(Vals,axis=1).min() - DV = np.max(np.nanmax(Vals,axis=1)-np.nanmin(Vals,axis=1)) - assert mmin+ratio*DV <= mmax-ratio*DV, "Profile changes too much !" - imin, imax = np.any(Vals<=mmin+ratio*DV,axis=0), np.any(Vals>=mmax-ratio*DV,axis=0) - DXmin, DYmin = [Points[0,imin].min(), Points[0,imin].max()], [Points[1,imin].min(), Points[1,imin].max()] - DXmax, DYmax = [Points[0,imax].min(), Points[0,imax].max()], [Points[1,imax].min(), Points[1,imax].max()] - Ptsmin, Ptsmax = get_XYgridFine(DXmin, DYmin, DXmax, DYmax, Margin, SubP2) - Valsmin, Valsmax = BF2.get_TotVal(Ptsmin, Deriv=Deriv, Coefs=Coefs, Test=Test), BF2.get_TotVal(Ptsmax, Deriv=Deriv, Coefs=Coefs, Test=Test) - else: - Ptsmin, Ptsmax = Points, Points - Valsmin, Valsmax = Vals, Vals - indmin, indmax = np.nanargmin(Valsmin,axis=1), np.nanargmax(Valsmax,axis=1) - if Ratio is None: - PMin, PMax = Ptsmin[:,indmin].T, Ptsmax[:,indmax].T - VMin, VMax = np.nanmin(Valsmin,axis=1), np.nanmax(Valsmax,axis=1) - else: - Nt = Coefs.shape[0] - PMin, PMax = np.empty((Nt,2)), np.empty((Nt,2)) - VMin, VMax = np.empty((Nt,)), np.empty((Nt,)) - for ii in range(0,Nt): - PMin[ii,:], PMax[ii,:], VMin[ii], VMax[ii] = getminmaxRatioFloat(Valsmax[ii,:], Valsmin[ii,:], indmax[ii], indmin[ii], Ratio, Ptsmin, Ptsmax) - Surf = np.sum(Vals >= np.tile(np.nanmax(Vals,axis=1)*0.5,(Vals.shape[1],1)).T,axis=1)*dS - - return PMin, PMax, VMin, VMax, Surf - - - - - - - - -def Calc_GetRoots(BF2, Deriv=0., Coefs=1., Test=True): - if Test: - assert isinstance(BF2, BF2D), "Arg BF2 must be a BF2D instance !" - assert Deriv in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI'], "Arg Deriv must be in [0,1,2,3,'D0','D1','D2','D3','D0N2','D1N2','D1FI'] !" - if type(Deriv) is str: - intDeriv = int(Deriv[1]) - else: - intDeriv = Deriv - assert BF2.Deg > 0 and intDeriv0)) and C4.size==4: - Inds[ii] = True - A = C4[0]+C4[3] - C4[1]+C4[2] - B = C4[1]*Kts[1,1] - C4[3]*Kts[1,0] - C4[0]*Kts[1,1] + C4[2]*Kts[1,0] - C = C4[1]*Kts[0,0] - C4[3]*Kts[0,0] - C4[0]*Kts[0,1] + C4[2]*Kts[0,1] - D = Kts[0,1]*(C4[0]*Kts[1,1]-C4[2]*Kts[1,0]) - Kts[0,0]*(C4[1]*Kts[1,1]-C4[3]*Kts[1,0]) - if A==0.: - if C==0.: - if B==0.: - Shape[ii] = ['all',[]] if D==0. else ['',[]] # Else not possible - else: - Shape[ii] = ['x',[-D/B]] - else: - Shape[ii] = ['yx',[-B/C,-D/C]] - else: - if -C/A>Kts[0,1] or -C/A0)) and C9.size==9: - Inds[ii] = True - print " Not finished yet !" - - - - - if intDeriv==1: - if Deriv[1]=='D1N2': - if BF2.Deg==2: - for ii in range(0,NCents): - ind = BF2._Cents_Funcind[:,ii] - C9 = Coefs[np.unique(ind[~np.isnan(ind)]).astype(int)] - Kts = BF2.Mesh.Knots[:,np.unique(BF2.Mesh._Cents_Knotsind[:,ii])] - - #A0, B0 = - #A1, B1 = - #A2, B2 = - #alpha0, beta0, gam0 = - #alpha1, beta1, gam1 = - #alpha2, beta2, gam2 = - return Inds, Pts, Shape - - - - - - -############################################ -##### Plotting functions -############################################ - - - -def Plot_BF2D(BF2, Coef=1., ax='None',SubP=0.1, SubMode='Rel', Name='Tot', TotDict=Tot2Dict_Def): - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert ax=='None' or isinstance(ax,plt.Axes), "Arg ax must be a plt.Axes instance !" - assert type(Name) is str, "Arg Name must be a str !" - - assert type(TotDict) is dict, "Arg TotDict must be a dict !" - - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP, SubMode=SubMode, Test=True) - nx, ny = X.size, Y.size - Xplot, Yplot = np.dot(np.ones((ny,1)),X.reshape((1,nx))), np.dot(Y.reshape((ny,1)),np.ones((1,nx))) - Points = np.concatenate((Xplot.reshape((1,nx*ny)), Yplot.reshape((1,nx*ny))),axis=0) - Z = Calc_BF2D_Val(BF2.LFunc, Points, Coef=Coef, Test=True) - Zplot= Z.reshape((ny,nx)) - - if ax=='None': - ax = tfd.Plot_BSpline_DefAxes('2D') - ax.plot_surface(Xplot,Yplot,Zplot, label=Name, **TotDict) - - ax.figure.canvas.draw() - return ax - - - - -def Plot_BF2D_BFuncMesh(BF2, ind, Coef=1., ax1='None', ax2='None',SubP=0.25, SubMode='Rel', Name='', TotDict=Tot2Dict_Def): - assert isinstance(BF2,BF2D), "Arg BF2 must be a BF2D instance !" - assert type(ind) is int, "Arg ind must be a int !" - assert ax1=='None' or isinstance(ax1,plt.Axes), "Arg ax1 must be a plt.Axes instance !" - assert ax2=='None' or isinstance(ax2,plt.Axes), "Arg ax2 must be a plt.Axes instance !" - assert type(Name) is str, "Arg Name must be a str !" - assert type(TotDict) is dict, "Arg TotDict must be a dict !" - - X, Y = Calc_SumMeshGrid2D(BF2.Mesh.MeshR.Knots, BF2.Mesh.MeshZ.Knots, SubP=SubP, SubMode=SubMode, Test=True) - nx, ny = X.size, Y.size - Xplot, Yplot = np.dot(np.ones((ny,1)),X.reshape((1,nx))), np.dot(Y.reshape((ny,1)),np.ones((1,nx))) - Points = np.concatenate((Xplot.reshape((1,nx*ny)), Yplot.reshape((1,nx*ny))),axis=0) - Z = Calc_BF2D_Val([BF2.LFunc[ind]], Points, Coef=Coef, Test=True) - Zplot= Z.reshape((ny,nx)) - - if ax1=='None' or ax2=='None': - ax1, ax2 = tfd.Plot_BF2D_BFuncMesh_DefAxes() - - BF2.Mesh.plot(ax=ax1) - BF2.Mesh.plot_Cents(ax=ax1,Ind=BF2.Func_Centsind[:,ind], Knots=False) - BF2.Mesh.plot_Knots(ax=ax1,Ind=BF2.Func_Knotsind[:,ind], Cents=False) - - ax2.plot_surface(Xplot,Yplot,Zplot, label=Name, **TotDict) - ax1.figure.canvas.draw() - return ax1, ax2 - - -def Plot_BFunc_SuppMax_PolProj(BF2, ind, ax='None', Supp=True,PMax=True,SuppDict=SuppDict_Def, PMaxDict=PMaxDict_Def): - assert type(ind) is int, "Arg ind must be a int !" - assert type(Supp) is bool, "Arg Supp must be a bool !" - assert type(PMax) is bool, "Arg Supp must be a bool !" - assert type(SuppDict) is dict, "Arg SuppDict must be a dict !" - assert type(PMaxDict) is dict, "Arg SuppDict must be a dict !" - assert isinstance(ax,plt.Axes) or ax=='None', "Arg ax must be a plt.Axes instance !" - - - if ax=='None': - ax = tfd.Plot_BFunc_SuppMax_PolProj_DefAxes() - - if Supp: - RZsupp = BF2.get_Func_SuppRZ()[:,ind] - verts = [(RZsupp[0], RZsupp[2]), # left, bottom - (RZsupp[1], RZsupp[2]), # left, top - (RZsupp[1], RZsupp[3]), # right, top - (RZsupp[0], RZsupp[3]), # right, bottom - (RZsupp[0], RZsupp[2])] - - codes = [Path.MOVETO, - Path.LINETO, - Path.LINETO, - Path.LINETO, - Path.CLOSEPOLY] - - patch = patches.PathPatch(Path(verts, codes), **SuppDict) - ax.add_patch(patch) - if PMax: - PMax = BF2.Func_PMax[:,ind] - ax.plot(PMax[0],PMax[1], **PMaxDict) - - return ax - - - -""" -############################################################################### -############################################################################### - Testing ground -############################################################################### -""" -""" -Deg = 2 -KnotsMult1 = np.array([0.,1.,2.,3.,4.,5., 5., 5.]) -KnotsMult2 = np.array([0.,0.,1.,2.,3.,4.,5.]) -BS1 = BSpline(Deg,KnotsMult1)[0] -BS2 = BSpline(Deg,KnotsMult2)[0] -#ax = Plot_BSpline1D(KnotsMult1,BS1,ax='None',SubP=0.05,SubMode='Rel') -ax1, ax2 = Plot_BSpline2D(KnotsMult1, KnotsMult2, BS1, BS2, ax1=None, ax2='None',SubP=0.05,SubMode='Rel') -""" - diff --git a/tofu/mesh/setup.py b/tofu/mesh/setup.py deleted file mode 100644 index c18687486..000000000 --- a/tofu/mesh/setup.py +++ /dev/null @@ -1,19 +0,0 @@ -from distutils.core import setup -from distutils.extension import Extension -from Cython.Build import cythonize -from os import environ -import numpy - -environ['CC'] = 'gcc' -environ['CXX'] = 'gcc' - -extensions = [ - Extension("_bsplines_cy", ["_bsplines_cy.pyx"], - include_dirs=[numpy.get_include()]) - ] - -setup( - name="_bsplines_cy", - ext_modules=cythonize(extensions) -) -