\[ \newcommand{\epe}{\text{EPE}} \newcommand{\E}{\text{E}} \newcommand{\mse}{\text{MSE}} \newcommand{\tdata}{\mathcal{T}} \newcommand{\bias}{\text{Bias}} \newcommand{\var}{\text{Var}} \newcommand{\cov}{\text{Cov}} \newcommand{\corr}{\text{Corr}} \newcommand{\rss}{\text{RSS}} \newcommand{\tr}{\text{tr}} \newcommand{\ridge}{\text{ridge}} \newcommand{\pcr}{\text{pcr}} \newcommand{\ls}{\text{ls}} \newcommand{\tr}{\text{tr}} \newcommand{\df}{\text{df}} \newcommand{\FS}{\text{FS}} \newcommand{\wt}{\widetilde} \] Linear regression on an indicator matrix
Here we consider a \(K\)-class problem and we encode the outcome (class) as one-hot vector. So, we have \(Y \in \mathbb{R}^{N \times K}\) matrix as the observed outcome. And here we fit the linear regression estimator: \(\hat{B} = (X'X)^{-1} X'Y\). And \(\hat{G}(x) = \arg\max_{g} \hat{f}_g(x)\) with \(\hat{f}_g(x) = \hat{B}_{\cdot g}' x\).
One way to think about \(\hat{f}_g(x)\) is to treat it as an approximation of \(\E(Y_g | X = x) = \Pr(G = g | X = x)\). But the question is how good is the approximation.
Note that when we include intercept in the model, \(\sum_g \hat{f}_g(x) = 1, ~\forall x\). See the code verification in below. And we can also verify it by considering \(\hat{f}_g(x) = x' (\wt{X}'\wt{X})' \wt{X}'\wt{Y}_g + \bar{Y}_g\) where \(\wt\cdot\) is the column-wise centered matrix and \(\bar{Y}_g\) is the mean of \(Y_g\). The key property is that \(\sum_g \wt{Y}_g = 0\).
set.seed(2020)
K = 5
N = 100
P = 50
X = matrix(rnorm(N * P), ncol = P)
Y = matrix(0, ncol = K, nrow = N)
for(i in 1 : N) {
k = sample(K, size = 1)
Y[i, k] = 1
}
X_ = cbind(rep(1, N), X)
Bhat = solve((t(X_) %*% X_), t(X_) %*% Y)
nt = 13
x = matrix(rnorm(nt * P), ncol = P)
x_ = cbind(rep(1, nt), x)
yhat = x_ %*% Bhat
# yhat
rowSums(yhat)
## [1] 1 1 1 1 1 1 1 1 1 1 1 1 1
But, we cannot ensure that \(\hat{f}_g(x) > 0\). Even with this drawback, this approach can yield similar results as compared to the more standard approach. And if we allow linear regression onto the basis expansions \(h(X)\) of the input, it can give consistent result as sample size gets big.
Another view is to think that we try to find $_g(x) = x’_g $ such that we can minimize \(\| Y_i - (f_1(X_i), \cdots, f_K(X_i))'\|_2^2\). We can see that it is a special case in Euclidean space. This view only works when the classes are decoupled.
There is a problem of this approach when there are more than 2 classes, i.e. some classes could be masked by others (see figure below).
The direct issue is that we cannot build a good linear model for “class 2” (when letting class-2 points be labeled as 1 and others have 0 as the label). And to augment the feature space with quadratic terms could largely solve this problem.
For the cases of more than three classes, we may need a higher degree of augmentation. A loose rule is that for \(K\) classes, we need \(K - 1\) degree of augmentation, which means that we need to deal with \(O(p^{K - 1})\) terms.
And note that the masking problem is prevalent for large \(K\) and small \(p\)!


Non-domestic Energy Performance Certificate Recommendation Report
Report Contents
Report number
9876-6789-5432-2345-1350
Valid until
30 September 2020
66 Primrose Hill
London
NW3 2UU
Energy rating and EPC
This building’s current energy rating is F.
For more information, see the Energy Performance Certificate for this report.
Recommendations
The assessment found opportunities to improve the building's energy efficiency.
Recommended improvements are grouped by the estimated time it would take for the change to pay for itself. The assessor may also make additional recommendations.
Each recommendation is marked as low, medium or high for the potential impact the change would have on reducing the building’s carbon emissions.
Changes that pay for themselves within 3 years
No recommendations for this period of time were made by the assessor.
Changes that pay for themselves within 3 to 7 years
No recommendations for this period of time were made by the assessor.
Changes that pay for themselves in more than 7 years
No recommendations for this period of time were made by the assessor.
Assessor’s details
- Assessor's name
- John Howard
- Employer's name
- Viridian Consulting Engineers Ltd
- Employer’s address
- Lloyds House, 18, Lloyd Street, Manchester, M2 5WA
- Assessor number
- ECMK201470
- Accreditation scheme
- ECMK Ltd
- Assessor’s declaration
-
No connection to the property
The assessor declared they have no personal or business connection with the property’s owner or anyone who may have an interest in the property.
Other certificates for this property
If you are aware of previous assessments for this property and they are not listed here, please contact the Help Desk at 0207 164 6672.
| Reference number | Report type | Expiry date |
|---|---|---|
| 9876-6789-5432-2345-1351 | EPC-RR | 8 August 2019 (Expired) |
| 1351-2345-5432-2345-9876 | EPC-RR | 12 May 2018 (Expired) |
| 2345-5432-9876-2345-2345 | EPC-RR | 1 June 2016(Expired) |


--- layout: post status: publish published: true title: 6/6 Notes author: display_name: Corey Fineran login: Corey email<EMAIL_ADDRESS>url: '' author_login: Corey author_email<EMAIL_ADDRESS>excerpt: "* It's been kind of quiet here at Ivy Envy. We try to keep things moving along and fresh for regular readers, but it's tougher to write when your team rolls off 9 straight and 10 out of 11. I'm naturally kind of a criticizer " wordpress_id: 93 wordpress_url: http://ivyenvy.wordpress.com/?p=93 date: '2008-06-06 10:55:52 +0000' date_gmt: '2008-06-06 10:55:52 +0000' categories: - The Cubs tags: - Angels - cubs - Earl Cunningham - Greg Maddux - Padres - Peoria Chiefs - Rockies comments: - id: 55 author: manstrength author_email<EMAIL_ADDRESS>author_url: '' date: '2008-06-08 04:38:46 +0000' date_gmt: '2008-06-08 04:38:46 +0000' content: Did you happen to see that the Cubs 1st rounder this year was the Cub's 29th rounder from last year? Hmm... Must really like that guy.. ---
* It's been kind of quiet here at Ivy Envy. We try to keep things moving along and fresh for regular readers, but it's tougher to write when your team rolls off 9 straight and 10 out of 11. I'm naturally kind of a criticizer and you can imagine that it's been pretty hard for me to find major faults with this team since they left Pittsburgh.
* It was nice to see Greg Maddux pitch again. The guy has still got it. I think he was just auditioning for a spot on the Cubs roster after the Padres admit they are out of any race.
* Yesterday was draft day and anytime I think of the Cubs drafting, I think of Earl Cunningham, the Cubs first pick in the 1989 draft. I had the pleasure of seeing Earl play for the Peoria Chiefs in 1990. He was ejected from the game for disputing a foul ball. Earl played 7 seasons and never made it out of Single-A ball for the Cubs, Angels and Rockies. What's even more impressive is that he struck out nearly half of the times he went to the plate.


@(link: String)
Distributed computing and functional programming is hard. Avoid complexity. Oh, and the devil is always in the details.
Yet another Java 8 Optional post
Play Framework 2.0 – javascriptRouter in Java
Simple IP Access List for Play 2 with Java
Cover template is without shame ripped from Bootstrap. Also, visit this site.


Hiking Around Arkansas
My wife and I like to hike around Arkansas. Below is a picture from around Big Cave Creek.
My wife and I like to hike around Arkansas. Below is a picture from around Big Cave Creek.
I like to hike, cook, and try new things.
I'm from Conway Arkansas.
Yes!


Toggle navigation
Vision Zero
GitHub
Portland's Vision Zero Initiative
Full Action Plan
Previous
Next
Making Portland Streets Smarter
Using GE sensors to help prevent pedestrian accidents
Learning from Portland's Traffic Data
Combining Real Time Data with Collaboration Tools
Start Real-Time Data with Slack!


Average score: 50%
List manager
This page enables admins and teachers to manage lists and create them using the Grammarer Table Builder.
After deleting a list, you will also need to unassign it from any cohorts.
| ID | Language | Name | Type | Delete | View source code |
|---|---|---|---|---|---|
{{list.identifier}} |
{{list.language}} | {{list.title || "Checklist "+list.number}} | {{list.type}} | New tab |
Add new {{modal.type}} list
|
{{column.name}}
|
|
|---|---|
| Original | English |
|
{{row.first.name}}
|
{{cell.name}}
|
|
{{row.original.name}}
|
{{row.english.name}}
|
Information
Preview
{{ modal.setup.language[0].toUpperCase() + modal.setup.language.substring(1) }} | {{ modal.setup.name }}
{{ modal.setup.language[0].toUpperCase() + modal.setup.language.substring(1) }} | Checklist {{ modal.setup.chck}}
Average score: 50%


Many Karaoke systems use subtitles imposed over a movie of some kind. This chapter looks at how to do this with Linux systems. There are limited choices, but it is possible.
Programs like kmid
and my Java programs
play lyrics on some sort of canvas object. This gives
a pretty boring background.
Video CDs or MPEG 4 files have a nicer background, but
have the lyrics hard-coded
onto the background video so there is little chance
for manipulation of them.
CD+G files keep the lyrics separate from the video
but there doesn't seem to be any way of playing them
directly from Linux. They can be converted to MP3+G
and these can be played by vlc
:
load the MP3 file and it will pick up the corresponding
.cdg
file.
This chapter considers subtitles that can be created independently, combined with video and audio in some way and then played. The current situation is not completely satisfactory.
We are concerned here with what are called "soft subtitles" where the subtitles are stored in a separate file to the video or audio and are combined during rendering. The Wikipedia page Subtitle (captioning) is a long article going into many issues about subtitling. It also contains a list of subtitle formats, but the one that seems to be of most use in in this context is SubStation Alpha.
According to the MPlayer page
Subtitles and OSD
The formats recognised by mplayer
are
According to the VLC playback Features - Subtitle/Tag VLC support under Linux includes the following subtitle formats:
If you play some sort of video file, say XYZ.mpg, and there is also a file with the same root name and appropriate extension such as XYZ.ass (extension for SubStation Alpha), then VLC will automatically load the subtitles file and play it. If the subtitles file has a different name then it can be loaded from the VLC menu Video->Subtitles Track. However, this does not appear to be as reliable as sharing the name.
See Playback tutorial 2: Subtitle management
See subtitleoverlay (Pipeline given doesn't work).
Has plugin assrender.
See Gnome Subtitles 1.3 is out! supports Adobe Encore DVD Advanced Sub Station Alpha AQ Title DKS Subtitle Format FAB Subtitler Karaoke Lyrics LRC Karaoke Lyrics VKT MacSUB MicroDVD MPlayer MPlayer 2 MPSub Panimator Phoenix Japanimation Society Power DivX Sofni SubCreator 1.x SubRip Sub Station Alpha SubViewer 1.0 SubViewer 2.0 ViPlay Subtitle File
The SSA/ASS specification is at MooDub.free It is brief and appears to contain some minor errors with respect to later specifications and implementations: for example, the time format is different. Or are the later ones all wrong?
SSA/ASS files can be used standalone. They can also be included in container formats such as Matroska files, discussed briefly in the Codecs chapter. When they are embedded into MKV files, some restrictions are made, such as the text being converted into UTF-8 Unicode.
ASS files are divided into several sections:
Under normal circumstances you would not directly create
such files using a text editor. Instead, the program
Aegisub
gives you a GUI environment in which
to create the files. Essentially, you just enter the text
by lines, plus the start and end times for the line to
be displayed.
A screen dump is
Many special effects are possible. The video on Bill Cresswell's blog is an excellent example. Here is the direct YouTube link.
For completeness, here is part of an ASS file I created:
[Script Info]
; Script generated by Aegisub 2.1.9
; http://www.aegisub.org/
Title: Default Aegisub file
ScriptType: v4.00+
WrapStyle: 0
PlayResX: 640
PlayResY: 480
ScaledBorderAndShadow: yes
Video Aspect Ratio: 0
Video Zoom: 6
Video Position: 0
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,Arial,20,&H00FFFFFF,&H00B4FCFC,&H00000008,&H80000008,0,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:18.22,0:00:19.94,Default,,0000,0000,0000,,Here comes the sun
Dialogue: 0,0:00:20.19,0:00:21.75,Default,,0000,0000,0000,,doo doo doo doo
Dialogue: 0,0:00:22.16,0:00:24.20,Default,,0000,0000,0000,,Here comes the sun
Dialogue: 0,0:00:24.61,0:00:28.24,Default,,0000,0000,0000,,I said it's alright
...
A line in an ASS file essentially consists of a time to start display, a time to finish the display and the text itself. However, Karaoke users are accustomed to the text being highlighted as it is played.
ASS supports two major highlight styles:
These effects are done by embedding "Karaoke overrides" into the text. These are in {} brackets with a duration time in hundredths of a second.
The details are
{\k100}Here {\k150}comes {\k50}the {\k150}sun
{\kf100}Here {\kf150}comes {\kf50}the {\kf150}sun
The three styles appear as
Ideally, a Karaoke system should have a "look ahead" mechanism whereby you can see the next line before having to sing it. This can be done by showing two lines of text with overlapping times at different heights. The algorithm is:
When line N with markup is shown,
show line N+1 without markup
After line N is finished, continue showing line N+1
When line N+1 is due to show,
finish showing unmarked line N+1
show line N+1 with markup
For the song Here Comes the Sun with lyrics
Here comes the sun
doo doo doo doo
Here comes the sun
I said it's alrigh
the resultant ASS file should look like
Dialogue: 0,0:00:18.22,0:00:19.94,Default,,0000,0000,0100,,{\kf16}Here {\kf46}comes {\kf43}the {\kf67}sun
Dialogue: 0,0:00:18.22,0:00:20.19,Default,,0000,0000,0000,,doo doo doo doo
Dialogue: 0,0:00:20.19,0:00:21.75,Default,,0000,0000,0000,,{\kf17}doo {\kf25}doo {\kf21}doo {\kf92}doo
Dialogue: 0,0:00:20.19,0:00:22.16,Default,,0000,0000,0100,,Here comes the sun
Dialogue: 0,0:00:22.16,0:00:24.20,Default,,0000,0000,0100,,{\kf17}Here {\kf46}comes {\kf43}the {\kf97}sun
Dialogue: 0,0:00:22.16,0:00:24.61,Default,,0000,0000,0000,,I said it's alright
with appearance
Sub Station Alpha and its renderers appear to have been through a complex history. According to The old and present: VSFilter the ASS format was finalised about 2004, and the renderer VSFilter was made open source at this time. However, around 2007 development of VSFilter ceased and several forks were made. These introduced several extensions to the format, such as the blur tag by Aegisub. Some of these forks since merged, some were abandoned, and for some of these forks there is still code in the wild.
libass is the main rendering library for Linux. An alternative, xy-vsfilter, claims to be faster, more reliable, etc but does not seem to have a Linux implementation. libass supports some of the later extensions - these seem to be the Aegisub 2008 extensions: VSFilter hacks .
Well, it's not hard...
DumpSequence
given in the
MIDI - JavaSound
chapter, as in
java DumpSequence song.kar > song.dump
to get a dump of all events
as in
python lyric2ass4kar.py song.dump > song.ass
as in
python lyric2karaokeass4kar.py song.dump > song.ass
as in
python lyric2karaokeass4kar.py song.dump > song.ass
fluidsynth
:
fluidsynth -F song.wav /usr/share/sounds/sf2/FluidR3_GM.sf2 song.kar
lame song.wav song.mp3
mkvmerge -o 54154.mkv 54154.mp3 54154.ass BACK01.MPG
The resultant MKV file can then by played as a standalone file by MPlayer:
mplayer song.mkv
It can also be played by VLC, but only with the ASS file present
vlc song.mkv
Screen captures were shown before, depending on the Karaoke effect chosen.
Timing is however an issue: the default MIDI tempo is 120 beats per minute and a common tick rate is 30 ticks per beat. This leads to a rate of 60 MIDI ticks per second. However, we are now playing MP3 files and ASS files neither of which are MIDI files any more and which are not necessarily synchronised, and with a rate of 60 ticks per second in converting from MIDI to ASS, the lyrics run too slow. Experimentally I have found 62.9 to be a reasonable rate for at least some files...
HTML 5 has support for video types, although exactly what video format is supported by which brower is variable. Standard audio and video was discussed in the chapter on Streaming HTML5 .
A more recent development has been to include subtitles in HTML5 video. Under Linux it is currently (June 2013) only supported by the Chromium browser. A tutorial is at Video Subtitling and WebVTT: HTML5 Doctor and specified at HTML5: 4.8.9 The track element .
You need to prepare a file of timing and text instructions. The format shown in examples is as a .vtt file and can be
WEBVTT
1
00:00:01.000 --> 00:00:30.000 D:vertical A:start
This is the first line of text, displaying from 1-30 seconds
2
00:00:35.000 --> 00:00:50.000
And the second line of text
separated over two lines from 35 to 50 seconds
where the first line is "WEBVTT" and blocks of text are separated by blank lines. The format of VTT files is specified at WebVTT: The Web Video Text Tracks Format .
The HTML then references the A/V files and the subtitle file as in
<video controls>
<source src="output.webm" controls>
<track src="54154.vtt" kind="subtitles" srclang="en" label="English" default />
<!-- fallback for rubbish browsers -->
</video>
A screen capture is
There does no seem to be any mechanism for highlighting words progressively in a line. Possibly JavaScript may be able to do so, but at a cursory look it doesn't seem likely. This makes it not yet suitable for Karaoke.
This chapter has discussed methods for overlaying subtitle text onto a changing video image. It is feasible, but there are only a few viable mechanisms.


ListElement QML Type
Defines a data item in a ListModel More...
| Import Statement: | import QtQml.Models 2.2 |
Detailed Description
List elements are defined inside ListModel definitions, and represent items in a list that will be displayed using ListView or Repeater items.
List elements are defined like other QML elements except that they contain a collection of role definitions instead of properties. Using the same syntax as property definitions, roles both define how the data is accessed and include the data itself.
The names used for roles must begin with a lower-case letter and should be common to all elements in a given model. Values must be simple constants; either strings (quoted and optionally within a call to QT_TR_NOOP), boolean values (true, false), numbers, or enumeration values (such as AlignText.AlignHCenter).
Referencing Roles
The role names are used by delegates to obtain data from list elements. Each role name is accessible in the delegate's scope, and refers to the corresponding role in the current element. Where a role name would be ambiguous to use, it can be accessed via the model property (e.g., model.cost
instead of cost
).
Example Usage
The following model defines a series of list elements, each of which contain "name" and "cost" roles and their associated values.
ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 } ListElement { name: "Orange" cost: 3.25 } ListElement { name: "Banana" cost: 1.95 } }
The delegate obtains the name and cost for each element by simply referring to name
and cost
:
ListView { anchors.fill: parent model: fruitModel delegate: Row { Text { text: "Fruit: " + name } Text { text: "Cost: $" + cost } } }
See also ListModel.


