@@ -356,6 +356,8 @@ namespace aspect
356
356
return (r0+r1)/2 .;
357
357
}
358
358
359
+
360
+
359
361
template <int dim>
360
362
bool
361
363
DynamicCore<dim>::solve_time_step(double &X, double &T, double &R) const
@@ -386,6 +388,8 @@ namespace aspect
386
388
double dT1 = get_dT (R_1);
387
389
double dT2 = get_dT (R_2);
388
390
391
+ // If the temperature difference at the core-mantle boundary and at the
392
+ // inner-outer core boundary have the same sign, we have a fully molten or fully solid core.
389
393
if (dT0 >= 0 . && dT2 >= 0 .)
390
394
{
391
395
// Fully molten core
@@ -399,48 +403,64 @@ namespace aspect
399
403
dT1 = 0 ;
400
404
}
401
405
else
402
- while (!(dT1==0 || steps>max_steps))
403
- {
404
- // If solution is out of the interval, then something is wrong.
405
- if (dT0*dT2>0 )
406
- {
407
- this ->get_pcout ()<<" Step: " <<steps<<std::endl
408
- <<" R=[" <<R_0/1e3 <<" ," <<R_2/1e3 <<" ]" <<" (km)"
409
- <<" dT0=" <<dT0<<" , dT2=" <<dT2<<std::endl
410
- <<" Q_CMB=" <<core_data.Q <<std::endl
411
- <<" Warning: Solution for inner core radius can not be found! Mid-point is used." <<std::endl;
412
- AssertThrow (dT0*dT2<=0 ,ExcMessage (" No single solution for inner core!" ));
413
- }
414
- else if (dT0*dT1 < 0 .)
415
- {
416
- R_2 = R_1;
417
- dT2 = dT1;
418
- }
419
- else if (dT2*dT1 < 0 .)
420
- {
421
- R_0 = R_1;
422
- dT0 = dT1;
423
- }
424
- R_1 = (R_0 + R_2) / 2 .;
425
- dT1 = get_dT (R_1);
426
- ++steps;
427
- }
406
+ {
407
+ // Use bisection method to find R_1 such that dT1 = 0
408
+ while (!(dT1==0 || steps>max_steps))
409
+ {
410
+ // If solution is out of the interval, then something is wrong.
411
+ if (dT0*dT2>0 )
412
+ {
413
+ this ->get_pcout ()<<" Step: " <<steps<<std::endl
414
+ <<" R=[" <<R_0/1e3 <<" ," <<R_2/1e3 <<" ]" <<" (km)"
415
+ <<" dT0=" <<dT0<<" , dT2=" <<dT2<<std::endl
416
+ <<" Q_CMB=" <<core_data.Q <<std::endl
417
+ <<" Warning: Solution for inner core radius can not be found! Mid-point is used." <<std::endl;
418
+ AssertThrow (dT0*dT2<=0 ,ExcMessage (" No single solution for inner core!" ));
419
+ }
420
+ else if (dT0*dT1 < 0 .)
421
+ {
422
+ R_2 = R_1;
423
+ dT2 = dT1;
424
+ }
425
+ else if (dT2*dT1 < 0 .)
426
+ {
427
+ R_0 = R_1;
428
+ dT0 = dT1;
429
+ }
430
+
431
+ // Update R_1 and recalculate dT1
432
+ R_1 = (R_0 + R_2) / 2 .;
433
+ dT1 = get_dT (R_1);
434
+ ++steps;
435
+ }
436
+ }
428
437
429
438
// Calculate new R,T,X
430
439
R = R_1;
431
440
T = get_Tc (R);
432
441
X = get_X (R);
433
442
443
+ // Check the signs of dT at the boundaries to classify the solution
434
444
if (dT0<0 . && dT2>0 .)
435
445
{
436
- // Normal solution
446
+ // Core partially molten, freezing from the inside, normal solution
437
447
return true ;
438
448
}
439
449
else if (dT0>0 . && dT2<0 .)
440
450
{
441
- // Snowing core solution
451
+ // Core partially molten, snowing core solution
442
452
return false ;
443
453
}
454
+ else if (dT0 >= 0 . && dT2 >= 0 .)
455
+ {
456
+ // Core fully molten, normal solution
457
+ return true ;
458
+ }
459
+ else if (dT0 <= 0 . && dT2 <= 0 .)
460
+ {
461
+ // Core fully solid, normal solution
462
+ return true ;
463
+ }
444
464
else
445
465
{
446
466
// No solution found.
0 commit comments