def __init__(self, meshes, models): self.geomFields = models.geomFields self.enableElecModel = models.enableElecModel self.enableFlowModel = models.enableFlowModel if self.enableElecModel == True: self.elecFields = models.elecFields else: print 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' print 'elecModel is OFF; Canot apply IBM on potential field' print 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' if self.enableFlowModel == True: self.flowFields = models.flowFields else: print 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' print 'flowModel is OFF; Canot apply IBM on flow field' print 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' self.solidBoundaryMeshes = meshes.solidBoundaryMeshes self.fluidMeshes = meshes.fluidMeshesNew self.sbMeshFaces = self.solidBoundaryMeshes[0].getFaces() self.fluidMetricsCalculator = meshes.fluidMetricsCalculator self.ibManager = fvmbaseExt.IBManager(self.geomFields, self.solidBoundaryMeshes[0], self.fluidMeshes)
foptions = fmodel.getOptions() foptions.momentumLinearSolver = momSolver foptions.pressureLinearSolver = contSolver foptions.momentumTolerance = 1e-5 foptions.continuityTolerance = 1e-5 foptions.setVar("momentumURF", 0.7) foptions.setVar("pressureURF", 0.3) foptions.transient = False foptions.setVar("timeStep", timeStep) foptions.printNormalizedResiduals = True fmodel.init() sbMeshFaces = solidBoundaryMeshes[0].getFaces() ibManager = fvmbaseExt.IBManager(geomFields, solidBoundaryMeshes[0], fluidMeshes) faceCount = sbMeshFaces.getCount() area = geomFields.area[sbMeshFaces] velocity = area.newSizedClone(faceCount) velocitya = velocity.asNumPyArray() velocitya[:, :] = 0.0 #velocitya[:,1] = 1.0 flowFields.velocity[sbMeshFaces] = velocity velWhole = flowFields.velocity[fluidMeshes[0].getCells()].asNumPyArray() #velWhole[:,0] = 0.0 ibManager.solidNeighborsPerIBFace = 2 globalCount = 0 globalTime = 0.0
def solveModels(self, appliedVoltage): print "--Solving Models--" maxdeformation = [] numIterations = 200 globalTime = 0 globalCount = 0 timeStep = 2e-7 saveFrequency = 2 initialTransient = False probeIndex = 3240 pc = fvmbaseExt.AMG() pc.verbosity = 0 defSolver = fvmbaseExt.BCGStab() defSolver.preconditioner = pc defSolver.relativeTolerance = 1e-6 defSolver.absoluteTolerance = 1.e-15 defSolver.nMaxIterations = 50000 defSolver.verbosity = 1 poptions = self.pmodel.getOptions() poptions.deformationLinearSolver = defSolver poptions.deformationTolerance = 1.0e-3 poptions.setVar("deformationURF", 1.0) poptions.printNormalizedResiduals = True poptions.timeDiscretizationOrder = 2 poptions.transient = False poptions.scf = 5. / 6. poptions.setVar('timeStep', timeStep) ### elec solver ### epc = fvmbaseExt.AMG() epc.verbosity = 0 elecSolver = fvmbaseExt.BCGStab() elecSolver.preconditioner = epc elecSolver.relativeTolerance = 1e-3 elecSolver.nMaxIterations = 1000 elecSolver.maxCoarseLevels = 20 elecSolver.verbosity = 0 eoptions = self.emodel.getOptions() eoptions.electrostaticsLinearSolver = elecSolver eoptions.electrostaticsTolerance = 0.5e-5 eoptions.electrostatics_enable = 1 eoptions.chargetransport_enable = 0 eoptions.tunneling = 0 eoptions.ibm_enable = 1 eoptions.transient_enable = False eoptions.printNormalizedResiduals = True ### initialize models and run ### self.pmodel.init() self.emodel.init() self.dmodel.init() ibManager = fvmbaseExt.IBManager(self.geomFields, self.solidBoundaryMeshes[0], self.fluidMeshes) for Voltage in appliedVoltage: for mesh in self.solidBoundaryMeshes: faces = mesh.getFaces() areaMag = self.geomFields.areaMag[faces] faceCount = faces.getCount() pot = areaMag.newSizedClone(faceCount) pota = pot.asNumPyArray() pota[:] = appliedVoltage self.elecFields.potential[faces] = pot sbMeshFaces = self.solidBoundaryMeshes[0].getFaces() ibManager.fluidNeighborsPerIBFace = 4 ibManager.solidNeighborsPerIBFace = 4 ibManager.fluidNeighborsPerSolidFace = 6 t1 = time.time() #--------------Timestep Loop --------------------------# for n in range(0, numIterations): # checkMarking(globalCount) # --------------- update IBM -------------------------# print "*** update IBM at globalCount %i ***" % globalCount ibManager.update() self.fluidMetricsCalculator.computeIBInterpolationMatrices( sbMeshFaces) self.fluidMetricsCalculator.computeSolidInterpolationMatrices( sbMeshFaces) #------------solve electrostatics--------# print "*** solving electric model at globalCount %i ***" % globalCount for i in range(0, 20): self.emodel.computeIBFacePotential(sbMeshFaces) self.emodel.advance(1) self.emodel.computeSolidSurfaceForcePerUnitArea( sbMeshFaces) #saveVTK(n) #------------update force on beam ----------# print "*** update force at globalCount %i ***" % globalCount sbElecForce = self.elecFields.force[sbMeshFaces].asNumPyArray() solidMesh = self.solidMeshes[0] solidCells = solidMesh.getCells() nCells = solidCells.getCount() nSelfCells = solidCells.getSelfCount() nSBFaces = sbMeshFaces.getCount() if (nSBFaces != 2 * nSelfCells + (nCells - nSelfCells)): print "the extruded solid boundary mesh has wrong face numbers!" force = self.plateFields.force[solidCells].asNumPyArray() thickness = self.plateFields.thickness[ solidCells].asNumPyArray() force[:] = 0. ### Need to correct~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ thickness[:] = self.beam_thickness # force on interior cells for c in range(0, nSelfCells): botFaceIndex = c topFaceIndex = c + nSelfCells force[c] = sbElecForce[botFaceIndex][2] + sbElecForce[ topFaceIndex][2] # force on boundary cells for c in range(nSelfCells, nCells): force[c] = sbElecForce[nSelfCells + c][2] #pdb.set_trace() #------------solve structure-------------# print "*** solving structure model at globalCount %i ***" % globalCount self.pmodel.advance(1) self.dmodel.calculateNodeDisplacement() self.dmodel.deformPlate() self.solidMetricsCalculator.recalculate_deform() #------------update solid boundary mesh---------------# #solidBoundaryMeshes = [m.extrude(1, beam_thickness, True) for m in solidMeshes] sbNodes = self.solidBoundaryMeshes[0].getNodes() nSBNodes = sbNodes.getCount() nodes = self.solidMeshes[0].getNodes() if nSBNodes != nodes.getCount() * 2: print "the extruded solid mesh has wrong node number!" nodeCoord = self.geomFields.coordinate[nodes].asNumPyArray() bNodeCoord = self.geomFields.coordinate[sbNodes].asNumPyArray() bMeshCoord = self.solidBoundaryMeshes[0].getNodeCoordinates( ).asNumPyArray() self.deformation = self.geomFields.nodeDisplacement[ nodes].asNumPyArray() #pdb.set_trace() for sbn in range(0, nSBNodes / 2): bNodeCoord[sbn][ 2] = -self.beam_thickness / 2 + nodeCoord[sbn][2] bMeshCoord[sbn][ 2] = -self.beam_thickness / 2 + nodeCoord[sbn][2] for sbn in range(nSBNodes / 2, nSBNodes): bNodeCoord[sbn][2] = self.beam_thickness / 2 + nodeCoord[ sbn - nSBNodes / 2][2] bMeshCoord[sbn][2] = self.beam_thickness / 2 + nodeCoord[ sbn - nSBNodes / 2][2] #pdb.set_trace() #solidBoundaryMetricsCalculator = models.MeshMetricsCalculatorA(geomFields,solidBoundaryMeshes) #solidBoundaryMetricsCalculator.init() self.solidBoundaryMetricsCalculator.recalculate_deform() cell = self.solidMeshes[0].getCells() deform = self.plateFields.deformation[cell].asNumPyArray() def_min = deform.min(axis=0) def_min_z = def_min[2] maxdeformation.append(def_min_z) if (n != 0): if ((maxdeformation[n] - maxdeformation[n - 1]) / maxdeformation[n] < 1e-3): print "Convergence reached" break # -----------------update time --------------------------# globalTime += timeStep globalCount += 1 #self.pmodel.updateTime() #saveVTK(n) #writeTrace( if (n % saveFrequency == 0): writer = exporters.VTKWriterA( self.geomFields, self.fluidMeshes, "elecfield-" + str(n) + ".vtk", "fix-fix beam", False, 0) writer.init() writer.writeScalarField(self.elecFields.potential, "potential") writer.writeVectorField(self.elecFields.electric_field, "potentialgradient") writer.finish() writer1 = exporters.VTKWriterA( self.geomFields, self.solidMeshes, "structural-" + str(n) + ".vtk", "Disk", False, 0) writer1.init() writer1.writeVectorField(self.plateFields.deformation, "Deformation") writer1.finish() t2 = time.time() print '\nsolution time = %f' % (t2 - t1) return maxdeformation[n]
#potential field on boundary mesh areaMag = pd.geomFields.areaMag[faces] faceCount = faces.getCount() pot = areaMag.newSizedClone(faceCount) pota = pot.asNumPyArray() pota[:] = 0.0 pd.elecFields.potential[faces] = pot #flow velocity field on boundary mesh area = pd.geomFields.area[faces] faceCount = faces.getCount() vel = area.newSizedClone(faceCount) vela = vel.asNumPyArray() vela[:, :] = 0.0 pd.flowFields.velocity[faces] = vel pd.ibManager = fvmbaseExt.IBManager(pd.geomFields, pd.solidBoundaryMeshes[0], pd.fluidMeshes) pd.ibManager.fluidNeighborsPerIBFace = 2 pd.ibManager.solidNeighborsPerIBFace = 6 pd.ibManager.fluidNeighborsPerSolidFace = 6 ### initialize models and run ### pd.smodel.init() pd.dmodel.init() pd.emodel.init() pd.fmodel.init() #initially, zero force is applied on beam createSolidForceBVFields(pd)
def solveModels(self, appliedVoltage): maxdeformation = [] ibManager = fvmbaseExt.IBManager(self.geomFields, self.solidBoundaryMeshes[0], self.fluidMeshes) for mesh in self.solidBoundaryMeshes: faces = mesh.getFaces() areaMag = self.geomFields.areaMag[faces] faceCount = faces.getCount() pot = areaMag.newSizedClone(faceCount) pota = pot.asNumPyArray() pota[:] = appliedVoltage self.elecFields.potential[faces] = pot sbMeshFaces = self.solidBoundaryMeshes[0].getFaces() ibManager.fluidNeighborsPerIBFace = 6 ibManager.solidNeighborsPerIBFace = 4 ibManager.fluidNeighborsPerSolidFace = 5 t1 = time.time() traceFile = open(("tracefile-%e.dat" % appliedVoltage), "w") #--------------Timestep Loop --------------------------# for n in range(0, self.numIterations): # checkMarking(globalCount) # --------------- update IBM -------------------------# print "*** update IBM at globalCount %i ***" % self.globalCount ibManager.update() self.fluidMetricsCalculator.computeIBInterpolationMatrices( sbMeshFaces) self.fluidMetricsCalculator.computeSolidInterpolationMatrices( sbMeshFaces) #------------solve electrostatics--------# print "*** solving electric model at globalCount %i ***" % self.globalCount for i in range(0, 20): self.emodel.computeIBFacePotential(sbMeshFaces) if (self.emodel.advance(1)): break self.emodel.computeSolidSurfaceForcePerUnitArea(sbMeshFaces) #------------update force on beam ----------# print "*** update force at globalCount %i ***" % self.globalCount sbElecForce = self.elecFields.force[sbMeshFaces].asNumPyArray() solidMesh = self.solidMeshes[0] solidCells = solidMesh.getCells() nCells = solidCells.getCount() nSelfCells = solidCells.getSelfCount() nSBFaces = sbMeshFaces.getCount() if (nSBFaces != 2 * nSelfCells + (nCells - nSelfCells)): print "the extruded solid boundary mesh has wrong face numbers!" force = self.plateFields.force[solidCells].asNumPyArray() thickness = self.plateFields.thickness[solidCells].asNumPyArray() force[:] = 0. ### Need to correct~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ thickness[:] = self.beam_thickness # force on interior cells for c in range(0, nSelfCells): botFaceIndex = c topFaceIndex = c + nSelfCells force[c] = sbElecForce[botFaceIndex][2] + sbElecForce[ topFaceIndex][2] # force on boundary cells for c in range(nSelfCells, nCells): force[c] = sbElecForce[nSelfCells + c][2] #pdb.set_trace() #------------solve structure-------------# print "*** solving structure model at globalCount %i ***" % self.globalCount self.pmodel.advance(1) self.dmodel.calculateNodeDisplacement() self.dmodel.deformPlate() self.solidMetricsCalculator.recalculate_deform() #------------update solid boundary mesh---------------# #solidBoundaryMeshes = [m.extrude(1, beam_thickness, True) for m in solidMeshes] sbNodes = self.solidBoundaryMeshes[0].getNodes() nSBNodes = sbNodes.getCount() nodes = self.solidMeshes[0].getNodes() if nSBNodes != nodes.getCount() * 2: print "the extruded solid mesh has wrong node number!" nodeCoord = self.geomFields.coordinate[nodes].asNumPyArray() bNodeCoord = self.geomFields.coordinate[sbNodes].asNumPyArray() bMeshCoord = self.solidBoundaryMeshes[0].getNodeCoordinates( ).asNumPyArray() self.deformation = self.geomFields.nodeDisplacement[ nodes].asNumPyArray() for sbn in range(0, nSBNodes / 2): bNodeCoord[sbn][ 2] = -self.beam_thickness / 2 + nodeCoord[sbn][2] bMeshCoord[sbn][ 2] = -self.beam_thickness / 2 + nodeCoord[sbn][2] for sbn in range(nSBNodes / 2, nSBNodes): bNodeCoord[sbn][2] = self.beam_thickness / 2 + nodeCoord[ sbn - nSBNodes / 2][2] bMeshCoord[sbn][2] = self.beam_thickness / 2 + nodeCoord[ sbn - nSBNodes / 2][2] self.solidBoundaryMetricsCalculator.recalculate_deform() cell = self.solidMeshes[0].getCells() deform = self.plateFields.deformation[cell].asNumPyArray() temp = np.array(deform[:]) val = 0.e0 for i in range(len(temp)): temp2 = temp[i] if (temp2[2] < val): val = temp2[2] maxdeformation.append(val) traceFile.write("%i %e\n" % (n, maxdeformation[n])) traceFile.flush() # -----------------update time --------------------------# self.globalTime += self.timeStep self.globalCount += 1 if (n % self.saveFrequency == 0 and self.saveVTKstate): writer = exporters.VTKWriterA( self.geomFields, self.fluidMeshes, "elecfield-" + str(appliedVoltage) + "V-" + str(n) + ".vtk", "fix-fix beam", False, 0) writer.init() writer.writeScalarField(self.elecFields.potential, "potential") writer.writeVectorField(self.elecFields.electric_field, "potentialgradient") writer.finish() writer1 = exporters.VTKWriterA( self.geomFields, self.solidMeshes, "structural-" + str(appliedVoltage) + "V-" + str(n) + ".vtk", "Disk", False, 0) writer1.init() writer1.writeVectorField(self.plateFields.deformation, "Deformation") writer1.finish() if (abs(maxdeformation[n]) > self.Gap): traceFile.write("Pull In") traceFile.flush() maxdeformation[n] = -self.Gap break if (n != 0): print abs((maxdeformation[n] - maxdeformation[n - 1]) / maxdeformation[n]) if (abs((maxdeformation[n] - maxdeformation[n - 1]) / maxdeformation[n]) < 1e-3): print "Convergence reached" break t2 = time.time() print '\nsolution time = %f' % (t2 - t1) traceFile.close() return maxdeformation[n]