contact us
Address Information
Ngong Lane Plaza
Phone : +254 2220564
Call us at +254 6889344
Email :
info@cookitmail.com


Liminal Light
keywords
: light, meditation, liminality, background radiation, time perception
Liminal Light is an ongoing project based on the concept of engaging with digital data captured from “universal energy” through the process of material oxymorons. The oxymoron results from the association of two contrasting elements - the digital data of our surroundings (radioactive decay) and the physical element (the object) generating infinite transitory shapes in light.
We use light to visualize the continuous process of perception of “universal energy”. The energy is embodied in tangible object, and the object’s body is not a static material but becomes a ‘phenomenon’ itself.
The Liminal Light object is characterised by a circular continuous movement; hence it behaves in a meditative way. It operates with “time” by capturing the audience’s attention and engaging them in contemplation.
---------------
ENSOU(Kotaro Abe, Pasquale Totaro, Danila Luppino)
Year: 2016-


[[IF MESSAGE]]
Skin Name: ?
Skin Path: ?
Skin Parent: ? {{skins}}
Page Title: ?
Parent Page: ? Site Root {{children}}
Redirect: ?
Menu Order: ?
Inherent Permissions: ?
Private: ?
Hide in Menu: ?
Selece a Page to Edit: {{children}}
Select Page to Delete: '; {{children}}
Are you sure you want to delete this page?
Add Permissions ? Modify Permissions ? Remove Permissions ?
User Permissions ?
Group Permissions ?
Enter Username: ?
[ Find a member ]
Choose Group: ? {{groups}}
Select Page: ? Site Root {{children}}
Permission Type ? View Page Modify Page
Are you sure you want to add, modify, or delete special permissions for this user?
Subject:
Team Members / Mentors Parents All
Tweet: ?


