Skip to content

Commit f15a202

Browse files
committed
Adding documentation
1 parent 94635b5 commit f15a202

File tree

7 files changed

+561
-131
lines changed

7 files changed

+561
-131
lines changed

doc/installation.rst

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,55 @@ matplotlib. Installation guidelines are given for various operating systems.
1818
Linux
1919
-----
2020

21-
The ''python'' program and the modules ''numpy'', ''scipy'' and ''matplotlib''
22-
are included in most common distributions of Linux and can be installed without any problems. In many
23-
cases, different versions of ''python'' are offered. Please make sure that ''python'' version 3.6 or higher is
24-
installed. In addition, the modules ''meshio'', ''pickle'' and ''h5py'' can be installed for additional functionality.
21+
The Python compiler and the modules ``numpy``, ``scipy``, and ``matplotlib`` are included in
22+
most common distributions of Linux and can be installed without any problems. In many cases,
23+
different versions of ``python`` are offered. Please make sure that ``python`` version 3.6 or
24+
higher is installed. In addition, the modules ``meshio``, ``pickle``, and ``h5py`` can be
25+
installed for additional functionality.
2526

26-
Execute the file ''install.py'' in the root directory ''pyfem''. In a terminal, one can type:
27+
Execute the file ``install.py`` in the root directory ``pyfem``. In a terminal, one can type:
2728

28-
python3 install.py
29+
.. code-block:: bash
2930
30-
This script will check if the correct versions of Python and the various modules are available. In addition,
31-
the total path to the executable is given. For your own convenience, you can add this to your ''.bashrc'' file:
31+
./install
3232
33-
alias pyfem="python <pyfemdir>/PyFEM.py"
33+
This script will check if the correct versions of Python and the various modules are available.
34+
If not, it will ask your permission to install the correct modules for you.
3435

35-
When using csh or tcsh add the following line to ''.cshrc'' or ''.tcshrc'':
36+
The main executables are created. In commandline you can run PyFEM by typing
3637

37-
alias pyfem "python <pyfemdir>/PyFEM.py"
38+
.. code-block:: bash
39+
<relative_path_to_this_directory>/pyfem.sh inputFile.pro
3840
39-
The main program ''pyfem'' can be run from the command prompt. For example, in order to run the
40-
file ''StressWave20x20.pro'' in the directory ''examples/ch05'', simply type:
41+
The Graphical User Interface of the code (currently under development) can be exectuted
42+
by typing from any directory:
4143

42-
pyfem StressWave20x20.pro
44+
.. code-block:: bash
45+
<relative_path_to_this_directory>/pyfem_gui.exe
46+
47+
It is advised to create aliases. When using a bash shell, please
48+
add the following lines to the file ``~/.bashrc``:
49+
50+
.. code-block:: bash
51+
alias pyfem='python3 /home/joris/Git/pyfem_github/PyFEM/PyFEM.py'
52+
alias pyfem_gui = '/home/joris/Git/pyfem_github/PyFEM/pyfem_gui.x'
53+
54+
You can then run PyFEM in commandline from any directory by typing:
55+
56+
.. code-block:: bash
57+
pyfem inputFile.pro
58+
59+
You can start the gui by typing:
60+
61+
.. code-block:: bash
62+
pyfem_gui
63+
64+
Windows
65+
-------
66+
67+
Under construction
68+
69+
MacOS
70+
-----
71+
72+
Under construction

pyfem/util/itemList.py

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,33 +30,78 @@
3030

3131
class itemList ( dict ):
3232

33-
def add ( self, ID, item ):
33+
"""
34+
Class to construct a list of items that have a coninuous local number, and
35+
a global ID.
36+
"""
37+
38+
def add ( self, ID: int, item ):
39+
40+
"""
41+
Adds an item with an ID to the list. This item will be stored in the list.
3442
35-
if ID in self:
36-
raise RuntimeError( 'ID ' + str(ID) + ' already exists in ' + type(self).__name__ )
43+
Args:
44+
ID (int): the ID of the item to be stored.
45+
item: the value(s) of the item to be stored.
46+
"""
47+
48+
if ID in self:
49+
raise RuntimeError( 'ID ' + str(ID) + ' already exists in ' + type(self).__name__ )
3750

38-
self[ID] = item
51+
self[ID] = item
3952

40-
def get ( self, IDs ):
53+
def get ( self, IDs ):
4154

