1#!/usr/local/bin/python3.8 2 3#------------------------------------------------------------------------------- 4 5# This file is part of Code_Saturne, a general-purpose CFD tool. 6# 7# Copyright (C) 1998-2021 EDF S.A. 8# 9# This program is free software; you can redistribute it and/or modify it under 10# the terms of the GNU General Public License as published by the Free Software 11# Foundation; either version 2 of the License, or (at your option) any later 12# version. 13# 14# This program is distributed in the hope that it will be useful, but WITHOUT 15# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 17# details. 18# 19# You should have received a copy of the GNU General Public License along with 20# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin 21# Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 23#------------------------------------------------------------------------------- 24 25""" 26This module describes the script used to run a study/case for Code_Saturne. 27 28This module defines the following functions: 29- process_cmd_line 30- main 31""" 32 33#=============================================================================== 34# Import required Python modules 35#=============================================================================== 36 37import os, sys 38import types, string, re, fnmatch 39 40import socket 41 42from optparse import OptionParser 43 44#=============================================================================== 45# Classes 46#=============================================================================== 47 48class controller: 49 """ 50 Controller class for running computation. 51 """ 52 53 #--------------------------------------------------------------------------- 54 55 def __init__(self, 56 path = None, # run directory 57 package = None): # main package 58 59 # Package specific information 60 61 self.package = package 62 63 # run directory 64 65 self.path = path 66 67 # Initialize connection 68 69 import random 70 71 key = str(random.randrange(0, 2**31)) 72 hostname = socket.getfqdn() 73 74 self.s = socket.socket() 75 self.s.bind(('', 0)) # OS will pick an available port. 76 77 port = self.s.getsockname()[1] 78 79 f_path = 'control_file' 80 if self.path != None: 81 f_path = os.path.append(self.path, f_path) 82 c = open(f_path, 'w') 83 c.write('connect ' + hostname+':'+str(port) + ' ' + key + '\n') 84 c.close() 85 86 self.s.listen(0) 87 (self.conn, self.address) = self.s.accept() 88 89 cmp_key = self.conn.recv(len(key)).decode("utf-8") 90 if cmp_key != key: 91 print('incorrect key returned: expected ' + key + ', got ' + cmp_key) 92 93 magic_string = 'CFD_control_comm_socket' 94 cmp_string = self.conn.recv(len(magic_string)).decode("utf-8") 95 96 if cmp_string != magic_string: 97 print('incorrect magic string returned: expected ' + magic_string) 98 print('got ' + cmp_string) 99 100 self.conn.send(magic_string.encode("utf-8")) 101 102 #--------------------------------------------------------------------------- 103 104 def send_string(self, str): 105 106 self.conn.send((str + "\n").encode("utf-8")) 107 # print("sent ", str) 108 109 #--------------------------------------------------------------------------- 110 111 def recv_string(self, l=32768): 112 113 str = self.conn.recv(l).decode("utf-8") 114 lr = len(str) 115 while lr >= l: 116 str0 = self.conn.recv(l).decode("utf-8") 117 l = len(str0) 118 str += str0 119 return str 120 121 #--------------------------------------------------------------------------- 122 123 def advance(self, n = 1): 124 125 self.send_string("advance " + str(n)) 126 retcode = self.recv_string() 127 # print(retcode) 128 129 #--------------------------------------------------------------------------- 130 131 def disconnect(self): 132 133 self.send_string("disconnect ") 134 135 self.conn.shutdown(socket.SHUT_RDWR) 136 self.conn.close() 137 138 self.s.shutdown(socket.SHUT_RDWR) 139 self.s.close() 140 141 #--------------------------------------------------------------------------- 142 143 def __del__(self): 144 145 self.disconnect() 146 147#------------------------------------------------------------------------------- 148# Process the command line arguments 149#------------------------------------------------------------------------------- 150 151def process_cmd_line(argv, pkg): 152 """ 153 Process the passed command line arguments. 154 """ 155 156 if sys.argv[0][-3:] == '.py': 157 usage = "usage: %prog [options]" 158 else: 159 usage = "usage: %prog run [options]" 160 161 parser = OptionParser(usage=usage) 162 163 parser.add_option("--exec-dir", dest="exec_dir", type="string", 164 metavar="<case>", 165 help="server's exection directory") 166 167 parser.set_defaults(exec_dir=None) 168 169 # Note: we could use args to pass a calculation status file as an argument, 170 # which would allow pursuing the later calculation stages. 171 172 (options, args) = parser.parse_args(argv) 173 174 return (options.exec_dir) 175 176#=============================================================================== 177# Main function 178#=============================================================================== 179 180def main(argv, pkg): 181 """ 182 Main function. 183 """ 184 185 (exec_dir) = process_cmd_line(argv, pkg) 186 187 c = controller(exec_dir, pkg) 188 189 c.advance(3) 190 c.advance(3) 191 192 return 0 193 194#------------------------------------------------------------------------------- 195 196if __name__ == '__main__': 197 198 # Run package 199 200 try: 201 from code_saturne.cs_package import package 202 pkg = package() 203 except Exception: 204 pkg = None 205 206 retval = main(sys.argv[1:], pkg) 207 208 sys.exit(retval) 209 210#------------------------------------------------------------------------------- 211# End 212#------------------------------------------------------------------------------- 213 214