1 review
In publishing and graphic design, lorem ipsum (derived from Latin dolorem ipsum, translated as "pain itself") is a filler text commonly used to demonstrate the graphic elements of a document or visual presentation
In publishing and graphic design, lorem ipsum (derived from Latin dolorem ipsum, translated as "pain itself") is a filler text commonly used to demonstrate the graphic elements of a document or visual presentation.
Size
20'X30'
Colors
Red, Blue
Material
100% Cotton
This is a review.


To begin, select a type of tableau for your output, using the radio buttons. Selecting a radio button will change the type used in subsequent runs of the algorithm.
The page can be used in two ways. First, you can have the page generate a random signed permutation. To do that, enter the size of the desired permutation in the first textbox. Then click one of the two buttons directly to the right. The Run button will display a randomly-generated signed permutation and the output of the Robinson-Schensted algorithm when applied to that permutation. Alternatively, the Run Steps button will also generate a random signed permutation, and will show you the intermediate steps of applying the Robinson-Schensted algorithm to that permutation.
Instead, you can enter a permutation in the second textbox. To do that, list the (positive and negative) numbers of the signed permutation, separated by spaces. Then, use the Run or Run Steps buttons to the right of that box, as above.
Pressing Enter while in one of these two textboxes will click the Run button to the right. Pressing a button a second time, or a different button, will clear the previous result as it gives you a new result, as will pressing Enter while in a textbox.
This page displays the Domino Robinson-Schensted algorithm. The Domino Robinson-Schensted algorithm is a relatively straightforward generalization of the Robinson-Schensted algorithm to the hyperoctrahedral group, that is, the group of signed permutations. The input to the Domino Robinson-Schensted algorithm is a "signed permutation", for example, 2 -5 3 6 -4 1. That is, the numbers 1 through n are permuted, and, in addition, each number has a sign (or orientation) associated with it. The output of the Domino Robinson-Schensted algorithm is a pair of domino tableaux with the same shape. That is, instead of a tableau being made of squares, it is made of 2 x 1 shapes (dominos), which can be horizontal or vertical in the tableau. However, unlike the dominos in a game, each domino has only one number in it.
As in the original Robinson-Schensted algorithm, the left tableau is the insertion, or bumping, tableau. The right tableau is the recording tableau. In this algorithm, insertion is either as a horizontal domino in the first row, if the number in the signed permutation is positive, or as a vertical domino in the first column, if the number in the signed permutation is positive. Bumping is also more complicated. A horizontal domino which is bumped entirely moves to the next row below. A vertical domino which is bumped entirely moves to the next column to the right. A domino which is bumped in one square rotates down and to the right on its unbumped square.
After a domino is added to the insertion tableau by this procedure, the resulting change to the shape of the insertion tableau is two squares, adjacent either horizontally or vertically. A domino is then added to the recording tableau to record this change.
You can see an animation of the bumping procedure here: Domino Robinson-Schensted Algorithm Animated.
Domino tableaux are used to answer questions about simple Lie groups of type B, C, or D. To use a domino tableau for a question about a Lie group of a specific type, you need to place the tableau on the grid associated to that type.
The B grid is associated with the group SO(2n + 1). Selecting the B grid will run the Domino Robinson-Schensted algorithm algorithm starting with two tableaux with zeros in their top-left corner. In that way, the resulting tableaux are made of 2n + 1 squares.


Some students take summer school as a way to get prerequisites out of the way so that they can take more advanced classes during the school year. ... These classes can help you get more used to what college classes will be like so that you feel more prepared and confident once you start college.


