-
Notifications
You must be signed in to change notification settings - Fork 5
Fix: combining structural and alt_structural tags #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2501448
15046b6
5e4c649
f98adfa
e50020f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -54,7 +54,9 @@ def simulate_tagging(damage, comps, sc_ids, sc_thresholds, red_tag_options ): | |
| num_comps = np.array(comps['story'][s]['qty_dir_' + str(direc)]) | ||
|
|
||
| # For each structural system | ||
| structural_systems = np.unique(np.array(damage['comp_ds_table']['structural_system'] + damage['comp_ds_table']['structural_system_alt'])) | ||
| structural_systems = np.unique(np.concatenate( | ||
| (np.array(damage['comp_ds_table']['structural_system']), np.array(damage['comp_ds_table']['structural_system_alt'])) | ||
| )) | ||
| structural_systems = np.delete(structural_systems, 0) # do not include components not assigned to a structural system | ||
|
|
||
| sys_tag = np.zeros([num_reals, len(structural_systems)]).astype(bool) | ||
|
|
@@ -69,30 +71,43 @@ def simulate_tagging(damage, comps, sc_ids, sc_thresholds, red_tag_options ): | |
|
|
||
| # Check damage among each series within this structural system | ||
| series = np.unique(np.array(damage['comp_ds_table']['structural_series_id'])[ss_filt_ds]) | ||
| ser_dmg = np.zeros([num_reals,len(series)]) | ||
| ser_qty = np.zeros([1,len(series)]) | ||
|
|
||
| # Allocate ONCE (outside the ser loop) | ||
| ser_dmg = np.zeros((num_reals, len(series))) # [num_reals x num_series] | ||
| ser_qty = np.zeros(len(series)) # [num_series] | ||
|
|
||
| for ser in range(len(series)): | ||
| ser_filt_ds = np.array(damage['comp_ds_table']['structural_series_id']) == series[ser] | ||
| ser_filt_comp = np.array(comps['comp_table']['structural_series_id']) == series[ser] | ||
| # Total damage within this series and system | ||
| ser_dmg[:,ser] = np.sum(sc_dmg[:,ser_filt_ds & ss_filt_ds], axis=1) | ||
| # Total number of components within this series and system | ||
| ser_qty[:,ser] = np.sum(num_comps[ser_filt_comp & ss_filt_comp]) | ||
| ser_filt_ds = np.array(damage['comp_ds_table']['structural_series_id']) == series[ser] | ||
| ser_filt_comp = np.array(comps['comp_table']['structural_series_id']) == series[ser] | ||
|
|
||
| # Total damage within this series and system (per realization) | ||
| ser_dmg[:, ser] = np.sum(sc_dmg[:, (ser_filt_ds & ss_filt_ds)], axis=1) | ||
|
|
||
| # Total number of components within this series and system (constant across realizations) | ||
| ser_qty[ser] = np.sum(num_comps[ser_filt_comp & ss_filt_comp]) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there a computational benefit to reducing the array dimensions here? I typically like to keep the "meanings" of array dimensions consistent where possible (ie rows = realizations, columns = comps), for more traceable matrix calculations, but that may be more of my matlab bent, and the traditional python approach may be to keep things as dimensionally simple as possilbe.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi Dustin, good point. I think it’s less about computational benefit and more about matching the physical meaning.
When it was 2D before, it would cause issues in some models. For example, reductions could be mathematically wrong, and empty selections can cause the analysis to error out.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will push back a bit on the physical meaning; the quantity of components can change with realization, if you are uncertain of the quantity (in fact I think PELICUN supports this). However, we just dont vary this in the examples (and probably dont robustly support it downstream). However, if its causing problems, then that is a bigger issue, and I am happy with the change. |
||
|
|
||
| # Check if this system is causing a red tag | ||
| if structural_systems[sys] == 12 and bool(red_tag_options.get('tag_coupling_beams_over_height', False)): | ||
| # HARED CODED CHECK FOR COUPLING BEAMS | ||
| # just do counts for now instead of adding to red tag per story check | ||
| coupling_beam_dmg[:, direc-1] = coupling_beam_dmg[:,direc-1] + np.nanmax(ser_dmg, axis = 1) | ||
| coupling_beam_qty[0, direc-1] = coupling_beam_qty[0,direc-1] + np.nanmax(ser_qty, axis = 1) | ||
| coupling_beam_qty[0, direc-1] = coupling_beam_qty[0, direc-1] + np.nanmax(ser_qty) | ||
| red_tag_impact_cb_sc = np.fmax(red_tag_impact_cb_sc, ss_filt_ds.reshape(1,-1) * sc_filt.reshape(1,-1) * (sc_dmg>0)) | ||
| else: | ||
| sys_dmg = np.nanmax(ser_dmg, axis = 1) | ||
| sys_qty = np.nanmax(ser_qty, axis = 1) | ||
| sys_ratio = sys_dmg / sys_qty | ||
| sys_tag[:,sys] = sys_ratio > sc_thresholds[sc] | ||
| empty_bin = (ser_dmg.size == 0 or ser_dmg.shape[1] == 0 or ser_qty.size == 0) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These changes seem good |
||
|
|
||
| if empty_bin: | ||
| sys_ratio = np.zeros((num_reals,), dtype=float) # implies "not tagged" for this bin | ||
| else: | ||
| sys_dmg = np.nanmax(ser_dmg, axis=1) # (num_reals,) | ||
| sys_qty = float(np.nanmax(ser_qty)) # scalar | ||
|
|
||
| # avoid division by 0 / NaN issues | ||
| sys_ratio = np.zeros((num_reals,), dtype=float) | ||
| if np.isfinite(sys_qty) and sys_qty > 0: | ||
| ok = np.isfinite(sys_dmg) | ||
| sys_ratio[ok] = sys_dmg[ok] / sys_qty | ||
| sys_tag[:, sys] = sys_ratio > sc_thresholds[sc] | ||
|
|
||
| '''Calculate the impact that each component has on red tag | ||
| (boolean, 1 = affects red tag, 0 = does not affect) | ||
|
|
@@ -160,7 +175,8 @@ def simulate_tagging(damage, comps, sc_ids, sc_thresholds, red_tag_options ): | |
|
|
||
|
|
||
| # Account for global red tag cases | ||
| replace_case = np.logical_not(np.isnan(np.array(simulated_replacement_time))) | ||
| sim_rt = np.array(simulated_replacement_time, dtype=float) | ||
| replace_case = ~np.isnan(sim_rt) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, so this is the third place where this exact same calc is occuring. Seems like we need to caluclate "replace_case" earlier, in preprocesseing, or as part of the build process. |
||
| red_tag[replace_case] = 1 | ||
|
|
||
| return red_tag, red_tag_impact, inspection_tag | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good