midas-civil 0.1.4__py3-none-any.whl → 0.1.6__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 midas-civil might be problematic. Click here for more details.

@@ -16,6 +16,8 @@ class Temperature:
16
16
  if cls.System.temps: cls.System.create()
17
17
  if cls.Element.temps: cls.Element.create()
18
18
  if cls.Gradient.temps: cls.Gradient.create()
19
+ if cls.Nodal.temps: cls.Nodal.create()
20
+ if cls.BeamSection.temps: cls.BeamSection.create()
19
21
 
20
22
  @classmethod
21
23
  def delete(cls):
@@ -23,6 +25,8 @@ class Temperature:
23
25
  cls.System.delete()
24
26
  cls.Element.delete()
25
27
  cls.Gradient.delete()
28
+ cls.Nodal.delete()
29
+ cls.BeamSection.delete()
26
30
 
27
31
 
28
32
  @classmethod
@@ -31,7 +35,9 @@ class Temperature:
31
35
  cls.System.sync()
32
36
  cls.Element.sync()
33
37
  cls.Gradient.sync()
34
-
38
+ cls.Nodal.sync()
39
+ cls.BeamSection.sync()
40
+
35
41
  # --------------------------------------------------------------------------------------------------
36
42
  # System Temperature
37
43
  # --------------------------------------------------------------------------------------------------
@@ -351,3 +357,258 @@ class Temperature:
351
357
  return MidasAPI("DELETE", "/db/gtmp")
352
358
 
353
359
  # --------------------------------------------------------------------------------------------------
