Skip to content
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

Baseline Correction #319

Closed
wants to merge 8 commits into from

Conversation

crswong888
Copy link
Contributor

@crswong888 crswong888 commented Jul 16, 2020

@cbolisetti and @somu15,

I created a Function object, BaselineCorrection, to perform baseline correction on acceleration time histories. The object behaves like PiecewiseLinear, except the input is first adjusted according to the least squares method for baseline correction, and then linearly interpolated over time before outputting. A BaselineCorrection object can also be passed to a PresetAcceleration object to be used as a BC, so long as the initial acceleration is properly set by a FunctionIC object. If this PR is merged, I could come back and create an action system that handles all three of these objects.

I also created several TestHarness objects for BaselineCorrection, many of which are described in detail in the MooseDocs syntax page I wrote. The syntax page may seem usually long, mostly, because I want to be sure that MASTODON developers understand how I came up with this code, and what its use is. My approach is also somewhat of a novel one that builds upon some references which I mentioned in the docs. I will likely try to publish a paper that describes my method, at which point, I can come back and add a reference to it. I'll have to describe some verifications I've made by comparing against SeismoSignal and Abaqus, and so I will create an SQA page for BaselineCorrection at that point as well.

I started a separate dict() for the MooseDocs Acronyms Extension at doc/acronyms.yml and updated the config.yml file to include both the one from MOOSE and this new one. This way, anyone can start adding acronyms that are unique to MASTODON documentation if they need to. This change was @aeslaughter approved ✔️

Interesting Demos

I describe several demonstrations in the syntax page at doc/content/source/functions/BaselineCorrection.md, which I encourage you guys' to run a live serve of on your own machines, but a couple of them are particularly interesting:

  1. The test at test/tests/functions/baselinecorrection/twenty_sines_with_bc.i applies a baseline corrected BC. I also ran this input file without baseline correction, and I rendered the two solutions, simultaneously, in the following GIF:

demo_5

  1. I found a raw record of a Chi-Chi earthquake accelerogram from the Strong Motion Database VDC and I applied BaselineCorrection to it in the test at test/tests/functions/baselinecorrection/chichi_A01263000_N.i. I used Newmark integration to get the displacements from both the raw record and the corrected one and superimposed their time history plots:

newplot

TODOs

The following items should be addressed in a future PR:

  • Create action system for applying a baseline corrected acceleration BC
  • Include reference to my paper describing this method when/if it becomes available
  • Write a V&V report on this object which compares a MASTODON result to reputable third-parties, e.g., PEER, Abaqus, and/or SeismoSignal

(closes #296)

@crswong888
Copy link
Contributor Author

I still need to create unit tests for the BaselineCorrectionUtils.

Also, since the syntax page is so long, perhaps we should discuss reorganizing it. Maybe I can move the part where I talk about the numerical implementation to the theory manual and move the part where I present demonstrations to examples.

@crswong888 crswong888 changed the title Baseline Correct Baseline Correction Jul 16, 2020
@moosebuild
Copy link

moosebuild commented Jul 16, 2020

Job Test on 90c34a6 wanted to post the following:

View the site here

This comment will be updated on new commits.

@crswong888 crswong888 self-assigned this Jul 16, 2020
@cbolisetti cbolisetti removed the request for review from sveerara July 21, 2020 16:12
const Real & beta,
const Real & dt);

/// Solves linear normal equation for minimum acceleration square error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a simpler explanation to the phrase linear normal equation?

Copy link
Contributor Author

@crswong888 crswong888 Jul 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@somu15 This is what it is referred to as in terms of linear algebra jargon. For example, see section 8.2 (page 510) of this textbook, or see this Wikipedia page.

It's just the equation that solves the least squares polynomial. I suppose I could be straight-up and call it this instead.

MooseUtils::DelimitedFileReader reader(getParam<FileName>("data_file"), &_communicator);
reader.read();

// Check if specific column headers were input
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to always have the column header names? Currently, as far as I know, when we input accelerations to MASTODON, we are not required to have column header names.

Copy link
Contributor Author

@crswong888 crswong888 Jul 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No this is not required, but, here, I enforced the case where if one variable was specified a header (e.g., time), then the other variable (acceleration), must also be specified a column header. This is to avoid errors when the file is read by the DelimitedFileReader class.

If no header is specified for either, then the default is to read the first column as time and the second column as acceleration.

