The script main.py follows.
import os import solver def CreateValuesLoad(analysis): analysis.CreateLoadObject("Values") initValues = {} sol = None solbystep = SerializableDictionary[int,dict]() values = {} steps = [] res = [0.] dScal = [0.] dVec = [0., 0., 0.] def WriteInitialValues(load,filename): global initValues propEx = load.Properties["Expression"] exp = propEx.Value if exp=="": return None vexp = compile(exp,'','eval') values = [] propGeo = load.Properties["Geometry"] refIds = propGeo.Value.Ids mesh = load.Analysis.MeshData for refId in refIds: meshRegion = mesh.MeshRegionById(refId) nodeIds = meshRegion.NodeIds for nodeId in nodeIds: node = mesh.NodeById(nodeId) x = node.X y = node.Y z = node.Z v = 0. try: v = eval(vexp) v = float(v) finally: initValues.Add(nodeId,v) def NodeValues(load,nodeIds): propEx = load.Properties["Expression"] exp = propEx.Value if exp=="": return None try: vexp = compile(exp,'','eval') except: return None values = [] mesh = load.Analysis.MeshData for id in nodeIds: node = mesh.NodeById(id) x = node.X y = node.Y z = node.Z v = 0. try: v = eval(vexp) v = float(v) finally: values.Add(v) return values def Solve(s): global steps global initValues global sol global solbystep global values solbystep = SerializableDictionary[int,dict]() solbystepTmp = {} f = open("solve.out","w") f.write("SolverEngine version 1.0\n\n\n") try: maxIter = int(s.Properties["MaxIter"].Value) f.write("Max. iteration : %d\n" % (maxIter)) mesh = s.Analysis.MeshData numEdges = 0 geo = ExtAPI.DataModel.GeoData nodeIds = [] for asm in geo.Assemblies: for part in asm.Parts: for body in part.Bodies: for edge in body.Edges: numEdges = numEdges + 1 ids = mesh.MeshRegionById(edge.Id).NodeIds nodeIds.extend(ids) steps = [] stepsTmp = [] f.write("Num. edges : %d\n" % (numEdges)) sol = solver.SolverEngine(mesh,initValues,nodeIds) initValues = sol.Run(maxIter,f,stepsTmp,solbystepTmp) nodeIds = mesh.NodeIds sol = solver.SolverEngine(mesh,initValues,nodeIds) values = sol.Run(maxIter,f,steps,solbystep) initValues = {} except StandardError, e: f.write("Error:\n"); f.write(e.message+"\n"); f.close() return False f.close() return True def GetSteps(solver): global steps return steps def Save(folder): global solbystep fm = System.Runtime.Serialization.Formatters.Binary.BinaryFormatter() try: stream = System.IO.StreamWriter(os.path.join(folder,"sol.res"),False) except: return try: fm.Serialize(stream.BaseStream,solbystep) finally: stream.Close() def Load(folder): global solbystep if folder==None: return fm = System.Runtime.Serialization.Formatters.Binary.BinaryFormatter() try: stream = System.IO.StreamReader(os.path.join(folder,"sol.res")) except: return try: solbystep = fm.Deserialize(stream.BaseStream) finally: stream.Close() class ExtSolver1Reader(ResultReaderBase): def __init__(self,infos): self.infos = infos self.step = 1 def get_CurrentStep(self): return self.step def set_CurrentStep(self,step): self.step = step def StepValues(self): global steps return steps def ResultNames(self): return ["U","VALUES"] def GetResultLocation(self,resultName): return "node" def GetResultType(self,resultName): if resultName=="U": return "vector" return "scalar" def ComponentNames(self,resultName): if resultName=="U": return ["X","Y","Z"] else: return ["VALUES"] def ComponentUnit(self,resultName,componentName): if resultName=="U": return "Length" return "Temperature" def GetValues(self,resultName,entityId): global values global solbystep global dVec global dScal if resultName=="U": values = solbystep[self.step] dVec[0] = 0. dVec[1] = 0. dVec[2] = 0. try: dVec[0] = values[entityId] finally: return dVec else: values = solbystep[self.step] try: dScal[0] = values[entityId] return dScal except: return None def GetReader(solver): return ["ExtSolver1Reader"]
The second line of the script main.py is import
solver
. The solver code is located in a separate script,
solver.py, which is placed in the same folder as
main.py. This technique of importing another script
supports reuse and maintainability. The script in solver.py
defines the class SolverEngine
.
The function Solve
is associated with the callback
<onsolve>
. This function creates a file
solve.out, which is read interactively by the product and
stored in the solution information.
By default, the product starts the resolution directly in the working directory, so it is not necessary to set the folder in which the file solve.out must be created.
The callback function must return True
or
False
to specify if the solve has succeeded or
failed.
Currently, it is not possible to return progress information.