fromtimeimporttimefrommathimportpifrommathimportcosfrommathimportsinimportnumpyasnpfromcompas.geometryimportTranslationfromcompas.utilitiesimportpairwisefromcompas_cem.diagramsimportTopologyDiagramfromcompas_cem.elementsimportNodefromcompas_cem.elementsimportDeviationEdgefromcompas_cem.equilibriumimportstatic_equilibriumfromcompas_cem.optimizationimportOptimizerfromcompas_cem.optimizationimportTrailEdgeForceConstraintfromcompas_cem.optimizationimportDeviationEdgeParameterfromcompas_cem.plottersimportPlotter# ------------------------------------------------------------------------------# Create a topology diagram# ------------------------------------------------------------------------------# geometry parametersdiameter=1.0num_sides=16# only even numbersappendix_length=0.10tension_force=1.0compression_force=-0.5bound=2.0grad_method="AD"# test number of subdivisions is evenassertnum_sides%2==0# create a topology diagramtopology=TopologyDiagram()# create nodes, removing lastthetas=np.linspace(0.0,2*pi,num_sides+1)[:-1]radius=diameter/2.0fori,thetainenumerate(thetas):x=radius*cos(theta)y=radius*sin(theta)# nodes in the wheeltopology.add_node(Node(i,[x,y,0.0]))# deviation edges in the perimeter of the wheel tensionforu,vinpairwise(list(range(num_sides))+[0]):topology.add_edge(DeviationEdge(u,v,force=tension_force))# internal deviation edges are in compressionhalf_num_sides=num_sides/2.0foruinrange(int(half_num_sides)):v=int(u+half_num_sides)topology.add_edge(DeviationEdge(u,v,force=compression_force))# ------------------------------------------------------------------------------# Generate trails and auto generate auxiliary trails# ------------------------------------------------------------------------------topology.auxiliary_trail_length=appendix_length*-1.0topology.build_trails(auxiliary_trails=True)# ------------------------------------------------------------------------------# Compute a state of static equilibrium# ------------------------------------------------------------------------------form=static_equilibrium(topology,eta=1e-6,tmax=100)# ------------------------------------------------------------------------------# Optimization# ------------------------------------------------------------------------------# create optimizeropt=Optimizer()# add constraint: force in axiliary trail edges should be zeroforedgeintopology.auxiliary_trail_edges():opt.add_constraint(TrailEdgeForceConstraint(edge,force=0.0))# add optimization parameters# the forces in all the deviation edges are allowed to changeforedgeintopology.deviation_edges():opt.add_parameter(DeviationEdgeParameter(edge,bound,bound))# optimizeform_opt=opt.solve(topology,algorithm="LBFGS",grad=grad_method,verbose=True)# ------------------------------------------------------------------------------# Plot results# ------------------------------------------------------------------------------ns=0.45shift=diameter*1.4plotter=Plotter(figsize=(16.0,9.0))# plot topology diagramplotter.add(topology,nodesize=ns)# plot translated form diagramT=Translation.from_vector([shift,0.0,0.0])plotter.add(form.transformed(T),nodesize=ns)# plot translated optimized form diagramT=Translation.from_vector([shift*2.0,0.0,0.0])plotter.add(form_opt.transformed(T),nodesize=ns)# show sceneplotter.zoom_extents(padding=-0.3)plotter.show()