pyconvexity 0.3.8.post2__tar.gz → 0.3.8.post3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyconvexity might be problematic. Click here for more details.
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/PKG-INFO +1 -1
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/pyproject.toml +2 -2
- pyconvexity-0.3.8.post3/src/pyconvexity/_version.py +1 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/solvers/pypsa/solver.py +124 -2
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity.egg-info/PKG-INFO +1 -1
- pyconvexity-0.3.8.post2/src/pyconvexity/_version.py +0 -1
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/README.md +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/setup.cfg +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/__init__.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/core/__init__.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/core/database.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/core/errors.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/core/types.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/README.md +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/__init__.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/__pycache__/__init__.cpython-313.pyc +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/loaders/__init__.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/loaders/__pycache__/__init__.cpython-313.pyc +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/loaders/__pycache__/cache.cpython-313.pyc +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/loaders/cache.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/schema/01_core_schema.sql +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/schema/02_data_metadata.sql +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/schema/03_validation_data.sql +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/schema/04_scenario_schema.sql +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/sources/__init__.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/sources/__pycache__/__init__.cpython-313.pyc +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/sources/__pycache__/gem.cpython-313.pyc +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/sources/gem.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/io/__init__.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/io/excel_exporter.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/io/excel_importer.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/io/netcdf_exporter.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/io/netcdf_importer.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/models/__init__.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/models/attributes.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/models/components.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/models/network.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/models/scenarios.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/solvers/__init__.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/solvers/pypsa/__init__.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/solvers/pypsa/api.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/solvers/pypsa/batch_loader.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/solvers/pypsa/builder.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/solvers/pypsa/constraints.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/solvers/pypsa/storage.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/timeseries.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/validation/__init__.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/validation/rules.py +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity.egg-info/SOURCES.txt +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity.egg-info/dependency_links.txt +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity.egg-info/requires.txt +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity.egg-info/top_level.txt +0 -0
- {pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/tests/test_core_types.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyconvexity"
|
|
7
|
-
version = "0.3.8.
|
|
7
|
+
version = "0.3.8.post3"
|
|
8
8
|
description = "Python library for energy system modeling and optimization with PyPSA"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "MIT"}
|
|
@@ -81,7 +81,7 @@ profile = "black"
|
|
|
81
81
|
line_length = 100
|
|
82
82
|
|
|
83
83
|
[tool.mypy]
|
|
84
|
-
python_version = "0.3.8.
|
|
84
|
+
python_version = "0.3.8.post3"
|
|
85
85
|
warn_return_any = true
|
|
86
86
|
warn_unused_configs = true
|
|
87
87
|
disallow_untyped_defs = true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.3.8.post3"
|
|
@@ -75,7 +75,9 @@ class NetworkSolver:
|
|
|
75
75
|
|
|
76
76
|
# Validate that it's a known solver
|
|
77
77
|
known_solvers = ['highs', 'gurobi', 'gurobi (barrier)', 'gurobi (barrier homogeneous)',
|
|
78
|
-
'gurobi (barrier+crossover balanced)', 'gurobi (dual simplex)',
|
|
78
|
+
'gurobi (barrier+crossover balanced)', 'gurobi (dual simplex)',
|
|
79
|
+
'mosek', 'mosek (default)', 'mosek (barrier)', 'mosek (barrier+crossover)', 'mosek (dual simplex)',
|
|
80
|
+
'cplex', 'glpk', 'cbc', 'scip']
|
|
79
81
|
|
|
80
82
|
if default_solver in known_solvers:
|
|
81
83
|
return default_solver
|
|
@@ -367,8 +369,128 @@ class NetworkSolver:
|
|
|
367
369
|
gurobi_dual_options.update(solver_options)
|
|
368
370
|
return 'gurobi', gurobi_dual_options
|
|
369
371
|
|
|
372
|
+
# Handle special Mosek configurations
|
|
373
|
+
elif solver_name == 'mosek (default)':
|
|
374
|
+
# No custom options - let Mosek use its default configuration
|
|
375
|
+
mosek_default_options = {
|
|
376
|
+
'solver_options': {
|
|
377
|
+
'MSK_IPAR_LOG': 10, # Enable full logging (10 = verbose)
|
|
378
|
+
'MSK_IPAR_LOG_INTPNT': 1, # Log interior-point progress
|
|
379
|
+
'MSK_IPAR_LOG_SIM': 4, # Log simplex progress
|
|
380
|
+
'MSK_IPAR_LOG_MIO': 4, # Log MIP progress (4 = full)
|
|
381
|
+
'MSK_IPAR_LOG_MIO_FREQ': 10, # Log MIP every 10 seconds
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if solver_options:
|
|
385
|
+
mosek_default_options['solver_options'].update(solver_options)
|
|
386
|
+
logger.info(f"Using Mosek with default configuration (auto-select optimizer)")
|
|
387
|
+
return 'mosek', mosek_default_options
|
|
388
|
+
|
|
389
|
+
elif solver_name == 'mosek (barrier)':
|
|
390
|
+
mosek_barrier_options = {
|
|
391
|
+
'solver_options': {
|
|
392
|
+
'MSK_IPAR_INTPNT_BASIS': 0, # Skip crossover (barrier-only) - 0 = MSK_BI_NEVER
|
|
393
|
+
'MSK_DPAR_INTPNT_TOL_REL_GAP': 1e-5, # Relaxed relative gap tolerance
|
|
394
|
+
'MSK_DPAR_INTPNT_TOL_PFEAS': 1e-6, # Primal feasibility tolerance
|
|
395
|
+
'MSK_DPAR_INTPNT_TOL_DFEAS': 1e-6, # Dual feasibility tolerance
|
|
396
|
+
'MSK_DPAR_INTPNT_TOL_INFEAS': 1e-8, # Infeasibility tolerance
|
|
397
|
+
'MSK_IPAR_NUM_THREADS': 4, # Number of threads
|
|
398
|
+
'MSK_IPAR_PRESOLVE_USE': 1, # Force presolve (1 = ON)
|
|
399
|
+
'MSK_IPAR_PRESOLVE_LINDEP_USE': 1, # Linear dependency check (1 = ON)
|
|
400
|
+
'MSK_DPAR_MIO_REL_GAP_CONST': 1e-5, # MIP relative gap tolerance
|
|
401
|
+
'MSK_IPAR_MIO_NODE_OPTIMIZER': 4, # Use interior-point for MIP nodes (4 = MSK_OPTIMIZER_INTPNT)
|
|
402
|
+
'MSK_IPAR_MIO_ROOT_OPTIMIZER': 4, # Use interior-point for MIP root (4 = MSK_OPTIMIZER_INTPNT)
|
|
403
|
+
'MSK_IPAR_LOG': 10, # Enable full logging (10 = verbose)
|
|
404
|
+
'MSK_IPAR_LOG_INTPNT': 1, # Log interior-point progress
|
|
405
|
+
'MSK_IPAR_LOG_MIO': 4, # Log MIP progress (4 = full)
|
|
406
|
+
'MSK_IPAR_LOG_MIO_FREQ': 10, # Log MIP every 10 seconds
|
|
407
|
+
# Note: Don't force MSK_IPAR_OPTIMIZER - let Mosek choose based on problem type (LP vs MILP)
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
if solver_options:
|
|
411
|
+
mosek_barrier_options['solver_options'].update(solver_options)
|
|
412
|
+
logger.info(f"Using Mosek Barrier (no crossover) configuration with verbose logging")
|
|
413
|
+
return 'mosek', mosek_barrier_options
|
|
414
|
+
|
|
415
|
+
elif solver_name == 'mosek (barrier+crossover)':
|
|
416
|
+
mosek_barrier_crossover_options = {
|
|
417
|
+
'solver_options': {
|
|
418
|
+
'MSK_IPAR_INTPNT_BASIS': 1, # Always crossover (1 = MSK_BI_ALWAYS)
|
|
419
|
+
'MSK_DPAR_INTPNT_TOL_REL_GAP': 1e-6, # Tighter relative gap tolerance
|
|
420
|
+
'MSK_DPAR_INTPNT_TOL_PFEAS': 1e-6, # Primal feasibility tolerance
|
|
421
|
+
'MSK_DPAR_INTPNT_TOL_DFEAS': 1e-6, # Dual feasibility tolerance
|
|
422
|
+
'MSK_IPAR_NUM_THREADS': 4, # Number of threads
|
|
423
|
+
'MSK_IPAR_PRESOLVE_USE': 1, # Force presolve
|
|
424
|
+
'MSK_IPAR_PRESOLVE_LINDEP_USE': 1, # Linear dependency check
|
|
425
|
+
'MSK_DPAR_MIO_REL_GAP_CONST': 1e-6, # MIP relative gap tolerance
|
|
426
|
+
'MSK_IPAR_MIO_NODE_OPTIMIZER': 4, # Use interior-point for MIP nodes
|
|
427
|
+
'MSK_IPAR_MIO_ROOT_OPTIMIZER': 4, # Use interior-point for MIP root
|
|
428
|
+
'MSK_IPAR_LOG': 10, # Enable full logging (10 = verbose)
|
|
429
|
+
'MSK_IPAR_LOG_INTPNT': 1, # Log interior-point progress
|
|
430
|
+
'MSK_IPAR_LOG_MIO': 4, # Log MIP progress (4 = full)
|
|
431
|
+
'MSK_IPAR_LOG_MIO_FREQ': 10, # Log MIP every 10 seconds
|
|
432
|
+
# Note: Don't force MSK_IPAR_OPTIMIZER - let Mosek choose based on problem type
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
if solver_options:
|
|
436
|
+
mosek_barrier_crossover_options['solver_options'].update(solver_options)
|
|
437
|
+
logger.info(f"Using Mosek Barrier+Crossover configuration with verbose logging")
|
|
438
|
+
return 'mosek', mosek_barrier_crossover_options
|
|
439
|
+
|
|
440
|
+
elif solver_name == 'mosek (dual simplex)':
|
|
441
|
+
mosek_dual_options = {
|
|
442
|
+
'solver_options': {
|
|
443
|
+
'MSK_IPAR_NUM_THREADS': 0, # Use all available cores (0 = automatic)
|
|
444
|
+
'MSK_IPAR_PRESOLVE_USE': 1, # Force presolve
|
|
445
|
+
'MSK_IPAR_SIM_SCALING': 2, # Aggressive scaling (2 = MSK_SCALING_AGGRESSIVE)
|
|
446
|
+
'MSK_DPAR_MIO_REL_GAP_CONST': 1e-6, # MIP relative gap tolerance
|
|
447
|
+
'MSK_IPAR_MIO_NODE_OPTIMIZER': 1, # Use dual simplex for MIP nodes (1 = MSK_OPTIMIZER_DUAL_SIMPLEX)
|
|
448
|
+
'MSK_IPAR_MIO_ROOT_OPTIMIZER': 1, # Use dual simplex for MIP root
|
|
449
|
+
'MSK_IPAR_LOG': 10, # Enable full logging (10 = verbose)
|
|
450
|
+
'MSK_IPAR_LOG_SIM': 4, # Log simplex progress (4 = full)
|
|
451
|
+
'MSK_IPAR_LOG_MIO': 4, # Log MIP progress (4 = full)
|
|
452
|
+
'MSK_IPAR_LOG_MIO_FREQ': 10, # Log MIP every 10 seconds
|
|
453
|
+
# Note: For pure LP, set optimizer; for MILP, only set node/root optimizers
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
if solver_options:
|
|
457
|
+
mosek_dual_options['solver_options'].update(solver_options)
|
|
458
|
+
logger.info(f"Using Mosek Dual Simplex configuration with verbose logging")
|
|
459
|
+
return 'mosek', mosek_dual_options
|
|
460
|
+
|
|
370
461
|
# Check if this is a known valid solver name
|
|
371
|
-
elif solver_name
|
|
462
|
+
elif solver_name == 'mosek':
|
|
463
|
+
# Add default MILP-friendly settings for plain Mosek
|
|
464
|
+
mosek_defaults = {
|
|
465
|
+
'solver_options': {
|
|
466
|
+
'MSK_DPAR_MIO_REL_GAP_CONST': 1e-4, # MIP relative gap tolerance (10^-4 = 0.01%)
|
|
467
|
+
'MSK_IPAR_MIO_MAX_TIME': 3600, # Max time 1 hour
|
|
468
|
+
'MSK_IPAR_NUM_THREADS': 0, # Use all cores (0 = auto)
|
|
469
|
+
'MSK_IPAR_LOG': 4, # Moderate logging
|
|
470
|
+
'MSK_IPAR_LOG_MIO': 2, # Log MIP occasionally
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if solver_options:
|
|
474
|
+
mosek_defaults['solver_options'].update(solver_options)
|
|
475
|
+
logger.info(f"Using Mosek with default MILP-friendly settings")
|
|
476
|
+
return solver_name, mosek_defaults
|
|
477
|
+
|
|
478
|
+
elif solver_name == 'gurobi':
|
|
479
|
+
# Add default MILP-friendly settings for plain Gurobi (for consistency)
|
|
480
|
+
gurobi_defaults = {
|
|
481
|
+
'solver_options': {
|
|
482
|
+
'MIPGap': 1e-4, # 0.01% gap
|
|
483
|
+
'TimeLimit': 3600, # 1 hour
|
|
484
|
+
'Threads': 0, # Use all cores
|
|
485
|
+
'OutputFlag': 1, # Enable output
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
if solver_options:
|
|
489
|
+
gurobi_defaults['solver_options'].update(solver_options)
|
|
490
|
+
logger.info(f"Using Gurobi with default MILP-friendly settings")
|
|
491
|
+
return solver_name, gurobi_defaults
|
|
492
|
+
|
|
493
|
+
elif solver_name in ['highs', 'cplex', 'glpk', 'cbc', 'scip', 'copt']:
|
|
372
494
|
return solver_name, solver_options
|
|
373
495
|
|
|
374
496
|
else:
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.3.8.post2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/loaders/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/schema/01_core_schema.sql
RENAMED
|
File without changes
|
{pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/schema/02_data_metadata.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/data/sources/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/solvers/pypsa/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/solvers/pypsa/batch_loader.py
RENAMED
|
File without changes
|
{pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/solvers/pypsa/builder.py
RENAMED
|
File without changes
|
{pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/solvers/pypsa/constraints.py
RENAMED
|
File without changes
|
{pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity/solvers/pypsa/storage.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyconvexity-0.3.8.post2 → pyconvexity-0.3.8.post3}/src/pyconvexity.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|