Releases: aatmdelissen/pyMOTO
v2.0.0
What's Changed
Main improvements with syntax change:
- More clear intent of code
- Much less boilerplate code. Adding modules to a Network does not require
appendanymore, but modules are automatically added to Network, user can select which Network(s) to use with context manager (with:) - Modules now accept optional positional arguments (not keyword arguments)
- Standard functions
__init__and__call__are used, for much better IDE integration and code hints - Normal variables can now be used instead of or in combination with signals as module inputs
- The module response is run once upon creation, which is more convenient for debugging
An examples gallery is added on the documentation page, which contains all examples in the new syntax style. Also, several new examples were added.
Renamed (old names will raise deprecation warning):
MathGeneral->MathExpressionDomainDefinition->VoxelDomainDyadCarrier->DyadicMatrixVecSet->SetValueConcatSignal->Concatenate
Module improvements:
AutoDiffmodule improvements, supporting backend based on HIPSautogradas alternative tojaxWriteToVTInow supports writing complex vectorsScalingnow supports double-sided constraints, where both a minimum and maximum value is requestedAssembleGeneralnow supports non-square matrices. Also, multiple element matrices can be passed with each their own individual scaling values to support multi-material topology optimization. The matrix assembly is also sped up by storing the sparsity pattern.OverhangFilternow supports freely choosing overhang angle for additive manufacturing, instead of only 45 degrees (for details see linked paper).
New modules:
SplitComplex- Splits complex value into its real and imaginary partsPrint- Print values in a signal to consoleSetValue- Set values in anumpyarray for specified indicesAddMatrix- Linear combination of sparse matricesConjugate- Complex conjugationTransientSolve- Calculation of transient response with numerical time-stepping (implemented for first order system)SeriesToVTI- Export of time-series data to VTI format (Paraview)
Other improvements:
- New methods in
VoxelDomain(formerlyDomainDefinition) (element_size,domain_size,size,get_dofnumber,get_element_indices) VoxelDomainnow also can voxelize mesh objects (e.g. from STL) using the methodscreate_for_mesh, which generates a suitable domain, andvoxelizewhich then converts a triangle mesh into voxel elements.- Switch from using
pypardisoto directly usingmklfor usage of Pardiso solver. Also enable solving matrices with complex and/or single precision. - MMA now supports unconstrained optimization (only an objective), see issue #7
- MMA optimizer can now also switch to the globally convergent version (GCMMA) with option
mmaversion='GCMMA') - MMA speedups
- SLP optimization algorithm
Software implementation:
- Improve publishing scripts
- Refactoring and formatting (
ruff) - Switch to
hatchlingas build backend to better support VSCode integration
How to port your code to version 2.0
Module definition
Old style (pymoto < 2)
class MyModule(pym.Module):
def _prepare(self, val1, val2=0.5)
... # Preparations here
def _response(self, x, *args):
if len(args) == 1:
y = args[0]
... # Response calculation here
return z
def _sensitivity(self, dz):
.... # Do sensitivity calculations here
return dx, ...In the new style (pymoto >= 2) this becomes
class MyModule(pym.Module):
# __init__ function is used instead of _prepare
def __init__(self, val1, val2=0.5):
... # Preparations here
# __call__ function is used instead of _response
def __call__(self, x, y=None): # Optional positional arguments are now supported
... # Response calculation here
return z
# No changes to sensitivity
def _sensitivity(self, dz):
.... # Do sensitivity calculations here
return dx, ...Module creation and usage
Old style (pymoto < 2)
fn = pym.Network()
sz1 = fn.append(MyModule(sx, val1=1.0, val2=3.0)) # Module with one input
sz2 = fn.append(MyModule([pym.Signal('constant', 1.0), sz1], val1=2.0)) # Module with two inputs
fn.response() # Only after calling `response()`, the response functions in the network will be run for the first time
pym.minimize_mma(fn, sx, sz2) # Optimize somethingNew style (pymoto >= 2)
with pym.Network() as fn: # Network as context manager
sz1 = MyModule(1.0, val2=3.0)(sx) # First options for the module (for __init__), after that the signal values (for __call__)
sz2 = MyModule(2.0)(1.0, sz1) # Constant values can be used directly as module input
# At this point all the response function in the network have been run once.
... # Change inputs signals
fn.response() # Usage of network remains the same. For updated values, response() can be called to re-calculate responses
pym.minimize_mma(sx, sz2, function=fn) # Passing function to the optimizer is now optional. If not passed, a global network will be used instead of the network called `fn`.Full Changelog: v1.5.1...v2.0.0
v2.0.0-rc2
What's Changed
Main improvements with syntax change:
- More clear intent of code
- Much less boilerplate code. Adding modules to a Network does not require
appendanymore, but modules are automatically added to Network, user can select which Network(s) to use with context manager (with:) - Modules now accept optional positional arguments (not keyword arguments)
- Standard functions
__init__and__call__are used, for much better IDE integration and code hints - Normal variables can now be used instead of or in combination with signals as module inputs
- The module response is run once upon creation, which is more convenient for debugging
An examples gallery is added on the documentation page, which contains all examples in the new syntax style. Also, several new examples were added.
Renamed:
MathGeneral->MathExpressionDomainDefinition->VoxelDomainDyadCarrier->DyadicMatrix
Module improvements:
AutoDiffmodule improvements, supporting backend based on HIPSautogradas alternative tojaxWriteToVTInow supports writing complex vectorsScalingnow supports double-sided constraints, where both a minimum and maximum value is requestedAssembleGeneralnow supports non-square matrices. Also, multiple element matrices can be passed with each their own individual scaling values to support multi-material topology optimization. The matrix assembly is also sped up by storing the sparsity pattern.
New modules:
SplitComplex- Splits complex value into its real and imaginary partsPrint- Print values in a signal to consoleSetValue- Set values in anumpyarray for specified indicesAddMatrix- Linear combination of sparse matricesConjugate- Complex conjugation
Other improvements:
- New methods in
VoxelDomain(formerlyDomainDefinition) (element_size,domain_size,size,get_dofnumber) VoxelDomainnow also can voxelize mesh objects (e.g. from STL) using the methodscreate_for_mesh, which generates a suitable domain, andvoxelizewhich then converts a triangle mesh into voxel elements.- Switch from using
pypardisoto directly usingmklfor usage of Pardiso solver. Also enable solving matrices with complex and/or single precision. - MMA now supports unconstrained optimization (only an objective), see issue #7
- MMA optimizer can now also switch to the globally convergent version (GCMMA) with option
mmaversion='GCMMA') - MMA speedups
- SLP optimization algorithm
Software implementation:
- Improve publishing scripts
- Refactoring and formatting (
ruff) - Switch to
hatchlingas build backend to better support VSCode integration
How to port your code to version 2.0
Module definition
Old style (pymoto < 2)
class MyModule(pym.Module):
def _prepare(self, val1, val2=0.5)
... # Preparations here
def _response(self, x, *args):
if len(args) == 1:
y = args[0]
... # Response calculation here
return z
def _sensitivity(self, dz):
.... # Do sensitivity calculations here
return dx, ...In the new style (pymoto >= 2) this becomes
class MyModule(pym.Module):
# __init__ function is used instead of _prepare
def __init__(self, val1, val2=0.5):
... # Preparations here
# __call__ function is used instead of _response
def __call__(self, x, y=None): # Optional positional arguments are now supported
... # Response calculation here
return z
# No changes to sensitivity
def _sensitivity(self, dz):
.... # Do sensitivity calculations here
return dx, ...Module creation and usage
Old style (pymoto < 2)
fn = pym.Network()
sz1 = fn.append(MyModule(sx, val1=1.0, val2=3.0)) # Module with one input
sz2 = fn.append(MyModule([pym.Signal('constant', 1.0), sz1], val1=2.0)) # Module with two inputs
fn.response() # Only after calling `response()`, the response functions in the network will be run for the first time
pym.minimize_mma(fn, sx, sz2) # Optimize somethingNew style (pymoto >= 2)
with pym.Network() as fn: # Network as context manager
sz1 = MyModule(1.0, val2=3.0)(sx) # First options for the module (for __init__), after that the signal values (for __call__)
sz2 = MyModule(2.0)(1.0, sz1) # Constant values can be used directly as module input
# At this point all the response function in the network have been run once.
... # Change inputs signals
fn.response() # Usage of network remains the same. For updated values, response() can be called to re-calculate responses
pym.minimize_mma(sx, sz2, function=fn) # Passing function to the optimizer is now optional. If not passed, a global network will be used instead of the network called `fn`.Full Changelog: v1.5.1...v2.0.0-rc2
v2.0.0-rc1
What's Changed
Main improvements with syntax change:
- More clear intent of code
- Much less boilerplate code. Adding modules to a Network does not require
appendanymore, but modules are automatically added to Network, user can select which Network(s) to use with context manager (with:) - Modules now accept optional positional arguments (not keyword arguments)
- Standard functions
__init__and__call__are used, for much better IDE integration and code hints - Normal variables can now be used instead of or in combination with signals as module inputs
- The module response is run once upon creation, which is more convenient for debugging
Other improvements:
- Add examples gallery on documentation page
- All examples now in same style with new syntax
- Several new examples
- AutoDiff module improvements, supporting backend based on
autogradas alternative tojax - New methods in DomainDefinition (
element_size,domain_size,size,get_dofnumber) - Improve publishing scripts
- Refactoring and formatting (Ruff)
- MMA now supports unconstraints optimization (only an objective), see issue #7
- Switch from using
pypardisoto directly usingmklfor usage of Pardiso solver. Also enable solving matrices with complex and/or single precision. - WriteToVTI now supports writing complex vectors
- SLP optimization algorithm
New modules:
- SplitComplex
- VecSet
- AddMatrix
- Conjugate
How to port your code to version 2.0
Module definition
Old style (pymoto < 2)
class MyModule(pym.Module):
def _prepare(self, val1, val2=0.5)
... # Preparations here
def _response(self, x, *args):
if len(args) == 1:
y = args[0]
... # Response calculation here
return z
def _sensitivity(self, dz):
.... # Do sensitivity calculations here
return dx, ...In the new style (pymoto >= 2) this becomes
class MyModule(pym.Module):
# __init__ function is used instead of _prepare
def __init__(self, val1, val2=0.5):
... # Preparations here
# __call__ function is used instead of _response
def __call__(self, x, y=None): # Optional positional arguments are now supported
... # Response calculation here
return z
# No changes to sensitivity
def _sensitivity(self, dz):
.... # Do sensitivity calculations here
return dx, ...Module creation and usage
Old style (pymoto < 2)
fn = pym.Network()
sz1 = fn.append(MyModule(sx, val1=1.0, val2=3.0)) # Module with one input
sz2 = fn.append(MyModule([pym.Signal('constant', 1.0), sz1], val1=2.0)) # Module with two inputs
fn.response() # Only after calling `response()`, the response functions in the network will be run for the first time
pym.minimize_mma(fn, sx, sz2) # Optimize somethingNew style (pymoto >= 2)
with pym.Network() as fn: # Network as context manager
sz1 = MyModule(1.0, val2=3.0)(sx) # First options for the module (for __init__), after that the signal values (for __call__)
sz2 = MyModule(2.0)(1.0, sz1) # Constant values can be used directly as module input
# At this point all the response function in the network have been run once.
... # Change inputs signals
fn.response() # Usage of network remains the same. For updated values, response() can be called to re-calculate responses
pym.minimize_mma(sx, sz2, function=fn) # Passing function to the optimizer is now optional. If not passed, a global network will be used instead of the network called `fn`.Full Changelog: v1.5.1...v2.0.0-rc1
v1.5.1
What's Changed
- Pass a and c parameters to MMA by @bva99 in #24
- Extra
originattribute ofDomainDefinition - Add support for complex eigenvalue and eigenvector sensitivities
- Add support for complex matrix sensitivities (using
AssembleGeneral) - Split up pure diagonal entries in LDAS solver for increased performance
- Allow plotting in log scale in
PlotIter
Bugfixes:
- Correct convergence tolerances for multiple RHS in CG solver
- Fix complex value contractions in
DyadCarrier - Type conversion in
SolverSparsePardisoin caseintvectors are passed - Fix memory leak in
SolverSparsePardisoin case it was constructed many times
New Contributors
Full Changelog: v1.5.0...v1.5.1
v1.5.0
What's Changed
- Thermo mechanical by @JoranZwet in #21 containing new modules
ElementAverage,NodalOperationandThermoMechanical - ScalarToFile to output scalar values to txt or csv files by @JoranZwet in #22
- Sparse eigenvector sensitivities
- Additional functionality in
DyadCarrier:min(),max(),n_dyads,shape - Add Svanberg 2007 version in MMA for better conversion
Bugfixes:
- Fix problem in MMA with identifiying scalar variable in
numpy2by @schnellerhase in #20 - Bugfixes in copying empty
DyadCarrier - Bugfix when calling 'H' or 'T' before calling 'N'-type solve in Pardiso solver
New Contributors
- @schnellerhase made their first contribution in #20
Full Changelog: v1.4.0...v1.5.0
v1.4.0
Changes:
- Add modules for element-wise operations (
ElementOperation,Stress, andStrain) (for usage, see the example examples/topology_optimization/ex_volume_stress.py) - Add density filter based on convolution, allowing 'padded' boundary conditions and custom filtering kernels (for usage, see the example examples/topology_optimization/ex_compliance_padding_filter.py)
- Aggregation modules with active-set and approximation correction strategies
- Rework of linear solvers as a separate package in pyMOTO
- Addition of iterative solver (CG) and several preconditioners (Jacobi, SOR, geometric multigrid)
- Geometric multigrid preconditioner for solving large-scale topology optimization problems (for usage, see the new example examples/topology_optimization/ex_compliance_multigrid.py)
- Several bugfixes and minor improvements
What's Changed
- Convolution filter by @aatmdelissen in #17
- v1.4 release by @aatmdelissen in #19
Full Changelog: v1.3.0...v1.4.0
v1.3.0
New features:
- Assembly of generic Poisson type matrices (
AssemblePoisson), which can be used for e.g. thermal conduction, electric permittivity - Mass matrix assembly
AssembleMassnow supports other type of physics; e.g. mass, damping, thermal capacity - Node coordinates and cartesian indices can now be obtained from
DomainDefinition, respectively, by using methodsget_node_position()andget_node_indices()
Examples:
- 3D thermal optimization now works! (
ex_compliance.py)
What's Changed
- Element matrices by @JoranZwet in #16
Full Changelog: v1.2.1...v1.3.0
v1.2.1
Bugfixes:
- Corrected shape functions for finite element assembly
What's Changed
- Bugfixes by @JoranZwet in #15
New Contributors
- @JoranZwet made their first contribution in #15
Full Changelog: v1.2.0...v1.2.1
v1.2.0
Contributions to modules:
- Allow for additional values on DOFs in assembly (
add_constantargument) - Modules for stress calculation, vonmises stress and constraint aggregation (in
ex_volume_stress.py) - Module for enforcing symmetry (in
ex_flexure.py) StaticCondensationmodule for use in kinetostatic formulation (ex_compliant_mechanism_kinetostatic.py)
New examples:
- Compliant mechanism design using springs (Sigmund formulation)
- Compliant mechanism design using kinetostatic approach (Koppen formulation)
- Volume minimization under stress constraints
- Thermo-mechanical example
ex_thermo_mech.py
Bug fixes:
- Fixed sensitivity analysis of SoQ as to allow for Nonetype sensitivity input
Tests:
- More tests for SoQ (test for Nonetype input sensitivity)
- Test StaticCondensation module
Documentation:
- Added documentation to multiple existing examples
What's Changed
- Topology optimization examples by @artofscience in #9
Full Changelog: v1.1.0...v1.2.0
v1.1.0
Features:
- New module
SystemOfEquationsfor solving a linear system of equations with constraints - New module
Scalingfor proper scaling of objective functions and constraints - New topology optimization examples for dynamic compliance, compliant mechanisms, and compliance optimization based on prescribed displacements
Bugfixes:
- Support for multiple right-hand-sides in
LinSolve - Mixed real and complex signals for
EinSum
What's Changed
- Examples flexure by @artofscience in #5
New Contributors
- @artofscience made their first contribution in #5
Full Changelog: v1.0.3...v1.1.0