def update_node_positions(self, skeleton, mesh): skeleton.incrementTimestamp() ## mesh is a Mesh Who object femesh = mesh.getObject() displacement = field.getField('Displacement') # TODO OPT: this should probably be moved to C for i in range(skeleton.nnodes()): node = skeleton.getNode(i) #Interface branch ## realnode = femesh.getNode(node.meshindex) skelel = node.getElement(0) realel = femesh.getElement(skelel.getIndex()) realnode = realel.getCornerNode(skelel.getNodeIndexIntoList(node)) dx = displacement.value(femesh, realnode, 0) dy = displacement.value(femesh, realnode, 1) if config.dimension() == 2: skeleton.moveNodeBy(node, primitives.Point(dx, dy)) elif config.dimension() == 3: dz = displacement.value(femesh, realnode, 2) skeleton.moveNodeBy(node, (dx, dy, dz))
def update_node_positions(self, skeleton, mesh): skeleton.timestamp.increment() ## mesh is a Mesh Who object femesh = mesh.getObject() displacement = field.getField('Displacement') for node in skeleton.nodes: #Interface branch ## realnode = femesh.getNode(node.meshindex) #TODO: Do we have to update all the realmesh nodes #that correspond to node? skelel = node.neighborElements()[0] realel = femesh.getElement(skelel.meshindex) realnode = realel.getCornerNode(skelel.getNodeIndexIntoList(node)) dx = displacement.value(femesh, realnode, 0) dy = displacement.value(femesh, realnode, 1) if config.dimension() == 2: skeleton.moveNodeBy(node, primitives.Point(dx, dy)) elif config.dimension() == 3: dz = displacement.value(femesh, realnode, 2) skeleton.moveNodeBy(node, primitives.Point(dx, dy, dz))
def make_linear_system(self, time, linsys): # Construct a LinearizedSystem object containing the # globally-indexed K, C, and M matrices, and the rhs vectors, # and the maps that extract submatrices and subvectors. # The linsys argument is either a LinearizedSystem object # previously created by this SubProblemContext, or None. If # it's not None, it will be updated and reused. mesh = self.getParent() femesh = mesh.getObject() subpobj = self.getObject() # Ask every *other* subproblem to interpolate its DoFs to the # given time. Our boundary conditions and/or material # properties may depend on them. for subproblem in mesh.subproblems(): if (subproblem is not self and subproblem.installedTime != time): vals = subproblem.interpolateValues(time) # This requires that the LinearizedSystem for the # other subproblem has already been computed. # However, it's never needed on the first call to # make_linear_system, so that's ok. subproblem.set_mesh_dofs(vals, time) ## TODO OPT: Be more sophisticated here. Instead of ## recomputing everything, only recompute the matrices and ## vectors that may have changed. ## TODO OPT: Recompute if nonlinear *and* relevant fields ## have changed, not just if nonlinear. Need field-specific ## timestamps in the Mesh? femesh.setCurrentSubProblem(self.getObject()) # Figure out which parts of the calculation have to be redone. # If always is set, all steps of the calculation will be # peformed, even if they're otherwise unnecessary. This can # be useful when debugging. # 'always' can be set with the command line option ## --command "always=True". always = False try: always = utils.OOFeval('always') except NameError: pass # If Properties depend nonlinearly on Fields, and if those # Fields have changed, the matrices need to be recomputed. # The relevant Fields are *all* the Fields defined in the # SubProblem's Elements, whether or not those Fields are # active in *this* SubProblem. flds = self.getParent().all_active_subproblem_fields() if linsys is not None: linsysComputed = linsys.computed else: linsysComputed = timestamp.timeZero newDefinition = self.defnChanged > linsysComputed or always newFieldValues = (max(self.fieldsInstalled, mesh.fieldsInitialized) > linsysComputed) or always newTime = linsys is None or linsys.time() != time or always newBdys = (mesh.boundariesChanged > linsysComputed or (newTime and self.timeDependentBCs()) ## TODO: Check for field dependent boundary conditions # or (newFieldValues and self.fieldDependentBCs(flds)) or always) newLinSys = (linsys is None) or newDefinition newMaterials = mesh.materialsChanged > linsysComputed or always rebuildMatrices = ( newLinSys or newMaterials or (self.nonlinear(flds) and (newBdys or newFieldValues)) or (newFieldValues and self.nonlinear_solver.needsResidual()) or (self.nonlinear_solver.needsJacobian() and self.nonlinear_solver.jacobianRequirementChanged() > linsysComputed) or (self.nonlinear_solver.needsResidual() and (newFieldValues or (self.nonlinear_solver.residualRequirementChanged() > linsysComputed))) or (newTime and self.timeDependentProperties(flds)) or always) if newDefinition: self.getObject().mapFields() # Create a new linearized system object if necessary if newLinSys: linsys = self.getObject().new_linear_system(time) linsys.computed = timestamp.TimeStamp() if newTime: linsys.set_time(time) # Apply boundary conditions to the linearized system object. # This has to be done before the matrix and rhs values are # computed. The matrix and rhs may be nonlinear and therefore # depend on field values, which may be determined by boundary # conditions. bcsReset = newLinSys or newBdys if bcsReset: # reset_bcs() calls Boundary.reset for all Boundaries in # the mesh, which resets all FloatBCs on the boundaries. femesh.reset_bcs() femesh.createAuxiliaryBCs() # convert PeriodicBCs --> FloatBCs femesh.createInterfaceFloatBCs(self) # jump conds --> FloatBCs # Find intersecting floating boundary conditions, and # arrange them into a tree structure. This must be done # *before* fixed boundary conditions are applied so that # intersecting fixed and floating bcs are treated # correctly. femesh.floatBCResolve(subpobj, time) # LinearizedSystem::force_bndy_rhs is used by # invoke_flux_bcs and invoke_force_bcs, and must be # cleared before either of them is called. linsys.clearForceBndyRhs() femesh.invoke_flux_bcs(subpobj, linsys, time) # Apply Dirichlet BCs. If new values have been assigned to # the Fields, the old Dirichlet BCs may have been overwritten, # so they have to be reapplied. if bcsReset or newFieldValues: linsys.resetFieldFlags() femesh.invoke_fixed_bcs(subpobj, linsys, time) if bcsReset: femesh.invoke_force_bcs(subpobj, linsys, time) # Set initial values of DoFs used in FloatBCs that # intersect fixedBCs. femesh.fix_float_bcs(subpobj, linsys, time) if rebuildMatrices: # Assemble vectors and matrices of the linearized system. linsys.clearMatrices() linsys.clearBodyRhs() if self.nonlinear_solver.needsResidual(): linsys.clearResidual() if self.nonlinear_solver.needsJacobian(): linsys.clearJacobian() # **** This is the cpu intensive step: **** self.getObject().make_linear_system(linsys, self.nonlinear_solver) self.newMatrixCount += 1 if bcsReset or rebuildMatrices or newFieldValues: linsys.build_submatrix_maps() # Apply floating boundary conditions by modifying maps in # the LinearizedSystem. This must follow # build_submatrix_maps() and precede build_MCK_maps(). femesh.invoke_float_bcs(subpobj, linsys, time) linsys.build_MCK_maps() # Construct vectors of first and second time derivatives # of the time-dependent Dirichlet boundary conditions. linsys.initDirichletDerivatives() femesh.setDirichletDerivatives(subpobj, linsys, time) if bcsReset: # Compute the part of the rhs due to fixed fields or fixed # time derivatives in boundary conditions. linsys.find_fix_bndy_rhs(self.getObject().get_meshdofs()) # Add the floating boundary condition profiles' # contributions to the rhs. This must come after # find_fix_bndy_rhs(), and must always be called if # find_fix_bndy_rhs() is called. ## TODO OPT: Only call float_contrib_rhs if solver needs ## to know the rhs explicitly. femesh.float_contrib_rhs(self.getObject(), linsys) femesh.clearCurrentSubProblem() linsys.computed.increment() # ## Don't remove this block. Comment it out instead. It's # ## likely to be needed later. # global debugcount # debugcount += 1 # if debugcount==3: # if always: # dumpfile = "dump-always" # else: # dumpfile = "dump" # linsys.dumpAll(dumpfile, time, "") # sys.exit() return linsys
def meshTimeChangedCB(self, mesh): # sb "time changed" debug.mainthreadTest() if mesh is self.currentMeshContext(): self.currentTimeEntry.set_text(`mesh.getObject().getCurrentTime()`)
def meshTimeChangedCB(self, mesh): # sb "time changed" debug.mainthreadTest() if mesh is self.currentMeshContext(): self.currentTimeEntry.set_text(`mesh.getObject().latestTime()`)