def set_params_for_side(self, model, side): ics = [] for interval in side.intervals: # if no interconnect then continue: try: interval.name['i'] except KeyError: continue equationNumber = interval.name['e'] equation = model.equations[equationNumber].copy() icRegion = interval.name['i']() blockNumber = icRegion.blockNumber side_num = icRegion.side_num funcName = ("Block" + str(blockNumber) + "Interconnect__Side" + str(side_num) + "_Eqn" + str(equationNumber)) # generate equation: parsedValues = self.parse_equations(equation, model.dimension, blockNumber, side_num, icRegion.firstIndex, icRegion.secondIndex) # fill params: ic = Params() ic.name = "Connection" # ic.firstIndex = icRegion.firstIndex # ic.secondIndex = icRegion.secondIndex ic.side_num = side_num # ic.ranges = icRegion.ranges # ic.equationNumber = equationNum ic.equation = equation ic.funcName = funcName ic.boundName = determineNameOfBoundary(side_num) ic.blockNumber = blockNumber ic.parsedValues = parsedValues ic.original = [e.sent for e in equation.eqs] # for functionMaps: interval.name['fm'] = ic # for cpp: # each block can connect to many other block # let other block discribe interconnect in # that case ics.append(ic) return(ics)
def _set_params_for_two_blocks(self, model, block, iconn, ics, blockNumber, firstIndex): '''Only for one block in pair.''' # choice side: if (iconn.block1 == blockNumber and iconn.block2 != blockNumber): # case differ 1 side_num = iconn.block1Side elif (iconn.block2 == blockNumber and iconn.block1 != blockNumber): # case differ 2 side_num = iconn.block2Side # len(ics for block) # firstIndex = len(ics) # FOR find equation for block Range = (side_num == 1) * block.size.sizeX coord = lambda region: ((side_num == 0) * region.xfrom + (side_num == 1) * region.xto) side_test = lambda eRegion: coord(eRegion) == Range equationNum = self.choice_equation_num(side_test, block) equation = model.equations[equationNum].copy() # END FOR funcName = ("Block" + str(blockNumber) + "Interconnect__Side" + str(side_num) + "_Eqn" + str(equationNum)) # generate equation: parsedValues = self.parse_equations(equation, model.dimension, blockNumber, side_num, firstIndex, 0) # fill params: ic = Params() ic.name = "Connection" ic.firstIndex = firstIndex ic.secondIndex = '0' ic.side_num = side_num ic.ranges = [] ic.equationNumber = equationNum ic.equation = equation ic.funcName = funcName ic.boundName = determineNameOfBoundary(side_num) ic.blockNumber = blockNumber ic.parsedValues = parsedValues ic.original = [e.sent for e in equation.eqs] # each block can connect to many other block # let other block discribe interconnect in # that case return(ic)
def _collect_eq_from_region(self, model, eRegion, dim, blockNumber, tFuncName): # equation = copy(model.equations[eRegion.equationNumber]) eParam = Params() eSystem = model.equations[eRegion.equationNumber].copy() eParam.equation = eSystem eParam.equationNumber = eRegion.equationNumber eParam.eRegion = eRegion eParam.dim = dim eParam.blockNumber = blockNumber eParam.funcName = tFuncName.substitute( blockNumber=blockNumber, equationNumber=eRegion.equationNumber) eParam.default = False eParam.parsedValues = self._get_eq_cpp(eSystem, eParam) eParam.original = [e.sent for e in eSystem.eqs] logger.debug("parsedValues") logger.debug(eParam.parsedValues) logger.debug('blockNumber eqReg=%s' % str(blockNumber)) return (eParam)
def _collect_eq_default(self, model, block, dim, blockNumber, tFuncName): # model.equations is a list of equation systems # equation = copy(model.equations[block.defaultEquation]) eSystem = model.equations[block.defaultEquation].copy() eParam = Params() eParam.equation = eSystem eParam.equationNumber = block.defaultEquation eParam.eRegion = None eParam.dim = dim eParam.blockNumber = blockNumber eParam.funcName = tFuncName.substitute( blockNumber=blockNumber, equationNumber=block.defaultEquation) eParam.default = True eParam.parsedValues = self._get_eq_cpp(eSystem, eParam) eParam.original = [e.sent for e in eSystem.eqs] logger.debug("parsedValues") logger.debug(eParam.parsedValues) logger.debug('blockNumber revSp=%s' % str(blockNumber)) return (eParam)
def _set_params_for_closed_block(self, model, block, iconn, blockNumber, srcFirstIndex, distFirstIndex): '''srcFirstIndex and distFirstIndex is first indexes of two interconects of same block''' # FOR finding equations: # choice left or right side of block # i.e. 0.0 or block.sizeX Range1 = (iconn.block1Side == 1) * block.size.sizeX Range2 = (iconn.block2Side == 1) * block.size.sizeX # return either xfrom or xto for block coord1 = lambda region: ((iconn.block1Side == 0) * region.xfrom + (iconn.block1Side == 1) * region.xto) coord2 = lambda region: ((iconn.block2Side == 0) * region.xfrom + (iconn.block2Side == 1) * region.xto) # find equation # for first block (one side of closed block) side_test = lambda eRegion: coord1(eRegion) == Range1 equationNum1 = self.choice_equation_num(side_test, block) # find equation # for second block (other side of closed block) side_test = lambda eRegion: coord2(eRegion) == Range2 equationNum2 = self.choice_equation_num(side_test, block) equation1 = model.equations[equationNum1].copy() equation2 = model.equations[equationNum2].copy() # END FOR funcName1 = ("Block" + str(blockNumber) + "Interconnect__Side" + str(iconn.block1Side) + "_Eqn" + str(equationNum1)) funcName2 = ("Block" + str(blockNumber) + "Interconnect__Side" + str(iconn.block2Side) + "_Eqn" + str(equationNum2)) # FOR equatioin cpp: # first equation: parsedValues_1 = self.parse_equations(equation1, model.dimension, blockNumber, iconn.block1Side, 1, 0) # second equation: parsedValues_2 = self.parse_equations(equation2, model.dimension, blockNumber, iconn.block2Side, 0, 0) # END FOR # fill params: ic1 = Params() ic1.name = "Connection" ic1.firstIndex = srcFirstIndex ic1.secondIndex = '0' ic1.side_num = iconn.block1Side ic1.ranges = [] ic1.equationNumber = equationNum1 ic1.equation = equation1 ic1.funcName = funcName1 ic1.parsedValues = parsedValues_1 ic1.original = [e.sent for e in equation1.eqs] ic1.boundName = determineNameOfBoundary(iconn.block1Side) ic1.blockNumber = blockNumber ic2 = Params() ic2.name = "Connection" ic2.firstIndex = distFirstIndex ic2.secondIndex = '0' ic2.side_num = iconn.block2Side ic2.ranges = [] ic2.equationNumber = equationNum2 ic2.equation = equation2 ic2.funcName = funcName2 ic2.parsedValues = parsedValues_2 ic2.original = [e.sent for e in equation2.eqs] ic2.boundName = determineNameOfBoundary(iconn.block2Side) ic2.blockNumber = blockNumber return((ic1, ic2))
def make_region(self, mainBlockSide, mainBlock, secondBlock, region_num, firstIndex): '''Make some data for each block in ic. First it's find side and intervals, in which ic to be used. For interval it used ``Interval`` object with bound and equation numbers set to ``None`` (i.e. ``name={'b': None, 'e': None}``). Change ``side.intervals`` to add ic intervals to it (i.e. first split ic interval at bouds/eq regions, then split all ``side.intervals`` at that ic_interval). Also It create ranges that is rectangle ``[xfrom, xto, yfrom, yto]`` where all in cell sizes. interval, xfrom, xto, yfrom, yto, lenOfConnection, beforeStartLen, ranges is all inteconnect data, relative to mainBlock. It also add first index of current inteconnect for created region and increase it global value (stored in ``model._ics_firstIndex``) It create ``secondIndex`` which is index to be used by ``mainBlock`` in order to get according ``ics`` data for according side coordinate. (ex (what ``secondIndex`` used for): secondIndex: ic[firstIndex][secondIndex] for mainBlock where ic is inteconnects array, firstIndex is index of ic mainBlock and secondBlock secondIndex according mainBlock side (see ex below)) (ex (how ``secondIndex`` created for side 2 or 3): secondIndex = idxX - to_cell(lenBSBSSC) where lenBSBSSC is len between start of block side and start of connection) Tests: >>> from envs.hs.model.model_main import ModelNet as Model >>> m = Model() >>> m.io.loadFromFile('problems/2dTests/tests_2d_two_blocks0') >>> ic = m.interconnects[0] >>> icr = ic.regions[1] >>> icr.ranges [0, 301, 0, 1] >>> icr = ic.regions[2] >>> icr.ranges [150, 451, 700, 701] ''' grid = self.net.model.grid den = mainBlock.defaultEquation if mainBlockSide == 0: xfrom = 0 # mainBlock.size.offsetX xto = 0 # mainBlock.size.offsetX yfrom = (max([secondBlock.size.offsetY, mainBlock.size.offsetY]) - mainBlock.size.offsetY) yto = (min([mainBlock.size.offsetY + mainBlock.size.sizeY, secondBlock.size.offsetY + secondBlock.size.sizeY]) - mainBlock.size.offsetY) interval = Interval([yfrom, yto]) beforeStartLen = yfrom lenOfConnection = yto - yfrom sideIndex = 'idxY' stepAlongSide = grid.gridStepY elif mainBlockSide == 1: xfrom = mainBlock.size.sizeX # + mainBlock.size.offsetX xto = mainBlock.size.sizeX # + mainBlock.size.offsetX yfrom = (max([secondBlock.size.offsetY, mainBlock.size.offsetY]) - mainBlock.size.offsetY) yto = (min([mainBlock.size.offsetY + mainBlock.size.sizeY, secondBlock.size.offsetY + secondBlock.size.sizeY]) - mainBlock.size.offsetY) interval = Interval([yfrom, yto]) beforeStartLen = yfrom lenOfConnection = yto - yfrom sideIndex = 'idxY' stepAlongSide = grid.gridStepY elif mainBlockSide == 2: xfrom = (max([mainBlock.size.offsetX, secondBlock.size.offsetX]) - mainBlock.size.offsetX) xto = (min([mainBlock.size.offsetX + mainBlock.size.sizeX, secondBlock.size.offsetX + secondBlock.size.sizeX]) - mainBlock.size.offsetX) yfrom = 0 # mainBlock.size.offsetY yto = 0 # mainBlock.size.offsetY interval = Interval([xfrom, xto]) beforeStartLen = xfrom lenOfConnection = xto - xfrom sideIndex = 'idxX' stepAlongSide = grid.gridStepX else: xfrom = (max([mainBlock.size.offsetX, secondBlock.size.offsetX]) - mainBlock.size.offsetX) xto = (min([mainBlock.size.offsetX + mainBlock.size.sizeX, secondBlock.size.offsetX + secondBlock.size.sizeX]) - mainBlock.size.offsetX) yfrom = mainBlock.size.sizeY # + mainBlock.size.offsetY yto = mainBlock.size.sizeY # + mainBlock.size.offsetY interval = Interval([xfrom, xto]) beforeStartLen = xfrom lenOfConnection = xto - xfrom sideIndex = 'idxX' stepAlongSide = grid.gridStepX # FOR collect data: out = Params() out.firstIndex = firstIndex # out.firstIndex = self.net.model._ics_firstIndex # self.net.model._ics_firstIndex += 1 out.side_num = mainBlockSide # out.stepAlongSide = stepAlongSide # out.beforeStartLen = beforeStartLen # map: block side index -> second index of ic # (ex: idxX -> secondIndex where secondIndex: ic[][secondIndex]): startCellIndex = determineCISC2D(beforeStartLen, stepAlongSide) out.secondIndex = ('(' + sideIndex + ' - ' + str(startCellIndex) + ') * Block' + str(mainBlock.blockNumber) + 'CELLSIZE') out.icLen = lenOfConnection side = mainBlock.sides[mainBlockSide] logger.debug("side.intervals:") logger.debug(side.intervals) logger.debug("icr.intervals:") logger.debug(interval) # add default name: interval.name = {'b': None, 'e': den, 'i': (lambda _self=self, _region_num=region_num: _self[_region_num])} # region_num - is global name # while _region_num is local name in lambda # that used because otherwise all regions # would have same region_num. # split at equation and bounds regions: out.intervals = interval.split_all([copy(interval) for interval in side.intervals], []) # add ic info into block.side: side.intervals = sum([i.split_all(out.intervals, []) for i in side.intervals], []) # reset vertexs: mainBlock.editor.set_vertexs() out.xfrom = xfrom out.xto = xto out.yfrom = yfrom out.yto = yto ''' ranges = getRangesInClosedInterval([xfrom, xto, grid.gridStepX], [yfrom, yto, grid.gridStepY]) out.ranges = ranges ''' out.blockNumber = mainBlock.blockNumber out.ic = self.net out.ic_regions = self # END FOR return(out)
def make_bound_param(self, model, vertex): '''Fill this parameters for block bound border (vertex in case of 1d):: Collect this parameters for template: - ``bParams.dim`` - ``bParams.values`` -- border_values - ``bParams.btype`` - ``bParams.side_num`` - ``bParams.boundNumber`` - ``bParams.equationNumber`` - ``bParams.equation`` -- system of equations - ``bParams.funcName`` - ``bParams.block`` - ``bParams.blockNumber`` - ``bParams.boundName`` -- for comment - ``bParams.parsedValues`` - ``bParams.original`` -- for comment This parameters also collected for dom: - ``bound.side`` - ``bound.blockNumber`` - ``bParams.funcName`` ''' block = vertex.block blockNumber = vertex.block.blockNumber # for 1d there is only one side: side_num = vertex.sides_nums[0] # find equation number for side or use default equationNum = vertex.equationNumber ''' regsEqNums = [eqReg.equationNumber for eqReg in block.equationRegions if self.test(block, eqReg, side_num)] equationNum = (regsEqNums[0] if len(regsEqNums) > 0 else block.defaultEquation) ''' eSystem = model.equations[equationNum].copy() # find bound region for side or use default boundNumber = vertex.boundNumber ''' regionsForSide = [bRegion for k in block.boundRegions for bRegion in block.boundRegions[k] if bRegion.side_num == side_num] ''' # if exist special region for that side # if len(regionsForSide) > 0: if boundNumber is not None: # region = block.boundsRegions[boundNumber] # region = regionsForSide[0] # boundNumber = region.boundNumber bound = model.bounds[boundNumber] args = (model, blockNumber, side_num, boundNumber, equationNum) # for Dirichlet bound if bound.btype == 0: func = self.get_func_for_dirichlet(*args) # for Neumann bound elif bound.btype == 1: func = self.get_func_for_neumann(*args) funcName = func[0] border_values = list(func[1]) btype = bound.btype else: # if not, use default args = (eSystem, blockNumber, side_num, equationNum) func = self.get_func_default(*args) funcName = func[0] border_values = func[1] btype = 1 boundNumber = -1 args = (eSystem, model, blockNumber, btype, side_num, border_values) parsed = self.parse_equations(*args) # print("bound bug debug:") # print(parsed) # FOR collect template data: bParams = Params() bParams.dim = model.dimension bParams.values = border_values bParams.btype = btype bParams.side_num = side_num bParams.boundNumber = boundNumber bParams.equationNumber = equationNum bParams.equation = eSystem bParams.funcName = funcName bParams.block = block bParams.blockNumber = blockNumber logger.debug("bParams.funcName") logger.debug(bParams.funcName) logger.debug("bParams.side_num") logger.debug(bParams.side_num) # in comment bParams.boundName = determineNameOfBoundary(side_num) bParams.parsedValues = parsed[0] bParams.border_values_parsed = parsed[1] bParams.original = [e.sent for e in eSystem.eqs] # END FOR vertex.fm = bParams return (bParams)
def make_bounds_for_vertex(self, vertex, params_edges): ''' DESCRIPTION: If vertex left edge closest region has ic value (i.e. this region donot exist in params_edges) then if right edge closest region has no ic value, use this region else use ic data (todo). Collect this parameters for template: - ``vParams.name`` - ``vParams.sides_nums`` - ``vParams.blockNumber`` - ``vParams.boundNumber`` - ``vParams.equationNumber`` - ``vParams.funcName`` - ``vParams.bound_side`` - ``vParams.btype`` - ``vParams.equation`` -- equation from left edge. - ``vParams.parsedValues`` - ``vParams.original`` This parameters also collected for dom: - ``bParams.blockNumber`` - ``bParams.side_num`` - ``bParams.funcName`` -- for defining func index in namesAndNumbers dict. - ``bParams.interval`` Inputs: - ``vertex`` -- is ``Vertex`` object:: vertex: - ``boundNumber`` -- of left edge (side) - ``equationNumber`` -- of left edge (side) - ``sides_nums`` -- like [0, 2] - ``interval`` -- of left edge (side) - ``params_edges`` -- out of make_bounds_for_edges. Used for side data for vertex. ''' # find bound for left edge: left_edges = [ bParams for bParams in params_edges if bParams.side_num == vertex.sides_nums[0] and bParams.blockNumber == vertex.block.blockNumber and bParams.interval == vertex.left_interval ] # if interconnect exist for left edges # (so there is no region in params_edges) # use right: try: vertex_edge = left_edges[0] except IndexError: right_edges = [ bParams for bParams in params_edges if bParams.side_num == vertex.sides_nums[1] and bParams.blockNumber == vertex.block.blockNumber and bParams.interval == vertex.right_interval ] # if interconnect exist for left and right # (so there is no region in params_edges) try: vertex_edge = right_edges[0] except IndexError: # TODO: add ic to vertex raise (BaseException("Case when vertex has ic regions" + " from both sides is not" + " implemented yet")) return (None) # END FOR vParams = Params() vParams.name = 'vertex bound' vParams.sides_nums = vertex.sides_nums vParams.blockNumber = vertex.block.blockNumber # data of left side (with index 0) vParams.boundNumber = vertex.boundNumber vParams.equationNumber = vertex.equationNumber # for make funcName for defaults funcName = self.get_vertex_funcName(vertex) vParams.funcName = funcName vParams.bound_side = vertex_edge vParams.btype = vertex_edge.btype eSystem = vertex_edge.equation.copy() parsedValues, bv_parsed = self.parse_equations_vertex( vertex, vertex_edge, eSystem) vParams.parsedValues = parsedValues vParams.border_values_parsed = bv_parsed # vParams.parsedValues = vertex_edge.parsedValues vParams.equation = eSystem logger.debug("parsedValues:") logger.debug(vParams.parsedValues) vParams.original = vertex_edge.original return (vParams)
def make_bounds_for_edges(self, model, side): ''' DESCRIPTION: Collect this parameters for template: - ``bParams.name`` - ``bParams.side_num`` - ``bParams.blockNumber`` - ``bParams.boundNumber`` - ``bParams.equationNumber`` - ``bParams.funcName`` -- func name in cpp - ``bParams.btype`` -- Dirichlet 0, Neumann 1 - ``bParams.equation`` -- system of equations SysNet object - ``bParams.parsedValues`` - ``bParams.original`` -- original for comment - ``bParams.boundName`` -- bound name for comment This parameters also collected for dom: - ``bParams.blockNumber`` - ``bParams.side_num`` - ``bParams.funcName`` -- for defining func index in namesAndNumbers dict. - ``bParams.region`` Inputs: - ``side`` -- is ``Side`` object:: side: - ``side_num``, - ``block.blockNumber``, - ``interval`` -- of type oIntervals where oIntervals = [Interval([x, y], name={'b': bval, 'e', eval})] ''' bounds = [] for interval in side.intervals: # if interconnect then continue: try: interval.name['i'] continue except KeyError: pass bParams = Params() bParams.name = 'sides bound' bParams.side_num = side.side_num bParams.blockNumber = side.block.blockNumber bParams.boundNumber = interval.name['b'] bParams.equationNumber = interval.name['e'] bParams.interval = interval eSystem = model.equations[bParams.equationNumber].copy() if bParams.boundNumber is not None: # FOR set up funcName and border values: args = (model, bParams.blockNumber, bParams.side_num, bParams.boundNumber, bParams.equationNumber) btype = model.bounds[bParams.boundNumber].btype # for Dirichlet bound if btype == 0: func = self.get_func_for_dirichlet(*args) # for Neumann bound elif btype == 1: func = self.get_func_for_neumann(*args) funcName = func[0] border_values = list(func[1]) else: btype = 0 args = (eSystem, bParams.blockNumber, bParams.side_num, bParams.equationNumber) func = self.get_func_default(*args) funcName = func[0] border_values = func[1] args = (eSystem, model, bParams.blockNumber, btype, bParams.side_num, border_values) parsed, bv_parsed = self.parse_equations(*args) bParams.funcName = funcName bParams.btype = btype bParams.equation = eSystem bParams.parsedValues = parsed bParams.border_values_parsed = bv_parsed bParams.original = [e.sent for e in eSystem.eqs] # for comment bParams.boundName = determineNameOfBoundary(bParams.side_num) # collect for functionMaps: interval.name['fm'] = bParams bounds.append(bParams) return (bounds)