Changeset 15079


Ignore:
Timestamp:
05/22/13 10:22:19 (12 years ago)
Author:
Mathieu Morlighem
Message:

CHG: base convergence on vectors rather than inputs (more accurate and makes more sense)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/c/analyses/steadystate_core.cpp

    r15055 r15079  
    1616
    1717/*Local prototypes*/
    18 bool steadystateconvergence(FemModel* femmodel);
     18bool steadystateconvergence(Vector<IssmDouble>* tg,Vector<IssmDouble>* tg_old,Vector<IssmDouble>* ug,Vector<IssmDouble>* ug_old,IssmDouble reltol);
    1919
    2020void steadystate_core(FemModel* femmodel){
     
    2222        /*intermediary: */
    2323        int step;
     24        Vector<IssmDouble>* ug     = NULL;
     25        Vector<IssmDouble>* ug_old = NULL;
     26        Vector<IssmDouble>* tg     = NULL;
     27        Vector<IssmDouble>* tg_old = NULL;
    2428
    2529        /*parameters: */
    26         bool save_results,isenthalpy;
    27         int  maxiter;
    28         int  numoutputs         = 0;
    29         int  *requested_outputs = NULL;
     30        bool        save_results,isenthalpy;
     31        int         maxiter;
     32        IssmDouble  reltol;
     33        int         numoutputs        = 0;
     34        int        *requested_outputs = NULL;
    3035
    3136        /* recover parameters:*/
     
    3439        femmodel->parameters->FindParam(&numoutputs,SteadystateNumRequestedOutputsEnum);
    3540        femmodel->parameters->FindParam(&isenthalpy,ThermalIsenthalpyEnum);
     41        femmodel->parameters->FindParam(&reltol,SteadystateReltolEnum);
    3642        femmodel->parameters->SetParam(false,SaveResultsEnum);
    3743        if(numoutputs) femmodel->parameters->FindParam(&requested_outputs,&numoutputs,SteadystateRequestedOutputsEnum);
     
    4652                if(isenthalpy==0){
    4753                        thermal_core(femmodel);
     54                        femmodel->SetCurrentConfiguration(ThermalAnalysisEnum);
     55                        GetSolutionFromInputsx(&tg,femmodel->elements, femmodel->nodes, femmodel->vertices,femmodel->loads, femmodel->materials, femmodel->parameters);
    4856                }
    4957                else{
    5058                        enthalpy_core(femmodel);
     59                        GetSolutionFromInputsx(&tg,femmodel->elements, femmodel->nodes, femmodel->vertices,femmodel->loads, femmodel->materials, femmodel->parameters);
    5160                }
    5261                #else
     
    5665                if(VerboseSolution()) _pprintLine_("   computing new velocity");
    5766                diagnostic_core(femmodel);
     67                GetSolutionFromInputsx(&ug,femmodel->elements, femmodel->nodes, femmodel->vertices,femmodel->loads, femmodel->materials, femmodel->parameters);
    5868
    59                 if (step>1){
    60                         if(VerboseSolution()) _pprintLine_("   checking velocity, temperature and pressure convergence");
    61                         if(steadystateconvergence(femmodel)) break;
     69                if(step>1){
     70                        if(VerboseSolution()) _pprintLine_("   checking steadystate convergence");
     71                        if(steadystateconvergence(tg,tg_old,ug,ug_old,reltol)) break;
    6272                }
    6373                if(step>maxiter){
     
    6676                }
    6777
    68                 if(VerboseSolution()) _pprintLine_("   saving velocity, temperature and pressure to check for convergence at next step");
    69                 InputDuplicatex(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VxEnum,VxPicardEnum);
    70                 InputDuplicatex(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VyEnum,VyPicardEnum);
    71                 InputDuplicatex(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,VzEnum,VzPicardEnum);
    72                 InputDuplicatex(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,PressureEnum,PressurePicardEnum);
    73                 InputDuplicatex(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,TemperatureEnum,TemperatureOldEnum);
    74 
    75                 //increase counter
     78                /*update results and increase counter*/
     79                delete tg_old;tg_old=tg;
     80                delete ug_old;ug_old=ug;
    7681                step++;
    7782        }
     
    9297
    9398        /*Free ressources:*/
     99        delete tg;
     100        delete ug;
    94101        xDelete<int>(requested_outputs);
    95102}
    96 bool steadystateconvergence(FemModel* femmodel){
     103bool steadystateconvergence(Vector<IssmDouble>* tg,Vector<IssmDouble>* tg_old,Vector<IssmDouble>* ug,Vector<IssmDouble>* ug_old,IssmDouble reltol){
    97104
    98         /*output: */
    99         bool converged=false;
    100         bool velocity_converged=false;
    101         bool temperature_converged=false;
     105        /*Output*/
     106        bool converged = true;
    102107
    103         /*intermediary: */
    104         int velocityenums[8]={VxEnum,VxPicardEnum,VyEnum,VyPicardEnum,VzEnum,VzPicardEnum,PressureEnum,PressurePicardEnum}; //pairs of enums (new and old) on which to carry out the converence tests
    105         int temperatureenums[2]={TemperatureEnum,TemperatureOldEnum};
    106         int convergencecriterion[1]={RelativeEnum}; //criterions for convergence, RelativeEnum or AbsoluteEnum
    107         IssmDouble convergencecriterionvalue[1]; //value of criterion to be respected
     108        /*Intermediary*/
     109        Vector<IssmDouble>* dug    = NULL;
     110        Vector<IssmDouble>* dtg    = NULL;
     111        IssmDouble          ndt,nt;
     112        IssmDouble          ndu,nu;
    108113
    109         /*retrieve parameters: */
    110         femmodel->parameters->FindParam(&convergencecriterionvalue[0],SteadystateReltolEnum);
     114        /*compute norm(du)/norm(u)*/
     115        dug=ug_old->Duplicate(); ug_old->Copy(dug); dug->AYPX(ug,-1.0);
     116        ndu=dug->Norm(NORM_TWO); nu=ug_old->Norm(NORM_TWO);
     117        if (xIsNan<IssmDouble>(ndu) || xIsNan<IssmDouble>(nu)) _error_("convergence criterion is NaN!");
     118        if((ndu/nu)<reltol){
     119                if(VerboseConvergence()) _pprintLine_("\n"<<setw(50)<<left<<"   Velocity convergence: norm(du)/norm(u)"<<ndu/nu*100<<" < "<<reltol*100<<" %");
     120        }
     121        else{
     122                if(VerboseConvergence()) _pprintLine_("\n"<<setw(50)<<left<<"   Velocity convergence: norm(du)/norm(u)"<<ndu/nu*100<<" > "<<reltol*100<<" %");
     123                converged=false;
     124        }
    111125
    112         /*figure out convergence at the input level, because we don't have the solution vectors!: */
    113         velocity_converged=InputConvergencex(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,&velocityenums[0],8,&convergencecriterion[0],&convergencecriterionvalue[0],1);
    114         temperature_converged=InputConvergencex(femmodel->elements,femmodel->nodes,femmodel->vertices,femmodel->loads,femmodel->materials,femmodel->parameters,&temperatureenums[0],2,&convergencecriterion[0],&convergencecriterionvalue[0],1);
     126        /*compute norm(dt)/norm(t)*/
     127        dtg=tg_old->Duplicate(); tg_old->Copy(dtg); dtg->AYPX(tg,-1.0);
     128        ndt=dtg->Norm(NORM_TWO); nt=tg_old->Norm(NORM_TWO);
     129        if (xIsNan<IssmDouble>(ndt) || xIsNan<IssmDouble>(nt)) _error_("convergence criterion is NaN!");
     130        if((ndt/nt)<reltol){
     131                if(VerboseConvergence()) _pprintLine_(setw(50)<<left<<"   Temperature convergence: norm(dt)/norm(t)"<<ndt/nt*100<<" < "<<reltol*100<<" %");
     132        }
     133        else{
     134                if(VerboseConvergence()) _pprintLine_(setw(50)<<left<<"   Temperature convergence: norm(dt)/norm(t)"<<ndt/nt*100<<" > "<<reltol*100<<" %");
     135                converged=false;
     136        }
    115137
    116         if(velocity_converged && temperature_converged) converged=true;
    117 
    118         /*return: */
     138        /*clean up and return*/
     139        delete dtg;
     140        delete dug;
    119141        return converged;
    120142}
Note: See TracChangeset for help on using the changeset viewer.