4 QDateTime
elapsed = QDateTime::currentDateTime();
5 #define ELAPSEDNOW (elapsed.msecsTo(QDateTime::currentDateTime()))
6 #define ELAPSEDSEC (elapsed.secsTo(QDateTime::currentDateTime()))
7 #define DbTimMsg(a) DbTiming << my_rank << generation << ELAPSEDNOW << a;
8 #define DRTiming DbTiming << my_rank
26 s_grid = ( keys.contains(
"s_grid" ) )
28 k_grid = ( keys.contains(
"k_grid" ) )
31 static const double extn_s = (double)(
s_grid - 1 );
32 static const double extn_k = (double)(
k_grid - 1 );
34 for (
int b = 0; b <
buckets.size(); b++ )
36 double x_min =
buckets[ b ].x_min;
37 double x_max =
buckets[ b ].x_max;
38 double y_min =
buckets[ b ].y_min;
39 double y_max =
buckets[ b ].y_max;
41 buckets[ b ].ds = ( x_max - x_min ) / extn_s;
42 buckets[ b ].dk = ( y_max - y_min ) / extn_k;
48 bool finished =
false;
57 DbgLv(0) <<
"Deme" << grp_nbr << deme_nbr
58 <<
": Generations finished, second" <<
ELAPSEDSEC;
80 switch ( status.MPI_TAG )
84 DbgLv(0) <<
" Deme" << grp_nbr << deme_nbr <<
":"
86 <<
" fitness checks maxrss" <<
maxrss;
105 for (
int e = dataset; e < dataset + count; e++ )
112 for (
int s = 0; s < scan_count; s++ )
116 for (
int r = 0; r < radius_points; r++ )
140 abort(
"Unknown message at end of GA worker loop" );
166 empty_fitness.
index = i;
178 int p_plague = p_crossover +
plague;
188 QDateTime
start = QDateTime::currentDateTime();
195 DbTimMsg(
"Worker start rank/generation/elapsed-secs");
205 DbTimMsg(
"Worker after get_fitness loop + sort");
210 DbgLv(
DL) <<
"Deme" << grp_nbr << deme_nbr
211 <<
": At last generation minimize.";
212 DbTimMsg(
"Worker before gsm rank/generation/elapsed");
216 DbgLv(
DL) <<
"Deme" << grp_nbr << deme_nbr
217 <<
": last generation minimize fitness=" << fitness[0].fitness;
218 DbTimMsg(
"Worker after gsm rank/generation/elapsed");
225 DbTimMsg(
"Worker after align_gene");
228 DbgLv(1) <<
"Best gene to master: gen" <<
generation <<
"worker" << deme_nbr;
248 DbTimMsg(
"Worker after send fitness,genes");
259 DbTimMsg(
"Worker after receive instructions");
265 DbgLv(0) <<
"Deme" << grp_nbr << deme_nbr
266 <<
": Finish signalled at deme generation" <<
generation + 1;
273 DbgLv(0) <<
"Deme" << grp_nbr << deme_nbr
274 <<
": At last generation";
282 const double NEAR_MATCH = 1.0e-8;
283 const double EPSF_SCALE = 1.0e-3;
285 double epsilon_f = pow( 10.0, fitpwr ) * EPSF_SCALE;
286 DbgLv(1) <<
"gw:" <<
my_rank <<
": Dup best-gene clean: fitness0 fitpwr epsilon_f"
287 << fitness[0].fitness << fitpwr << epsilon_f;
289 while ( f1 < population )
291 double fitdiff = qAbs( fitness[ f0 ].fitness - fitness[ f1 ].fitness );
293 if ( fitdiff < epsilon_f )
296 int g0 = fitness[ f0 ].index;
297 int g1 = fitness[ f1 ].index;
299 for (
int ii = 0; ii <
buckets.size(); ii++ )
301 double sdif = qAbs(
genes[ g0 ][ ii ].s -
genes[ g1 ][ ii ].s );
302 double kdif = qAbs(
genes[ g0 ][ ii ].k -
genes[ g1 ][ ii ].k );
304 if ( sdif > NEAR_MATCH || kdif > NEAR_MATCH )
306 DbgLv(1) <<
"gw:" <<
my_rank <<
": Dup NOT cleaned: f0 f1 fit0 fit1"
307 << f0 << f1 << fitness[f0].fitness << fitness[f1].fitness <<
"ii g0 g1 g0s g1s"
308 << ii << g0 << g1 <<
genes[g0][ii].s <<
genes[f1][ii].s;
317 DbgLv(1) <<
"gw:" <<
my_rank <<
": Dup cleaned: f0 f1 fit0 fit1"
318 << f0 << f1 << fitness[f0].fitness << fitness[f1].fitness;
319 fitness[ f1 ].fitness =
LARGE;
331 QList< Gene > old_genes =
genes;
335 for (
int g = 0; g <
elitism; g++ )
336 genes[ g ] = old_genes[ fitness[ g ].index ];
340 DbTimMsg(
"Worker before elitism loop");
342 for (
int g = elitism + immigrants; g <
population; g++ )
347 Gene gene = old_genes[ gene_index ];
348 int probability =
u_random( p_plague );
351 else if ( probability < p_crossover )
cross_gene ( gene, old_genes );
356 DbTimMsg(
"Worker after elitism loop");
361 DbTimMsg(
" +++Worker after generation loop");
369 for (
int i = 0; i < gene.size(); i++ )
371 double s = gene[ i ].s;
372 double s_min =
buckets[ i ].x_min;
373 double ds = s - s_min;
380 gridpoint = qMin( grid_es, gridpoint );
381 s = s_min + gridpoint *
buckets[ i ].ds;
384 double k = gene[ i ].k;
385 double k_min =
buckets[ i ].y_min;
386 double dk = k - k_min;
393 gridpoint = qMin( grid_ek, gridpoint );
394 k = k_min + gridpoint *
buckets[ i ].dk;
418 int nisols = gene.size();
422 for (
int cc = 0; cc < nisols; cc++ )
424 key += str.sprintf(
"%.5f%.5f", sim.
solutes[ cc ].s,
428 DbgLv(2) <<
"get_fitness: nisols" << nisols <<
"key" << key;
443 int solute_count = 0;
444 int nosols = sim.
solutes.size();
448 for (
int cc = 0; cc < nosols; cc++ )
465 fitness /= (double)datasets_to_process;
467 for (
int cc = 0; cc < nosols; cc++ )
472 for (
int cc = 0; cc < nosols; cc++ )
474 if ( sim.
solutes[ cc ].c >= cthresh ) solute_count++;
486 <<
fitness_map.size() << fitness << nisols << nosols
507 int size = vv.
size() / 2;
511 for (
int ii = 0; ii < size; ii++ )
513 gene[ ii ].s = vv[ index++ ];
514 gene[ ii ].k = vv[ index++ ];
521 DbgLv(
DL) <<
"Dem :" << grp_nbr << deme_nbr <<
"gene.s" << gene[0].s <<
"FIT_V";
543 const double divisor = 8.0;
548 int gene_index = (int)( -log( 1.0 - randx ) * beta );
549 gene_index = qMin( ( gnsize - 1 ), qMax( 0, gene_index ) );
560 static const int p_k = p_mutate_s +
p_mutate_k;
563 int solute =
u_random( gene.size() );
566 if ( rand < p_mutate_s )
568 else if ( rand < p_k )
589 double delta = qRound( x );
594 solute.
s += delta *
buckets[ b ].ds;
595 solute.
s = qMax( solute.
s,
buckets[ b ].x_min );
596 solute.
s = qMin( solute.
s,
buckets[ b ].x_max );
612 double delta = qRound( x );
617 solute.
k += delta *
buckets[ b ].dk;
618 solute.
k = qMax( solute.
k,
buckets[ b ].y_min );
619 solute.
k = qMin( solute.
k,
buckets[ b ].y_max );
626 Gene cross_from = old_genes[
fitness[ gene_index ].index ];
630 int solute_index =
u_random( gene.size() - 1 ) + 1;
641 for (
int i = solute_index; i <
buckets.size(); i++ )
643 gene[ i ] = cross_from[ i ];
656 static const int migrate_pcent =
parameters[
"migration" ].toInt();
657 static const int elitism_count =
parameters[
"elitism" ].toInt();
659 QVector< US_Solute > emmigres;
679 int bucket_sols =
buckets.size();
680 int migrate_sols = migrate_count * bucket_sols;
690 MPI_Send( emmigres.data(),
698 QVector< US_Solute > immigres( migrate_sols );
701 MPI_Recv( immigres.data(),
710 MPI_Get_count( &status, MPI_DOUBLE, &solutes_sent );
712 int mgenes_count = solutes_sent / bucket_sols;
715 if ( mgenes_count > 0 )
719 DbgLv(1) <<
"MG:Deme" << deme_nbr <<
": solsent mg_count" << solutes_sent
720 << mgenes_count <<
" elit" << elitism_count <<
"sol_dbls" <<
solute_doubles;
721 for (
int i = 0; i < mgenes_count; i++ )
723 Gene gene = immigres.mid( i * bucket_sols, bucket_sols );
724 genes[ elitism_count + i ] = gene;
742 for (
int b = 0; b <
buckets.size(); b++ )
746 double x_min =
buckets[ b ].x_min;
747 double y_min =
buckets[ b ].y_min;
774 static long totms=0L;
775 static long totT1=0L;
776 static long totT2=0L;
777 static long totT3=0L;
778 static long totT4=0L;
779 static long totT5=0L;
780 static long totT6=0L;
782 QDateTime clcSt0=QDateTime::currentDateTime();
784 int gsize = gene.size();
785 int vsize = gsize * 2;
790 QVector< QVector< double > > hessian( vsize );
792 for (
int ii = 0; ii < vsize; ii++ )
794 hessian[ ii ] = QVector< double >( vsize, 0.0 );
795 hessian[ ii ][ ii ] = 1.0;
800 QString Phd =
"MIN:" + QString().sprintf(
"%d:%d",grp_nbr,deme_nbr) +
":";
801 DbgLv(
DL) << Phd <<
"vsize" << vsize <<
"fitness" << fitness
802 <<
"gene0.s" << gene[0].s;
806 for (
int ii = 0; ii < gsize; ii++ )
808 vv.
assign( index++, gene[ ii ].s );
809 vv.
assign( index++, gene[ ii ].k );
812 DbgLv(
DL) << Phd <<
" (0)call lamm_gsm_df";
814 DbgLv(
DL) << Phd <<
" (0) rtn fr lamm_gsm_df u0" << uu[0];
816 QDateTime clcSt1=QDateTime::currentDateTime();
817 totT1+=clcSt0.msecsTo(clcSt1);
820 static const double epsilon_f = 1.0e-7;
823 double epsilon = epsilon_f * fitness * 4.0;
824 DbgLv(
DL) << Phd <<
"epsilon" << epsilon <<
"uL2norm" << uu.L2norm();
825 bool neg_cnstr = ( vv[ 0 ] < 0.1 );
830 clcSt1=QDateTime::currentDateTime();
834 if ( fitness == 0.0 )
break;
846 if ( neg_cnstr && v_s2[ 0 ] < 0.1 )
848 DbgLv(
DL) << Phd <<
" NEG-CNSTR:01: v_s2[0]" << v_s2[0];
852 DbgLv(
DL) << Phd <<
" iter" << iteration <<
"v_s2[0]" << v_s2[0];
854 DbgLv(
DL) << Phd <<
" iter" << iteration <<
"g_s2" << g_s2;
857 while ( s2 > epsilon && g_s2 > g_s1 )
863 DbgLv(
DL) << Phd <<
" s2 g_s2 g_s1" << s2 << g_s2 << g_s1;
864 if ( neg_cnstr && v_s2[ 0 ] < 0.1 )
866 DbgLv(
DL) << Phd <<
" NEG-CNSTR:02: v_s2[0]" << v_s2[0];
867 v_s2.assign( 0, 0.1 +
u_random( 100 ) * 0.001 );
873 QDateTime clcSt2=QDateTime::currentDateTime();
874 totT2+=clcSt1.msecsTo(clcSt2);
876 DbgLv(
DL) << Phd <<
" g_s2" << g_s2 <<
"s2 s3" << s2 << s3;
879 if ( s2 <= epsilon || ( s3 - s2 ) < epsilon )
break;
886 if ( neg_cnstr && v_s3[ 0 ] < 0.1 )
888 DbgLv(
DL) << Phd <<
" NEG-CNSTR:03: v_s3[0]" << v_s3[0];
894 QDateTime clcSt3=QDateTime::currentDateTime();
895 totT3+=clcSt2.msecsTo(clcSt3);
897 DbgLv(
DL) << Phd <<
" g_s3" << g_s3 <<
"s1 s2 s3" << s1 << s2 << s3;
900 static const int max_reps = 100;
902 while ( ( ( s2 - s1 ) > epsilon ) &&
903 ( ( s3 - s2 ) > epsilon ) &&
904 ( reps++ < max_reps ) )
906 double s1_s2 = 1.0 / ( s1 - s2 );
907 double s1_s3 = 1.0 / ( s1 - s3 );
908 double s2_s3 = 1.0 / ( s2 - s3 );
910 double s1_2 =
sq( s1 );
911 double s2_2 =
sq( s2 );
912 double s3_2 =
sq( s3 );
914 double aa = ( ( g_s1 - g_s3 ) * s1_s3 -
915 ( g_s2 - g_s3 ) * s2_s3
918 double bb = ( g_s3 * ( s2_2 - s1_2 ) +
919 g_s2 * ( s1_2 - s3_2 ) +
920 g_s1 * ( s3_2 - s2_2 )
922 s1_s2 * s1_s3 * s2_s3;
924 static const double max_a = 1.0e-25;
926 DbgLv(
DL) << Phd <<
" reps" << reps <<
"aa" << aa;
927 if ( qAbs( aa ) < max_a )
932 for (
int ii = 0; ii < gsize; ii++ )
934 gene[ ii ].s = vv[ index++ ];
935 gene[ ii ].k = vv[ index++ ];
939 QDateTime clcSt4=QDateTime::currentDateTime();
940 totT4+=clcSt3.msecsTo(clcSt4);
941 insms=(long)clcSt0.msecsTo(clcSt4);
944 DRTiming <<
"MINIMIZE: msecs" << insms <<
"totmsecs calls" << totms << ncalls;
945 DRTiming <<
" MMIZE: t1 t2 t3 t4 t5 t6"
946 << totT1 << totT2 << totT3 << totT4 << totT5 << totT6;
951 double xx = -bb / ( 2.0 * aa );
952 double prev_g_s2 = g_s2;
956 if ( xx < ( s1 + s1 - s2 ) )
959 if ( xx < 0 ) xx = s1 / 2.0;
964 if ( s1 < 0 ) s1 = 0.0;
980 if ( neg_cnstr && v_s1[ 0 ] < 0.1 )
982 DbgLv(
DL) << Phd <<
" NEG-CNSTR:04: v_s1[0]" << v_s1[0];
986 DbgLv(
DL) << Phd <<
" x<s1 get_fitness";
999 if ( neg_cnstr && v_s2[ 0 ] < 0.1 )
1001 DbgLv(
DL) << Phd <<
" NEG-CNSTR:05: v_s2[0]" << v_s2[0];
1002 v_s2.assign( 0, 0.1 +
u_random( 100 ) * 0.001 );
1005 DbgLv(
DL) << Phd <<
" xx<s2 get_fitness";
1018 if ( neg_cnstr && v_s2[ 0 ] < 0.1 )
1020 DbgLv(
DL) << Phd <<
" NEG-CNSTR:06: v_s2[0]" << v_s2[0];
1021 v_s2.assign( 0, 0.1 +
u_random( 100 ) * 0.001 );
1024 DbgLv(
DL) << Phd <<
" xx<s3 get_fitness";
1029 if ( xx > ( s3 + s3 - s2 ) )
1035 if ( neg_cnstr && v_s4[ 0 ] < 0.1 )
1037 DbgLv(
DL) << Phd <<
" NEG-CNSTR:07: v_s4[0]" << v_s4[0];
1041 DbgLv(
DL) << Phd <<
" xx>=s3 get_fitness (A)";
1044 if ( g_s4 > g_s2 && g_s4 > g_s3 && g_s4 > g_s1 )
1062 if ( neg_cnstr && v_s3[ 0 ] < 0.1 )
1064 DbgLv(
DL) << Phd <<
" NEG-CNSTR:01: v_s2[0]" << v_s2[0];
1068 DbgLv(
DL) << Phd <<
" xx>=s3 get_fitness";
1072 DbgLv(
DL) << Phd <<
" p_g_s2 g_s2" << prev_g_s2 << g_s2;
1073 if ( qAbs( prev_g_s2 - g_s2 ) < epsilon )
break;
1078 if ( g_s2 < g_s3 && g_s2 < g_s1 )
1083 else if ( g_s1 < g_s3 )
1096 QDateTime clcSt4=QDateTime::currentDateTime();
1097 totT4+=clcSt3.msecsTo(clcSt4);
1099 DbgLv(
DL) << Phd <<
" call lamm_gsm_df";
1102 DbgLv(
DL) << Phd <<
" retn fr lamm_gsm_df";
1104 QDateTime clcSt5=QDateTime::currentDateTime();
1105 totT5+=clcSt4.msecsTo(clcSt5);
1122 for (
int ii = 0; ii < vsize; ii++ )
1124 double dotprod = 0.0;
1126 for (
int jj = 0; jj < vsize; jj++ )
1127 dotprod += ( hessian[ ii ][ jj ] * v_dg[ jj ] );
1129 v_hdg.
assign( ii, dotprod );
1132 double fac = v_dg.
dot( v_dx );
1133 double fae = v_dg.
dot( v_hdg );
1134 double sumdg = v_dg.
dot( v_dg );
1135 double sumxi = v_dx.
dot( v_dx );
1136 DbgLv(
DL) << Phd <<
" fac sumdg sumxi" << fac << sumdg << sumxi;
1138 if ( fac > sqrt( epsilon * sumdg * sumxi ) )
1141 double fad = 1.0 / fae;
1143 for (
int ii = 0; ii < vsize; ii++ )
1145 v_dg.
assign( ii, fac * v_dx[ ii ] - fad * v_hdg[ ii ] );
1148 for (
int ii = 0; ii < vsize; ii++ )
1150 for (
int jj = ii; jj < vsize; jj++ )
1152 hessian[ ii ][ jj ] +=
1153 fac * v_dx [ ii ] * v_dx [ jj ] -
1154 fad * v_hdg[ ii ] * v_hdg[ jj ] +
1155 fae * v_dg [ ii ] * v_dg [ jj ];
1158 hessian[ jj ][ ii ] = hessian[ ii ][ jj ];
1164 for (
int ii = 0; ii < vsize; ii++ )
1166 double dotprod = 0.0;
1168 for (
int jj = 0; jj < vsize; jj++ )
1169 dotprod += ( hessian[ ii ][ jj ] * v_g[ jj ] );
1171 uu.
assign( ii, dotprod );
1175 QDateTime clcSt6=QDateTime::currentDateTime();
1176 totT6+=clcSt5.msecsTo(clcSt6);
1183 for (
int ii = 0; ii < gsize; ii++ )
1185 gene[ ii ].s = vv[ index++ ];
1186 gene[ ii ].k = vv[ index++ ];
1188 DbgLv(
DL) << Phd <<
"OUT:fitness" << fitness <<
"gene0.s" << gene[0].s;
1191 insms=(long)clcSt0.msecsTo(QDateTime::currentDateTime());
1194 DRTiming <<
"MINIMIZE: msecs" << insms <<
"totmsecs calls" << totms << ncalls;
1195 DRTiming <<
" MMIZE: t1 t2 t3 t4 t5 t6"
1196 << totT1 << totT2 << totT3 << totT4 << totT5 << totT6;
1205 int sizec = qMin( cc.
size(), qMin( aa.
size(), bb.
size() ) );
1208 for (
int ii = 0; ii < sizec; ii++ )
1209 cc.
assign( ii, aa[ ii ] * sa + bb[ ii ] );
1211 for (
int ii = 0; ii < sizec; ii++ )
1212 cc.
assign( ii, aa[ ii ] * sa + bb[ ii ] * sb );
1224 static QVector< double > nnls_a;
1225 static QVector< double > nnls_b;
1226 QVector< double > nnls_x;
1227 QVector< double > nnls_c;
1228 QVector< double > w_nnls_a;
1229 QVector< double > w_nnls_b;
1235 int ntotal = nscans * npoints;
1236 int vsize = v.
size();
1237 int nsols = vsize / 2;
1238 int navals = nsols * ntotal;
1239 double fixval =
parameters[
"bucket_fixed" ].toDouble();
1246 sd.manual = dset->
manual;
1247 sd.vbar20 = dset->
vbar20;
1253 zcomponent.
f_f0 = 0.0;
1254 zcomponent.
mw = 0.0;
1265 nnls_a.resize( navals );
1266 nnls_b.resize( ntotal );
1270 for (
int vv = 0; vv < vsize; vv += 2 )
1272 double xval = v[ vv ];
1273 double yval = v[ vv + 1 ];
1285 for (
int ss = 0; ss < nscans; ss++ )
1286 for (
int rr = 0; rr < npoints; rr++ )
1287 nnls_a[ kk++ ] = simdat.
value( ss, rr );
1293 for (
int ss = 0; ss < nscans; ss++ )
1294 for (
int rr = 0; rr < npoints; rr++ )
1295 nnls_b[ kk++ ] = edata->
value( ss, rr );
1301 nnls_x.resize( nsols );
1302 nnls_c.resize( ntotal );
1319 int kk = index * ntotal;
1322 for (
int ss = 0; ss < nscans; ss++ )
1324 for (
int rr = 0; rr < npoints; rr++ )
1326 nnls_c[ jj++ ] = nnls_a[ kk ];
1327 nnls_a[ kk++ ] = simdat.
value( ss, rr );
1338 w_nnls_b.data(), nnls_x.data() );
1340 kk = index * ntotal;
1344 for (
int ss = 0; ss < nscans; ss++ )
1345 for (
int rr = 0; rr < npoints; rr++ )
1346 nnls_a[ kk++ ] = nnls_c[ jj++ ];
1352 for (
int cc = 0; cc < nsols; cc++ )
1354 double soluval = nnls_x[ cc ];
1356 if ( soluval > 0.0 )
1363 model.
components[ kk++ ].signal_concentration = soluval;
1378 for (
int ss = 0; ss < nscans; ss++ )
1380 for (
int rr = 0; rr < npoints; rr++ )
1382 double resid = edata->
value( ss, rr ) - simdat.
value( ss, rr );
1383 fitness +=
sq( resid );
1391 fitness /= (double)( ntotal );
1400 static const double hh = 0.01;
1401 static const double h2_recip = 0.5 / hh;
1411 for (
int ii = 0; ii < tt.
size(); ii++ )
1413 double save = tt[ ii ];
1416 tt.
assign( ii, save - hh );
1419 tt.
assign( ii, save + hh );
1422 vd.
assign( ii, ( y2 - y0 ) * h2_recip );
1430 for (
int ii = 0; ii < tt.
size(); ii++ )
1432 double save = tt[ ii ];
1434 tt.
assign( ii, save - hh );
1437 tt.
assign( ii, save + hh );
1440 vd.
assign( ii, ( y2 - y0 ) * h2_recip );
1445 DbgLv(
DL) <<
"GDF: vd0..." << vd[0] << vd[1] << vd[2] << vd[3];
1446 DbgLv(
DL) <<
"GDF: ...vdn" << vd[nn-3] << vd[nn-2] << vd[nn-1] << vd[nn];
1454 DbgLv(1) <<
"Buckets:";
1456 for (
int b = 0; b <
buckets.size(); b++ )
1473 QString s =
"Gene " + QString::number( gene ) +
": ";
1475 for (
int b = 0; b <
genes[ gene ].size(); b++ )
1477 s += QString(
"(%1, %2); " )
1478 .arg(
genes[ gene ][ b ]. s )
1479 .arg(
genes[ gene ][ b ]. k );
1487 DbgLv(1) <<
"Genes:";
1489 for (
int g = 0; g <
genes.size(); g++ )
1493 for (
int b = 0; b <
genes[ g ].size(); b++ )
1495 s += QString(
"(%1, %2)\n" )
1496 .arg(
genes[ g ][ b ]. s )
1497 .arg(
genes[ g ][ b ]. k );
1509 QString s =
"Fitness:\n";
1511 for (
int f = 0; f < fitness.size(); f++ )
1514 s += QString().sprintf(
"i, index, fitness: %3i, %3i, %.6e\n",
1515 f, fitness[ f ].index, fitness[ f ].fitness );
1523 double covalue,
int attribx )
1529 mcomp.
s = covalue * 1.e-13;
1532 mcomp.
f_f0 = covalue;
1582 for (
int cc = 0; cc < nsols; cc++ )
1584 double sval = solutes[ cc ].s;
1585 double kval = solutes[ cc ].k;
1595 solutes[ cc ].s = sval * 1.0e-13;
1598 solutes[ cc ].k = sval;
1603 solutes[ cc ].d = sval;
1606 solutes[ cc ].v = sval;
1613 solutes[ cc ].s = kval * 1.0e-13;
1616 solutes[ cc ].k = kval;
1621 solutes[ cc ].d = kval;
1624 solutes[ cc ].v = kval;