99
1010from compas .data import Data
1111from compas_dem .models import SurfaceModel
12- from compas_tno .diagrams import FormDiagram
12+
13+ from compas_tna .envelope import Envelope
14+ from compas_tna .diagrams import FormDiagram
15+
1316from compas_tno .optimisers import Optimiser
1417from compas_tno .problems import set_up_convex_optimisation
1518from compas_tno .problems import set_up_general_optimisation
16- from compas_tno .shapes import Shape
1719from compas_tno .solvers import run_optimisation_CVXPY
1820from compas_tno .solvers import run_optimisation_ipopt
1921from compas_tno .solvers import run_optimisation_MATLAB
@@ -38,14 +40,14 @@ class Analysis(Data):
3840
3941 """
4042
41- form : FormDiagram
42- shape : Shape
43+ formdiagram : FormDiagram
44+ envelope : Envelope
4345 optimiser : Optimiser
44- model : SurfaceModel
4546
4647 def __init__ (
4748 self ,
48- model : SurfaceModel ,
49+ formdiagram : FormDiagram ,
50+ envelope : Envelope ,
4951 optimiser : Optimiser ,
5052 settings : Optional [dict ] = None ,
5153 name : Optional [str ] = None ,
@@ -55,7 +57,8 @@ def __init__(
5557 super ().__init__ (name = name )
5658
5759 self .settings = settings or {}
58- self .model = model
60+ self .formdiagram = formdiagram
61+ self .envelope = envelope
5962 self .optimiser = optimiser
6063
6164 def __str__ (self ):
@@ -65,17 +68,18 @@ def __str__(self):
6568 @property
6669 def __data__ (self ) -> dict :
6770 data = {
68- "form" : self .form ,
71+ "formdiagram" : self .formdiagram ,
72+ "envelope" : self .envelope ,
6973 "optimiser" : self .optimiser ,
70- "shape" : self .shape ,
7174 "settings" : self .settings ,
7275 }
7376 return data
7477
7578 @classmethod
7679 def create_minthk_analysis (
7780 cls ,
78- model : SurfaceModel ,
81+ formdiagram : FormDiagram ,
82+ envelope : Envelope ,
7983 printout : bool = False ,
8084 plot : bool = False ,
8185 max_iter : int = 500 ,
@@ -118,12 +122,13 @@ def create_minthk_analysis(
118122 print ("Minimum thickness analysis created" )
119123 print (optimiser )
120124
121- return cls (model , optimiser = optimiser )
125+ return cls (formdiagram , envelope , optimiser = optimiser )
122126
123127 @classmethod
124128 def create_bestfit_analysis (
125129 cls ,
126- model : SurfaceModel ,
130+ formdiagram : FormDiagram ,
131+ envelope : Envelope ,
127132 printout : bool = False ,
128133 plot : bool = False ,
129134 max_iter : int = 500 ,
@@ -168,12 +173,13 @@ def create_bestfit_analysis(
168173 print ("Minimum thickness analysis created" )
169174 print (optimiser )
170175
171- return cls (model , optimiser = optimiser )
176+ return cls (formdiagram , envelope , optimiser = optimiser )
172177
173178 @classmethod
174179 def create_minthrust_analysis (
175180 cls ,
176- model : SurfaceModel ,
181+ formdiagram : FormDiagram ,
182+ envelope : Envelope ,
177183 printout : bool = False ,
178184 plot : bool = False ,
179185 max_iter : int = 500 ,
@@ -214,12 +220,13 @@ def create_minthrust_analysis(
214220 print ("Minimum thrust analysis created" )
215221 print (optimiser )
216222
217- return cls (model , optimiser = optimiser )
223+ return cls (formdiagram , envelope , optimiser = optimiser )
218224
219225 @classmethod
220226 def create_maxthrust_analysis (
221227 cls ,
222- model : SurfaceModel ,
228+ formdiagram : FormDiagram ,
229+ envelope : Envelope ,
223230 printout : bool = False ,
224231 plot : bool = False ,
225232 max_iter : int = 500 ,
@@ -260,13 +267,13 @@ def create_maxthrust_analysis(
260267 print ("Maximium thrust analysis created" )
261268 print (optimiser )
262269
263- return cls (model , optimiser = optimiser )
270+ return cls (formdiagram , envelope , optimiser = optimiser )
264271
265272 @classmethod
266273 def create_max_load_analysis (
267274 cls ,
268- form : FormDiagram ,
269- shape : Shape ,
275+ formdiagram : FormDiagram ,
276+ envelope : Envelope ,
270277 printout : bool = False ,
271278 plot : bool = False ,
272279 horizontal : bool = False ,
@@ -336,12 +343,13 @@ def create_max_load_analysis(
336343 print ("Max vertical load analysis created" )
337344 # print(optimiser)
338345
339- return cls (form , optimiser = optimiser , shape = shape )
346+ return cls (formdiagram , envelope , optimiser = optimiser )
340347
341348 @classmethod
342349 def create_compl_energy_analysis (
343350 cls ,
344- model : SurfaceModel ,
351+ formdiagram : FormDiagram ,
352+ envelope : Envelope ,
345353 printout : bool = False ,
346354 solver : str = "IPOPT" ,
347355 plot : bool = False ,
@@ -390,12 +398,13 @@ def create_compl_energy_analysis(
390398 print ("Complementary energy created" )
391399 print (optimiser )
392400
393- return cls (model , optimiser = optimiser )
401+ return cls (formdiagram , envelope , optimiser = optimiser )
394402
395403 @classmethod
396404 def create_quad_compl_energy_analysis (
397405 cls ,
398- model : SurfaceModel ,
406+ formdiagram : FormDiagram ,
407+ envelope : Envelope ,
399408 printout : bool = False ,
400409 solver : str = "IPOPT" ,
401410 plot : bool = False ,
@@ -440,13 +449,13 @@ def create_quad_compl_energy_analysis(
440449 print ("Complementary energy analysis created" )
441450 print (optimiser )
442451
443- return cls (model , optimiser = optimiser )
452+ return cls (formdiagram , envelope , optimiser = optimiser )
444453
445454 @classmethod
446455 def create_lp_analysis (
447456 cls ,
448- form : FormDiagram ,
449- shape : Shape = None ,
457+ formdiagram : FormDiagram ,
458+ envelope : Envelope ,
450459 solver : str = "CVXPY" ,
451460 printout : bool = False ,
452461 plot : bool = False ,
@@ -482,7 +491,7 @@ def create_lp_analysis(
482491 print ("Load path Analysis created" )
483492 print (optimiser )
484493
485- return cls (form , optimiser = optimiser , shape = shape )
494+ return cls (formdiagram , envelope , optimiser = optimiser )
486495
487496 # =============================================================================
488497 # Methods
@@ -515,42 +524,76 @@ def clear_previous_results(self):
515524 self .optimiser .clear_optimiser ()
516525
517526 def apply_selfweight (self , normalize_loads = True ):
518- """Invoke method to apply selfweight to the nodes of the form diagram based on the shape """
519- self .model . apply_selfweight ( normalize = normalize_loads )
527+ """Invoke method to apply selfweight to the nodes of the form diagram based on the envelope """
528+ self .envelope . apply_selfweight_to_formdiagram ( self . formdiagram , normalize = normalize_loads )
520529
521- def apply_selfweight_from_pattern (self , pattern , plot = False ):
522- """Apply selfweight to the nodes considering a different Form Diagram to locate loads.
530+ # def apply_selfweight_from_pattern(self, pattern, plot=False):
531+ # """Apply selfweight to the nodes considering a different Form Diagram to locate loads.
523532
524- Warnings
525- --------
526- The base pattern has to coincide with nodes from the original form diagram.
533+ # Warnings
534+ # --------
535+ # The base pattern has to coincide with nodes from the original form diagram.
527536
528- """
529- self .form .apply_selfweight_from_pattern (pattern , plot = plot )
537+ # """
538+ # self.form.apply_selfweight_from_pattern(pattern, plot=plot)
539+
540+ def apply_hor_multiplier (self , multiplier = 1.0 , component = "x" ):
541+ """Apply a multiplier on the selfweight to the nodes of the form diagram based on the envelope
542+
543+ Parameters
544+ ----------
545+ multiplier : float, optional
546+ Value of the horizontal multiplier, by default ``1.0``.
547+ component : str, optional
548+ Direction to apply the loads, ``x`` or ``y``, by default ``x``.
549+
550+ Returns
551+ -------
552+ None
553+ The FormDiagram is modified in place.
530554
531- def apply_hor_multiplier ( self , multiplier , component ):
532- """Apply a multiplier on the selfweight to the nodes of the form diagram based"""
555+ """
556+ arg = "p" + component
533557
534- self .form .apply_horizontal_multiplier (lambd = multiplier , direction = component )
558+ for key in self .formdiagram .vertices ():
559+ pz = self .formdiagram .vertex_attribute (key , "pz" )
560+ self .formdiagram .vertex_attribute (key , arg , - 1 * pz * multiplier ) # considers that swt (pz) is negative
535561
536562 def apply_envelope (self ):
537- """Invoke method to apply ub and lb to the nodes based on the shape's intrados and extrados"""
563+ """Invoke method to apply ub and lb to the nodes based on the envelope's intrados and extrados"""
564+
565+ self .envelope .apply_bounds_to_formdiagram (self .formdiagram )
566+
567+ def apply_bounds_on_q (self , qmin = - 1e4 , qmax = 1e-8 ) -> None :
568+ """Apply bounds on the magnitude of the edges'force densities.
538569
539- self .model .apply_envelope ()
570+ Parameters
571+ ----------
572+ qmin : float, optional
573+ The minimum allowed force density ``qmin``, by default -1e+4
574+ qmax : float, optional
575+ The maximum allowed force density ``qmax``, by default 1e-8
540576
541- def apply_bounds_on_q (self , qmax = 0.0 , qmin = - 10000.0 ):
542- """Invoke method to apply bounds on the force densities of the pattern (qmax, qmin)"""
577+ Returns
578+ -------
579+ None
580+ The formdiagram is updated in place in the attributes.
543581
544- self .form .apply_bounds_on_q (qmax = qmax , qmin = qmin )
582+ """
583+ if isinstance (qmin , list ):
584+ for i , edge in enumerate (self .formdiagram .edges_where ({"_is_edge" : True })):
585+ self .formdiagram .edge_attribute (edge , "qmin" , qmin [i ])
586+ self .formdiagram .edge_attribute (edge , "qmax" , qmax [i ])
587+ else :
588+ for i , edge in enumerate (self .formdiagram .edges_where ({"_is_edge" : True })):
589+ self .formdiagram .edge_attribute (edge , "qmin" , qmin )
590+ self .formdiagram .edge_attribute (edge , "qmax" , qmax )
545591
546592 def apply_target (self ):
547593 """Apply target to the nodes based on the shape's target surface"""
548- for key in self .form .vertices ():
549- x , y , _ = self .form .vertex_coordinates (key )
550- self .form .vertex_attribute (key , "target" , value = self .shape .get_middle (x , y ))
551-
552- # Go over nodes and find node = key and apply the pointed load pz += magnitude
553594
595+ self .envelope .apply_target_heights_to_formdiagram (self .formdiagram )
596+
554597 def apply_envelope_on_xy (self , c = 0.5 ):
555598 """_summary_
556599
@@ -568,7 +611,7 @@ def apply_cracks(self, key, position):
568611
569612 def apply_reaction_bounds (self , assume_shape = None ):
570613 """Apply limit thk to be respected by the anchor points"""
571- self .form . apply_bounds_reactions (self .shape , assume_shape )
614+ self .envelope . apply_reaction_bounds_to_formdiagram (self .formdiagram )
572615
573616 def set_up_optimiser (self ):
574617 """With the data from the elements of the problem compute the matrices for the optimisation"""
0 commit comments