def SetPackageParams(self, Dic: dict): """ Args: Verbose (TYPE, optional): DESCRIPTION. Defaults to False. Returns: None. """ for A, V in Dic.items(): if V is not None: if not hasattr(self, 'Doc') or self.Doc is None: self.Doc = UBoxDoc() Result = self.Doc.Search(A.split('[')[0], Exact=True, Silent=True) if len(Result) > 0: Pkg = Result[0]['Package'] comm = '{}.{}={}'.format(Pkg, A, V) if self.Verbose: print(comm) try: exec(comm, globals(), globals()) except: print('Cannot set {}.{} = {} '.format(Pkg, A, V)) else: print('No package found for {}'.format(A))
def __init__(self,Verbose=False,VerboseParserVar=False,VerboseArgout=False,Doc=None): self.Verbose=Verbose self.VerboseArgout=VerboseArgout self.VerboseParserVar=VerboseParserVar self.ActionKeyWord=['read','remark'] self.TypeBas=['integer','real','character','real8','integer8'] self.ExcludeList=['echo','oldecho','exponseed'] self.Doc=UBoxDoc() self.MathSymbols=['+','-','/','*']
def Launch(self, CreateAliases=True, *args, **kwargs): super().__init__(*args, **kwargs) self.Doc = UBoxDoc() self.Dic['Doc'] = self.Doc self.Dic['CurrentProject'] = self.CurrentProjectGetter self.Print( 'UEDGEToolBox sucessfully launched. Type QuickStart() for basic commands.' ) if CreateAliases: CreateGlobalAliases(self.Doc, Verbose=self.Verbose) CreateGlobalAliases(self, Include=GetMethods(UBoxSim), Verbose=self.Verbose) CreateGlobalAliases( self, Include=['SetCaseName', 'Source', 'SourceGrid'], Verbose=self.Verbose) CreateGlobalAliases(self, Include=['ReadGridFile'], Verbose=self.Verbose)
def GetFortranTree(self, UEDGESourcePath, ExcludeList=[]): self.UEDGESourcePath = os.path.abspath(UEDGESourcePath) print('Parsing UEDGE Fortran source files in the folder:{}'.format( self.UEDGESourcePath)) print('Excluding files:{}'.format(ExcludeList)) self.ListTree = {} InitDir = os.getcwd() self.Doc = UBoxDoc() for pkg in self.Doc.ListPkg: os.chdir(os.path.join(self.UEDGESourcePath, pkg)) for file in glob.glob("*.F"): if file not in ExcludeList: print('Processing {} ...'.format(file)) name = os.path.splitext(file)[0] print(os.path.join(os.getcwd(), file)) tree = parse(os.path.join(os.getcwd(), file), isfree=False) DicG = globals() DicG['tree'] = tree exec(name + '=tree', DicG, self.ListTree) else: print('Skipping {} ...'.format(file)) os.chdir(InitDir)
class UBoxBas2Py(): def __init__(self,Verbose=False,VerboseParserVar=False,VerboseArgout=False,Doc=None): self.Verbose=Verbose self.VerboseArgout=VerboseArgout self.VerboseParserVar=VerboseParserVar self.ActionKeyWord=['read','remark'] self.TypeBas=['integer','real','character','real8','integer8'] self.ExcludeList=['echo','oldecho','exponseed'] self.Doc=UBoxDoc() self.MathSymbols=['+','-','/','*'] def Convert(self,BasFileName,PyFileName=None,ExcludeList=[],Imax=None,Verbose=None): if Verbose is not None: self.Verbose=Verbose self.VerboseArgout=Verbose self.VerboseParserVar=Verbose if PyFileName is None: PyFileName=os.path.splitext(BasFileName)[0] + '.py' print('Converting Basis file:{} -> {}'.format(BasFileName,PyFileName)) with open(BasFileName,'r') as self.f: with open(PyFileName,'w') as self.fw: #Lines = f.readlines() self.Line=next(self.f,None) self.LineNumber=0 self.fw.write('#>>> Produced by UBoxBas2Py. Original file: {}\n'.format(BasFileName)) self.fw.write('#>>> Timestamp: {:%Y-%m-%d %H:%M:%S}\n'.format(datetime.now())) self.fw.write('iota=np.array([np.arange(1,i+1) for i in range(1,300)],dtype=np.ndarray)\n') self.fw.write("api.apidir=Source('api',Folder='InputDir')\n") self.fw.write("aph.aphdir=Source('aph',Folder='InputDir')\n") while self.Line: if Imax is not None and self.LineNumber>Imax: break LineOut=self.__LineParser(self.Line,self.ExcludeList+ExcludeList) self.LineNumber+=1 self.fw.write(LineOut+'\n') self.Line=next(self.f,None) def __LineParser(self,Line,ExcludeList=[]): Out=[] Line=Line.strip('\n').strip('\r').strip() if self.Verbose: print('>>>> Parsing Line #{} : {}'.format(self.LineNumber,Line)) # First we ignore all comments in line #Gather cut lines while Line.endswith('\\'): Lnext=next(self.f) self.Line=Lnext Line=Line.split('\\')[0]+Lnext.rstrip() Line=Line.strip('\n').strip('\r').strip() #remove trailing comments Comment='' if Line.count('#')>0: Comment='#'+Line.split('#',1)[1] Line=Line.split('#',1)[0] Line=Line.strip('\n').strip('\r').strip() if Line=='': pass # Second we look for several commands in one line elif Line.count(';')>0: Line=Line.split(';') for L in Line: Out.append(self.__LineParser(L)+'\n') elif Line.startswith('!'): Out.append('#>> '+Line) else: ############################################## #Third Let do the special keywords and commands Splt=Line.strip().split(' ',1) Kw=Line.strip().split(' ',1)[0].strip() if len(Splt)>1: Arg=Line.strip().split(' ',1)[1].strip() if self.Verbose: print('>>>>>>>> Keyword found:{} with argument:{}'.format(Kw,Arg)) else: Arg='' if Kw in ExcludeList: Out.append('##'+Line) elif Kw in 'read': if len(Arg)>0 and 'plate' not in Arg: Out.append('ReadInput("'+Arg+'")') else: Out.append('#>> '+Line) #deal with remark: elif Kw in 'remark' or Kw in '<<': if len(Arg)>0: Out.append('print('+Arg+')') else: Out.append('#>> '+Line) elif Kw in self.TypeBas or 'character*' in Kw.lower(): if '=' in Arg: Out.append(self.__LineParser(Arg)) else: Out.append('#>> '+Arg) elif Kw in 'call': Out.append('#>> '+Arg) else: if Line.count('=')==0: # not an assignment if Line.strip()=='allocate': OutVar='bbb.allocate()' else: OutVar=self.__ParseVariable(Line,ForceCheck=True) if OutVar is None: Out.append('#>> '+Line) else: Out.append(OutVar) else: Var=Line.split('=')[0].strip() Arg=Line.split('=')[1].strip() if Var in self.ExcludeList: Out.append('#>> '+Var+'='+Arg) if Var=='probname': Out.append('SetCaseName({})'.format(Arg)) else: if Var=='del': Var='delperturb' Varout=self.__ParseVariable(Var,ForceCheck=False,ExcludeList=ExcludeList) Argout=self.__ParseArgout(Arg) if self.Verbose: print('>>>>>>>> Assignment found for "{}" -> {}={}'.format(Line,Varout,Argout)) if Varout is not None: Out.append(Varout+'='+Argout) else: Out.append(Var+'='+Argout) if Out==[]: Out=[Comment] else: Out.append(' '+Comment) Out=''.join(Out) if self.Verbose: print('>>>> Result of parsing:{}'.format(Out)) return Out def __ParseArgout(self,Arg,SymbolIndex=0): if SymbolIndex>len(self.MathSymbols)-1: return Arg else: Symbol=self.MathSymbols[SymbolIndex] Args=Arg.strip().split(Symbol) CArgs=Arg.strip().count(Symbol) if self.VerboseArgout: print('Splitting Argout={}, with Symbol "{}":{}'.format(Arg,Symbol,Args)) SymbolIndex_=SymbolIndex+1 Argouts=[] for Argo in Args: Argo=Argo.strip() Argo=self.__ParseArgout(Argo,SymbolIndex_) Argo=self.__SubExpo(Argo) Argo=self.__ParseVariable(Argo,ForceCheck=False) Argo=Argo.strip() if CArgs>0 and Argo.startswith('[') and Argo.endswith(']'): Argo="np.array({})".format(Argo) Argouts.append(Argo) return Symbol.join(Argouts) def __SubExpo(self,Arg): if self.IsFloat(Arg): Arg=Arg.replace('D','e') Arg=Arg.replace('d','e') return Arg def __GetPackageMethod(self,VarName): Out=self.Doc.Search(VarName,Exact=True,Silent=True) if len(Out)<1 or Out[0] is None or Out[0].get('Function') is None: return None else: return Out[0] def __GetPackageVariable(self,VarName,IsDim=False): Info=self.Doc.Search(VarName,Silent=True,Exact=True) if len(Info)>1: raise ValueError('More than one variable name found for {}'.format(VarName)) if len(Info)<1: # if not a variable of a package, check if this is a package method Out=None else: Out=Info[0]['Package']+'.'+VarName if Info[0].get('Dimension') is not None and '(' in Info[0]['Dimension'] and IsDim: Out=Out+'[0]' return Out def __ParseVariable(self,Var,ForceCheck=True,ExcludeList=[],IsDim=False): Var=Var.strip() if Var in ExcludeList: return '#>> '+ Var # Does Var has dimension? #print('#Var:',Var) if Var.isnumeric() or self.IsFloat(Var): return Var if Var.startswith('array') or Var.startswith('np.array'): return Var if Var.startswith('[') and Var.endswith(']'): return Var VarName=Var.strip().split('(')[0].strip() if VarName.endswith('array') or VarName.endswith('np.array'): return Var Out=self.__ParseVariableName(VarName,IsDim=IsDim) if Out is None: if ForceCheck: return '#>> ' + Var else: Out=Var.strip().split('(')[0].strip() if '(' in Var: il=Var.find('(')+1 ir=Var.rfind(')') Dim=Var[il:ir].strip() Dout=self.__ParseVariableDim(Dim,VarName) #print(Dim,'->',Dout) Out=Out+'['+Dout+']' if self.VerboseParserVar: print('Parsing variable "{}" -> {}'.format(Var,Out)) return Out def __ParseVariableName(self,VarName,IsDim=False): Out=self.__GetPackageVariable(VarName,IsDim=IsDim) if Out is None: Out=self.__GetPackageMethod(VarName) return Out def __ParseMathSymbol(self,Str): Out=[] W='' for c in Str: if c in self.MathSymbols: Out.append(W) Out.append(c) W='' else: W=W+c Out.append(W) return Out def ParseDimDoc(self,S): OffsetStartList=[] OffsetEndList=[] if S is None or S.count('(')<1: return (None,None) else: OffsetStartList=[] OffsetEndList=[] if S.count('(')!=S.count(')'): raise ValueError('Mismatch # of brackets in parsing Dimension Doc:{}'.format(S)) Str=S.split('(')[1].split(')')[0] for D in Str.split(','): if D.count(':')>0: istart=D.split(':')[0] if istart.isnumeric(): if int(istart)==0: OffsetStart=0 OffsetEnd=1 elif int(istart)==1: OffsetStart=-1 OffsetEnd=0 else: raise ValueError('Mismatch # of brackets in parsing Dimension Doc:{}'.format(S)) else: OffsetStart=-1 OffsetEnd=0 else: OffsetStart=-1 OffsetEnd=0 OffsetStartList.append(OffsetStart) OffsetEndList.append(OffsetEnd) return (OffsetStartList,OffsetEndList) def GetOffsetDim(self,VarName): Dic=self.Doc.Search(VarName,Exact=True,Silent=True) if Dic==[]: return (None,None) else: return self.ParseDimDoc(Dic[0].get('Dimension')) def __ParseVariableDim(self,Dim,VarName=None): Dout=[] idl=self.findall(Dim,'(') idr=self.findall(Dim,')') idc=self.findall(Dim,',') Ind=[-1] OffsetsStart=None OffsetsEnd=None if VarName is not None: (OffsetsStart,OffsetsEnd)=self.GetOffsetDim(VarName) if OffsetsStart is None: OffsetsStart=[-1 for i in idc] if OffsetsEnd is None: OffsetsEnd=[0 for i in idc] if self.Verbose and VarName is not None: print('Offsets::: VarName:{}; OffsetStart:{}; OffsetEnd:{}'.format(VarName,OffsetsStart,OffsetsEnd)) if (len(idl)!=len(idr)): raise ValueError('Cannot parse expression with incomplete bracket:',Dim) Ind.extend([i for i in idc if all([False for (il,ir) in zip(idl,idr) if i>=il and i<=ir])]) DimArgs = [Dim[i+1:j] for i,j in zip(Ind, Ind[1:]+[None])] #print('DimArgs:',DimArgs) if len(DimArgs)>len(OffsetsEnd): print('VarName:{} :: # of elements in DimArgs:{} > # of elements in OffsetsEnd:{}'.format(VarName,DimArgs,OffsetsEnd)) OffsetsEnd=[0 for d in DimArgs] OffsetsStart=[-1 for d in DimArgs] for (D,OffsetStart,OffsetEnd) in zip(DimArgs,OffsetsStart,OffsetsEnd): #print('D:',D) d=D.strip() if d!='': rout=[] IsFirst=True for r in d.split(':'): rr=self.__ParseMathSymbol(r) outrr=[] for rrr in rr: if rrr in self.MathSymbols: outrr.append(rrr) else: O=self.__ParseVariable(rrr,ForceCheck=False,IsDim=True) outrr.extend(O) routrr=outrr if IsFirst: if len(routrr)==1 and routrr[0].isnumeric(): routrr=[str(int(routrr[0])+OffsetStart)] else: if OffsetStart>0: routrr.extend('+'+str(OffsetStart)) elif OffsetStart<0: routrr.extend(str(OffsetStart)) else: if len(routrr)==1 and routrr[0].isnumeric(): routrr=[str(int(routrr[0])+OffsetEnd)] else: #if OffsetEnd!=0: if OffsetEnd>0: routrr.extend('+'+str(OffsetEnd)) elif OffsetEnd<0: routrr.extend(str(OffsetEnd)) IsFirst=False rout.append(''.join(routrr)) Dout.append(':'.join(rout)) else: Dout.append(':') Dout=','.join(Dout) return Dout @staticmethod def IsFloat(Str): try: float(Str) # for int, long and float except ValueError: return False return True def findall(self,string,substring): """ Function: Returning all the index of substring in a string Arguments: String and the search string Return:Returning a list """ length = len(substring) c=0 indexes = [] while c < len(string): if string[c:c+length] == substring: indexes.append(c) c=c+1 return indexes
class UBoxRunSettings(): @staticmethod def DefaultNumerics(): Dic = {} Dic['dtreal'] = 1e-8 Dic['t_stop'] = 10 Dic['ftol_min'] = 1e-10 Dic['ftol_dt'] = 1e-10 Dic['ftol'] = 1e-8 Dic['itermx'] = 7 Dic['rlx'] = 0.9 Dic['incpset'] = 7 Dic['isbcwdt'] = 1 return Dic def SetDefaultNumerics(self): self.SetPackageParams(self.DefaultNumerics()) def OverrideObjectParams(self, **kwargs): """ Args: **kwargs (TYPE): DESCRIPTION. Returns: None. """ for k, v in kwargs.items(): if self.__dict__.get(k) is not None: self.__dict__[k] = v def SetPackageParams(self, Dic: dict): """ Args: Verbose (TYPE, optional): DESCRIPTION. Defaults to False. Returns: None. """ for A, V in Dic.items(): if V is not None: if not hasattr(self, 'Doc') or self.Doc is None: self.Doc = UBoxDoc() Result = self.Doc.Search(A.split('[')[0], Exact=True, Silent=True) if len(Result) > 0: Pkg = Result[0]['Package'] comm = '{}.{}={}'.format(Pkg, A, V) if self.Verbose: print(comm) try: exec(comm, globals(), globals()) except: print('Cannot set {}.{} = {} '.format(Pkg, A, V)) else: print('No package found for {}'.format(A)) def SetUEDGEParams(self, **kwargs): """ Args: Verbose (TYPE, optional): DESCRIPTION. Defaults to False. Returns: None. """ for k, v in kwargs: pass
class UBoxDataFilter(): """Utility class to handle construction of list of variables.""" @ClassInstanceMethod def CollectUEDGEDataSet(self,DataSet=None,ExtraVars:list=[])->dict: return self.CollectDataSet(DataSet,DataType='UEDGE',ExtraVars=ExtraVars)['UEDGE'] @ClassInstanceMethod def CollectDataSet(self,DataSet=None,DataType='UEDGE',ExtraVars:list=[],RemovePackage=False)->dict: """ Get a list of variable names from a data set/or and a list of variable name and return a dictionary with variable names as keys and variable values as values. Args: DataSetName (str or None, optional): Name of a data set. ExtraVars (list(str), optional): List of variable names. Return: dict: dictionary dict[variable name]=variable value. """ if type(DataType)!=str: raise ValueError('DataType must be a string') VarList=self.MakeVarList(DataSet,ExtraVars) Data=self.CollectData(VarList,DataType,RemovePackage) return {DataType:Data} @ClassInstanceMethod def CollectData(self,VarList:str or list,DataType='UEDGE',RemovePackage=False): if type(VarList)!=list: VarList=[VarList] VarList=[self.AddPackage(V,DataType) for V in VarList] if self.Verbose: print("Varlist to be collected:",VarList) if DataType=='UEDGE': Data=self.UEDGEDataToDict(VarList,RemovePackage=RemovePackage,Verbose=self.Verbose) else: Data=self.StoredDataToDict(VarList,DataType,RemovePackage=RemovePackage,Verbose=self.Verbose) return Data @ClassInstanceMethod def MakeVarList(self,DataSet:str or None or list or tuple=None,VarList=[],ExtraVars:list=[]): """ Return a list of variable names from a dataset and/or a tuple of variable names or a list of dataset/tuple. Warning: Tuple cannot contain only one element when created. To create tuple of length 1, type: tuple(1,) Example: >>> UBoxIO.MakeVarList(['grid']) ['iysptrx', 'ngsp', 'nisp', 'nx', 'ny', 'rm', 'zm'] >>> UBoxIO.MakeVarList(('te','ti')) ['te', 'ti'] >>> UBoxIO.MakeVarList(['grid',('SpecialField',)]) ['SpecialField', 'iysptrx', 'ngsp', 'nisp', 'nx', 'ny', 'rm', 'zm'] Args: DataSetName (str, optional): Name of a data set. Defaults to None. ExtraVars (list(str), optional): List of variable names. Defaults to []. Returns: List (TYPE): DESCRIPTION. """ List=ExtraVars.copy() if DataSet is None: List.extend(self.GetDataSet(DataSet)) elif type(DataSet)==tuple: List.extend([v for v in DataSet]) else: if type(DataSet)==str: DataSet=[DataSet] if type(DataSet)==list: for Set in DataSet: if type(Set)==tuple: List.extend(list(Set)) else: if Set=='all': List.extend(VarList) else: List.extend(self.GetDataSet(Set)) if type(DataSet)==tuple: List.extend(list(DataSet)) List=list(dict.fromkeys(List)) List.sort() if self.Verbose: print('Output MakeVarList for DataSet "{}" : {} with ExtraVars:{}'.format(DataSet,List,ExtraVars)) return List @ClassInstanceMethod def SetDoc(self): from UEDGEToolBox.Utils.Doc import UBoxDoc if not hasattr(self,'Doc') or self.Doc is None: self.Doc=UBoxDoc() @staticmethod def SplitVarName(VarName): Str=VarName.split('.') if len(Str)>1: return tuple(Str) else: return (None,Str) @ClassInstanceMethod def FindPackage(self,VarName:str,SearchUEDGEPackage=True)->str: Str=VarName.split('.') if len(Str)>1: return Str[0] elif SearchUEDGEPackage: self.SetDoc() DicVar=self.Doc.Search(VarName,Exact=True,Silent=True) if len(DicVar)>1: raise ValueError('More than one package found for {}'.format(VarName)) if len(DicVar)<1: return None return DicVar[0]['Package'] else: return None @ClassInstanceMethod def SelectData(self,Data:dict,DataSet=None,DataType='UEDGE')->dict: """Return a subset of a dictionary with keys set by a loader.""" if DataType=='' or DataType is None: D=Data else: D=Data.get(DataType) if D is not None and type(D)==dict: # Check if a DataType entry is present and if it is a dictionary and get variables with a packagename DataOut=dict((k,v) for (k,v) in D.items() if type(v)!=dict) else: DataOut=dict((k,v) for (k,v) in Data.items() if type(v)!=dict) ListUEDGEPkg=GetListPackage() VarList=self.MakeVarList(DataSet,VarList=list(DataOut.keys())) VarList=self.AddPackage(VarList,DataType) if DataType=='UEDGE': DataOut=dict((self.AddPackage(k,DataType),v) for (k,v) in DataOut.items() if self.FindPackage(k) in ListUEDGEPkg and k in VarList) else: DataOut=dict((self.AddPackage(k,DataType),v) for (k,v) in DataOut.items() if k in VarList) return DataOut @staticmethod def RemovePkg(VarName:str)->str: """Return variable name without object prefix. Example: >>> RemovePkg('bbb.te') 'te' """ if len(VarName.split('.'))>1: return VarName.split('.')[1] else: return VarName @ClassInstanceMethod def AddPackage(self,VarName,DataType='UEDGE'): """Add the name of a package/object to a variable name if no package/object is present. Example: >>> AddPackage('te',DataType='UEDGE') 'bbb.te' >>> AddPackage('te',DataType='DataStore') 'DataStore.te' >>> AddPackage('ccc.te') 'ccc.te' """ if type(VarName)==list: return [self.AddPackage(V,DataType) for V in VarName] else: if VarName.count('.')>0: return VarName if DataType=='' or DataType is None: return VarName elif DataType=='UEDGE': return self.AddUEDGEPackage(VarName) elif DataType!='': return '{}.{}'.format(DataType,VarName) @ClassInstanceMethod def AddUEDGEPackage(self,VarName:str or list,Verbose:bool=False)->list: """ Add UEDGE package in front variable names when variable is part of an UEDGE pakage. Example: >>> ProcessVarList('ne') 'bbb.ne' Returns ------- list: DESCRIPTION. """ Pkg=self.FindPackage(VarName,SearchUEDGEPackage=True) if Pkg is not None: return "{}.{}".format(Pkg,VarName) else: return VarName @ClassInstanceMethod def StoredDataToDict(self,VarList:list,DataType:str,RemovePackage=False)->dict: if DataType=='': raise ValueError('DataType cannot be an empty string ...') if hasattr(self,DataType) and type(getattr(self,DataType))==dict: if RemovePackage: Data=dict((K,V) for (K,V) in getattr(self,DataType).items() if self.AddPackage(K,DataType) in VarList) else: Data=dict((DataType+'.'+K,V) for (K,V) in getattr(self,DataType).items() if self.AddPackage(K,DataType) in VarList) return Data else: print('Cannot retrieve dictionary "{}" from current object...'.format(DataType)) return {} @staticmethod def UEDGEDataToDict(VarList:list,RemovePackage=False,Verbose=False)->dict: """ Save a list of UEDGE and regular variables into a dictionary (e.g. VarList=['ne'] -> Dic['ne']=bbb.ne). Args: DataSetName (str or None, optional): DESCRIPTION. Defaults to None. ExtraVars (list(str), optional): DESCRIPTION. Defaults to []. Returns ------- TYPE: DESCRIPTION. """ for pkg in GetListPackage(): exec('from uedge import '+pkg) Dic=locals() Dic['Data']={} for V in VarList: if Verbose:print('Preparing data {}'.format(V)) if RemovePackage: #remove package name : bbb.ne->ne if len(V.split('.'))>1 : VV=V.split('.')[1] else: VV=V else: VV=V try: if Verbose: print('Executing: ',"Data['{}']={}".format(VV,V)) exec("Data['{}']={}".format(VV,V),globals(),Dic) except Exception as e: if Verbose: print('Error:',repr(e)) print('Unable to collect data "{}" from UEDGE package "{}"'.format(V,VV)) if Dic.get('Data') is None: Data={} else: Data=Dic['Data'] return Data
def SetDoc(self): from UEDGEToolBox.Utils.Doc import UBoxDoc if not hasattr(self,'Doc') or self.Doc is None: self.Doc=UBoxDoc()
class UBoxSimUtils(UBoxGrid, UBoxSource, UBoxDataSet): def __init__(self, Verbose=False, *args, **kwargs): # Import Uedge packages as attribute of the class instance # WARNING: this is not a deep copy!!! super().__init__() self.InputLines = [] self.ListPkg = GetListPackage() self.Verbose = Verbose print('Loaded Packages:', self.ListPkg) self.ExcludeList = ['ExcludeList', 'ListPkg', 'IO'] + self.ListPkg self.SetDefault() def SetDefault(self): self.UBoxRunDefaults = { 'Jmax': 5, 'Imax': 3000, 'mult_dt_fwd': 3.4, 'mult_dt_bwd': 3, 'ISave': 10, 'SaveSim': True } self.UBoxRunDefaults['dt_ftol_threshold'] = 5e-11 self.UBoxRunDefaults['dt_ContCallOff_min'] = 5e-2 self.UBoxRunDefaults['dt_ContCallOff_max'] = 5e-3 self.UBoxRunDefaults['CorrectTemp'] = 1.602176634e-19 self.UBoxRunDefaults['Adjustftol'] = False self.UBoxRunDefaults['ContCall'] = True self.bbbRunDefault = {} self.bbbRunDefault['dt_tot'] = 0 self.bbbRunDefault['dtreal'] = 5e-8 self.bbbRunDefault['t_stop'] = 10 self.bbbRunDefault['ftol_min'] = 1e-10 self.bbbRunDefault['ftol_dt'] = 1e-9 self.bbbRunDefault['itermx'] = 25 self.bbbRunDefault['rlx'] = 0.9 self.bbbRunDefault['incpset'] = 10 self.bbbRunDefault['isbcwdt'] = 1 self.SetPackageParams(self.bbbRunDefault) self.SetPackageParams(self.UBoxRunDefaults, self, AddAttr=True) def SetUEDGEParams(self, Dic: dict): Dic = dict((k, v) for k, v in Dic.items() if k in list(self.bbbRunDefault.keys())) self.SetPackageParams(Dic) def SetPackageParams(self, Dic: dict, Pkg=None, AddAttr=False): """ Args: Verbose (TYPE, optional): DESCRIPTION. Defaults to False. Returns: None. """ if Pkg is None: if not hasattr(self, 'Doc') or self.Doc is None: self.Doc = UBoxDoc() for A, V in Dic.items(): if V is not None: Result = self.Doc.Search(A.split('[')[0], Exact=True, Silent=True) if len(Result) > 0: Pkg = Result[0]['Package'] comm = '{}.{}={}'.format(Pkg, A, V) if self.Verbose: print('Setting {}'.format(comm)) try: exec(comm, globals(), globals()) except: print('Cannot set {}.{} = {} '.format(Pkg, A, V)) else: print('No package found for {}'.format(A)) else: for A, V in Dic.items(): if AddAttr or hasattr(Pkg, A): if self.Verbose: print('Setting {}.{}={}'.format(Pkg, A, V)) setattr(Pkg, A, V) @staticmethod def InitPlasma(): bbb.ngs = 1e18 bbb.ng = 1e18 bbb.nis = 1e18 bbb.ni = 1e18 bbb.ups = 0.0 bbb.up = 0.0 bbb.tes = 1 * bbb.ev bbb.te = 1 * bbb.ev bbb.tis = 1 * bbb.ev bbb.ti = 1 * bbb.ev bbb.tgs = 1 * bbb.ev bbb.tg = 1 * bbb.ev bbb.phis = 0 bbb.phi = 0 def PrintTimeStepModif(self, i): self.PrintInfo('New time-step = {:.4E}'.format(bbb.dtreal), color=Back.MAGENTA) def PrintError(self, E, i, j=None): if j is None: self.PrintInfo( '{cn}: Exmain failure i={i}/{imax} dtreal={dt:.4E}' .format(cn=self.CaseName, i=i, imax=self.Imax, dt=bbb.dtreal), color=Back.RED) else: self.PrintInfo( '{cn}: Exmain failure i={i}/{imax} j={j}/{jmax} dtreal={dt:.4E}' .format(cn=self.CaseName, i=i, imax=self.Imax, j=j, jmax=self.Jmax, dt=bbb.dtreal), color=Back.RED) print("Exception: {}".format(E)) def PrintCurrentIteration(self, i, j=None): if j is None: self.PrintInfo( '{cn}: Main loop i={i}/{imax} dtreal={dt:.4E}'.format( cn=self.CaseName, i=i, imax=self.Imax, dt=bbb.dtreal), color=Back.BLUE) else: self.PrintInfo( '{cn}: Subloop i={i}/{imax} j={j}/{jmax} dtreal={dt:.4E}'. format(cn=self.CaseName, i=i, imax=self.Imax, j=j, jmax=self.Jmax, dt=bbb.dtreal), color=Back.YELLOW) def PrintInfo(self, Str, color=Back.CYAN, Extra=False): if Extra: print( "*---------------------------------------------------------*") print("{color}{}{reset}".format(Str, color=color, reset=Style.RESET_ALL)) if Extra: print( "*---------------------------------------------------------*") def SaveLast(self, DataSet='regular'): self.Save('last', DataSet=DataSet, DataType='UEDGE', OverWrite=True) def GetFinalStateFileName(self, WithDate=False): if WithDate: return self.SetFormat('final_state_{}'.format(GetTimeStamp()))[1] else: return self.SetFormat('final_state')[1] def SaveFinalState(self, DataSet='regular'): self.Save(self.GetFinalStateFileName(), DataSet=DataSet, DataType='UEDGE', OverWrite=True) self.Save(self.GetFinalStateFileName(WithDate=True), DataSet=DataSet, DataType='UEDGE', OverWrite=True) def AutoSave(self, DataSet='regular'): self._iSave += 1 if self._iSave > self.ISave: self._iSave = 1 self.Save('save_{}'.format(GetTimeStamp()), DataSet=DataSet, DataType='UEDGE') def GetTag(self) -> dict: """ Generate a dictionary containing settings of a UBox instance. Args: UBoxObject (UBoxSimulation, optional): Simulation instance. Defaults to None. Return: Dictionary with """ try: from uedge import __version__ except: __version__ = None try: from uedge import GitHash except: GitHash = None today = date.today() now = datetime.now() Tag = {} Tag['Date'] = today.strftime("%d%b%Y") Tag['Time'] = now.strftime("%H-%M-%S") Tag['GitHash'] = GitHash Tag['Version'] = __version__ if hasattr(self, 'UserName'): Tag['User'] = self.UserName else: Tag['User'] = '******' if not hasattr(self, 'PlatForm') or getattr(self, 'PlatForm') is None: self.PlatForm = GetPlatform() Tag['PythonVersion'] = self.PlatForm['python_version'] Tag['Machine'] = self.PlatForm['machine'] Tag['Processor'] = self.PlatForm['processor'] Tag['PlatForm'] = self.PlatForm['platform'] if hasattr(self, 'CurrentProject') and self.CurrentProject is not None: Tag['Project'] = self.CurrentProject.toDict() else: Tag['Project'] = {} if hasattr(self, 'Description'): Tag['CaseName'] = self.CaseName else: Tag['CaseName'] = '' if hasattr(self, 'Description'): Tag['Description'] = self.Description else: Tag['Description'] = '' return Tag @ClassInstanceMethod def GetData(self, Field: str, DataType: str = 'UEDGE', CorrectTempUnit=True): """Get data values from data dictionary stored in the instance.""" Out = self.CollectData(Field, DataType, RemovePackage=True) if self.Verbose: print('GetData:', Out) Out = Out.get(Field) if Out is not None and Out.size == 1 and Out.dtype.char == 'S': Out = Out[0].decode().strip() F = Field.lower() if Field.count('.') > 0: F = F.split('.')[1] if Out is not None and CorrectTempUnit and any( [F == L for L in ['tes', 'tis', 'tgs', 'te', 'ti', 'tg']]): if not hasattr(self, 'CorrectTemp'): self.CorrectTemp = 1.602176634e-19 Out = Out / self.CorrectTemp return Out @ClassInstanceMethod def GetDataField(self, Field: str or list, DataType: str = 'UEDGE'): """Get data values from data dictionary stored in the instance.""" if DataType is None: DataType = 'UEDGE' if type(Field) == str: return self.GetData(Field, DataType) elif type(Field) == list: return [self.GetData(k, DataType) for k in Field] else: raise IOError('Field must be a string or a list of strings') # # def GetDataField(self,Field): # # if type(Field)!=str: # # raise ValueError('Field must be a string') # # return self.CollectUEDGEData(Field).get(Field) # # def GetData(self,Field): # # if type(Field)==str: # # Field=(Field,) # # if type(Field)==list: # # Field=tuple(Field) # Dic=self.CollectUEDGEData(Field) # return dict((self.RemovePkg(k),v) for k,v in Dic.items()) # def GetData(self,Field,Package='bbb'): # """ # Args: # Field (TYPE): DESCRIPTION. # Package (TYPE, optional): DESCRIPTION. Defaults to 'bbb'. # Returns: # TYPE: DESCRIPTION. # """ # self.GetPackage # # UEDGE packages are reloaded in the local namespace of the method. # #However, no new instances of UEDGE packages are created. # # Instances in the local namespace are the same instances that were previously loaded # for pkg in self.ListPkg: # exec('from uedge import '+pkg) # Out=locals() # comm='{}={}.{}'.format(Field.lower(),Package,Field.lower()) # if self.Verbose: print('Retrieving data:',comm) # try: # exec(comm,globals(),Out) # except: # print('Cannot set {}={}.{} '.format(Field,Package,Field)) # if Out.get(Field) is None: # print('Cound not get data for {}'.format(Field)) # return Out.get(Field.lower()) # def SetData(self): # for pkg in self.ListPkg: # exec('from uedge import '+pkg) # Out=locals() # comm='{}={}.{}'.format(Field.lower(),'bbb',Field.lower()) # if self.Verbose: print('Setting data:',comm) # try: # exec(comm,globals(),Out) # except: # print('Cannot set {}={}.{} '.format(Field,'bbb',Field)) # if Out.get(Field) is None: # print('Cound not get data for {}'.format(Field)) # self.Data=Out def GetGrid(self): self.SetGrid() return self.Grid def SetGrid(self, Grid=None): if Grid is None: Dic = self.CollectDataSet(DataSet='grid', DataType='UEDGE')['UEDGE'] self.Grid = dict((self.RemovePkg(k), v) for k, v in Dic.items()) else: self.Grid = Grid if hasattr(self, 'SetPsinc'): self.SetPsinc() # @classmethod # def GetClassAttr(cls,Verbose=False): # """ # Args: # cls (TYPE): DESCRIPTION. # Verbose (TYPE, optional): DESCRIPTION. Defaults to False. # Returns: # Attr (TYPE): DESCRIPTION. # """ # Attr = dict((k,v) for k,v in cls.__dict__.items() if '__' not in k and not isinstance(v,types.FunctionType) and not isinstance(v,classmethod)) # if Verbose: print(Attr) # return Attr # def GetInstanceAttr(self,Verbose=False): # Attr = dict((k,v) for k,v in self.__dict__.items() if '__' not in k and not isinstance(v,types.FunctionType) and not isinstance(v,classmethod)) # if Verbose: print(Attr) # return Attr # @classmethod # def ShowClass(cls,Verbose=False): # Attr = dict((k,v) for k,v in cls.__dict__.items() if '__' not in k and not isinstance(v,types.FunctionType) and not isinstance(v,classmethod)) # if Verbose: print(Attr) # for A,V in Attr.items(): # comm='print("{}","=",)'.format(A,V) # print('{}={}'.format(A,V)) def Show(self, Verbose=False): print('Internal UEDGE parameters:') for A, V in self.GetInstanceAttr().items(): Result = SearchSilent(A) if len(Result) > 0: Pkg = Result[0]['Package'] print(' - {}.{}={}'.format(Pkg, A, V)) else: print(' - XXX.{}={}'.format(A, V)) print('\n Run parameters:') for A, V in self.__class__.GetClassAttr().items(): print(' - {}={}'.format(A, V)) # def OverrideClassParams(self,**kwargs): # #Override class attribute # Dic=self.__class__.GetClassAttr() # for k,v in kwargs.items(): # if k in Dic: # self.__class__.__dict__[k]=v def SetCaseName(self, CaseName): self.CaseName = CaseName def GetCaseName(self): try: return bbb.CaseName[0].decode().rstrip() except: return None def SetDescription(self, Str): self.Description = Str def GetDescription(self): return self.Description def GetVersion(self): return uedge.__version__ def GetGitHash(self): return uedge.GitHash def SetVersion(self): try: bbb.uedge_ver = uedge.__version__ except: print('Cannot set Uedge version') @staticmethod def Pandf(): bbb.pandf1(-1, -1, 0, bbb.neq, 1., bbb.yl, bbb.yldot) def Updateftol(self): bbb.ylodt = bbb.yl bbb.pandf1(-1, -1, 0, bbb.neq, 1., bbb.yl, bbb.yldot) fnrm_old = math.sqrt( sum((bbb.yldot[0:bbb.neq - 1] * bbb.sfscal[0:bbb.neq - 1])**2)) ftol_dt = bbb.ftol_dt * self.AdjustFtolTime(bbb.dtreal, self.dt_ftol_threshold) if ftol_dt != bbb.ftol_dt: self.PrintInfo( 'Increasing ftol_dt: ftol_dt={} | bbb.ftol_dt={}'.format( ftol_dt, bbb.ftol_dt)) return max(min(ftol_dt, 0.01 * fnrm_old), bbb.ftol_min) @staticmethod def AdjustFtolTime(dt, dt0=1e-11, p=2.5): if type(dt) != np.ndarray: if dt > dt0: return 1.0 else: return (dt0 / dt)**p else: f = (dt0 / dt)**p f[(dt > dt0)] = 1.0 return f @staticmethod def Resetftol(): bbb.ftol_min = 1e-10 bbb.ftol_dt = 1e-10 print("Reset ftol: bbb.ftol_dt={};bbb.ftol_min={}".format( bbb.ftol_min, bbb.ftol_dt)) @staticmethod def Setftol(ftol): bbb.ftol_min = ftol bbb.ftol_dt = ftol print("Set ftol to {}".format(ftol)) @staticmethod def Changeftol(factor): bbb.ftol_min *= factor bbb.ftol_dt *= factor print("Change ftol by a factor {}: bbb.ftol_dt={};bbb.ftol_min={}". format(factor, bbb.ftol_min, bbb.ftol_dt)) def Controlftol(self, dtreal_threshold=5e-10, Mult=10): if self.Adjustftol: if not hasattr(self, 'CftolCount'): self.CftolCount = 0 if not hasattr(self, 'CftolMult'): self.CftolMult = Mult if not hasattr(self, 'dtreal_bkp'): self.dtreal_bkp = bbb.dtreal if not hasattr(self, 'dtreal_threshold'): self.dtreal_threshold = dtreal_threshold if bbb.dtreal < self.dtreal_threshold: print('CftolCount:', self.CftolCount) if bbb.dtreal < self.dtreal_bkp: self.Changeftol(self.CftolMult) self.CftolCount += 1 else: if self.CftolCount > 0: self.Changeftol(1 / self.CftolMult) self.CftolCount -= 1 else: if self.CftolCount > 0: self.Changeftol(1 / self.CftolMult) self.CftolCount -= 1 self.dtreal_bkp = bbb.dtreal def SetContCall(self): if bbb.dtreal >= self.dt_ContCallOff_min and bbb.dtreal <= self.dt_ContCallOff_max: self.ContCall = False else: if self.dt_ContCallOff_min < self.dt_ContCallOff_max: self.ContCall = True