pyconvexity 0.3.8.post2__py3-none-any.whl → 0.3.8.post3__py3-none-any.whl

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/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.3.8.post2"
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)', 'cplex', 'glpk', 'cbc', 'scip']
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 in ['highs', 'gurobi', 'cplex', 'glpk', 'cbc', 'scip', 'copt', 'mosek']:
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyconvexity
3
- Version: 0.3.8.post2
3
+ Version: 0.3.8.post3
4
4
  Summary: Python library for energy system modeling and optimization with PyPSA
5
5
  Author-email: Convexity Team <info@convexity.com>
6
6
  License: MIT
@@ -1,5 +1,5 @@
1
1
  pyconvexity/__init__.py,sha256=eiAFroO4n-z8F0jTLpJgBIO7vtSxu9ovu3G2N-qqpUo,4783
2
- pyconvexity/_version.py,sha256=5t0ABI3rYvXT23PJYWULhcBoa2OPGm5Tmm8NT3aXvDk,28
2
+ pyconvexity/_version.py,sha256=jxRGlI_N8vedEkv7nqYjYQvDc31-O3CwZMs1KZ9Odq8,28
3
3
  pyconvexity/timeseries.py,sha256=4p1Tdpa1otqDvCq2zppA4tw660sF_XWb8Xobib-cCms,11340
4
4
  pyconvexity/core/__init__.py,sha256=MgVa5rrRWIi2w1UI1P4leiBntvHeeOPv0Thm0DEXBHo,1209
5
5
  pyconvexity/core/database.py,sha256=M02q4UkJqAPeTXuwng9I7kHm16reJ7eq7wccWxnhE5I,15227
@@ -36,11 +36,11 @@ pyconvexity/solvers/pypsa/api.py,sha256=05IN6KgjpVNJ3TrH0gv1F2-GLRnffLQOc3rsT1ZE
36
36
  pyconvexity/solvers/pypsa/batch_loader.py,sha256=eQb8B11akQYtH3aK93WAOoXEI-ktk4imATw9gaYDNR4,13547
37
37
  pyconvexity/solvers/pypsa/builder.py,sha256=WrimcBvG4mNFLTrLq7131Ku0AXY_0oRKxfI81ywc5Cs,24460
38
38
  pyconvexity/solvers/pypsa/constraints.py,sha256=MycS-pvuYIEEa0s2tkskiydX_HhAKNTnsQdVc842u50,19792
39
- pyconvexity/solvers/pypsa/solver.py,sha256=95YdzoG6ch0niIoaPeUWCmJ01TyI0zDdNjf-bZ5FQTw,57748
39
+ pyconvexity/solvers/pypsa/solver.py,sha256=2EB1EL6VRtYJ-KAk00vecEn8egMfdjOUaMfFuT8aPgA,65763
40
40
  pyconvexity/solvers/pypsa/storage.py,sha256=T-0qEryiEy_8G4KiscPoiiWvTPd_OGqpLczW0_Xm85E,87331
41
41
  pyconvexity/validation/__init__.py,sha256=_6SVqXkaDFqmagub_O064Zm_QIdBrOra-Gvvbo9vM4I,549
42
42
  pyconvexity/validation/rules.py,sha256=6Kak12BVfUpjmgB5B7Wre55eGc5e1dvIdFca-vN-IFI,9296
43
- pyconvexity-0.3.8.post2.dist-info/METADATA,sha256=ubU7D_qpYA1FtZcix27_yjOQM7bmZBTevlVWOqwfPCE,4886
44
- pyconvexity-0.3.8.post2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
45
- pyconvexity-0.3.8.post2.dist-info/top_level.txt,sha256=wFPEDXVaebR3JO5Tt3HNse-ws5aROCcxEco15d6j64s,12
46
- pyconvexity-0.3.8.post2.dist-info/RECORD,,
43
+ pyconvexity-0.3.8.post3.dist-info/METADATA,sha256=bqoTl9zga7X365E-kBanrXKrvepNvxvFrSSEEqBwTkg,4886
44
+ pyconvexity-0.3.8.post3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
45
+ pyconvexity-0.3.8.post3.dist-info/top_level.txt,sha256=wFPEDXVaebR3JO5Tt3HNse-ws5aROCcxEco15d6j64s,12
46
+ pyconvexity-0.3.8.post3.dist-info/RECORD,,