ccaprani / pycba

Python Continuous Beam Analysis
https://ccaprani.github.io/pycba/
Apache License 2.0
64 stars 29 forks source link

Augmenting envelopes for vehicles of different lengths #6

Closed mayermelhem closed 2 years ago

mayermelhem commented 2 years ago

The tutorial for Access Assessment adopts three vehicles that, while axle spacings vary, the total length is the same. Consequently, the Envelope.nres attribute is equal for each object in the list of envelopes, allowing the Envelope.augment method to work.

If the envelopes of vehicles with different lengths wish to be augmented, this is currently not possible as their Envelope.nres will be of different values. This is demonstrated in the following PR..

ccaprani commented 2 years ago

This is correct behaviour for reaction 'envelopes' which are just a sort of time history of the reaction as the vehicle moves over the beam. Reaction envelopes for different length vehicles can't be augmented as a result (different number of points). In a sense, the reaction envelope should strictly be a two numbers - the extreme reactions observed during the traverse. This would be consistent with the envelope for any other cross-section (e.g. max & min bending moments at x = 3 m).

So there are a few options here:

I guess my preference is for the second one - seems easy enough to implement.

mayermelhem commented 2 years ago

My preference is the first one. After some thinking, I don't think the code for the augment method is too complex (see below). Just need to indicate somewhere in the documentation that the envelope of envelopes (or super-envelope) does not have a time-history of reaction if vehicle of different lengths.


if self.npts != env.npts or self.nsup != env.nsup:
    raise ValueError("Cannot augment with an inconsistent envelope")

self.Vmax = np.maximum(self.Vmax, env.Vmax)
self.Vmin = np.minimum(self.Vmin, env.Vmin)

self.Mmax = np.maximum(self.Mmax, env.Mmax)
self.Mmin = np.minimum(self.Mmin, env.Mmin)

if self.nres == env.nres:
    self.Rmax = np.maximum(self.Rmax, env.Rmax)
    self.Rmin = np.minimum(self.Rmin, env.Rmin)
else:
    self.Rmax, self.Rmin = [np.amax(i,1) if i.ndim !=1 else i for i in [self.Rmax,self.Rmin]]
    self.Rmax = np.maximum(self.Rmax, np.amax(env.Rmax,1))
    self.Rmin = np.minimum(self.Rmin, np.amin(env.Rmin,1))
ccaprani commented 2 years ago

Great minds...! Just saw this now after implementing something very close to it. Note the comment for future development in #8 , but at least this solves the problem for now.

Thanks for the PR and issue!