|
AZX (AppZone eXtensions) documentation
1.1.9-CxL
A set of companion utilities that make AZ development easier
|
Functions that can be used to manipulate strings. More...
Functions | |
| INT32 | azx_str_to_l (char *str, INT32 *output) |
| Converts a string to a signed long integer. More... | |
| INT32 | azx_str_to_ul (char *str, UINT32 *output) |
| Converts a string to an unsigned long integer. More... | |
| INT32 | azx_str_to_ull (char *str, UINT64 *output) |
| Converts a string to an unsigned long long integer. More... | |
| INT32 | azx_str_to_ul_hex (char *str, UINT32 *output) |
| Converts a string in hex format to an unsigned long integer. More... | |
| INT8 | azx_str_to_uc (char *str, UINT8 *output) |
| Converts a string in to an unsigned char integer. More... | |
| UINT8 | azx_asc_to_dec (char ch) |
| Converts a hex ASCII character in to an unsigned char integer. More... | |
| INT8 | azx_str_to_d (char *str, FLOAT64 *output) |
| Converts a string in to a double. More... | |
| INT8 | azx_str_to_f (char *str, FLOAT32 *output) |
| Converts a string in to a float. More... | |
| UINT8 | azx_str_rem_ch (char *str, char chr) |
| Remove all the character recurrences from the given string. More... | |
| UINT8 | azx_str_l_trim (char *str) |
| Remove all the blank leading spaces. More... | |
Trim Macros | |
| #define | AZX_TRIM_LEADING_QUOTES(a) if('\"'==a[0]){a++;} |
| #define | AZX_TRIM_TRAILING_QUOTES(a) if('\"'==a[strlen(a)-1]){a[strlen(a)-1]=0;} |
| #define | AZX_TRIM_LEADING_AND_TRAILING_QUOTES(a) TRIM_LEADING_QUOTES(a)TRIM_TRAILING_QUOTES(a) |
Functions that can be used to manipulate strings.
| #define AZX_TRIM_LEADING_AND_TRAILING_QUOTES | ( | a | ) | TRIM_LEADING_QUOTES(a)TRIM_TRAILING_QUOTES(a) |
Trim quotes at the beginning AND at the end of the string
| #define AZX_TRIM_LEADING_QUOTES | ( | a | ) | if('\"'==a[0]){a++;} |
Trim quotes at the beginning of the string
| #define AZX_TRIM_TRAILING_QUOTES | ( | a | ) | if('\"'==a[strlen(a)-1]){a[strlen(a)-1]=0;} |
Trim quotes at the end of the string
| UINT8 azx_asc_to_dec | ( | char | ch | ) |
Converts a hex ASCII character in to an unsigned char integer.
This function converts the input ASCII character (0-9 A-F) to the corresponding decimal value. E.g. 'F' -> 0x0F
| [in] | ch | input character containing the number to be converted |
Sample usage
| UINT8 azx_str_l_trim | ( | char * | str | ) |
Remove all the blank leading spaces.
Remove all the blank leading spaces. Resize the input string accordingly
| [in] | str | input string |
| UINT8 azx_str_rem_ch | ( | char * | str, |
| char | chr | ||
| ) |
Remove all the character recurrences from the given string.
Remove all the character recurrences from the given string
| [in] | str | input string |
| [in] | chr | character to be removed |
| INT8 azx_str_to_d | ( | char * | str, |
| FLOAT64 * | output | ||
| ) |
Converts a string in to a double.
This function converts the input stringto a double (64 bits)
| [in] | str | input string containing the number to be converted |
| [out] | output | variable where the converted number will be stored |
Sample usage
| INT8 azx_str_to_f | ( | char * | str, |
| FLOAT32 * | output | ||
| ) |
Converts a string in to a float.
This function converts the input stringto a float (32 bits)
| [in] | str | input string containing the number to be converted |
| [out] | output | variable where the converted number will be stored |
Sample usage
| INT32 azx_str_to_l | ( | char * | str, |
| INT32 * | output | ||
| ) |
Converts a string to a signed long integer.
This function converts the input string in decimal format to a signed long integer
| [in] | str | input string containing the number to be converted |
| [out] | output | variable where the converted number will be stored |
Sample usage
| INT8 azx_str_to_uc | ( | char * | str, |
| UINT8 * | output | ||
| ) |
Converts a string in to an unsigned char integer.
This function converts the input stringto an unsigned char integer (8 bits)
| [in] | str | input string containing the number to be converted |
| [out] | output | variable where the converted number will be stored |
Sample usage
| INT32 azx_str_to_ul | ( | char * | str, |
| UINT32 * | output | ||
| ) |
Converts a string to an unsigned long integer.
This function converts the input string in decimal format to an unsigned long integer
| [in] | str | input string containing the number to be converted |
| [out] | output | variable where the converted number will be stored |
Sample usage
| INT32 azx_str_to_ul_hex | ( | char * | str, |
| UINT32 * | output | ||
| ) |
Converts a string in hex format to an unsigned long integer.
This function converts the input string in hex format to an unsigned long integer
| [in] | str | input string containing the number to be converted |
| [out] | output | variable where the converted number will be stored |
Sample usage
| INT32 azx_str_to_ull | ( | char * | str, |
| UINT64 * | output | ||
| ) |
Converts a string to an unsigned long long integer.
This function converts the input string in decimal format to an unsigned long long integer (64 bits)
| [in] | str | input string containing the number to be converted |
| [out] | output | variable where the converted number will be stored |
Sample usage


WKDU Philadelphia Music Department Homepage
Home
View Playlists
New Playlist
View Catalog
Submit
Browse Submissions
Contact
wkdu.org


This is a dynamic node with value: {{ pathParams?.group }}
Navigation node configuration for dynamic node demo:


×
Task Detail
Id:
{{searchTaskId}}
Name:
{{searchTaskName}}
Due to Date:
{{searchTaskDueDate | date :"yyyy-MM-dd"}}
Add
×
Add New Task
Name:
Due to Date:
ID
Name
Due Date
Actions
{{item.id}}
{{item.name}}
{{item.dueDate | date:"yyyy-MM-dd"}}
×
Add New Task
Name:
Due to Date:


--- layout: page permalink: /features title: Features heading: Meshery is the service mesh management plane description: Adopt and operate any service mesh with confidence using Meshery's management features. features_table: - name: Lifecycle color: "#00B39F" features: - text: Manage any service mesh highlight: true featureli: false - text: Consul, Istio, Linkerd, Network Service Mesh, Open Service Mesh, App Mesh, Kuma, Traefik Mesh, Citrix Service Mesh, Octarine highlight: false featureli: true - text: Explore service mesh functionality with 10 different sample applications highlight: false featureli: true - text: Validate each service mesh's compliance with Service Mesh Interface (SMI) specifications highlight: false featureli: true - text: highlight: - text: highlight: call_to_action: link: https://docs.meshery.io/functionality/lifecycle-management#lifecycle-management text: Get started - name: Configuration color: "#00B39F" features: - text: Operates with best practices highlight: true featureli: false - text: Built-in industry patterns and known best practices highlight: false featureli: true - text: Apply custom configuration to your service mesh highlight: false featureli: true - text: Advanced reporting highlight: false featureli: true - text: Management of task/operation lifecycle for Operators Actors using CloudEvents specification highlight: false featureli: true - text: highlight: - text: highlight: call_to_action: link: https://docs.meshery.io/functionality/lifecycle-management#configuration-management text: Get started - name: Performance color: "#00B39F" features: - text: Assess the performance of your service mesh highlight: true featureli: false - text: Distributed performance analysis supporting 3 different types of load generators highlight: false featureli: true - text: Built-in statistical analysis of service latency quartiles highlight: false featureli: true - text: Integration with Prometheus and Grafana highlight: false featureli: true - text: Baseline and track deltas of workload performance over time. highlight: false featureli: true call_to_action: link: https://docs.meshery.io/functionality/performance-management text: Get started - name: Wasm Filters color: "#00B39F" features: - text: WebAssembly based sandbox programs that can modify your envoy proxies highlight: true featureli: false - text: Modify Istio service mesh proxies to add custom functionalities highlight: false featureli: true - text: Integration with Prometheus and Grafana highlight: false featureli: true call_to_action: link: https://docs.meshery.io/functionality/filter-management text: Get started ---


