December 4, 2016

Pen and paper

In twenty five years, I have not had the time to wonder what happened to my handwriting. The only time I made an effort was when I was trying to write letters of affection to my then fiancé. This was in 1997. She complained, and said I was better off typing. I did not disagree, but the feedback, strong as this, came as a bit of a shock. Nonetheless, having collectively filled reams of paper during my school days, the itch to write has been just as strong as the itch to type. So, I made it a point to take notes on paper, even when I had a computer, and that’s kept my handwriting FWIW alive and well. It’s easy to guess the kinds of pens I must have used. With pens relegated to mere commodity, from office supplies to those at home, there’s always a ballpoint pen lying around to jot something down. But as Josh Giesbrecht says:

Fountain pens want to connect letters. Ballpoint pens need to be convinced to write.

So, I got myself a Lamy Safari last month, and I am having fun writing again. In the process, I am rediscovering that the fountain pen is a bit of a primadonna. For instance, the pen does not like to be written on photo-copying paper — feels scratchy when you do. But on writing paper, it glides like butter on a hot plate. These days, I stock up writing paper whenever I am in a shopping mall’s bookstore, or in an airport gift shop — now that shops around the corner are all but gone.

The pen is just great, and it’s now my primary writing tool, but I have not taken one through airport security and on a plane before, and I am wondering, will they allow, and will it bleed in flight?

November 27, 2016

Converting end releases

STAAD has an odd way of coding end-releases for rod elements, in which start-sides and end-sides are defined as separate commands. Here is an example:

MEMBER RELEASE
561 567 TO 570 573 694 TO 698 START MY MZ
482 483 488 693 694 TO 696 END MY MZ

The conversion tool, stadred application included in USFOS does not convert member-end releases. And so, very quickly, this manual conversion can become time-consuming, say, for hundred odd elements and above. Here are the things to pay attention to:

  1. Elements: There are single elements, and then there are ranges.
  2. Command: Start and end explicit commands introduce the need to manually sift to segregate in three sets, viz., elements with releases at start only, end only, and at both ends.

USFOS, on the other hand, uses a format of defining both start as well as end in one command like thus:

'        [- START SIDE --]  [-- END SIDE --]  
'        X  Y  Z  MX MY MZ  X  Y  Z MX MY MZ  ELEM LIST
BEAMHING 1  1  1   1  0  0  1  1  1  1  0  0  686 687 688 689 690 691 692

To convert end-releases from STAAD to USFOS, one needs to do the following:

  1. Pick out range elements and list them first.
  2. Convert ranges to full numerical list, as USFOS does not recognise ranges like 686 TO 692.
  3. Pick single elements and add them to the list above.
  4. Once a full list of elements per two explicit release commands with START and END, like START MY MZ and END MY MZ, segregate them in to start only, end only and both end release list of elements.

I’ve tried to automate all the above. Here’s that code:

#!/usr/bin/env python
# encoding: utf-8
"""
fltr.py: Member end release conversion from STAAD to USFOS
ckunte, 2016-11-27
"""

import re

# Use one file for START MY MZ and one file for END MY MZ
fname1 = "start.txt" # required
fname2 = "end.txt" # required

""" Example of start.txt
MEMBER RELEASE
468 TO 489 522 TO 550 552 553 555 556 558 559 561 567 TO 570 -
573 575 TO 578 598 TO 615 617 620 TO 623 625 627 628 631 TO 636 -
651 TO 663 665 TO 679 693 694 TO 698 700 TO 702 704 705 -
707 TO 728 743 TO 770 829 TO 831 833 834 836 838 TO 841 843 -
845 TO 848 850 852 TO 855 857 859 TO 862 864 866 TO 869 872 -
873 TO 876 878 880 TO 883 885 887 888 895 973 984 986 TO 988 -
995 998 1003 1004 1009 1012 1014 TO 1019 1021 TO 1024 -
1047 TO 1052 1054 1055 1057 1066 1071 TO 1073 1088 TO 1091 -
1097 TO 1102 1104 TO 1108 1135 TO 1141 1143 1145 57 59 60 -
423 TO 455 564 1146 TO 1151 1158 1165 TO 1167 1169 1171 1173 - 
1402 START MY MZ
"""

""" Example of end.txt
482 483 488 TO 507 522 TO 550 552 553 555 556 558 559 561 -
567 TO 570 573 575 576 TO 578 612 TO 615 620 TO 622 624 -
626 TO 628 630 TO 663 665 TO 679 693 694 TO 695 699 TO 701 -
704 TO 714 729 TO 770 829 830 832 TO 834 836 838 TO 841 843 -
845 TO 848 850 852 TO 855 857 859 TO 862 864 866 TO 869 872 -
873 TO 876 878 880 TO 883 885 887 895 984 986 TO 988 -
999 TO 1001 1012 1014 1015 TO 1024 1027 1028 1047 TO 1057 -
1062 1063 1066 1071 TO 1073 1084 TO 1086 1088 1092 1095 -
1097 TO 1108 1122 TO 1124 1136 TO 1146 1148 1152 1153 1159 -
1161 1162 1165 1166 1169 1171 TO 1173 1402 END MY MZ
"""
 # for searching for elements in ranges
