Source code for Muscat.FE.WeakForms.NumericalWeakForm
# -*- coding: utf-8 -*-## This file is subject to the terms and conditions defined in# file 'LICENSE.txt', which is part of this source code package.#importnumpyasnpfromsympyimportpprintfromsympy.core.containersimportTuplefromsympyimportSymbol,FunctionfromMuscat.FE.SymWeakFormimportGetNormalUseCpp=Falsetry:fromMuscat.FE.WeakForms.NativeNumericalWeakFormimportPyWeakTermasPyWeakTermfromMuscat.FE.WeakForms.NativeNumericalWeakFormimportPyWeakMonomasPyWeakMonomfromMuscat.FE.WeakForms.NativeNumericalWeakFormimportPyWeakFormasPyWeakFormUseCpp=Trueexcept:UseCpp=Falseprint("Warning NativeNumericalWeakForm (cpp) not available, using python variant")classPyWeakForm(object):def__init__(self):super().__init__()self.form=[]defAddTerm(self,monom):self.form.append(monom)defGetNumberOfTerms(self):returnlen(self.form)defGetMonom(self,i):returnself.form[i]defGetRightPart(self,unknownvars):res=PyWeakForm()forpinself:foruvinunknownvars:ifp.hasVariable(uv):breakelse:res.AddTerm(p)returnresdefGetLeftPart(self,unknownvars):res=PyWeakForm()forpinself:tocopy=Falseforuvinunknownvars:ifp.hasVariable(uv):tocopy=Truebreakiftocopy:res.AddTerm(p)returnresdefGetMaxDerivativeDimensionality(self):""" return the number of coordinate needed on the mesh to correctly compute the derivatives"""res=0forpinself:tocopy=Falseforminp:ifm.derDegree>0andm.normal==0:res=max(res,m.derCoordIndex_+1)returnresdef__str__(self):res=""foriinrange(self.GetNumberOfTerms()):res+=str(self.GetMonom(i))+"\n"returnresdef__iter__(self):returniter(self.form)classPyWeakMonom(object):def__init__(self):super().__init__()self.prefactor=1self.prod=[]defAddProd(self,term):self.prod.append(term)defGetNumberOfProds(self):returnlen(self.prod)defGetProd(self,n):returnself.prod[n]defhasVariable(self,var):forminself:ifm.fieldName==str(var):returnTruereturnFalsedef__str__(self):res=str(self.prefactor)foriinrange(self.GetNumberOfProds()):res+="*"res+=str(self.GetProd(i))returnresdef__iter__(self):returniter(self.prod)defcopy(self):importcopyreturncopy.deepcopy(self)classPyWeakTerm(object):EnumError=-1EnumNormal=0EnumConstant=1EnumUnknownField=2EnumTestField=3EnumExtraField=4EnumExtraIPField=5def__init__(self):super().__init__()self.fieldName=""self.derCoordName=""self.derDegree=-1self.constant=Falseself.normal=False# internal data repr for integrationself.internalType=PyWeakTerm.EnumErrorself.spaceIndex_=Noneself.numberingIndex_=Noneself.valuesIndex_=Noneself.modeIndex_=Noneself.derCoordIndex_=Nonedef__str__(self):res=""ifself.derDegree>0andself.normal==0:# #res += "d" + self.fieldName + "/" + "d" + str(self.derCoordName)res+="Derivative("+str(self.fieldName)+", "+str(self.derCoordName)+","+str(self.derDegree)+")"else:res+=self.fieldNamereturnresdefcopy(self):importcopyreturncopy.deepcopy(self)
[docs]defSymWeakMonomToNumWeakMono(exp):fromsympy.core.mulimportMulfromsympy.core.powerimportPowifexp.func==Mul:res=PyWeakMonom()forarginexp.args:ifarg.is_Number:res.prefactor=float(arg)continueifisinstance(arg,Pow):term=ConverTermToProd(arg.args[0])iftermisNone:print(type(arg.args[0]))print(arg.args[0])raise(Exception("Unable to treat term "+str(arg.args[0])))foriinrange(arg.args[1]):res.AddProd(term)continueterm=ConverTermToProd(arg)iftermisnotNone:#res.prod.append(term)res.AddProd(term)continueprint(type(arg))print(arg)raisereturnreselse:#only one term no productres=PyWeakMonom()term=ConverTermToProd(exp)iftermisnotNone:res.AddProd(term)returnres
__cached_normal=GetNormal(3)
[docs]defConverTermToProd(arg):ifisinstance(arg,Symbol):t=PyWeakTerm()t.constant=Truet.derDegree=0t.fieldName=str(arg)returntfromsympy.core.functionimportDerivativeiftype(arg)==Derivative:t=PyWeakTerm()t.fieldName=str(arg.args[0].func)#Python 3t.derDegree=1ifTuple==type(arg.args[1]):#sympy 1.2t.derCoordName=str(arg.args[1][0])else:#sympy 1.1.1t.derCoordName=str(arg.args[1])sn=[]foriinrange(0,len(arg.args[0].args)):sn.append(str(arg.args[0].args[i]))t.derCoordIndex_=sn.index(t.derCoordName)returntifisinstance(arg,Function):t=PyWeakTerm()#print(str(arg.func)+"* * * * * * ")#print(arg.func)#print (N)#print ([arg == nc for nc in N])ifnp.any([arg==ncforncin__cached_normal]):t.normal=Truet.derDegree=int(str(arg.func).split("_")[1])else:t.derDegree=0t.fieldName=str(arg.func)returntraiseException(f"Error!! arg of type ({type(arg)}) not supported: {arg}")