42-
if isinstance(IDs,int):
43-
return self[IDs]
44-
elif isinstance(IDs,list):
45-
return [ self[ID] for ID in IDs ]
55+
"""
56+
Returns the index / indices of an ID or list of IDs of items in the list.
57+
58+
Args:
59+
IDs (list[int]|int,optional): the ID/IDs. If ommited, a list with all indces
60+
will be returned.
61+
Returns:
62+
list[int]: a list with the indices. In the case of a single ID, this list has
63+
length 1.
64+
"""
65+
66+
if isinstance(IDs,int):
67+
return self[IDs]
68+
elif isinstance(IDs,list):
69+
return [ self[ID] for ID in IDs ]
4670

47-
raise RuntimeError('illegal argument for itemList.get')
71+
raise RuntimeError('illegal argument for itemList.get')
4872

49-
def getIndices ( self, IDs = -1 ):
73+
def getIndices ( self, IDs : list[int] | int = -1 ) -> list[int]:
74+
75+
"""
76+
Returns the index / indices of an ID or list of IDs of items in the list.
5077
51-
if IDs == -1:
52-
return list(self.keys())
53-
elif isinstance(IDs,int):
54-
return list(self.keys()).index( IDs )
55-
elif isinstance(IDs,list):
56-
return [ list(self.keys()).index( ID ) for ID in IDs ]
78+
Args:
79+
IDs (list[int]|int,optional): the ID/IDs. If ommited, a list with all indces
80+
will be returned.
81+
Returns:
82+
list[int]: a list with the indices. In the case of a single ID, this list has
83+
length 1.
84+
"""
85+
86+
if IDs == -1:
87+
return list(self.keys())
88+
elif isinstance(IDs,int):
89+
return list(self.keys()).index( IDs )
90+
elif isinstance(IDs,list):
91+
return [ list(self.keys()).index( ID ) for ID in IDs ]
5792

58-
raise RuntimeError('illegal argument for itemList.getIndices')
93+
raise RuntimeError('illegal argument for itemList.getIndices')
5994

60-
def findID( self , index ):
95+
def findID( self , index : int ) -> int:
6196

62-
return list(self.keys())[index]
97+
"""
98+
Returns the ID of an index in the list.
99+
100+
Args:
101+
index (int): the index of the item
102+
103+
Returns:
104+
int: the ID of the item
105+
"""
106+
107+
return list(self.keys())[index]

pyfem/util/kinematics.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,19 @@
3232

3333
class Kinematics:
3434

35-
def __init__( self , nDim , nStr ):
35+
"""
36+
Class that contains the kinematic state of a material
37+
point, i.e. strain and deformation gradient.
38+
39+
Args:
40+
nDim (int): the number of spatial dimensions of the problem (2 or 3)
41+
nStr (int): the number of strain components (2, 3 or 6)
42+
"""
43+
44+
def __init__( self , nDim: int , nStr: int ):
3645

37-
self.F = zeros( shape=( nDim , nDim ) )
38-
self.E = zeros( shape=( nDim , nDim ) )
39-
self.strain = zeros( nStr )
40-
self.dgdstrain = zeros( nStr )
41-
self.g = 0.
46+
self.F = zeros( shape=( nDim , nDim ) )
47+
self.E = zeros( shape=( nDim , nDim ) )
48+
self.strain = zeros( nStr )
49+
self.dgdstrain = zeros( nStr )
50+
self.g = 0.

pyfem/util/logger.py

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,48 +30,56 @@
3030

3131
import logging
3232

33-
#-------------------------------------------------------------------------------
34-
#
35-
#-------------------------------------------------------------------------------
3633

37-
38-
def setLogger( props ):
34+
def setLogger( props : dict ):
3935

40-
level = "normal"
36+
"""
37+
Creates a logger for the current analysis with a given format and level.
38+
39+
Args:
40+
props(dict): A dictionary containing the input file of the problem.
41+
Returns:
42+
logger: an instance of the logger.
43+
"""
44+
45+
level = "normal"
4146

42-
if hasattr(props,"logger"):
43-
level = props.logger.level
47+
if hasattr(props,"logger"):
48+
level = props.logger.level
4449

45-
if level not in ["normal","info","debug","critical","warning","silent"]:
46-
raise NotImplementedError('Logger level should be "normal", "info", "debug", "critical", "silent" or "warning"')
50+
if level not in ["normal","info","debug","critical","warning","silent"]:
51+
raise NotImplementedError('Logger level should be "normal", "info", "debug", "critical", "silent" or "warning"')
4752

48-
logger = logging.getLogger()
49-
handler = logging.StreamHandler()
53+
logger = logging.getLogger()
54+
handler = logging.StreamHandler()
5055