rdig = re.compile('\d+ TO \d+')
# for searching all elements
sdig = re.compile('\d+')

def main():
    with open(fname1, "r") as f:
        # empty container for all single elements
        s_all = []
        # empty container for all elements in ranges
        r_all = []
        for line in f:
            sd = sdig.findall(line) # find single numbers
            rd = rdig.findall(line) # find range numbers
            for i in sd:
                s_all.append(int(i))
            for i in rd:
                # format ranges
                j = re.sub(" TO ", ",", i)
                k = re.findall(r'\d+', j) 
                # expand ranges
                h = range(int(k[0]), int(k[1]) + 1)
                r_all.append(h)
        # empty container for multiple lists in to one
        r_merg = []
        for i in r_all:
            r_merg += i

    s = list(set(s_all).union(r_merg))

    with open(fname2, "r") as f:
        s_all = []
        r_all = []
        for line in f:
            sd = sdig.findall(line)
            rd = rdig.findall(line)
            for i in sd:
                s_all.append(int(i))
            for i in rd:
                j = re.sub(" TO ", ",", i)
                k = re.findall(r'\d+', j)
                h = range(int(k[0]), int(k[1]) + 1)
                r_all.append(h)
        r_merg = []
        for i in r_all:
            r_merg += i

    e = list(set(s_all).union(r_merg))
    # for elements with both end releases
    print "Both: ", set(s).intersection(e)
    # for elements with start only end releases
    print "Start: ", set(s).difference(e)
    # for elements with end only end releases
    print "End: ", set(e).difference(s)

if __name__ == '__main__':
    main()

The output looks like this:

Both:  set([1024, 1023, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 1047, 1048, 537, 1050, 1051, 1052, 541, 1054, 1055, 544, 1057, 546, 547, 548, 549, 550, 552, 553, 1066, 555, 556, 558, 1071, 1072, 561, 567, 568, 569, 570, 573, 575, 1088, 577, 578, 1097, 1098, 1099, 1100, 1101, 1102, 1104, 1105, 1106, 1107, 1108, 887, 612, 613, 614, 615, 620, 621, 622, 1136, 1137, 1138, 1139, 1140, 1141, 1143, 632, 1145, 1146, 635, 1148, 535, 652, 1165, 1166, 655, 656, 1169, 658, 1171, 660, 1173, 662, 1049, 665, 666, 667, 668, 538, 670, 671, 672, 673, 674, 539, 676, 677, 678, 679, 540, 711, 627, 542, 694, 695, 628, 543, 700, 701, 704, 705, 707, 708, 709, 710, 545, 712, 713, 714, 631, 633, 634, 536, 743, 744, 636, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 895, 559, 987, 1073, 829, 830, 833, 834, 651, 836, 838, 839, 840, 841, 843, 845, 846, 653, 848, 693, 850, 852, 654, 854, 855, 857, 859, 860, 861, 862, 864, 866, 867, 868, 869, 657, 872, 873, 874, 875, 876, 878, 880, 881, 882, 659, 885, 745, 1402, 661, 576, 663, 883, 669, 675, 984, 986, 847, 988, 482, 483, 488, 489, 1012, 1014, 1015, 1016, 1017, 1018, 1019, 1021, 1022, 853])
Start:  set([564, 57, 59, 60, 1089, 1090, 1091, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 617, 1135, 625, 1147, 1149, 1150, 1151, 1158, 1167, 623, 696, 697, 698, 702, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 831, 998, 888, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 973, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 995, 484, 485, 486, 487, 1003, 1004, 1009])
End:  set([1027, 1028, 1053, 1056, 1062, 1063, 1084, 1085, 1086, 1092, 1095, 1103, 1122, 1123, 1124, 624, 626, 1142, 1144, 637, 638, 639, 1152, 1153, 642, 643, 644, 645, 646, 1159, 648, 1161, 1162, 1172, 699, 706, 630, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 640, 641, 647, 649, 650, 832, 999, 1000, 1001, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 1020])

October 15, 2016

Jackup interface

Jackup interface

Substructure – jackup rig interface check has gotten simpler over the years. In the past, I would spend hours using drawings, sketching, evaluating clashes and overburdens. Now, it takes much less to sketch and check. Here’s what I do: draw silhouettes of structures in 3D, which lets me iterate rapidly, and check positions for an optimum placement.