UltraScan III
us_zsolute.cpp
Go to the documentation of this file.
1 
3 #include "us_zsolute.h"
4 #include "us_math2.h"
5 
6 US_ZSolute::US_ZSolute( double x0, double y0, double z0, double c0 )
7 {
8  x = x0;
9  y = y0;
10  z = z0;
11  c = c0;
12 }
13 
14 // Public function to put a model component attribute value
16  double& aval, const int a_type )
17 {
18  switch ( a_type )
19  {
20  default:
21  case ATTR_S: // Sedimentation Coefficient
22  comp.s = aval;
23  break;
24  case ATTR_K: // Frictional Ratio
25  comp.f_f0 = aval;
26  break;
27  case ATTR_W: // Molecular Weight
28  comp.mw = aval;
29  break;
30  case ATTR_V: // Vbar 20W
31  comp.vbar20 = aval;
32  break;
33  case ATTR_D: // Diffusion Coefficient
34  comp.D = aval;
35  break;
36  case ATTR_C: // Concentrations
37  comp.signal_concentration = aval;
38  break;
39  }
40 }
41 
42 // Public function to put a solute attribute value
44  double& aval, const int a_type )
45 {
46  switch ( a_type )
47  {
48  default:
49  case 0: // X value
50  solute.x = aval;
51  break;
52  case 1: // Y value
53  solute.y = aval;
54  break;
55  case 2: // Z value
56  solute.z = aval;
57  break;
58  case 9: // C value
59  solute.c = aval;
60  break;
61  }
62 }
63 
64 // Public function to get a model component attribute value
66  double& aval, const int a_type )
67 {
68  switch ( a_type )
69  {
70  default:
71  case ATTR_S: // Sedimentation Coefficient
72  aval = comp.s;
73  break;
74  case ATTR_K: // Frictional Ratio
75  aval = comp.f_f0;
76  break;
77  case ATTR_W: // Molecular Weight
78  aval = comp.mw;
79  break;
80  case ATTR_V: // Vbar 20W
81  aval = comp.vbar20;
82  break;
83  case ATTR_D: // Diffusion Coefficient
84  aval = comp.D;
85  break;
86  case ATTR_C: // Concentration
87  aval = comp.signal_concentration;
88  break;
89  }
90 }
91 
92 // Public function to get a solute attribute value
94  double& aval, const int a_type )
95 {
96  switch ( a_type )
97  {
98  default:
99  case 0: // X value
100  aval = solute.x;
101  break;
102  case 1: // Y value
103  aval = solute.y;
104  break;
105  case 2: // Z value
106  aval = solute.z;
107  break;
108  case 9: // C value
109  aval = solute.c;
110  break;
111  }
112 }
113 
114 // Public function to set model component values from a solute
116  US_ZSolute& solute, const int s_type,
117  const bool concv )
118 {
119  int attr_x = ( s_type >> 6 ) & 7;
120  int attr_y = ( s_type >> 3 ) & 7;
121  int attr_z = s_type & 7;
122  double aval = 0.0;
123 
124  get_solute_attr( solute, aval, 0 );
125  put_mcomp_attr ( comp, aval, attr_x );
126 
127  get_solute_attr( solute, aval, 1 );
128  put_mcomp_attr ( comp, aval, attr_y );
129 
130  get_solute_attr( solute, aval, 2 );
131  put_mcomp_attr ( comp, aval, attr_z );
132 
133  if ( concv )
134  { // Copy concentration value, too
135  get_solute_attr( solute, aval, 9 );
136  put_mcomp_attr ( comp, aval, 9 );
137  }
138 }
139 
140 // Public function to set solute values from a model component
142  US_ZSolute& solute, const int s_type )
143 {
144  int attr_x = ( s_type >> 6 ) & 7;
145  int attr_y = ( s_type >> 3 ) & 7;
146  int attr_z = s_type & 7;
147  double aval = 0.0;
148 
149  get_mcomp_attr ( comp, aval, attr_x );
150  put_solute_attr( solute, aval, 0 );
151 
152  get_mcomp_attr ( comp, aval, attr_y );
153  put_solute_attr( solute, aval, 1 );
154 
155  get_mcomp_attr ( comp, aval, attr_z );
156  put_solute_attr( solute, aval, 2 );
157 
158  get_mcomp_attr ( comp, aval, 9 );
159  put_solute_attr( solute, aval, 9 );
160 }
161 
162 // Public function to initialize grid solutes
163 void US_ZSolute::init_grid_solutes( double x_min, double x_max, int x_res,
164  double y_min, double y_max, int y_res,
165  int grid_reps, double* z_coeffs,
166  QList< QVector< US_ZSolute > >& solutes )
167 {
168  if ( grid_reps < 1 ) grid_reps = 1;
169 
170  int nprx = qMax( 1, ( ( x_res / grid_reps ) - 1 ) );
171  int npry = qMax( 1, ( ( y_res / grid_reps ) - 1 ) );
172  double x_step = qAbs( x_max - x_min ) / (double)nprx;
173  double y_step = qAbs( y_max - y_min ) / (double)npry;
174  x_step = ( x_step > 0.0 ) ? x_step : ( x_min * 1.001 );
175  y_step = ( y_step > 0.0 ) ? y_step : ( y_min * 1.001 );
176  double x_grid = x_step / grid_reps;
177  double y_grid = y_step / grid_reps;
178 
179  // Allow a 1% overscan
180  x_max += 0.01 * x_step;
181  y_max += 0.01 * y_step;
182 
183  solutes.reserve( sq( grid_reps ) );
184 
185  // Generate solutes for each grid repetition
186  for ( int ii = 0; ii < grid_reps; ii++ )
187  {
188  for ( int jj = 0; jj < grid_reps; jj++ )
189  {
190  solutes << create_grid_solutes(
191  x_min + x_grid * ii, x_max, x_step,
192  y_min + y_grid * jj, y_max, y_step,
193  z_coeffs );
194  }
195  }
196 }
197 
198 // Internal function to flag the type of Z function used
199 int US_ZSolute::zcoeff_flag( double* zcoeffs )
200 {
201  int zcflg = ( ( zcoeffs[ 1 ] == 0.0 ) ? 0 : 1 ) // =0 -> Constant
202  + ( ( zcoeffs[ 2 ] == 0.0 ) ? 0 : 2 ) // =1 -> Linear
203  + ( ( zcoeffs[ 3 ] == 0.0 ) ? 0 : 4 ); // >1 -> Polynomial
204 
205  return zcflg;
206 }
207 
208 // Internal static function to create a single solute vector
209 QVector< US_ZSolute > US_ZSolute::create_grid_solutes(
210  double x_min, double x_max, double x_step,
211  double y_min, double y_max, double y_step,
212  double* z_coeffs )
213 {
214  QVector< US_ZSolute > solute_vector;
215  double zz = z_coeffs[ 0 ];
216  bool x_is_s = ( x_max < 1.0e-10 );
217  bool y_is_s = ( y_max < 1.0e-10 );
218 
219  int zcflg = zcoeff_flag( z_coeffs );
220 
221  if ( zcflg == 0 )
222  { // Z is constant
223  for ( double xx = x_min; xx <= x_max; xx += x_step )
224  {
225  if ( x_is_s && xx >= -1.0e-14 && xx <= 1.0e-14 ) continue;
226 
227  for ( double yy = y_min; yy <= y_max; yy += y_step )
228  {
229  if ( y_is_s && yy >= -1.0e-14 && yy <= 1.0e-14 ) continue;
230 
231  solute_vector << US_ZSolute( xx, yy, zz, 0.0 );
232  }
233  }
234  }
235 
236  else if ( zcflg == 1 )
237  { // Z varies linearly with X
238  for ( double xx = x_min; xx <= x_max; xx += x_step )
239  {
240  if ( x_is_s && xx >= -1.0e-14 && xx <= 1.0e-14 ) continue;
241  zz = z_coeffs[ 0 ] + z_coeffs[ 1 ] * xx;
242 
243  for ( double yy = y_min; yy <= y_max; yy += y_step )
244  {
245  if ( y_is_s && yy >= -1.0e-14 && yy <= 1.0e-14 ) continue;
246 
247  solute_vector << US_ZSolute( xx, yy, zz, 0.0 );
248  }
249  }
250  }
251 
252  else
253  { // Z varies by ( a + bX + cX^2 + dX^3 )
254  for ( double xx = x_min; xx <= x_max; xx += x_step )
255  {
256  if ( x_is_s && xx >= -1.0e-14 && xx <= 1.0e-14 ) continue;
257  zz = z_coeffs[ 0 ] + z_coeffs[ 1 ] * xx
258  + z_coeffs[ 2 ] * xx * xx
259  + z_coeffs[ 3 ] * xx * xx * xx;
260 
261  for ( double yy = y_min; yy <= y_max; yy += y_step )
262  {
263  if ( y_is_s && yy >= -1.0e-14 && yy <= 1.0e-14 ) continue;
264 
265  solute_vector << US_ZSolute( xx, yy, zz, 0.0 );
266  }
267  }
268  }
269 
270  return solute_vector;
271 }
272 
273