"""
Particle Size Functions
=======================
This module provides empirical functions for computing particle sizes (bubble
and droplets) from jet releases into water. Model equations are from::
Johansen et al. (2013)
Li et al. (2017)
Wang et al. (2018)
Utilities are also included to generate log-normal or Rosin-Rammler size
distributions and to apply the d_95 rule (the idea that the d_95 value of a
volume-size distribution should not exceed the maximum stable particle size).
The functions in this module are used by the `particle_size_models` module
and are not intended to be called directly. In the future, these functions
could, for example, be ported to Fortran or another language and wrapped
in Python for use by the `particle_size_models` class objects.
See Also
--------
particle_size_models.ModelBase, particle_size_models.PureJet,
particle_size_models.Model
Notes
-----
Particle size distributions are computed from the following sources::
* Johansen, O., Brandvik, P. J., and Farooq, U. (2013) "Droplet breakup in
subsea oil releases - Part 2: Predictions of droplet size distributions
with and without injection of chemical dispersants." Mar Pollut Bull,
73(1), 327-335. This reference is intended for liquid oil breakup only.
* Li, Z., Spaulding, M., French McCay, D., Crowley, D., and Payne, J. R.
(2017) "Development of a unified oil droplet size distribution model with
application to surface breaking waves and subsea blowout releases
considering dispersant effects." Mar Pollut Bull, 114(1), 247-257. The
authors apply this reference for breakup of gas bubble or oil droplets.
* Wang, B., Socolofsky, S. A., Lai, C. C. K., Adams, E. E., and Boufadel, M.
C. (2018). "Behavior and dynamics of bubble breakup in gas pipeline leaks
and accidental subsea oil well blowouts." Mar Pollut Bull, 131, 72-86.
This reference is only intended for gas bubble breakup.
The maximum stable droplet size of an immiscible liquid in seawater is taken
from::
* Clift, R., Grace, J., and Weber, M. E. (1978) *Bubbles, Drops, and \
Particles*, Dover Publications, Inc., Mineola, New York.
For gas bubbles in water, the maximum stable bubble size is taken from a
method in Grace et al::
* Grace, J.R., Wairegi, T., Brophy, J., (1978) "Break-up of drops and bubbles
in stagnant media," Can. J. Chem. Eng. 56 (1), 3-8.
"""
# S. Socolofsky, December 2019, Texas A&M University<EMAIL_ADDRESS>from __future__ import (absolute_import, division, print_function)
from tamoc import dbm
import numpy as np
from scipy.optimize import fsolve
from scipy.optimize import minimize
# Use SI units throughout
G = 9.81
# General Utilities ----------------------------------------------------------
[docs]def mass2vol(m, rho):
"""
Convert a mass or mass flux to a volume or volume flux
Parameters
----------
m : ndarray
Array of masses (kg) or mass fluxes (kg/s) for each component of a
given fluid
rho : float
In-situ density of a given fluid (kg/m^3)
Returns
-------
q : float
Corresponding volume (m^3) or volume flux (m^3/s) of a given fluid
"""
# Compute volume handling zero-fluxes correctly
if np.sum(m) > 0:
q = np.sum(m) / rho
else:
q = 0.
return q
# Probabiity Density Functions -----------------------------------------------
[docs]def rosin_rammler(nbins, d50, k, alpha):
"""
Return the volume size distribution from the Rosin-Rammler distribution
Returns the fluid particle diameters in the selected number of bins on
a volume-fraction basis from the Rosin Rammler distribution with
parameters d_50, k, and alpha.
Parameters
----------
nbins : int
Desired number of size bins in the particle volume size distribution
d50 : float
Volume mean particle diameter (m)
k : float
Scale parameter of the Rosin-Rammler distribution (=log(0.5) for d_50)
alpha : float
Shape parameter of the Rosin-Rammler distribution
Returns
-------
de : ndarray
Array of particle sizes at the center of each bin in the distribution
(m)
vf : ndarray
Volume fraction in each bin (--)
"""
# Get the de/d50 ratio for the edges of each bin in the distribution
# using a log-spacing
a99 = (np.log(1. - 0.995) / k)**(1. / alpha)
a01 = (np.log(1. - 0.01) / k)**(1. / alpha)
bin_edges = np.logspace(np.log10(a01), np.log10(a99), nbins + 1)
# Find the logarithmic average location of the center of each bin
bin_centers = np.zeros(len(bin_edges) - 1)
for i in range(len(bin_centers)):
bin_centers[i] = np.exp(np.log(bin_edges[i]) +
(np.log(bin_edges[i+1]) - np.log(bin_edges[i])) / 2.)
# Compute the actual diameters of each particle
de = d50 * bin_centers
# Get the volume fraction within each bin
if d50 == 0:
vf = np.zeros(len(bin_centers))
else:
vn = 1. - np.exp(k * bin_edges**alpha)
vf = np.zeros(len(bin_centers))
for i in range(len(bin_edges) - 1):
vf[i] = vn[i+1] - vn[i]
vf = vf / np.sum(vf)
# Return the particle size distribution
return (de, vf)
[docs]def log_normal(nbins, d50, sigma):
"""
Return the volume size distribution from the Log-normal distribution
Returns the fluid particle diameters in the selected number of bins on
a volume-fraction basis from the Log-normal distribution with parameters
d50 and sigma_x.
Parameters
----------
nbins : int
Desired number of size bins in the particle volume size distribution
d50 : float
Volume mean particle diameter (m)
sigma : float
Standard deviation of the Log-normal distribution in logarithmic
units.
Returns
-------
de : ndarray
Array of particle sizes at the center of each bin in the distribution
(m)
vf : ndarray
Volume fraction in each bin (--)
Notes
-----
This function uses the log-normal distribution defined at::
https://en.wikipedia.org/wiki/Log-normal_distribution
last accessed on 1/10/2020. The relationship between mu_x and sigma_x
of the real x values and mu and sigma of the log(x) values is from the
notes for ENGR 102 posted here:
https://ceprofs.civil.tamu.edu/ssocolofsky/ENGR102/
Downloads/19c/Week_12/week_12.pdf
last accessed on 1/10/2020.
"""
# Get the de/d50 ratio for the edges of each bin in the distribution
# using a log-spacing
a0 = np.exp(np.log(d50) - 2.8 * sigma) / d50
a1 = np.exp(np.log(d50) + 2.3 * sigma) / d50
bin_edges = np.logspace(np.log10(a0), np.log10(a1), nbins + 1)
# Find the logarithmic average location of the center of each bin
bin_centers = np.zeros(len(bin_edges) - 1)
for i in range(len(bin_centers)):
bin_centers[i] = np.exp(np.log(bin_edges[i]) +
(np.log(bin_edges[i+1]) - np.log(bin_edges[i])) / 2.)
# Compute the actual diameters of each particle
de = d50 * bin_centers
# Compute log-normal parameters for de/d50 distribution
mu = np.log(1.)
# Get the volume fraction within each bin
if d50 == 0:
vf = np.zeros(len(bin_centers))
else:
vf = 1. / bin_centers * 1. / (sigma * np.sqrt(2. * np.pi)) * \
np.exp(-(np.log(bin_centers) - mu)**2 / (2. * sigma**2))
vf = vf / np.sum(vf)
# Return the particle size distribution
return (de, vf)
[docs]def ln2rr(d50, sigma):
"""
Convert the parameters of a log-normal distribution to Rosin-Rammler
Parameters
----------
d50 : float
The median particle size of a volume distribution
sigma : float
Standard deviation of the Log-normal distribution in logarithmic
units.
Returns
-------
d50 : float
Volume mean particle diameter (m)
k : float
Scale parameter of the Rosin-Rammler distribution (=log(0.5) for d_50)
alpha : float
Shape parameter of the Rosin-Rammler distribution
"""
# Compute d95 of the log-normal distribution
mu = np.log(d50)
mu_95 = mu + 1.6449 * sigma
d95 = np.exp(mu_95)
# Find parameters of Rosin-Rammler with same d50 and d95
k = np.log(0.5)
alpha = np.log(np.log(1. - 0.95) / k) / np.log(d95 / d50)
return (d50, k, alpha)
[docs]def rr2ln(d50, k, alpha):
"""
Convert the parameters of a Rosin-Rammler distribution to log-normal
Parameters
----------
d50 : float
Volume mean particle diameter (m)
k : float
Scale parameter of the Rosin-Rammler distribution (=log(0.5) for d_50)
alpha : float
Shape parameter of the Rosin-Rammler distribution
Returns
-------
d50 : float
The median particle size of a volume distribution
sigma : float
Standard deviation of the Log-normal distribution in logarithmic
units.
"""
# Compute d95 of the Rosin-Rammler distribution
k = np.log(0.5)
d95 = d50 * (np.log(1. - 0.95) / k)**(1. / alpha)
# Find the parameters of log-normal with same d50 and d95
sigma = (np.log(d95) - np.log(d50)) / 1.6449
return (d50, sigma)
[docs]def rosin_rammler_fit(d50, d_max, alpha=1.8):
"""
Return d_50, k, and alpha for the Rosin-Rammler distribution
Parameters
----------
d_50 : float
Volume median diameter (m)
d_max : float
Maximum stable diameter (m)
alpha : float, default=1.8
Returns
-------
d_50 : float
Volume median diameter (m)
k : float
Scale parameter for the Rosin-Rammler size distribution (--)
alpha : float
Shape parameter for the Rosin-Rammler size distribution (--)
Notes
-----
This function follows the idea of Sintef to not let d_95 of the Rosin-
Rammler distribution exceed the maximum stable particle size. If the
original d_50 and d_max result in d_95 exceeding d_max, the d_50 is
shifted downward such that d_95 will equal d_max. Otherwise, the original
d_50 is preserved.
Uses the Rosin-Rammler distribution equations at:
https://en.wikipedia.org/wiki/Particle-size_distribution
last access on 03/17/20.
"""
# k parameter for d50
k = np.log(0.5)
# Adjust down if d95 exceeds the de_max
if d_max == None:
d50 = d50
else:
# Compute d95 for the given d50
d95 = d50 * (np.log(1. - 0.95) / k)**(1. / alpha)
# Adjust d50 so that d95 does not exceed d_max
if d95 > d_max:
d95 = d_max
k95 = np.log(0.05)
d50 = d95 * (np.log(1. - 0.5) / k95)**(1. / alpha)
# Return the final distribution fit
return (d50, k, alpha)
[docs]def log_normal_fit(d50, d_max, sigma=0.27):
"""
Return d_50 and sigma for the log-normal distribution
Parameters
----------
d_50 : float
Volume median diameter (m)
d_max : float
Maximum stable diameter (m)
sigma : float, default=0.27
Standard deviation of the Log-normal distribution in logarithmic
units.
Returns
-------
d_50 : float
Volume median diameter (m)
sigma : float
Standard deviation of the Log-normal distribution in logarithmic
units.
Notes
-----
This function follows the idea of Sintef to not let d_95 of the particle
size distribution exceed the maximum stable particle size. If the
original d_50 and d_max result in d_95 exceeding d_max, the d_50 is
shifted downward such that d_95 will equal d_max. Otherwise, the original
d_50 is preserved.
"""
# Adjust down if d50 exceeds the de_max
if d_max == None:
# Do not adjust the fit
d50 = d50
else:
# Comnpute d95 for the given d50 and sigma
mu = np.log(d50)
mu_95 = mu + 1.6449 * sigma
d95 = np.exp(mu_95)
# Adjust d_50 so that d_95 does not exceed d_max
if d95 > d_max:
d50 = np.exp(np.log(d_max) - 1.6449 * sigma)
# Return the final distribution fit
return (d50, sigma)
# Functions for computing maximum stable particle size -----------------------
[docs]def de_max_oil(rho_p, sigma, rho):
"""
Calculate the maximum stable oil droplet size
Predicts the maximum stable liquid particle size per Clift et al. (1978)
via the equation:
d_max = 4. * np.sqrt(sigma / (g (rho - rho_p)))
Parameters
----------
rho_p : float
Density of the phase undergoing breakup (kg/m^3)
sigma : float
Interfacial tension between the phase undergoing breakup and the
ambient receiving continuous phase (N/m)
rho : float
Density of the ambient receiving continuous phase (kg/m^3)
Returns
-------
d_max : float
Maximum stable particle size (m)
"""
return 4. * np.sqrt(sigma / (G * (rho - rho_p)))
def grow_rate(n, k, nu_c, nu_d, sigma, g, dp, rho_c, rho_d, K):
"""
Compute the instability growth rate on a gas bubble
Write instability growth rate equation in Grace et al. as a root
problem for n = f(k)
Returns
-------
res : float
The residual of the growth-rate equation expressed as a root-finding
problem.
Notes
-----
This function is used by the `grace()` function for maximum stable
particle size. It should not be called directly.
"""
# Compute more derived variables
m_c = np.sqrt(k**2 + n / nu_c)
m_d = np.sqrt(k**2 + n / nu_d)
mu_c = nu_c / rho_c
# Compute the residual of the root function
res = (sigma * k**3 - g * k * dp + n**2 * (rho_c + rho_d)) * \
(k + m_c + K * (k + m_d)) + 4 * n * k * mu_c * (k + K * m_d) * \
(K * k + m_c)
# Return the residual
return res
def grow_time(lam, de, U, nu_c, nu_d, sigma, g, dp, rho_c, rho_d, K, c_0):
"""
Compare the available and needed disturbance growth times for instability
Compares the time available for a disturbance to grow to the time needed
for that disturbance to break a bubble.
Returns
-------
t_cr : float
The critical time (s) for which the required grow time equals the
available time
Notes
-----
This function is used by the `grace()` function for maximum stable
particle size. It should not be called directly.
"""
# Compute the derived variables
k = 2. * np.pi / lam
# Consider disturbances with a node at the nose
theta_1 = lam / (2. * de)
# Compute the available time for disturbance growth
t_a = de / 2 / U * (1. + 3. / 2. * K) * np.log(1. / np.tan(
theta_1 / 2.))
# Compute the grwoth rate of this disturbance
n0 = 1. / t_a
n = fsolve(grow_rate, n0, args=(k, nu_c, nu_d, sigma, g, dp, rho_c,
rho_d, K)
)[0]
# Relate n to t_e
t_e = 1. / n
# Return the critical growth time
return c_0 * t_e - t_a
def find_de(de, rho_d, rho_c, mu_d, mu_c, sigma, nu_d, nu_c, g, dp, K,
lam_crit, c_0):
"""
Search for the critical stable bubble size
Search for the maximum stable bubble size of a gas bubble in water using
the method in Grace et al.
Returns
-------
t_min : float
The minimum time required for a disturbance of the given size to
break the fluid particle.
Notes
-----
This function is used by the `grace()` function for maximum stable
particle size. It should not be called directly.
"""
# Time available for growth, t_a
# The travel time from the position where disturance starts to the equator
from tamoc import dbm_f
# Compute the rise velocity of this bubble size
shape = dbm_f.particle_shape(de, rho_d, rho_c, mu_c, sigma)
if shape == 1:
U = dbm_f.us_sphere(de, rho_d, rho_c, mu_c)
elif shape == 2:
U = dbm_f.us_ellipsoid(de, rho_d, rho_c, mu_d, mu_c, sigma, -1)
else:
U = dbm_f.us_spherical_cap(de, rho_d, rho_c)
# lam_max is upper limit on leading interface disturbance size
lam_max = np.pi * de / 2.
# Find the wave length that corresponds to the maximum growth rate
lam = minimize(grow_time, 1.001 * lam_crit, args=(de, U, nu_c, nu_d,
sigma, g, dp, rho_c,
rho_d, K, c_0),
bounds=[(lam_crit, lam_max)]
).x[0]
t_min = grow_time(lam, de, U, nu_c, nu_d,sigma, g, dp, rho_c, rho_d, K,
c_0)
# Return the growth time
return t_min
[docs]def grace(rho_c, rho_d, mu_c, mu_d, sigma, fp_type=0):
"""
Implement the Grace et al. algorithm for maximum stable particle size
Computes the maximum stable particle size of an immiscible particle
rising in stagnant water following a method in Grace et al.
Parameters
----------
rho_c : float
Density of the continuous-phase ambient fluid (kg/m^3)
rho_d : float
Density of the immiscible fluid particle subject to breakup (kg/m^3)
mu_c : float
Dynamic viscosity of the continuous-phase ambient fluid (Pa s)
mu_d : float
Dynamic viscosity of the immiscible fluid particle subject to breakup
(Pa s)
sigma : float
Interfacial tension between the continuous phase ambient fluid and
the immiscible fluid particle subject to breakup (N/m)
fp_type : int, default=0
Phase of the immiscible fluid particle; 0 = gas, 1 = liquid.
Returns
-------
de_max : float
Equivalent spherical diameter of the maximum stable fluid particle
subject to breakup in stagnant water (m)
See Also
--------
grow_rate, grow_time, find_de
Notes
-----
Implements the method in * Grace, J.R., Wairegi, T., Brophy, J., (1978)
"Break-up of drops and bubbles in stagnant media," Can. J. Chem. Eng. 56
(1), 3-8.
"""
# Set the fit parameter
if fp_type == 0:
# This is gas
c_0 = 3.8
else:
# This is liquid
c_0 = 1.4
# Compute the derived properties
dp = np.abs(rho_c - rho_d)
K = mu_d / mu_c
nu_c = mu_c / rho_c
nu_d = mu_d / rho_d
# Region of instability.
# lam_crit is lower limit on unstable wavelengths
lam_crit = 2. * np.pi * np.sqrt(sigma / (G * dp))
# Lower limit on maximum stable diameter is lam_crit = lam_max
de_max_star = 2. / np.pi * lam_crit
# Choose Initialize the search near this minimum
de = 1.01 * de_max_star
# Find the maximum stable bubble size
de_max = fsolve(find_de, de, args=(rho_d, rho_c, mu_d, mu_c, sigma, nu_d,
nu_c, G, dp, K, lam_crit, c_0)
)[0]
# Return the result
return de_max
# SINTEF Model Equations -----------------------------------------------------
[docs]def sintef(d0, m_gas, rho_gas, m_oil, rho_oil, mu_p, sigma, rho, mu,
fp_type=1, use_d95=True):
"""
Compute characteristic values for jet breakup
Computes the characteristic particle sizes for jet breakup using the
equations in Johansen et al. (2013) (sintef model equations) and using
the model coefficients updated in technical reports to API.
Parameters
----------
d0 : float
Equivalent circular diameter of the release (m)
m_gas : np.array
Mass fluxes of each pseudo-component of the gas-phase fluid at the
release (kg/s)
rho_gas : float
Density of the gas-phase petroleum fluid at the release (kg/m^3)
m_oil : np.array
Mass fluxes of each pseudo-component of the liquid-phase petroleum
fluid at the release (kg/s)
rho_oil : float
Density of the liquid-phase petroleum fluid at the release (kg/m^3)
mu_p : float
Dynamic viscosity of the fluid phase of interest at the release
(Pa s)
sigma : float
Interfacial tension between the fluid phase of interest and water at
the release (N/m)
rho : float
Density of seawater at the release (kg/m^3)
mu : float
Dynamic viscosity of seawater at the release (Pa s)
fp_type : int, default=1
Fluid phase to compute breakup; 0 = gas, 1 = liquid. The SINTEF
equation authors do not recommend using this method for gas; hence,
fp_type should normally equal 1.
use_d95 : bool, default=True
Flag indicating whether or not to implement the d_95 rule (see
module documentation above); `True` means to use the rule.
Returns
-------
d50 : float
Volume median diameter of the fluid phase of interest (m)
de_max : float
Maximum stable particle size of the fluid phase of interest (m)
k : float
Scale parameter for the Rosin-Rammler size distribution (--)
alpha : float
Shape parameter for the Rosin-Rammler size distribution (--)
"""
# Convert mass-flux to volume flux
if np.sum(m_gas) > 0:
q_gas = mass2vol(m_gas, rho_gas)
else:
q_gas = 0.
if np.sum(m_oil) > 0:
q_oil = mass2vol(m_oil, rho_oil)
else:
q_oil = 0.
# Get the void-fraction adjusted characteristic exit velocity
n = q_gas / (q_gas + q_oil)
if q_oil == 0.:
# This is gas only
Un = 4. * q_gas / (np.pi * d0**2)
rho_m = rho_gas
elif q_gas == 0:
# This is oil only
Un = 4. * q_oil / (np.pi * d0**2)
rho_m = rho_oil
else:
# This is oil and gas
Un = 4. * q_oil / (np.pi * d0**2) / (1. - n)**(1./2.)
rho_m = rho_oil * (1. - n) + rho_gas * n
Fr = Un / (G * (rho - rho_m) / rho * d0)**(1./2.)
Uc = Un * (1. + 1./Fr)
# Compute the particle size distribution parameters
if fp_type == 0:
d50, de_max, k, alpha = sintef_model(Uc, d0, q_gas, rho_gas, mu_p,
sigma, rho, mu, is_gas=True,
use_d95=use_d95)
else:
d50, de_max, k, alpha = sintef_model(Uc, d0, q_oil, rho_oil, mu_p,
sigma, rho, mu, is_gas=False,
use_d95=use_d95)
return (d50, de_max, k, alpha)
def sintef_model(Uc, d0, q, rho_p, mu_p, sigma, rho, mu, is_gas=False,
use_d95=True):
"""
Computes the particle size for the Sintef equation
Evaluates the parameters of the particle size distribution for the
SINTEF equation and implements the d_95 rule as appropriate. This
function returns the parameters of the Rosin-Rammler size distribution
with the spreading rates as reported in Johansen et al.
Returns
-------
d50 : float
Volume median diameter of the fluid phase of interest (m)
de_max : float
Maximum stable particle size of the fluid phase of interest (m)
k : float
Scale parameter for the Rosin-Rammler size distribution (--)
alpha : float
Shape parameter for the Rosin-Rammler size distribution (--)
Notes
-----
This function is called by the `sintef()` function after several
intermediate parameters are computed. This function should not be
called directly.
"""
if q > 0.:
# Compute d_50 from the We model
d50 = sintef_d50(Uc, d0, rho_p, mu_p, sigma, rho)
# Get an estimate of de_max
if is_gas:
de_max = grace(rho, rho_p, mu, mu_p, sigma, fp_type=0)
else:
de_max = de_max_oil(rho_p, sigma, rho)
# Get the adjusted particle size distribution
d50_from95, k, alpha = rosin_rammler_fit(d50, de_max)
# Return the desired value for d50
if use_d95:
# Use the d_95 rule
d50 = d50_from95
elif d50 > de_max:
# Truncate the distribution
d50 = de_max
else:
# Return an empty set of particles
de_max = None
d50, k, alpha = rosin_rammler_fit(0., de_max)
return (d50, de_max, k, alpha)
def sintef_d50(u0, d0, rho_p, mu_p, sigma, rho):
"""
Compute d_50 from the SINTEF equations
Returns
-------
d50 : float
Volume median diameter of the fluid phase of interest (m)
Notes
-----
This function is called by the `sintef()` function after several
intermediate parameters are computed. This function should not be
called directly.
"""
# Compute the non-dimensional constants
We = rho_p * u0**2 * d0 / sigma
Vi = mu_p * u0 / sigma
if We > 350.:
# Atomization...use the the We model
A = 24.8
B = 0.08
# Solve for the volume mean diameter from the implicit equation
def residual(dp):
"""
Compute the residual of the SINTEF modified Weber number model
Evaluate the residual of the non-dimensional diameter
dp = de_50 / D for the SINTEF droplet break-up model.
Input variables are:
We, Vi, A, B = constant and global from above
dp = Non-dimensional diameter de_50 / D (--)
"""
# Compute the non-dimensional diameter and return the residual
return dp - A * (We / (1. + B * Vi * dp**(1./3.)))**(-3./5.)
# Find the gas and liquid fraction for the mixture
dp = fsolve(residual, 5.)[0]
# Compute the final d_50
d50 = dp * d0
else:
# Sinuous wave breakup...use the pipe diameter
d50 = 1.2 * d0
# Return the result
return d50
# Li et al. Equations --------------------------------------------------------
[docs]def li_etal(d0, m_gas, rho_gas, m_oil, rho_oil, mu_p, sigma, rho, mu,
fp_type=1):
"""
Compute characteristic values for jet breakup
Computes the characteristic particle sizes for jet breakup using the
equations in Li et al. (2017) (li_etal model equations). The authors
provide different equation fit parameters for gas or liquid breakup,
and this function selects the correct parameters for the fluid phase
of interest.
Parameters
----------
d0 : float
Equivalent circular diameter of the release (m)
m_gas : np.array
Mass fluxes of each pseudo-component of the gas-phase fluid at the
release (kg/s)
rho_gas : float
Density of the gas-phase petroleum fluid at the release (kg/m^3)
m_oil : np.array
Mass fluxes of each pseudo-component of the liquid-phase petroleum
fluid at the release (kg/s)
rho_oil : float
Density of the liquid-phase petroleum fluid at the release (kg/m^3)
mu_p : float
Dynamic viscosity of the fluid phase of interest at the release
(Pa s)
sigma : float
Interfacial tension between the fluid phase of interest and water at
the release (N/m)
rho : float
Density of seawater at the release (kg/m^3)
mu : float
Dynamic viscosity of seawater at the release (Pa s)
fp_type : int, default=1
Fluid phase to compute breakup; 0 = gas, 1 = liquid. The SINTEF
equation authors do not recommend using this method for gas; hence,
fp_type should normally equal 1.
Returns
-------
d50 : float
Volume median diameter of the fluid phase of interest (m)
de_max : float
Maximum stable particle size of the fluid phase of interest (m)
k : float
Scale parameter for the Rosin-Rammler size distribution (--)
alpha : float
Shape parameter for the Rosin-Rammler size distribution (--)
"""
# Convert mass-flux to volume flux
q_gas = mass2vol(m_gas, rho_gas)
q_oil = mass2vol(m_oil, rho_oil)
# Get the void-fraction adjusted characteristic exit velocity
n = q_gas / (q_gas + q_oil)
if fp_type == 0:
Uc = 4. * q_gas / (np.pi * d0**2) / n
elif fp_type == 1:
Uc = 4. * q_oil / (np.pi * d0**2) / (1. - n)
# Compute the particle size distribution for gas and oil
if fp_type == 0:
d50, de_max, k, alpha = li_etal_model(Uc, d0, q_gas, rho_gas, mu_p,
sigma, rho, mu, is_gas=True)
else:
d50, de_max, k, alpha = li_etal_model(Uc, d0, q_oil, rho_oil, mu_p,
sigma, rho, mu, is_gas=False)
return (d50, de_max, k, alpha)
def li_etal_model(Uc, d0, q, rho_p, mu_p, sigma, rho, mu, is_gas=False):
"""
Computes the particle size for the Li et al. equation
Evaluates the parameters of the particle size distribution for the Li et
al. equation and implements the d_95 rule. This function returns the
parameters of the Rosin-Rammler size distribution with the spreading
rates as reported in Li et al.
Returns
-------
d50 : float
Volume median diameter of the fluid phase of interest (m)
de_max : float
Maximum stable particle size of the fluid phase of interest (m)
k : float
Scale parameter for the Rosin-Rammler size distribution (--)
alpha : float
Shape parameter for the Rosin-Rammler size distribution (--)
Notes
-----
This function is called by the `li_etal()` function after several
intermediate parameters are computed. This function should not be
called directly.
"""
if q > 0.:
# Compute d_50 from the We model
d50 = li_etal_d50(Uc, d0, rho_p, mu_p, sigma, rho, is_gas)
# Get an estimate of de_max
if is_gas:
de_max = grace(rho, rho_p, mu, mu_p, sigma, fp_type=0)
else:
de_max = de_max_oil(rho_p, sigma, rho)
# Get the adjusted particle size distribution
d50, k, alpha = rosin_rammler_fit(d50, None)
else:
# Return an empty set of particles
de_max = None
d50, k, alpha = rosin_rammler_fit(0., de_max)
return (d50, de_max, k, alpha)
def li_etal_d50(Uc, d0, rho_p, mu_p, sigma, rho, is_gas=True):
"""
Compute d_50 from the Li et al. equations
Returns
-------
d50 : float
Volume median diameter of the fluid phase of interest (m)
Notes
-----
This function is called by the `li_etal()` function after several
intermediate parameters are computed. This function should not be
called directly.
"""
# Get the constants of the fit for a jet release
p = 0.460
q = -0.518
if is_gas:
r = 2.988
else:
r = 14.05
# The Li et al. (2017) model wrongly uses the oil equation for the
# maximum stable particle size of gas
de_max = de_max_oil(sigma, rho_p, rho)
if de_max < d0:
dc = de_max
else:
dc = d0
# Compute dimensionless groups
We = rho * Uc**2 * dc / sigma
Oh = mu_p / np.sqrt(rho_p * sigma * dc)
# Compute the non-dimensional d50
ds = r * (1 + 10 * Oh)**p * We**q
d50 = ds * dc
return d50
# Wang et al. Equations ------------------------------------------------------
[docs]def wang_etal(d0, m_g, rho_g, mu_g, sigma_g, rho, mu,
m_l=0., rho_l=None, P=4.e6, T=288.15):
"""
Compute characteristic values for gas jet breakup
Computes the characteristic gas bubble sizes for jet breakup using the
equations in Wang et al. (2018) (wang_etal model equations).
Parameters
----------
d0 : float
Equivalent circular diameter of the release (m)
m_g : np.array
Mass fluxes of each pseudo-component of the gas-phase fluid at the
release (kg/s)
rho_g : float
Density of the gas-phase fluid at the release (kg/m^3)
mu_g : float
Dynamic viscosity of the gas-phase fluid at the release (Pa s)
sigma_g : float
Interfacial tension between the gas-phase fluid and water at the
release (N/m)
rho : float
Density of seawater at the release (kg/m^3)
mu : float
Dynamic viscosity of seawater at the release (Pa s)
m_l : np.array
Mass fluxes of each pseudo-component of the liquid-phase fluid at the
release (kg/s)
rho_l : float
Density of the liquid-phase fluid at the release (kg/m^3)
P : float, default=4.e6
Pressure in the receiving fluid (Pa); used to compute the speed of
sound in the released gas.
T : float, default=288.15
Temperature of the gas phase at the release (K); used to compute the
speed of sound in the released gas.
Returns
-------
d50_gas : float
Volume median diameter of the gas bubbles (m)
m_gas : float
Mass fluxes of each pseudo-component of the gas-phase fluid at the
release (kg/s). This may be different from the input value in the
case of choked flow at the orifice.
m_oil : float
Mass fluxes of each pseudo-component of the liquid-phase fluid at the
release (kg/s). This may be different from the input value in the
case of choked flow at the orifice.
de_max : float
Maximum stable particle size of the fluid phase of interest (m)
sigma : float
Standard deviation of the Log-normal distribution in logarithmic
units.
"""
# Convert mass-flux to volume flux
Qg = mass2vol(m_g, rho_g)
if np.sum(m_l) == 0.:
Ql = 0.
else:
Ql = mass2vol(m_l, rho_l)
# Compute the exit velocity assuming no choked flow and single exit
# velocity
n = Qg / (Qg + Ql)
A = np.pi * d0**2 / 4.
Ug = (Qg + Ql) / A
# Check for choked flow using methane for speed of sound
ch4 = dbm.FluidMixture(['methane'])
delta_rho = ch4.density(np.array([1.]), T, P)[0,0] - \
ch4.density(np.array([1.]), T, 1.01 * P)[0,0]
a = np.sqrt((P - 1.01 * P) / delta_rho)
if 10. * Ug < a:
U_E = Ug
else:
# Compute the cp / cv ratio
cp_ch4 = 35.69 # J/mol/K; CO2 = 37.13
cv_ch4 = cp_ch4 - 8.31451 # From Poling et al. for ideal gases
kappa = cp_ch4 / cv_ch4 # Assume approximately ok for petroleum
# Get the Mach number
Ma = Ug / a
# Correct the exit velocity for choked flow
if Ma < np.sqrt((kappa + 1.) / 2.):
U_E = a * (-1. + np.sqrt(1. + 2. * (kappa - 1.) * Ma**2.)) / \
((kappa - 1.) * Ma)
else:
U_E = a * np.sqrt(2. / (kappa + 1.))
# Update the gas and oil exit velocities
if Qg > 0:
Ug = U_E
else:
Ug = 0
if Ql > 0:
Ul = U_E
else:
Ul = 0
# Compute the particle size distribution for gas
d50_gas, m_gas, m_oil, de_max, sigma = wang_etal_model(A, n, Ug, rho_g,
mu_g, sigma_g, Ul,
rho_l, rho, mu)
return (d50_gas, m_gas, m_oil, de_max, sigma)
def wang_etal_model(A, n, Ug, rho_g, mu_g, sigma_g, Ul, rho_l, rho, mu):
"""
Computes the particle size for the Wang et al. equation
Evaluates the parameters of the gas bubble size distribution for the Wang
et al. equation and implements the d_95 rule. This function returns the
parameters of the log-normal size distribution with the spreading
rates as reported in Wang et al.
Returns
-------
d50_gas : float
Volume median diameter of the gas bubbles (m)
m_gas : float
Mass fluxes of each pseudo-component of the gas-phase fluid at the
release (kg/s). This may be different from the input value in the
case of choked flow at the orifice.
m_oil : float
Mass fluxes of each pseudo-component of the liquid-phase fluid at the
release (kg/s). This may be different from the input value in the
case of choked flow at the orifice.
de_max : float
Maximum stable particle size of the fluid phase of interest (m)
sigma_ln : float
Standard deviation of the Log-normal distribution in logarithmic
units.
Notes
-----
This function is called by the `wang_etal()` function after several
intermediate parameters are computed. This function should not be
called directly.
"""
if Ug > 0:
# Compute d50 from the model
(d, m_gas, m_oil) = wang_etal_d50(A, n, Ug, rho_g, mu_g, sigma_g, Ul,
rho_l, rho, mu)
# Compute the maximum stable bubble size
de_max = grace(rho, rho_g, mu, mu_g, sigma_g, fp_type=0)
# Get the adjusted particle size distribution
d50_gas, sigma_ln = log_normal_fit(d, de_max, sigma=0.27)
else:
# Return an empty set of particles
m_gas = 0.
m_oil = rho_l * A * Ul
de_max = None
d50_gas, sigma_ln = log_normal_fit(0., de_max)
return (d50_gas, m_gas, m_oil, de_max, sigma_ln)
def wang_etal_d50(A, n, Ug, rho_g, mu_g, sigma_g, Ul, rho_l, rho, mu):
"""
Compute d_50 from the Wang et al. equations
Returns
-------
d50 : float
Volume median diameter of the gas bubbles (m)
Notes
-----
This function is called by the `wang_etal()` function after several
intermediate parameters are computed. This function should not be
called directly.
"""
# Compute the total dynamic momentum and buoyancy fluxes
Ag = A * n
Al = A * (1. - n)
mg = rho_g * Ag * Ug**2
bg = (rho - rho_g) * G * Ag * Ug
if n == 1:
ml = 0.
bl = 0.
else:
ml = rho_l * Al * Ul**2
bl = (rho - rho_l) * G * Al * Ul
mo = mg + ml
bo = bg + bl
# The kinematic momentum and buoyancy fluxes are
M = mo / rho
B = bo / rho
# Jet-to-plume transition length scale
l_M = M**(3./4.) / B**(1./2.)
# Characteristic velocity scale
Ua = np.sqrt(mo / (rho * A))
# Compute the mixture density
if n == 1:
rho_l = 0.
rho_m = n * rho_g + (1. - n) * rho_l
# Get the modified Weber number
We_m = rho_m * Ua**2 * l_M / sigma_g
# Compute the characteristic droplet size
d = 4.3 * We_m**(-3./5.) * l_M
# Compute the actual gas and oil flow rate
m_g = rho_g * Ag * Ug
m_l = rho_l * Al * Ul
# Return the characteristic size
return (d, m_g, m_l)