@@ -0,0 +1,409 @@
# Baseline Correction

`BaselineCorrection` is a [`Function`](syntax/Functions/index.md) object that applies a [!ac](BLC) to an acceleration time history, $\ddot{u}(t)$, and outputs the adjusted values. The corrections are performed by first computing the nominal (*uncorrected*) velocity, $\dot{u}$, and displacement, $u$, by the [Newmark-beta method](manuals/theory/index.md#time-integration). An $n$-th order polynomial approximation of the acceleration, velocity, and/or displacement is then found by the method of least squares and each are successively subtracted from the nominal acceleration to obtain the corrected one, $\ddot{u}^{\ast}$. That is, the corrected acceleration time history is given by the following:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An $n$-th order polynomial approximation of the acceleration, velocity, and/or displacement is then found by the method of least squares and each are successively subtracted from the nominal acceleration to obtain the corrected one, $\ddot{u}^{\ast}$. looks a bit confusing and you may want to break it up. Also, consider explaining more each are subtracted from.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@somu15 the next section about the numerical implementation explains this. Please read on.

@somu15
Copy link
Contributor

somu15 commented Jul 21, 2020

@crswong888 Nice PR. I made a few comments for now. Please make changes if you agree with them. @cbolisetti may have additional comments.

@crswong888
Copy link
Contributor Author

crswong888 commented Jul 21, 2020

@somu15 Thank you very much for taking the time to go through my work. I replied to most of your comments, perhaps you will continue some discussions there. I am in agreement with many of your comments and will make those changes.

@somu15
Copy link
Contributor

somu15 commented Oct 7, 2020

Hi @crswong888 What's the status of this?

@crswong888
Copy link
Contributor Author

@somu15 I still haven't gotten around to addressing your comments. I can do this by the end of next week, the latest, if this is okay.

@crswong888
Copy link
Contributor Author

@somu15 I have addressed some of the things we have talked about. I have made some pretty significant changes, mainly, I've made it possible for the function to output the corrected values for any of the three types of time series: acceleration, velocity, or displacement, since there's no reason why this wasn't allowed.

Please review my work when you get the chance.

@moosebuild
Copy link

All jobs on 90c34a6 : invalidated by @cbolisetti

re-running.

@moosebuild
Copy link

Job Precheck on 90c34a6 wanted to post the following:

Warning: This PR changes repo size by 10.87 MiB.

@somu15
Copy link
Contributor

somu15 commented Dec 11, 2020

Could you please exclude the .gif file? We thought that it's big, memory wise.

@somu15
Copy link
Contributor

somu15 commented Dec 11, 2020

How much time are the baseline correction tests taking now, Chris?

Copy link
Contributor

@somu15 somu15 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cbolisetti I am done with my review. I have some additional comments for Chris.

@@ -0,0 +1,6 @@
<!--placeholder page for BaselineCorrection examples, do not link this to examples index-->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please list this example in the index.md file as well?


<!-- reference action system here when/if it becomes available-->

The corrected acceleration output from the `BaselineCorrection` object can be passed to [`PresetAcceleration`](source/bcs/PresetAcceleration.md) to be used as a dynamic excitation on a mesh boundary. However, the initial corrected acceleration may not be zero-valued, and by default, MOOSE assumes that $\ddot{u}(0) = 0$ for a given instance of `NewmarkAccelAux`. Thus, to set the correct initial condition, i.e., $\ddot{u}(0) = \ddot{u}^{\ast}(0)$, so that integration is properly handled by the boundary condition object, a user may invoke the `FunctionIC` object, as demonstrated in [example-3].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that this documentation is really good. Can the user know which combination (i.e., AVD or VD, etc.) will work the best apriori? If not, is there any guidance for this? Also, the optimal polynomial order can only be determined by trial and error, right?


The corrected acceleration output from the `BaselineCorrection` object can be passed to [`PresetAcceleration`](source/bcs/PresetAcceleration.md) to be used as a dynamic excitation on a mesh boundary. However, the initial corrected acceleration may not be zero-valued, and by default, MOOSE assumes that $\ddot{u}(0) = 0$ for a given instance of `NewmarkAccelAux`. Thus, to set the correct initial condition, i.e., $\ddot{u}(0) = \ddot{u}^{\ast}(0)$, so that integration is properly handled by the boundary condition object, a user may invoke the `FunctionIC` object, as demonstrated in [example-3].

!listing baselinecorrection/twenty_sines_with_bc.i
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I want to use the VD combination, should I set acceleration_fit_order to zero?

design = functions/BaselineCorrection.md

[test_correction]
requirement = "The BaselineCorrection class shall accurately adjust a raw acceleration time history according to the method of using least squares polynomial fits."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The BaselineCorrection class shall accurately adjust a raw acceleration time history according to the method of using least squares polynomial fits for

input = half_sine_scaled.i
csvdiff = half_sine_scaled_out.csv

detail = "The output should be a displacement time history scaled by a factor of 4.886 that does not exhibit drifting behavior. The input acceleration time history is a half cycle of `9.87 \sin(\pi t)`."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a half-sine acceleration input.

input = missing_value_param_error.i
expect_err = "In BaselineCorrection corrected_accel_func: Either `data_file` or `time_values` and `acceleration_values` must be specified exclusively."

detail = "This error shall occur since the `time_values` and `acceleration_values` parameters were not provided together."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the time_values and acceleration_values parameters are not provided together.

input = missing_file_param_error.i
expect_err = "In BaselineCorrection corrected_accel_func: A column header name was specified for the for the time data. Please specify a header for the acceleration data using the 'acceleration_name' parameter."

detail = "This error shall occur since the `time_name` and `acceleration_name` parameters were not provided together."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the time_name and acceleration_name parameters are not provided together.

input = size_mismatch_error.i
expect_err = "In BaselineCorrection corrected_accel_func: The length of time and acceleration data must be equal."

detail = "This error shall occur since the lengths of the time data and acceleration data are not equal"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the lengths of the time data and acceleration data are not equal.

input = no_data_error.i
expect_err = "In BaselineCorrection corrected_accel_func: The length of time and acceleration data must be > 0."

detail = "This error shall occur since no data was provided at all."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no data is provided at all.

input = no_order_error.i
expect_err = "In BaselineCorrection corrected_accel_func: No values were input for parameters 'accel_fit_order', 'vel_fit_order', or 'disp_fit_order'. Please specify an integer value from 0 to 9 for at least one of these parameters."

detail = "This error shall occur since no least squares polynomials would be computed and, therefore, no adjustments would be made."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no least squares polynomials can be computed and, therefore, no adjustments can be made.

Comment on lines +66 to +69
void buildFromFile();

/// Builds data from pairs of `time_values` and `acceleration_values'
void buildFromXandY();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@crswong888 you might already have looked into this, but why not inherit from PiecewiseTabularBase? I think that class is more general than what you are trying to do here. If not, you can just override the buildFromFile() method. You can also set/suppress some of the params in there that are not needed for baseline correction.

Comment on lines +59 to +76
params.addRangeCheckedParam<unsigned int>(
"accel_fit_order",
"(0 <= accel_fit_order) & (accel_fit_order < 10)",
"If this is provided, the acceleration time history will be adjusted using an nth-order "
"polynomial fit of the nominal acceleration data, where n = accel_fit_order (only integer "
"values from 0 to 9 are supported).");
params.addRangeCheckedParam<unsigned int>(
"vel_fit_order",
"(0 <= vel_fit_order) & (vel_fit_order < 10)",
"If this is provided, the acceleration time history will be adjusted using an nth-order "
"polynomial fit of the nominal velocity data, where n = vel_fit_order (only integer values "
"from 0 to 9 are supported).");
params.addRangeCheckedParam<unsigned int>(
"disp_fit_order",
"(0 <= disp_fit_order) & (disp_fit_order < 10)",
"If this is provided, the acceleration time history will be adjusted using an nth-order "
"polynomial fit of the nominal displacement data, where n = disp_fit_order (only integer "
"values from 0 to 9 are supported).");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add defaults to addRangeCheckedParams? If so, can you please specify defaults?

mooseError(
"In BaselineCorrection ", _name, ": The length of time and acceleration data must be > 0.");

// check that at lease one least squares fit will be applied
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*at least

@crswong888
Copy link
Contributor Author

@cbolisetti @somu15 i will be addressing your comments very soon

@cbolisetti cbolisetti marked this pull request as draft March 2, 2021 18:44
@crswong888
Copy link
Contributor Author

@cbolisetti @somu15 I am going to close this PR and start from scratch. My algorithm has changed significantly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Baseline Correction for Kinematic Variables
4 participants