def est_rcool_pair(oph0, oph1, ct): # Sides 0 and 1 of the {Contact} object {ct} must be in the oriented # paths {oph0} and {oph1}, respectively. Returns {est_rcool(oph,ct)} where # {oph} is the hypothetical concatenation of {oph0} and {oph1}. # # Assumes that an extra {tconn} seconds will lapse between the # end of {oph0} and the start of {oph1}, e.g. because of the # need to inserrt a connecting link or jump. This time is added # even if {pfin(opho) == pini(oph1}). # # This procedure saves computing time because it does not actually # construct the path {oph}. However, it only considers the case of # {oph0} being added to the path before {oph1}. # # This procedure executes in time {O(nmv0+nmv1)}, where {nmv0} and {nmv1} # are the number of moves in the two paths. return contact_IMP.pair_rcool_closed(oph0, tconn, oph1, ct) def max_rcool_active(oph, CTS): # The parameter {oph} must be an oriented path and {CTS} must be a # list or tuple of {Contact} objects. Returns the maximum, over all contacts {ct} of {CTS} # that are partially covered by {oph}, of a lower bound # # If there are no such contacts, returns {+inf}. # # Note that the results for {oph} and for {path.rev(oph)} are usually # different, and may NOT be complementary relative to # {path.fabtime(oph)} (since they may be realized by different # contacts). # # This procedure takes time {O(nct*nmv}) where {nct} is the number # of contacts and {nmv} is the move count of {oph}, because it calls # {path.find_move} twice for each contact. return contact_IMP.min_rcov(oph, CTS) def pair_max_rcool(oph0, tconn, oph1, CTS): # Equivalent to {max_rcool(oph, CTS)} where {oph} is the hypothetical # concatenation of {oph0} and {oph1}, assuming that an extra {tconn} # seconds will lapse between the end of {oph0} and the start of # {oph1}. # # The result is the maximum value of {pair_rcool(oph0,tconn,oph1,ct)} # over every contact {ct} of {CTS} that would be closed by path {oph}. # # This procedure saves time because it does not actually construct the # path {oph}. However, if side 0 of a contact in {CTS} is covered by # {oph}, it must be covered by {oph0} only; and if side 1 is covered # by {oph}, it must be covered by {oph1} only. # # This procedure runs in time {nct*(nmv0+nmv1)) where {nct} is the number # of contacts in {CTS} and {nmv0,nm1} are the move counts of {oph0,oph1}, # because it calls {path.find_move} once for each contact and path. return contact_IMP.pair_max_rcool(oph0, tconn, oph1, CTS) def est_max_rcool_blocks(CTS, BCS): # Given a list of contacts {CTS} and a list of blocks {BCS}, returns a # lower bound to the value of {contact.max_rcool(P,CTS)} for any path {P} # built from those blocks. # # The list {CTS} must contain only relevant contacts, that have at least # one side covered by one of blocks of {BCS}. # # For each contact {ct} of {CTS}, it finds the two blocks {bc0} and {bc1} # of {BCS} that include the sides of {ct}. They must both exist, be # unique, and distinct. Computes a min cooling time ratio {rcm(ct)} assuming # that the best possible choices {ph0,ph1} of those blocks that contain # the sides of {ct} are added in sequence to the tool-path. Ignores any # choice of either block that does not contain those sides, assuming # that the contact {ct} will become irrelevant if that choice is # selected for the tool-path. # Then it returns the maximum of {rcm(ct)} among all contacts {ct} of {CTS}. # If {CTS} is empty, returns 0. return contact_IMP.min_max_rcool(CTS, BCS) def pair_rcool(oph0, tconn, oph1, ct): # Get the two sides of {ct}: imv0 = path.find_move(oph0,side(ct,0)) imv1 = path.find_move(oph1,side(ct,1)) if imv0 == None or imv1 == None: rc = None else: tc0 = covtime(oph0,imv0,ct,0) tc1 = covtime(oph1,imv1,ct,1) tc1 += path.fabtime(oph0) + tconn assert tc1 >= tc0 rc = (tc1 - tc0)/tcool_lim(ct) return rc # ---------------------------------------------------------------------- def pair_max_rcool(oph0, tconn, oph1, CTS): assert type(CTS) is list or type(CTS) is tuple rc_max = -inf for ct in CTS: rc = pair_rcool(oph0, tconn, oph1, ct) if rc != None and rc > rc_max: rc_max = rc return rc_max # ---------------------------------------------------------------------- # # This procedure executes in time {O(nmv)} where {nmv} is {path.nelems(oph)}, # because it calls {covindices}. # # This procedure runs in time {O(nct*nmv*nmb)} in the worst case, # where {nct} is the number of contacts in {CTS}, {nmv} is the number # of moves in {oph}, and {nmb} is the total number of moves in the # blocks of {BCS}, because it calls {path.find_move} twice for {oph} # and once for each choice of each block of {BCS}.