*** empty log message ***

This commit is contained in:
Dave Goodwin 2004-05-24 13:21:34 +00:00
parent 25d9d8bac7
commit deb25434b8
12 changed files with 337 additions and 152 deletions

View file

@ -937,13 +937,14 @@ extern "C" {
}
int DLL_EXPORT getCanteraError(int buflen, char* buf) {
string e; // = "<no error>";
//if (nErrors() > 0)
string e;
e = lastErrorMessage();
int n = min(e.size(), buflen-1);
copy(e.begin(), e.begin() + n, buf);
buf[min(n, buflen-1)] = '\0';
return 0;
if (buflen > 0) {
int n = min(e.size(), buflen-1);
copy(e.begin(), e.begin() + n, buf);
buf[min(n, buflen-1)] = '\0';
}
return int(e.size());
}
int DLL_EXPORT addCanteraDirectory(int buflen, char* buf) {

View file

@ -1,37 +1,27 @@
import sys
bindir = 'c:/cantera/bin'
libdir = 'd:/dgg/dv/sf/cantera/build/lib/i686-pc-win32'
incdir = 'd:/dgg/dv/sf/cantera/build/include'
dflibdir = 'D:\Program Files\Microsoft Visual Studio\DF98\LIB'
libs = ['clib', 'oneD', 'zeroD', 'transport', 'cantera', 'recipes',
'cvode', 'ctlapack', 'ctmath', 'ctblas', 'tpx']
bindir = '/usr/local/bin'
libdir = '/Users/dgg/dv/sf/cantera/build/lib/powerpc-apple-darwin7.3.0'
incdir = '/Users/dgg/dv/sf/cantera/build/include'
libs = '-lclib -luser -loneD -lzeroD -ltransport -lcantera -lrecipes -lcvode -lctlapack -lctmath -lctblas -ltpx -lg2c -lgcc'
f = open('setup.m','w')
f.write('cd cantera\nbuild_cantera\nexit\n')
f.write('cd cantera\nbuildux\nexit\n')
f.close()
fb = open('cantera/build_cantera.m','w')
fb = open('cantera/buildux.m','w')
fb.write("""
disp('building Cantera..');
mex -I"""+incdir+""" private/ctmethods.cpp private/ctfunctions.cpp ...
mex private/ctmethods.cpp private/ctfunctions.cpp ...
private/xmlmethods.cpp private/phasemethods.cpp ...
private/thermomethods.cpp private/kineticsmethods.cpp ...
private/transportmethods.cpp private/reactormethods.cpp ...
private/reactornetmethods.cpp ...
private/wallmethods.cpp private/flowdevicemethods.cpp ...
private/funcmethods.cpp ...
private/funcmethods.cpp ...
private/onedimmethods.cpp private/surfmethods.cpp private/write.cpp ...
"""+'-I'+incdir+' -L'+libdir+' '+libs+'\n'+"""disp('done.');
""")
s = ''
for lib in libs:
s += ' '+libdir+'/'+lib+'.lib ...\n'
fb.write(s)
fb.write(' "'+dflibdir+'/dformd.lib" ...\n')
fb.write(' "'+dflibdir+'/dfconsol.lib" ...\n')
fb.write(' "'+dflibdir+'/dfport.lib" \n')
fb.close()
fp = open('cantera/ctbin.m','w')

View file

@ -22,7 +22,7 @@ class XML_Node:
If 'wrap' is greater than zero, then only a Python wrapper is
created - no new kernel object results.
"""
self._xml_id = 0
self.wrap = wrap
# create a wrapper for an existing kernel object

View file

@ -59,3 +59,7 @@ def refCount(a):
"""Return the reference count for an object."""
import _cantera
return _cantera.ct_refcnt(a)
def addDirectory(dir):
import _cantera
return _cantera.ct_addDirectory(dir)

View file

@ -13,17 +13,13 @@ from Cantera.solution import Solution
#import _cantera
import os
def IdealGasMix(src="", id = ""):
def IdealGasMix(src="", id = "", loglevel = 0):
"""Return a Solution object representing an ideal gas mixture.
src --- input file
root --- root of an XML tree containing the phase specification.
Specify src or root but not both.
thermo --- auxiliary thermo database
transport --- transport model
trandb --- transport database
id --- XML id tag for phase
"""
return Solution(src=src,id=id)
return Solution(src=src,id=id,loglevel=loglevel)
def GRI30(transport = ""):

View file

@ -1,16 +1,16 @@
static PyObject *
ct_buildSolutionFromXML(PyObject *self, PyObject *args)
{
int ixml, ith, ikin;
char *src=0, *id=0;
if (!PyArg_ParseTuple(args, "sisii:buildSolutionFromXML", &src, &ixml,
&id, &ith, &ikin))
return NULL;
int ok = buildSolutionFromXML(src, ixml, id, ith, ikin);
if (ok == -1) { return reportCanteraError();}
return Py_BuildValue("i",ok);
}
// static PyObject *
// ct_buildSolutionFromXML(PyObject *self, PyObject *args)
// {
// int ixml, ith, ikin;
// char *src=0, *id=0;
// if (!PyArg_ParseTuple(args, "sisii:buildSolutionFromXML", &src, &ixml,
// &id, &ith, &ikin))
// return NULL;
// int ok = buildSolutionFromXML(src, ixml, id, ith, ikin);
// if (ok == -1) { return reportCanteraError();}
// return Py_BuildValue("i",ok);
// }
static PyObject *
ct_get_cantera_error(PyObject *self, PyObject *args)
@ -27,35 +27,45 @@ ct_refcnt(PyObject *self, PyObject *args)
{
PyObject* o;
if (!PyArg_ParseTuple(args, "O", &o)) return NULL;
cout << "refcnt = " << o->ob_refcnt << endl;
PyObject* cnt = Py_BuildValue("i",o->ob_refcnt);
return cnt;
}
// static PyObject *
// ct_print(PyObject *self, PyObject *args)
// {
// char* msg;
// if (!PyArg_ParseTuple(args, "s:print", &msg))
// return NULL;
// printf(msg);
// return Py_BuildValue("i",0);
// }
static PyObject *
ct_print(PyObject *self, PyObject *args)
ct_addDirectory(PyObject *self, PyObject *args)
{
char* msg;
if (!PyArg_ParseTuple(args, "s:print", &msg))
char* dir;
if (!PyArg_ParseTuple(args, "s:addDirectory", &dir))
return NULL;
printf(msg);
int n = strlen(dir);
addCanteraDirectory(n, dir);
return Py_BuildValue("i",0);
}
static PyObject *
ct_readlog(PyObject *self, PyObject *args)
{
char* msg = 0;
int n = readlog(-1, msg);
if (n > 0) {
msg = new char[n+1];
readlog(n, msg);
PyObject* r = Py_BuildValue("s",msg);
return r;
}
else
return Py_BuildValue("s","");
}
// static PyObject *
// ct_readlog(PyObject *self, PyObject *args)
// {
// char* msg = 0;
// int n = readlog(-1, msg);
// if (n > 0) {
// msg = new char[n+1];
// readlog(n, msg);
// PyObject* r = Py_BuildValue("s",msg);
// return r;
// }
// else
// return Py_BuildValue("s","");
//}
// static PyObject *
// ct_ck2cti(PyObject *self, PyObject *args)

View file

@ -62,17 +62,17 @@ py_natoms(PyObject *self, PyObject *args) {
return Py_BuildValue("d",phase_nAtoms(ph, k, m));
}
static PyObject*
py_addelement(PyObject *self, PyObject *args) {
int ph;
char* name;
double wt;
if (!PyArg_ParseTuple(args, "isd:py_addelement", &ph, &name, &wt))
return NULL;
int ok = phase_addElement(ph, name, wt);
if (ok < 0) return reportError(ok);
else return Py_BuildValue("i",0);
}
// static PyObject*
// py_addelement(PyObject *self, PyObject *args) {
// int ph;
// char* name;
// double wt;
// if (!PyArg_ParseTuple(args, "isd:py_addelement", &ph, &name, &wt))
// return NULL;
// int ok = phase_addElement(ph, name, wt);
// if (ok < 0) return reportError(ok);
// else return Py_BuildValue("i",0);
// }
static PyObject*
py_elementindex(PyObject *self, PyObject *args) {

View file

@ -11,7 +11,7 @@ static PyMethodDef ct_methods[] = {
{"phase_nelements", py_nelements, METH_VARARGS},
{"phase_nspecies", py_nspecies, METH_VARARGS},
{"phase_natoms", py_natoms, METH_VARARGS},
{"phase_addelement", py_addelement, METH_VARARGS},
//{"phase_addelement", py_addelement, METH_VARARGS},
{"phase_elementindex", py_elementindex, METH_VARARGS},
{"phase_speciesindex", py_speciesindex, METH_VARARGS},
{"phase_getarray", phase_getarray, METH_VARARGS},
@ -82,10 +82,11 @@ static PyMethodDef ct_methods[] = {
{"tran_setParameters", py_setParameters, METH_VARARGS},
{"get_Cantera_Error", ct_get_cantera_error, METH_VARARGS},
{"ct_print", ct_print, METH_VARARGS},
//{"ct_print", ct_print, METH_VARARGS},
{"ct_addDirectory", ct_addDirectory, METH_VARARGS},
{"ct_refcnt", ct_refcnt, METH_VARARGS},
{"readlog", ct_readlog, METH_VARARGS},
{"buildSolutionFromXML", ct_buildSolutionFromXML, METH_VARARGS},
//{"readlog", ct_readlog, METH_VARARGS},
//{"buildSolutionFromXML", ct_buildSolutionFromXML, METH_VARARGS},
{"domain_clear", py_domain_clear, METH_VARARGS},
{"domain_del", py_domain_del, METH_VARARGS},

View file

@ -4,8 +4,10 @@
#include "Python.h"
static PyObject* reportCanteraError() {
char* buf = new char[400];
getCanteraError(400, buf);
char* buf = 0;
int buflen = getCanteraError(0, buf);
buf = new char[buflen+1];
getCanteraError(buflen, buf);
PyErr_SetString(ErrorObject,buf);
delete buf;
return NULL;

View file

@ -1,33 +1,95 @@
#################################################################
#
# Getting started
#
###################################################################
#################################
print """
Tutorial 1: Getting started
"""
##################################
# Start Python, and at the prompt type:
# Put this statement at the top of each Python script to import the
# most commonly-used parts of Cantera:
from Cantera import *
# This statement imports the most commonly-used components of Cantera.
# Now type
# The first thing you need is an object representing some phase of
# matter. We'll create here a gas mixture:
gas1 = GRI30()
# To view the state of the mixture, just print it:
print gas1
# If you have successfully installed the Cantera package,
# you should see something like this:
# You should see something like this:
#
#
# temperature 300 K
# pressure 101325 Pa
# density 0.081896 kg/m^3
# mean mol. weight 2.01594 amu
#
# X Y
# ------------- ------------
# H2 1.000000e+000 1.000000e+000
#
# (except that it will list many more species).
# temperature 300 K
# pressure 101325 Pa
# density 0.081889 kg/m^3
# mean mol. weight 2.01588 amu
# 1 kg 1 kmol
# ----------- ------------
# enthalpy 26470.1 5.336e+04 J
# internal energy -1.21088e+06 -2.441e+06 J
# entropy 64914 1.309e+05 J/K
# Gibbs function -1.94477e+07 -3.92e+07 J
# heat capacity c_p 14311.8 2.885e+04 J/K
# heat capacity c_v 10187.3 2.054e+04 J/K
# X Y
# ------------- ------------
# H2 1.000000e+00 1.000000e+00
# H 0.000000e+00 0.000000e+00
# O 0.000000e+00 0.000000e+00
# O2 0.000000e+00 0.000000e+00
# OH 0.000000e+00 0.000000e+00
# H2O 0.000000e+00 0.000000e+00
# HO2 0.000000e+00 0.000000e+00
# H2O2 0.000000e+00 0.000000e+00
# C 0.000000e+00 0.000000e+00
# CH 0.000000e+00 0.000000e+00
# CH2 0.000000e+00 0.000000e+00
# CH2(S) 0.000000e+00 0.000000e+00
# CH3 0.000000e+00 0.000000e+00
# CH4 0.000000e+00 0.000000e+00
# CO 0.000000e+00 0.000000e+00
# CO2 0.000000e+00 0.000000e+00
# HCO 0.000000e+00 0.000000e+00
# CH2O 0.000000e+00 0.000000e+00
# CH2OH 0.000000e+00 0.000000e+00
# CH3O 0.000000e+00 0.000000e+00
# CH3OH 0.000000e+00 0.000000e+00
# C2H 0.000000e+00 0.000000e+00
# C2H2 0.000000e+00 0.000000e+00
# C2H3 0.000000e+00 0.000000e+00
# C2H4 0.000000e+00 0.000000e+00
# C2H5 0.000000e+00 0.000000e+00
# C2H6 0.000000e+00 0.000000e+00
# HCCO 0.000000e+00 0.000000e+00
# CH2CO 0.000000e+00 0.000000e+00
# HCCOH 0.000000e+00 0.000000e+00
# N 0.000000e+00 0.000000e+00
# NH 0.000000e+00 0.000000e+00
# NH2 0.000000e+00 0.000000e+00
# NH3 0.000000e+00 0.000000e+00
# NNH 0.000000e+00 0.000000e+00
# NO 0.000000e+00 0.000000e+00
# NO2 0.000000e+00 0.000000e+00
# N2O 0.000000e+00 0.000000e+00
# HNO 0.000000e+00 0.000000e+00
# CN 0.000000e+00 0.000000e+00
# HCN 0.000000e+00 0.000000e+00
# H2CN 0.000000e+00 0.000000e+00
# HCNN 0.000000e+00 0.000000e+00
# HCNO 0.000000e+00 0.000000e+00
# HOCN 0.000000e+00 0.000000e+00
# HNCO 0.000000e+00 0.000000e+00
# NCO 0.000000e+00 0.000000e+00
# N2 0.000000e+00 0.000000e+00
# AR 0.000000e+00 0.000000e+00
# C3H7 0.000000e+00 0.000000e+00
# C3H8 0.000000e+00 0.000000e+00
# CH2CHO 0.000000e+00 0.000000e+00
# CH3CHO 0.000000e+00 0.000000e+00
#
# What you have just done is to create an object ("gas1") that
# implements GRI-Mech 3.0, the 53-species, 325-reaction natural gas
@ -50,6 +112,7 @@ print gas1
# general, whichever species is listed first will initially have a
# mole fraction of 1.0, and all of the others will be zero.
# Setting the state
# -----------------
@ -72,6 +135,7 @@ print gas1
# X Y
# ------------- ------------
# H2 1.000000e+000 1.000000e+000
# (other species not shown)
#
# Notice that the temperature has been changed as requested, but the
# pressure has changed too. The density and composition have
@ -97,49 +161,112 @@ print gas1
# and density fixed. (The pressure changes).
#
# Instead of using a method like 'setTemperature' to set one property,
# you can use a single method 'set' to set any property or combination
# of properties:
# Setting multiple properties
# ---------------------------------------------------
# If you want to set multiple properties at once, use the 'set' function:
set(gas1, Temperature = 900.0, Pressure = 1.e5)
gas1.set(Temperature = 900.0, Pressure = 1.e5)
# This statement sets both temperature and pressure at the same
# time. Any number of property/value pairs can be specified in a
# call to 'set'. For example, the following sets the mole fractions
# too:
set(gas1, Temperature = 900.0, Pressure = 1.e5,
MoleFractions = 'CH4:1,O2:2,N2:7.52')
gas1.set(Temperature = 900.0, Pressure = 1.e5,
MoleFractions = 'CH4:1,O2:2,N2:7.52')
# The 'set' function also accepts abbreviated property names:
set(gas1,T = 900.0, P = 1.e5, X = 'CH4:1,O2:2,N2:7.52')
gas1.set(T = 900.0, P = 1.0e5, X = 'CH4:1,O2:2,N2:7.52')
# Either version results in:
print gas1
# temperature 900 K
# pressure 100000 Pa
# density 0.369279 kg/m^3
# mean mol. weight 27.6332 amu
# 1 kg 1 kmol
# ----------- ------------
# enthalpy 455660 1.259e+07 J
# internal energy 184862 5.108e+06 J
# entropy 8529.31 2.357e+05 J/K
# Gibbs function -7.22072e+06 -1.995e+08 J
# heat capacity c_p 1304.4 3.604e+04 J/K
# heat capacity c_v 1003.52 2.773e+04 J/K
# X Y
# ------------- ------------
# H2 0.000000e+00 0.000000e+00
# H 0.000000e+00 0.000000e+00
# O 0.000000e+00 0.000000e+00
# O2 1.901141e-01 2.201487e-01
# OH 0.000000e+00 0.000000e+00
# H2O 0.000000e+00 0.000000e+00
# HO2 0.000000e+00 0.000000e+00
# H2O2 0.000000e+00 0.000000e+00
# C 0.000000e+00 0.000000e+00
# CH 0.000000e+00 0.000000e+00
# CH2 0.000000e+00 0.000000e+00
# CH2(S) 0.000000e+00 0.000000e+00
# CH3 0.000000e+00 0.000000e+00
# CH4 9.505703e-02 5.518632e-02
# CO 0.000000e+00 0.000000e+00
# CO2 0.000000e+00 0.000000e+00
# HCO 0.000000e+00 0.000000e+00
# CH2O 0.000000e+00 0.000000e+00
# CH2OH 0.000000e+00 0.000000e+00
# CH3O 0.000000e+00 0.000000e+00
# CH3OH 0.000000e+00 0.000000e+00
# C2H 0.000000e+00 0.000000e+00
# C2H2 0.000000e+00 0.000000e+00
# C2H3 0.000000e+00 0.000000e+00
# C2H4 0.000000e+00 0.000000e+00
# C2H5 0.000000e+00 0.000000e+00
# C2H6 0.000000e+00 0.000000e+00
# HCCO 0.000000e+00 0.000000e+00
# CH2CO 0.000000e+00 0.000000e+00
# HCCOH 0.000000e+00 0.000000e+00
# N 0.000000e+00 0.000000e+00
# NH 0.000000e+00 0.000000e+00
# NH2 0.000000e+00 0.000000e+00
# NH3 0.000000e+00 0.000000e+00
# NNH 0.000000e+00 0.000000e+00
# NO 0.000000e+00 0.000000e+00
# NO2 0.000000e+00 0.000000e+00
# N2O 0.000000e+00 0.000000e+00
# HNO 0.000000e+00 0.000000e+00
# CN 0.000000e+00 0.000000e+00
# HCN 0.000000e+00 0.000000e+00
# H2CN 0.000000e+00 0.000000e+00
# HCNN 0.000000e+00 0.000000e+00
# HCNO 0.000000e+00 0.000000e+00
# HOCN 0.000000e+00 0.000000e+00
# HNCO 0.000000e+00 0.000000e+00
# NCO 0.000000e+00 0.000000e+00
# N2 7.148289e-01 7.246650e-01
# AR 0.000000e+00 0.000000e+00
# C3H7 0.000000e+00 0.000000e+00
# C3H8 0.000000e+00 0.000000e+00
# CH2CHO 0.000000e+00 0.000000e+00
# CH3CHO 0.000000e+00 0.000000e+00
# Either version results in
#
# temperature 900 K
# pressure 100000 Pa
# density 0.3693 kg/m^3
# mean mol. weight 27.6332 amu
#
# X Y
# ------------- ------------
# O2 1.901141e-001 2.201489e-001
# CH4 9.505703e-002 5.518732e-002
# N2 7.148289e-001 7.246638e-001
#
# Other properties may also be set using 'set', including some that
# can't be set individually. The following property pairs may be
# set: (Enthalpy, Pressure), (IntEnergy, Volume), (Entropy,
# Volume), (Entropy, Pressure). In each case, the values of the
# extensive properties must be entered *per unit mass*.
# can only be set in combination with others. The following property
# pairs may be set: (Enthalpy, Pressure), (IntEnergy, Volume),
# (Entropy, Volume), (Entropy, Pressure). In each case, the values of
# the extensive properties must be entered *per unit mass*.
# Setting the enthalpy and pressure:
set(gas1, Enthalpy = 2*gas1.enthalpy_mass(), Pressure = 2*OneAtm)
gas1.set(Enthalpy = 2*gas1.enthalpy_mass(), Pressure = 2*OneAtm)
# This sets gas1 to a state with P = 2 atm, and a specific enthalpy
# twice its previous value.
# Note that the abbreviations T, P, H, U, S, V can also be used with
# the 'set' method.
# The composition above was specified using a string. The format is a
# comma-separated list of <species name>:<relative mole numbers>

View file

@ -5,23 +5,47 @@ print """
"""
####################################################################
from Cantera import *
from time import clock
# You can build a gas mixture object by importing element, species,
# and reaction definitions from input files in the format described in
# the document "Defining Phases and Interfaces". A set of input files
# in this format is contained in the data folder.
# In the last tutorial, we used function GRI30 to create an object
# that models an ideal gas mixture with the species and reactions of
# GRI-Mech 3.0. Another way to do this is shown here:
# Many existing reaction mechanism files are in "CK format," by
# which we mean the input file format developed for use with the
# Chemkin-II software package. [See R. J. Kee, F. M. Rupley, and
# J. A. Miller, Sandia National Laboratories Report SAND89-8009
# (1989).]
gas = importPhase('gri30.cti', 'gri30')
# Cantera comes with a converter utility program 'ck2cti' (or 'ck2cti.exe')
# that converts CK format into Cantera format. This program should be run
# from the command line first to convert any CK files you plan to use into
# Cantera format.
# Function 'importPhase' constructs an object representing a phase of
# matter by reading in attributes of the phase from a file, which in
# this case is 'gri30.cti'. This file contains a complete
# specification of the GRI-Mech 3.0 reaction mechanism, including
# element data (name, atomic weight), species data (name, elemental
# composition, coefficients to compute thermodynamic and transport
# properties), and reaction data (stoichiometry, rate coefficient
# parameters). The file is written in a format understood by Cantera,
# which is described in the document "Defining Phases and Interfaces."
# CTI files distributed with Cantera
#---------------------------------
# Several reaction mechanism files in this format are included in the
# Cantera distribution, including ones that model high-temperature
# air, a hydrogen/oxygen reaction mechanism, and a few surface
# reaction mechanisms. Under Windows, the installation program puts
# these files in 'C:\Program File\Common Files\Cantera.' On a
# unix/linux/Mac OSX machine, they are usually kept in the 'data'
# subdirectory within the Cantera installation directory.
# If for some reason Cantera has difficulty finding where these files
# are on your system, set environment variable CANTERA_DATA to the
# directory where they are located. Alternatively, you can call function
# addDirectory to add a directory to the Cantera search path:
addDirectory('/usr/local/data')
ggg = importPhase('dummy.cti')
# Cantera input files are plain text files, and can be created with
# any text editor. See the document 'Defining Phases and Interfaces'
# for more information.
from Cantera import *
t0 = clock()
@ -34,6 +58,7 @@ print 'time to create gas1 = ',clock() - t0
# Files\Common Files\Cantera and/or C:\CANTERA\DATA. On most other
# platforms, it is usually in /usr/local/cantera/data.
# A Cantera input file may contain more than one phase specification, or may
# contain specifications of interfaces (surfaces).
@ -89,4 +114,20 @@ diamonnd_surf2 = importInterface('diamond.xml','diamond_100',
phases = [gas2, diamond])
# Converting CK-format files
# --------------------------
# Many existing reaction mechanism files are in "CK format," by
# which we mean the input file format developed for use with the
# Chemkin-II software package. [See R. J. Kee, F. M. Rupley, and
# J. A. Miller, Sandia National Laboratories Report SAND89-8009
# (1989).]
# Cantera comes with a converter utility program 'ck2cti' (or
# 'ck2cti.exe') that converts CK format into Cantera format. This
# program should be run from the command line first to convert any CK
# files you plan to use into Cantera format. This utility program can
# also be downloaded from the Cantera User's Group web site.

View file

@ -22,14 +22,27 @@ help(g.__class__)
# You can also use the Python module browser to view this same
# information in a web browser.
# Under Windows, on the Start menu
# select Programs/Python2.x/Module Docs. On unix or Mac OSX, type
# 'pydoc -g' at a shell prompt, A small pop-up window will
# appear. Click on 'open browser', then navigate to the Cantera module, and then select what you want documentation about.
# information in a web browser. Under Windows, on the Start menu
# select
# Start
# |---Programs
# |---Python2.x
# |---Module Docs
#
# On unix, linux, or Mac OSX, at a shell prompt type
#
# pydoc -g
#
# A small pop-up window will appear. Enter 'Cantera' in the search
# box, or else simply click on 'open browser', then navigate to the
# Cantera module, and then select what you want documentation about.
# The module browser can also be started from within a Python script
# as follows:
import pydoc
pydoc.gui()
# Note: if you run into problems running the module browser this way,
# do this instead: Run 'pythonw' interactively (not 'python'), import
# module 'pydoc', and call function 'gui':
#
# pythonw
# >>> import pydoc
# >>> pydoc.gui()
#