51-
if level == "debug":
52-
formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s')
53-
logger .setLevel(logging.DEBUG)
54-
elif level == "critical" or level == "silent":
55-
formatter = logging.Formatter(' %(message)s')
56-
logger .setLevel(logging.CRITICAL)
57-
elif level == "warning":
58-
formatter = logging.Formatter(' %(message)s')
59-
logger .setLevel(logging.WARNING)
60-
else:
61-
formatter = logging.Formatter(' %(message)s')
62-
logger .setLevel(logging.INFO)
56+
if level == "debug":
57+
formatter = logging.Formatter('%(asctime)s %(levelname)-8s %(message)s')
58+
logger .setLevel(logging.DEBUG)
59+
elif level == "critical" or level == "silent":
60+
formatter = logging.Formatter(' %(message)s')
61+
logger .setLevel(logging.CRITICAL)
62+
elif level == "warning":
63+
formatter = logging.Formatter(' %(message)s')
64+
logger .setLevel(logging.WARNING)
65+
else:
66+
formatter = logging.Formatter(' %(message)s')
67+
logger .setLevel(logging.INFO)
6368

64-
handler.setFormatter(formatter)
65-
logger .addHandler(handler)
69+
handler.setFormatter(formatter)
70+
logger .addHandler(handler)
6671

67-
return logger
72+
return logger
6873

69-
70-
#-------------------------------------------------------------------------------
71-
#
72-
#-------------------------------------------------------------------------------
7374

74-
7575
def getLogger():
7676

77-
return logging.getLogger()
77+
"""
78+
Function that returns an instance of the active logger.
79+
80+
Args:
81+
None
82+
Returnslogger: an instance of the active logger.
83+
"""
84+
85+
return logging.getLogger()

pyfem/util/plotUtils.py

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# R. de Borst, M.A. Crisfield, J.J.C. Remmers and C.V. Verhoosel #
66
# John Wiley and Sons, 2012, ISBN 978-0470666449 #
77
# #
8-
# Copyright (C) 2011-2024. The code is written in 2011-2012 by #
8+
# Copyright (C) 2011-2025. The code is written in 2011-2012 by #
99
# Joris J.C. Remmers, Clemens V. Verhoosel and Rene de Borst and since #
1010
# then augmented and maintained by Joris J.C. Remmers. #
1111
# All rights reserved. #
@@ -28,39 +28,50 @@
2828
# event caused by the use of the program. #
2929
################################################################################
3030

31+
import numpy as np
3132

32-
#-------------------------------------------------------------------------------
33-
#
34-
#-------------------------------------------------------------------------------
33+
def plotCurve( output: np.ndarray ) -> None:
3534

35+
"""
36+
Plots a curve based on the given output data points.
3637
37-
def plotCurve( output ):
38+
Args:
39+
output (List[Tuple[float, float]]): A list of (x, y) data points to plot.
3840
39-
from pylab import plot, show, xlabel, ylabel
41+
Returns:
42+
None
43+
"""
4044

41-
plot( [x[0] for x in output], [x[1] for x in output], 'r-o' )
45+
from pylab import plot, show, xlabel, ylabel
4246

43-
show()
44-
45-
46-
#-
47-
#
48-
#----------------
47+
plot( [x[0] for x in output], [x[1] for x in output], 'r-o' )
4948

49+
show()
50+
51+
52+
def plotTime(t: float) -> str:
53+
54+
"""
55+
Formats a given time duration into a human-readable string.
5056
51-
def plotTime( t ):
57+
Args:
58+
t (float): Time duration in seconds.
5259
60+
Returns:
61+
str: A formatted string representing the time in seconds, minutes, or hours.
62+
"""
5363
if t < 0.1:
5464
return f"{t:.1e} sec."
5565
elif t < 60.0:
5666
return f"{t:.3f} sec."
5767
elif t < 3600.0:
58-
minutes = int(t // 60 )
68+
minutes = int(t // 60)
5969
seconds = t % 60
6070
return f"{minutes} min. {seconds:.2f} sec."
6171
else:
62-
hours = int(t // 3600 )
63-
minutes = int((t % 3600 ) // 60 )
72+
hours = int(t // 3600)
73+
minutes = int((t % 3600) // 60)
6474
seconds = t % 60
65-
return f"{hours} hrs. {minutes} min. {seconds:.2f} sec."
75+
return f"{hours} hrs. {minutes} min. {seconds:.2f} sec."
76+
6677

0 commit comments

Comments
 (0)