360
+ # Nodal Temperature
361
+ # --------------------------------------------------------------------------------------------------
362
+ class Nodal:
363
+ """
364
+ Create Nodal Temperature
365
+
366
+ Parameters:
367
+ node (int): Node ID
368
+ temperature (float): Temperature value
369
+ lcname (str): Load case name **(Must exist in the model)**
370
+ group (str): Load group name (default "")
371
+ id (int): Temperature ID (optional)
372
+
373
+ Example:
374
+ Temperature.Nodal(6, 10, "Test")
375
+ """
376
+ temps = []
377
+
378
+ def __init__(self, node, temperature, lcname, group="", id=None):
379
+ if group:
380
+ chk = 0
381
+ try:
382
+ a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
383
+ if group in a:
384
+ chk = 1
385
+ except:
386
+ pass
387
+ if chk == 0:
388
+ Group.Load(group)
389
+
390
+ self.NODE = node
391
+ self.TEMPER = temperature
392
+ self.LCNAME = lcname
393
+ self.GROUP_NAME = group
394
+
395
+ if id is None:
396
+ existing_ids = []
397
+ for temp in Temperature.Nodal.temps:
398
+ if temp.NODE == node:
399
+ existing_ids.extend([item.get('ID', 0) for item in temp.ITEMS if hasattr(temp, 'ITEMS')])
400
+ self.ID = max(existing_ids, default=0) + 1
401
+ else:
402
+ self.ID = id
403
+
404
+ existing_temp = None
405
+ for temp in Temperature.Nodal.temps:
406
+ if temp.NODE == node:
407
+ existing_temp = temp
408
+ break
409
+
410
+ item_data = {
411
+ "ID": self.ID, "LCNAME": self.LCNAME,
412
+ "GROUP_NAME": self.GROUP_NAME, "TEMPER": self.TEMPER
413
+ }
414
+
415
+ if existing_temp:
416
+ if not hasattr(existing_temp, 'ITEMS'):
417
+ existing_temp.ITEMS = []
418
+ existing_temp.ITEMS.append(item_data)
419
+ else:
420
+ self.ITEMS = [item_data]
421
+ Temperature.Nodal.temps.append(self)
422
+
423
+ @classmethod
424
+ def json(cls):
425
+ """Creates JSON with 'Assign' key from Nodal Temperature objects defined in Python"""
426
+ json_data = {"Assign": {}}
427
+ for temp in cls.temps:
428
+ json_data["Assign"][str(temp.NODE)] = {"ITEMS": temp.ITEMS}
429
+ return json_data
430
+
431
+ @staticmethod
432
+ def create():
433
+ """Creates Nodal Temperatures in MIDAS Civil NX"""
434
+ MidasAPI("PUT", "/db/ntmp", Temperature.Nodal.json())
435
+
436
+ @staticmethod
437
+ def get():
438
+ """Get the JSON of Nodal Temperatures from MIDAS Civil NX"""
439
+ return MidasAPI("GET", "/db/ntmp")
440
+
441
+ @staticmethod
442
+ def sync():
443
+ """Sync Nodal Temperatures from MIDAS Civil NX to Python"""
444
+ Temperature.Nodal.temps = []
445
+ a = Temperature.Nodal.get()
446
+
447
+ if a and 'NTMP' in a:
448
+ temp_data = a.get('NTMP', {})
449
+ for node_id, node_data in temp_data.items():
450
+ node_obj = type('obj', (object,), {
451
+ 'NODE': int(node_id),
452
+ 'ITEMS': node_data.get('ITEMS', [])
453
+ })()
454
+ Temperature.Nodal.temps.append(node_obj)
455
+
456
+ @staticmethod
457
+ def delete():
458
+ """Delete Nodal Temperatures from MIDAS Civil NX and Python"""
459
+ Temperature.Nodal.temps = []
460
+ return MidasAPI("DELETE", "/db/ntmp")
461
+
462
+
463
+ # --------------------------------------------------------------------------------------------------
464
+ # Beam Section Temperature
465
+ # --------------------------------------------------------------------------------------------------
466
+ class BeamSection:
467
+ """
468
+ Create Beam Section Temperature Object in Python.
469
+
470
+ Parameters:
471
+ element (int): Element ID to apply the load.
472
+ lcname (str): Load Case Name (must exist in the model).
473
+ section_type (str, optional): 'General' or 'PSC'. Defaults to 'General'.
474
+ type (str, optional): 'Element' or 'Input'. Defaults to 'Element'.
475
+ group (str, optional): Load Group Name.
476
+ id (int, optional): Load ID.
477
+ dir (str, optional): Direction, 'LY' or 'LZ'. Defaults to 'LZ'.
478
+ ref_pos (str, optional): Reference Position, 'Centroid', 'Top', or 'Bot'. Defaults to 'Centroid'.
479
+ val_b (float, optional): B Value.
480
+ val_h1 (float, optional): H1 Value.
481
+ val_h2 (float, optional): H2 Value.
482
+ val_t1 (float, optional): T1 Value.
483
+ val_t2 (float, optional): T2 Value.
484
+ elast (float, optional): Modulus of Elasticity (required for 'Input' type).
485
+ thermal (float, optional): Thermal Coefficient (required for 'Input' type).
486
+ psc_ref (int, optional): Reference for PSC, 0 for Top, 1 for Bottom.
487
+ psc_opt_b (int, optional): B-Type option for PSC. (0 for Section type)
488
+ psc_opt_h1 (int, optional): H1-Type option for PSC. (0 - Z1 , 1- Z2 ,2 - Z2)
489
+ psc_opt_h2 (int, optional): H2-Type option for PSC. (0 - Z1 , 1- Z2 ,2 - Z2)
490
+ """
491
+ temps = []
492
+
493
+ def __init__(self, element, lcname, section_type='General', type='Element', group="", id=None,
494
+ dir='LZ', ref_pos='Centroid', val_b=0, val_h1=0, val_h2=0, val_t1=0, val_t2=0,
495
+ elast=None, thermal=None, psc_ref=0, psc_opt_b=1, psc_opt_h1=3, psc_opt_h2=3):
496
+
497
+ # Validate required parameters for Input type
498
+ if type.upper() == 'INPUT':
499
+ if elast is None or thermal is None:
500
+ raise ValueError("For 'Input' type, both 'elast' and 'thermal' parameters are required.")
501
+
502
+ # Handle load group creation
503
+ if group:
504
+ chk = 0
505
+ try:
506
+ a = [v['NAME'] for v in Group.Load.json()["Assign"].values()]
507
+ if group in a:
508
+ chk = 1
509
+ except:
510
+ pass
511
+ if chk == 0:
512
+ Group.Load(group)
513
+
514
+ self.ELEMENT = element
515
+
516
+ # Auto-assign ID if not provided
517
+ if id is None:
518
+ existing_ids = []
519
+ for temp in Temperature.BeamSection.temps:
520
+ if temp.ELEMENT == element:
521
+ existing_ids.extend([item.get('ID', 0) for item in temp.ITEMS if hasattr(temp, 'ITEMS')])
522
+ self.ID = max(existing_ids, default=0) + 1
523
+ else:
524
+ self.ID = id
525
+
526
+ # Construct the nested dictionary for vSECTTMP
527
+ vsec_item = {
528
+ "TYPE": type.upper(),
529
+ "VAL_B": val_b,
530
+ "VAL_H1": val_h1,
531
+ "VAL_H2": val_h2,
532
+ "VAL_T1": val_t1,
533
+ "VAL_T2": val_t2,
534
+ }
535
+
536
+ is_psc = section_type.lower() == 'psc'
537
+
538
+ # Add material properties for Input type
539
+ if type.upper() == 'INPUT':
540
+ vsec_item["ELAST"] = elast
541
+ vsec_item["THERMAL"] = thermal
542
+
543
+ # Add PSC-specific parameters
544
+ if is_psc:
545
+ vsec_item["REF"] = psc_ref
546
+ vsec_item["OPT_B"] = psc_opt_b
547
+ vsec_item["OPT_H1"] = psc_opt_h1
548
+ vsec_item["OPT_H2"] = psc_opt_h2
549
+
550
+ # Construct the main item dictionary
551
+ item_data = {
552
+ "ID": self.ID,
553
+ "LCNAME": lcname,
554
+ "GROUP_NAME": group,
555
+ "DIR": dir,
556
+ "REF": ref_pos,
557
+ "NUM": 1,
558
+ "bPSC": is_psc,
559
+ "vSECTTMP": [vsec_item]
560
+ }
561
+
562
+ # Check if an object for this element already exists
563
+ existing_temp = None
564
+ for temp in Temperature.BeamSection.temps:
565
+ if temp.ELEMENT == element:
566
+ existing_temp = temp
567
+ break
568
+
569
+ if existing_temp:
570
+ if not hasattr(existing_temp, 'ITEMS'):
571
+ existing_temp.ITEMS = []
572
+ existing_temp.ITEMS.append(item_data)
573
+ else:
574
+ self.ITEMS = [item_data]
575
+ Temperature.BeamSection.temps.append(self)
576
+
577
+ @classmethod
578
+ def json(cls):
579
+ """Creates JSON from Beam Section Temperature objects defined in Python"""
580
+ json_data = {"Assign": {}}
581
+ for temp in cls.temps:
582
+ json_data["Assign"][str(temp.ELEMENT)] = {"ITEMS": temp.ITEMS}
583
+ return json_data
584
+
585
+ @staticmethod
586
+ def create():
587
+ """Creates Beam Section Temperatures in MIDAS Civil NX"""
588
+ MidasAPI("PUT", "/db/btmp", Temperature.BeamSection.json())
589
+
590
+ @staticmethod
591
+ def get():
592
+ """Get the JSON of Beam Section Temperatures from MIDAS Civil NX"""
593
+ return MidasAPI("GET", "/db/btmp")
594
+
595
+ @staticmethod
596
+ def sync():
597
+ """Sync Beam Section Temperatures from MIDAS Civil NX to Python"""
598
+ Temperature.BeamSection.temps = []
599
+ a = Temperature.BeamSection.get()
600
+
601
+ if a and 'BTMP' in a:
602
+ temp_data = a.get('BTMP', {})
603
+ for element_id, element_data in temp_data.items():
604
+ element_obj = type('obj', (object,), {
605
+ 'ELEMENT': int(element_id),
606
+ 'ITEMS': element_data.get('ITEMS', [])
607
+ })()
608
+ Temperature.BeamSection.temps.append(element_obj)
609
+
610
+ @staticmethod
611
+ def delete():
612
+ """Delete Beam Section Temperatures from MIDAS Civil NX and Python"""
613
+ Temperature.BeamSection.temps = []
614
+ return MidasAPI("DELETE", "/db/btmp")