Changeset 9761


Ignore:
Timestamp:
09/11/11 00:00:59 (14 years ago)
Author:
Eric.Larour
Message:

Added --with-control macro to configure script.
Can now strip out all control related routines from the parallel issm compilation.

Location:
issm/trunk/src
Files:
2 added
107 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/ad/Makefile.am

    r9760 r9761  
    102102                                        ./objects/Inputs/DoubleInput.h\
    103103                                        ./objects/Inputs/DoubleInput.cpp\
    104                                         ./objects/Inputs/ControlInput.h\
    105                                         ./objects/Inputs/ControlInput.cpp\
    106104                                        ./objects/Inputs/DatasetInput.h\
    107105                                        ./objects/Inputs/DatasetInput.cpp\
     
    190188                                        ./Container/Vertices.cpp\
    191189                                        ./shared/shared.h\
    192                                         ./shared/Threads/issm_threads.h\
    193                                         ./shared/Threads/LaunchThread.cpp\
    194                                         ./shared/Threads/PartitionRange.cpp\
    195190                                        ./shared/Alloc/alloc.h\
    196191                                        ./shared/Alloc/alloc.cpp\
     
    207202                                        ./shared/Numerics/cross.cpp\
    208203                                        ./shared/Numerics/norm.cpp\
    209                                         ./shared/Numerics/BrentSearch.cpp\
    210                                         ./shared/Numerics/OptimalSearch.cpp\
    211                                         ./shared/Numerics/OptFunc.cpp\
    212204                                        ./shared/Numerics/extrema.cpp\
    213205                                        ./shared/Numerics/UnitConversion.cpp\
     
    308300                                        ./modules/ModelProcessorx/SurfaceSlope/CreateConstraintsSurfaceSlope.cpp\
    309301                                        ./modules/ModelProcessorx/SurfaceSlope/CreateLoadsSurfaceSlope.cpp\
    310                                         ./modules/ModelProcessorx/Control/CreateParametersControl.cpp\
    311                                         ./modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp\
    312                                         ./modules/ModelProcessorx/Thermal/UpdateElementsThermal.cpp\
    313                                         ./modules/ModelProcessorx/Thermal/CreateNodesThermal.cpp\
    314                                         ./modules/ModelProcessorx/Thermal/CreateConstraintsThermal.cpp\
    315                                         ./modules/ModelProcessorx/Thermal/CreateLoadsThermal.cpp\
    316                                         ./modules/ModelProcessorx/Enthalpy/UpdateElementsEnthalpy.cpp\
    317                                         ./modules/ModelProcessorx/Enthalpy/CreateNodesEnthalpy.cpp\
    318                                         ./modules/ModelProcessorx/Enthalpy/CreateConstraintsEnthalpy.cpp\
    319                                         ./modules/ModelProcessorx/Enthalpy/CreateLoadsEnthalpy.cpp\
    320302                                        ./modules/ModelProcessorx/Hydrology/UpdateElementsHydrology.cpp\
    321303                                        ./modules/ModelProcessorx/Hydrology/CreateNodesHydrology.cpp\
    322304                                        ./modules/ModelProcessorx/Hydrology/CreateConstraintsHydrology.cpp\
    323305                                        ./modules/ModelProcessorx/Hydrology/CreateLoadsHydrology.cpp\
    324                                         ./modules/ModelProcessorx/Melting/UpdateElementsMelting.cpp\
    325                                         ./modules/ModelProcessorx/Melting/CreateNodesMelting.cpp\
    326                                         ./modules/ModelProcessorx/Melting/CreateConstraintsMelting.cpp\
    327                                         ./modules/ModelProcessorx/Melting/CreateLoadsMelting.cpp\
    328306                                        ./modules/ModelProcessorx/Prognostic/UpdateElementsPrognostic.cpp\
    329307                                        ./modules/ModelProcessorx/Prognostic/CreateNodesPrognostic.cpp\
     
    371349                                        ./modules/InputScalex/InputScalex.h\
    372350                                        ./modules/InputScalex/InputScalex.cpp\
    373                                         ./modules/InputControlUpdatex/InputControlUpdatex.h\
    374                                         ./modules/InputControlUpdatex/InputControlUpdatex.cpp\
    375351                                        ./modules/SurfaceAreax/SurfaceAreax.h\
    376352                                        ./modules/SurfaceAreax/SurfaceAreax.cpp\
    377                                         ./modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.h\
    378                                         ./modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.cpp\
    379                                         ./modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.h\
    380                                         ./modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.cpp\
    381                                         ./modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.h\
    382                                         ./modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.cpp\
    383                                         ./modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.h\
    384                                         ./modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.cpp\
    385                                         ./modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.h\
    386                                         ./modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.cpp\
    387                                         ./modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.h\
    388                                         ./modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.cpp\
    389                                         ./modules/CostFunctionx/CostFunctionx.h\
    390                                         ./modules/CostFunctionx/CostFunctionx.cpp\
    391353                                        ./modules/CreateNodalConstraintsx/CreateNodalConstraintsx.h\
    392354                                        ./modules/CreateNodalConstraintsx/CreateNodalConstraintsx.cpp\
    393                                         ./modules/Orthx/Orthx.h\
    394                                         ./modules/Orthx/Orthx.cpp\
    395355                                        ./modules/UpdateDynamicConstraintsx/UpdateDynamicConstraintsx.h\
    396356                                        ./modules/UpdateDynamicConstraintsx/UpdateDynamicConstraintsx.cpp\
    397                                         ./modules/Gradjx/Gradjx.h\
    398                                         ./modules/Gradjx/Gradjx.cpp\
    399357                                        ./modules/IoModelToConstraintsx/IoModelToConstraintsx.h\
    400358                                        ./modules/IoModelToConstraintsx/IoModelToConstraintsx.cpp\
     
    439397                                        ./modules/MassFluxx/MassFluxx.cpp\
    440398                                        ./modules/MassFluxx/MassFluxx.h\
    441                                         ./modules/ControlInputGetGradientx/ControlInputGetGradientx.cpp\
    442                                         ./modules/ControlInputGetGradientx/ControlInputGetGradientx.h\
    443                                         ./modules/ControlInputSetGradientx/ControlInputSetGradientx.cpp\
    444                                         ./modules/ControlInputSetGradientx/ControlInputSetGradientx.h\
    445                                         ./modules/ControlInputScaleGradientx/ControlInputScaleGradientx.cpp\
    446                                         ./modules/ControlInputScaleGradientx/ControlInputScaleGradientx.h\
    447399                                        ./modules/SystemMatricesx/SystemMatricesx.cpp\
    448400                                        ./modules/SystemMatricesx/SystemMatricesx.h\
     
    451403                                        ./modules/ConstraintsStatex/ConstraintsStateLocal.h\
    452404                                        ./modules/ConstraintsStatex/RiftConstraintsState.cpp\
    453                                         ./modules/ConstraintsStatex/ThermalConstraintsState.cpp\
    454                                         ./modules/ConstraintsStatex/ThermalIsPresent.cpp\
    455405                                        ./modules/Responsex/Responsex.h\
    456406                                        ./modules/Responsex/Responsex.cpp\
     
    459409                                        ./modules/ResetConstraintsx/ResetConstraintsx.h\
    460410                                        ./modules/ResetConstraintsx/ResetConstraintsx.cpp\
    461                                         ./modules/ResetConstraintsx/ThermalConstraintsReset.cpp\
    462411                                        ./modules/Solverx/Solverx.cpp\
    463412                                        ./modules/Solverx/Solverx.h\
     
    473422                                        ./modules/OutputRiftsx/OutputRiftsx.h\
    474423                                        ./modules/OutputRiftsx/OutputRiftsx.cpp\
    475                                         ./modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.cpp\
    476                                         ./modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.h\
    477                                         ./modules/ThicknessAbsGradientx/ThicknessAbsGradientx.cpp\
    478                                         ./modules/ThicknessAbsGradientx/ThicknessAbsGradientx.h\
    479                                         ./modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.cpp\
    480                                         ./modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.h\
    481424                                        ./modules/RheologyBbarx/RheologyBbarx.cpp\
    482425                                        ./modules/RheologyBbarx/RheologyBbarx.h\
    483426                                        ./solutions/diagnostic_core.cpp\
    484427                                        ./solutions/convergence.cpp\
    485                                         ./solutions/thermal_core.cpp\
    486                                         ./solutions/thermal_core_step.cpp\
    487                                         ./solutions/enthalpy_core.cpp\
    488428                                        ./solutions/WriteLockFile.cpp\
    489                                         ./solutions/control_core.cpp\
    490                                         ./solutions/controltao_core.cpp\
    491                                         ./solutions/controlrestart.cpp\
    492                                         ./solutions/controlconvergence.cpp\
    493                                         ./solutions/objectivefunctionC.cpp\
    494                                         ./solutions/gradient_core.cpp\
    495                                         ./solutions/adjointdiagnostic_core.cpp\
    496                                         ./solutions/adjointbalancethickness_core.cpp\
    497429                                        ./solutions/prognostic_core.cpp\
    498430                                        ./solutions/balancethickness_core.cpp\
     
    508440                                        ./solutions/AnalysisConfiguration.cpp\
    509441                                        ./solutions/CorePointerFromSolutionEnum.cpp\
    510                                         ./solutions/AdjointCorePointerFromSolutionEnum.cpp\
    511442                                        ./solvers/solver_linear.cpp\
    512                                         ./solvers/solver_adjoint_linear.cpp\
    513443                                        ./solvers/solver_nonlinear.cpp\
    514                                         ./solvers/solver_stokescoupling_nonlinear.cpp\
    515                                         ./solvers/solver_thermal_nonlinear.cpp
     444                                        ./solvers/solver_stokescoupling_nonlinear.cpp
    516445
    517446
     
    553482                                          ./modules/ModelProcessorx/Qmu/CreateParametersQmu.cpp\
    554483                                          ./modules/AverageOntoPartitionx/AverageOntoPartitionx.h
    555 
    556 libDAKOTA_a_CXXFLAGS = -fPIC -D_PARALLEL_   -D_C_ $(CXXOPTFLAGS)
    557 endif
    558 
    559 #}}}
     484endif
     485
     486#}}}
     487#Thermal sources  {{{1
     488
     489if THERMAL
     490libpISSM_a_SOURCES +=  ./solutions/thermal_core.cpp\
     491                                           ./solutions/thermal_core_step.cpp\
     492                                           ./solutions/enthalpy_core.cpp\
     493                                           ./solvers/solver_thermal_nonlinear.cpp\
     494                                           ./modules/ModelProcessorx/Thermal/UpdateElementsThermal.cpp\
     495                                           ./modules/ModelProcessorx/Thermal/CreateNodesThermal.cpp\
     496                                           ./modules/ModelProcessorx/Thermal/CreateConstraintsThermal.cpp\
     497                                           ./modules/ModelProcessorx/Thermal/CreateLoadsThermal.cpp\
     498                                           ./modules/ModelProcessorx/Enthalpy/UpdateElementsEnthalpy.cpp\
     499                                           ./modules/ModelProcessorx/Enthalpy/CreateNodesEnthalpy.cpp\
     500                                           ./modules/ModelProcessorx/Enthalpy/CreateConstraintsEnthalpy.cpp\
     501                                           ./modules/ModelProcessorx/Enthalpy/CreateLoadsEnthalpy.cpp\
     502                                           ./modules/ModelProcessorx/Melting/UpdateElementsMelting.cpp\
     503                                           ./modules/ModelProcessorx/Melting/CreateNodesMelting.cpp\
     504                                           ./modules/ModelProcessorx/Melting/CreateConstraintsMelting.cpp\
     505                                           ./modules/ModelProcessorx/Melting/CreateLoadsMelting.cpp\
     506                                           ./modules/ConstraintsStatex/ThermalConstraintsState.cpp\
     507                                           ./modules/ConstraintsStatex/ThermalIsPresent.cpp\
     508                                           ./modules/ResetConstraintsx/ThermalConstraintsReset.cpp
     509
     510
     511endif
     512
     513#}}}
     514#Control sources  {{{1
     515
     516if CONTROL
     517libpISSM_a_SOURCES += ./solutions/control_core.cpp\
     518                                          ./solutions/controltao_core.cpp\
     519                                          ./solutions/controlrestart.cpp\
     520                                          ./solutions/controlconvergence.cpp\
     521                                          ./solutions/objectivefunctionC.cpp\
     522                                          ./solutions/gradient_core.cpp\
     523                                          ./solutions/adjointdiagnostic_core.cpp\
     524                                          ./solutions/adjointbalancethickness_core.cpp\
     525                                          ./solutions/AdjointCorePointerFromSolutionEnum.cpp\
     526                                          ./solvers/solver_adjoint_linear.cpp\
     527                                          ./modules/ControlInputGetGradientx/ControlInputGetGradientx.cpp\
     528                                          ./modules/ControlInputGetGradientx/ControlInputGetGradientx.h\
     529                                          ./modules/ControlInputSetGradientx/ControlInputSetGradientx.cpp\
     530                                          ./modules/ControlInputSetGradientx/ControlInputSetGradientx.h\
     531                                          ./modules/ControlInputScaleGradientx/ControlInputScaleGradientx.cpp\
     532                                          ./modules/ControlInputScaleGradientx/ControlInputScaleGradientx.h\
     533                                          ./modules/ModelProcessorx/Control/CreateParametersControl.cpp\
     534                                          ./modules/ModelProcessorx/Control/UpdateElementsAndMaterialsControl.cpp\
     535                                          ./modules/InputControlUpdatex/InputControlUpdatex.h\
     536                                          ./modules/InputControlUpdatex/InputControlUpdatex.cpp\
     537                                          ./modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.h\
     538                                          ./modules/SurfaceAbsVelMisfitx/SurfaceAbsVelMisfitx.cpp\
     539                                          ./modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.h\
     540                                          ./modules/SurfaceRelVelMisfitx/SurfaceRelVelMisfitx.cpp\
     541                                          ./modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.h\
     542                                          ./modules/SurfaceLogVelMisfitx/SurfaceLogVelMisfitx.cpp\
     543                                          ./modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.h\
     544                                          ./modules/SurfaceLogVxVyMisfitx/SurfaceLogVxVyMisfitx.cpp\
     545                                          ./modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.h\
     546                                          ./modules/SurfaceAverageVelMisfitx/SurfaceAverageVelMisfitx.cpp\
     547                                          ./modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.h\
     548                                          ./modules/ThicknessAbsMisfitx/ThicknessAbsMisfitx.cpp\
     549                                          ./modules/CostFunctionx/CostFunctionx.h\
     550                                          ./modules/CostFunctionx/CostFunctionx.cpp\
     551                                          ./modules/Orthx/Orthx.h\
     552                                          ./modules/Orthx/Orthx.cpp\
     553                                          ./modules/Gradjx/Gradjx.h\
     554                                          ./modules/Gradjx/Gradjx.cpp\
     555                                          ./modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.cpp\
     556                                          ./modules/DragCoefficientAbsGradientx/DragCoefficientAbsGradientx.h\
     557                                          ./modules/ThicknessAbsGradientx/ThicknessAbsGradientx.cpp\
     558                                          ./modules/ThicknessAbsGradientx/ThicknessAbsGradientx.h\
     559                                          ./modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.cpp\
     560                                          ./modules/RheologyBbarAbsGradientx/RheologyBbarAbsGradientx.h\
     561                                          ./objects/Inputs/ControlInput.h\
     562                                          ./objects/Inputs/ControlInput.cpp\
     563                                          ./shared/Numerics/BrentSearch.cpp\
     564                                          ./shared/Numerics/OptimalSearch.cpp\
     565                                          ./shared/Numerics/OptFunc.cpp
     566
     567endif
     568
     569#}}}
     570
    560571#Executable {{{1
    561572
  • issm/trunk/src/c/Container/DataSet.cpp

    r9320 r9761  
    1919#include "../objects/objects.h"
    2020#include "../shared/shared.h"
     21#include "../io/io.h"
    2122#include "../include/include.h"
    2223#include "../EnumDefinitions/EnumDefinitions.h"
     
    240241                                dataset->AddObject(transientinput);}
    241242                                break;
     243                        #ifdef _HAVE_CONTROL_
    242244                        case ControlInputEnum:{
    243245                           ControlInput* controlinputinput=NULL;
     
    246248                                dataset->AddObject(controlinputinput);}
    247249                                break;
     250                        #endif
    248251                        case DatasetInputEnum:{
    249252                                DatasetInput* datasetinputinput=NULL;
  • issm/trunk/src/c/Container/Options.cpp

    r9320 r9761  
    1616#include "./DataSet.h"
    1717#include "../shared/shared.h"
     18#include "../io/io.h"
    1819#include "../include/include.h"
    1920#include "../shared/shared.h"
  • issm/trunk/src/c/Makefile.am

    r9571 r9761  
    307307                                        ./shared/Threads/PartitionRange.cpp\
    308308                                        ./shared/Matlab/matlabshared.h\
    309                                         ./shared/Matlab/PrintfFunction.cpp\
    310309                                        ./shared/Matlab/ModuleBoot.cpp\
    311310                                        ./shared/Matlab/mxGetAssignedField.cpp\
     
    355354                                        ./shared/Elements/GetGlobalDofList.cpp\
    356355                                        ./shared/Elements/GetNumberOfDofs.cpp\
    357                                         ./shared/String/DescriptorIndex.cpp\
    358356                                        ./shared/String/sharedstring.h\
    359357                                        ./shared/Bamg/Abs.h \
     
    415413                                        ./io/Matlab/FetchMatlabData.cpp\
    416414                                        ./io/Matlab/OptionParse.cpp\
     415                                        ./io/PrintfFunction.cpp\
    417416                                        ./EnumDefinitions/EnumDefinitions.h\
    418417                                        ./EnumDefinitions/EnumToModelField.cpp\
     
    685684                                        ./modules/Dakotax/SpawnCore.cpp\
    686685                                        ./modules/Dakotax/SpawnCoreSerial.cpp\
     686                                        ./modules/Dakotax/DescriptorIndex.cpp\
    687687                                        ./modules/InputToResultx/InputToResultx.cpp\
    688688                                        ./modules/InputToResultx/InputToResultx.h\
     
    10001000                                        ./shared/Alloc/alloc.cpp\
    10011001                                        ./shared/Matlab/matlabshared.h\
    1002                                         ./shared/Matlab/PrintfFunction.cpp\
    10031002                                        ./shared/Matlab/ModuleBoot.cpp\
    10041003                                        ./shared/Matlab/mxGetAssignedField.cpp\
     
    10461045                                        ./shared/Elements/GetGlobalDofList.cpp\
    10471046                                        ./shared/Elements/GetNumberOfDofs.cpp\
    1048                                         ./shared/String/DescriptorIndex.cpp\
    10491047                                        ./shared/String/sharedstring.h\
    10501048                                        ./shared/Bamg/Abs.h \
     
    11041102                                        ./io/Matlab/FetchMatlabData.cpp\
    11051103                                        ./io/Matlab/OptionParse.cpp\
     1104                                        ./io/PrintfFunction.cpp\
    11061105                                        ./EnumDefinitions/EnumDefinitions.h\
    11071106                                        ./EnumDefinitions/EnumToModelField.cpp\
     
    13661365                                        ./modules/Dakotax/SpawnCore.cpp\
    13671366                                        ./modules/Dakotax/SpawnCoreParallel.cpp\
     1367                                        ./modules/Dakotax/DescriptorIndex.cpp\
    13681368                                        ./modules/InputToResultx/InputToResultx.cpp\
    13691369                                        ./modules/InputToResultx/InputToResultx.h\
  • issm/trunk/src/c/include/globals.h

    r1 r9761  
    66#define GLOBALS_H_
    77
    8 extern int my_rank;
    9 extern int num_procs;
     8int my_rank;
     9int num_procs;
    1010
    1111#endif
  • issm/trunk/src/c/include/include.h

    r3775 r9761  
    66#define  _INCLUDEGLOBAL_H_
    77
    8 #include "./globals.h" 
    98#include "./macros.h"
    109#include "./typedefs.h"
  • issm/trunk/src/c/io/Matlab/OptionParse.cpp

    r9336 r9761  
    99
    1010#include "../../shared/shared.h"
     11#include "../../io/io.h"
    1112#include "../../include/include.h"
    1213#include "./matlabio.h"
  • issm/trunk/src/c/io/io.h

    r8910 r9761  
    66#define _IO_H_
    77
     8#ifdef HAVE_CONFIG_H //config.h {{{1
     9#include <config.h>
     10#else
     11#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
     12#endif
     13//}}}
     14
    815#include "./Disk/diskio.h"
     16
     17#ifdef _SERIAL_
    918#include "./Matlab/matlabio.h"
     19#endif
     20
     21/*printf: */
     22int PrintfFunction(char* format,...);
    1023
    1124#endif  /* _IO_H_ */
  • issm/trunk/src/c/issm.h

    r9320 r9761  
    2222#include "./modules/modules.h"
    2323
     24
    2425#endif //ifndef _ISSM_H_
  • issm/trunk/src/c/modules/ConfigureObjectsx/ConfigureObjectsx.cpp

    r6412 r9761  
    77#include "../../shared/shared.h"
    88#include "../../include/include.h"
     9#include "../../io/io.h"
    910#include "../../toolkits/toolkits.h"
    1011#include "../../EnumDefinitions/EnumDefinitions.h"
  • issm/trunk/src/c/modules/ConstraintsStatex/ConstraintsStatex.cpp

    r9679 r9761  
    77#include "../../shared/shared.h"
    88#include "../../include/include.h"
     9#include "../../io/io.h"
    910#include "../../toolkits/toolkits.h"
    1011#include "../../EnumDefinitions/EnumDefinitions.h"
     
    3536                RiftConstraintsState(&converged,&num_unstable_constraints,loads,min_mechanical_constraints,analysis_type);
    3637        }
     38        #ifdef _HAVE_THERMAL_
    3739        else if(ThermalIsPresent(loads,analysis_type)){
    3840                ThermalConstraintsState(loads,&converged,&num_unstable_constraints,analysis_type);
    3941        }
     42        #endif
    4043        else{
    4144                /*Do nothing, no constraints management!:*/
  • issm/trunk/src/c/modules/ConstraintsStatex/RiftConstraintsState.cpp

    r8404 r9761  
    66#include "../../EnumDefinitions/EnumDefinitions.h"
    77#include "../../include/include.h"
     8#include "../../io/io.h"
    89#include "../../shared/shared.h"
    910
  • issm/trunk/src/c/modules/Dakotax/DakotaFree.cpp

    r9571 r9761  
    2020
    2121        int i;
     22        extern int my_rank;
    2223       
    2324        double* variables=NULL;
  • issm/trunk/src/c/modules/Dakotax/DakotaMPI_Bcast.cpp

    r9571 r9761  
    1515
    1616        int i;
     17        extern int my_rank;
    1718
    1819        /*inputs and outputs: */
  • issm/trunk/src/c/modules/Dakotax/Dakotax.h

    r9571 r9761  
    1111/* local prototypes: */
    1212int SpawnCore(double* responses, int numresponses, double* variables, char** variables_descriptors,int numvariables, void* femmodel,int counter);
     13int  DescriptorIndex(char* root, int* pindex,char* descriptor);
    1314
    1415#ifdef _SERIAL_
  • issm/trunk/src/c/modules/Dakotax/SpawnCoreParallel.cpp

    r9681 r9761  
    2929#include "../../io/io.h"
    3030#include "../../EnumDefinitions/EnumDefinitions.h"
     31#include "../../io/io.h"
    3132#include "../../shared/shared.h"
    3233#include "./Dakotax.h"
  • issm/trunk/src/c/modules/Exp2Kmlx/Exp2Kmlx.cpp

    r8747 r9761  
    66#include "../../shared/shared.h"
    77#include "../../include/include.h"
     8#include "../../io/io.h"
    89#include "../../toolkits/toolkits.h"
    910#include "../../EnumDefinitions/EnumDefinitions.h"
  • issm/trunk/src/c/modules/GroundingLineMigrationx/GroundingLineMigrationx.cpp

    r9356 r9761  
    77
    88#include "../../shared/shared.h"
     9#include "../../io/io.h"
    910#include "../../include/include.h"
     11#include "../../io/io.h"
    1012#include "../../toolkits/toolkits.h"
    1113#include "../../EnumDefinitions/EnumDefinitions.h"
  • issm/trunk/src/c/modules/GroundingLineMigrationx/GroundingLineMigrationxUtils.cpp

    r9211 r9761  
    66#include "./GroundingLineMigrationxLocal.h"
    77#include "../../shared/shared.h"
     8#include "../../io/io.h"
     9#include "../../io/io.h"
    810#include "../../include/include.h"
    911#include "../../toolkits/toolkits.h"
  • issm/trunk/src/c/modules/InputConvergencex/InputConvergencex.cpp

    r6412 r9761  
    55#include "../../shared/shared.h"
    66#include "../../include/include.h"
     7#include "../../io/io.h"
    78#include "../../toolkits/toolkits.h"
    89#include "../../EnumDefinitions/EnumDefinitions.h"
  • issm/trunk/src/c/modules/KMLMeshWritex/KMLFileReadx.cpp

    r8468 r9761  
    55#include "../../shared/shared.h"
    66#include "../../include/include.h"
     7#include "../../io/io.h"
    78#include "../../toolkits/toolkits.h"
    89#include "../../EnumDefinitions/EnumDefinitions.h"
  • issm/trunk/src/c/modules/KMLMeshWritex/KMLMeshWritex.cpp

    r9259 r9761  
    55#include "../../shared/shared.h"
    66#include "../../include/include.h"
     7#include "../../io/io.h"
    78#include "../../toolkits/toolkits.h"
    89#include "../../EnumDefinitions/EnumDefinitions.h"
  • issm/trunk/src/c/modules/KMLOverlayx/KMLOverlayx.cpp

    r8605 r9761  
    55#include "../../shared/shared.h"
    66#include "../../include/include.h"
     7#include "../../io/io.h"
    78#include "../../toolkits/toolkits.h"
    89#include "../../EnumDefinitions/EnumDefinitions.h"
  • issm/trunk/src/c/modules/Kml2Expx/Kml2Expx.cpp

    r9259 r9761  
    66#include "../../shared/shared.h"
    77#include "../../include/include.h"
     8#include "../../io/io.h"
    89#include "../../toolkits/toolkits.h"
    910#include "../../EnumDefinitions/EnumDefinitions.h"
  • issm/trunk/src/c/modules/Ll2xyx/Ll2xyx.cpp

    r8715 r9761  
    55#include "../../include/include.h"
    66#include "../../shared/shared.h"
     7#include "../../io/io.h"
    78#include <math.h>
    89
  • issm/trunk/src/c/modules/Mergesolutionfromftogx/Mergesolutionfromftogx.cpp

    r8809 r9761  
    44
    55#include "../VecMergex/VecMergex.h"
     6#include "../../io/io.h"
    67#include "./Mergesolutionfromftogx.h"
    78
  • issm/trunk/src/c/modules/ModelProcessorx/CreateDataSets.cpp

    r9340 r9761  
    6767                        break;
    6868
     69                case HydrologyAnalysisEnum:
     70                        CreateNodesHydrology(pnodes, iomodel);
     71                        CreateConstraintsHydrology(pconstraints,iomodel);
     72                        CreateLoadsHydrology(ploads,iomodel);
     73                        UpdateElementsHydrology(elements,iomodel,analysis_counter,analysis_type);
     74                        break;
     75
     76                #ifdef _HAVE_THERMAL_
    6977                case ThermalAnalysisEnum:
    7078                        CreateNodesThermal(pnodes, iomodel);
     
    7381                        UpdateElementsThermal(elements,iomodel,analysis_counter,analysis_type);
    7482                        break;
    75                
     83       
    7684                case EnthalpyAnalysisEnum:
    7785                        CreateNodesEnthalpy(pnodes, iomodel);
     
    8189                        break;
    8290               
    83                 case HydrologyAnalysisEnum:
    84                         CreateNodesHydrology(pnodes, iomodel);
    85                         CreateConstraintsHydrology(pconstraints,iomodel);
    86                         CreateLoadsHydrology(ploads,iomodel);
    87                         UpdateElementsHydrology(elements,iomodel,analysis_counter,analysis_type);
    88                         break;
    89 
    9091                case MeltingAnalysisEnum:
    9192                        CreateNodesMelting(pnodes, iomodel);
     
    9495                        UpdateElementsMelting(elements,iomodel,analysis_counter,analysis_type);
    9596                        break;
     97                #endif
    9698
    9799                case PrognosticAnalysisEnum:
     
    114116
    115117        /*Update Elements and Materials For Control methods*/
     118        #ifdef _HAVE_CONTROL_
    116119        UpdateElementsAndMaterialsControl(elements,materials,iomodel);
     120        #endif
    117121
    118122        /*Generate objects that are not dependent on any analysis_type: */
  • issm/trunk/src/c/modules/ModelProcessorx/CreateParameters.cpp

    r9725 r9761  
    22 * \brief general driver for creating parameters dataset
    33 */
     4
     5#ifdef HAVE_CONFIG_H
     6        #include <config.h>
     7#else
     8#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
     9#endif
     10
    411
    512#include "../../Container/Container.h"
     
    93100       
    94101        /*Before returning, create parameters in case we are running Qmu or control types runs: */
     102        #ifdef _HAVE_CONTROL_
    95103        CreateParametersControl(&parameters,iomodel,solution_type,analysis_type);
     104        #endif
     105
     106        #ifdef _HAVE_DAKOTA_
    96107        CreateParametersQmu(&parameters,iomodel,solution_type,analysis_type);
     108        #endif
    97109
    98110        /*Go through all parameters, and convert units to SI: */
  • issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.cpp

    r9719 r9761  
    1111#include "../../objects/objects.h"
    1212#include "../../shared/shared.h"
     13#include "../../io/io.h"
    1314#include "../../Container/Container.h"
    1415#include "../../EnumDefinitions/EnumDefinitions.h"
  • issm/trunk/src/c/modules/Reduceloadx/Reduceloadx.cpp

    r9320 r9761  
    1010
    1111#include "./Reduceloadx.h"
     12#include "../../io/io.h"
    1213
    1314void    Reduceloadx( Vec pf, Mat Kfs, Vec y_s,bool flag_ys0){
  • issm/trunk/src/c/modules/ResetConstraintsx/ResetConstraintsx.cpp

    r9127 r9761  
    66#include "../modules.h"
    77#include "../../shared/shared.h"
     8#include "../../io/io.h"
    89#include "../../include/include.h"
    910#include "../../toolkits/toolkits.h"
  • issm/trunk/src/c/modules/Solverx/Solverx.cpp

    r9320 r9761  
    66#include "../../shared/shared.h"
    77#include "../../include/include.h"
     8#include "../../io/io.h"
    89
    910#ifdef HAVE_CONFIG_H
  • issm/trunk/src/c/modules/SystemMatricesx/SystemMatricesx.cpp

    r9705 r9761  
    66#include "../../shared/shared.h"
    77#include "../../include/include.h"
     8#include "../../io/io.h"
    89#include "../../toolkits/toolkits.h"
    910#include "../../EnumDefinitions/EnumDefinitions.h"
  • issm/trunk/src/c/modules/UpdateConstraintsx/UpdateConstraintsx.cpp

    r9285 r9761  
    88#include "../../include/include.h"
    99#include "../../modules/modules.h"
     10#include "../../io/io.h"
    1011#include "../../toolkits/toolkits.h"
    1112#include "../../EnumDefinitions/EnumDefinitions.h"
  • issm/trunk/src/c/modules/Xy2llx/Xy2llx.cpp

    r8715 r9761  
    55#include "../../include/include.h"
    66#include "../../shared/shared.h"
     7#include "../../io/io.h"
    78#include <math.h>
    89
  • issm/trunk/src/c/objects/Bamg/include.h

    r5130 r9761  
    66#define  _INCLUDE2_H_
    77
     8#include "../../include/macros.h"
    89#include "./macros.h"
    910#include "./typedefs.h"
  • issm/trunk/src/c/objects/Contour.cpp

    r9320 r9761  
    1111#include "./objects.h"
    1212#include "../include/include.h"
    13 #include "../shared/Matlab/matlabshared.h"
     13#include "../io/io.h"
    1414
    1515void ContourEcho(Contour* contour){
  • issm/trunk/src/c/objects/Elements/Element.h

    r9206 r9761  
    4040                virtual void   GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue)=0;
    4141                virtual void   GetParameterValue(double* pvalue,Node* node,int enumtype)=0;
     42                #ifdef _HAVE_CONTROL_
    4243                virtual void   Gradj(Vec gradient,int control_type)=0;
    4344                virtual double ThicknessAbsMisfit(bool process_units  ,int weight_index)=0;
     
    5051                virtual double RheologyBbarAbsGradient(bool process_units,int weight_index)=0;
    5152                virtual double DragCoefficientAbsGradient(bool process_units,int weight_index)=0;
     53                virtual void   ControlInputGetGradient(Vec gradient,int enum_type)=0;
     54                virtual void   ControlInputSetGradient(double* gradient,int enum_type)=0;
     55                virtual void   ControlInputScaleGradient(int enum_type, double scale)=0;
     56                virtual void   InputControlUpdate(double scalar,bool save_parameter)=0;
     57                #endif
    5258                virtual double SurfaceArea(void)=0;
    5359                virtual void   InputDepthAverageAtBase(int enum_type,int average_enum_type,int object_enum)=0;
     
    6369                virtual void   InputCreate(double scalar,int name,int code)=0;
    6470                virtual void   InputCreate(double* vector, int index,IoModel* iomodel,int M,int N,int vector_type,int vector_enum,int code)=0;
    65                 virtual void   ControlInputGetGradient(Vec gradient,int enum_type)=0;
    66                 virtual void   ControlInputSetGradient(double* gradient,int enum_type)=0;
    67                 virtual void   ControlInputScaleGradient(int enum_type, double scale)=0;
    68                 virtual void   ProcessResultsUnits(void)=0;
     71                                virtual void   ProcessResultsUnits(void)=0;
    6972                virtual void   RequestedOutput(int output_enum,int step,double time)=0;
    7073                virtual void   MinVel(double* pminvel, bool process_units)=0;
     
    8184                virtual void   InputScale(int enum_type,double scale_factor)=0;
    8285                virtual void   GetVectorFromInputs(Vec vector,int NameEnum)=0;
    83                 virtual void   InputControlUpdate(double scalar,bool save_parameter)=0;
    8486                virtual void   InputArtificialNoise(int enum_type,double min,double max)=0;
    8587                virtual bool   InputConvergence(double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums)=0;
  • issm/trunk/src/c/objects/Elements/Penta.cpp

    r9733 r9761  
    524524}
    525525/*}}}*/
    526 /*FUNCTION Penta::ControlInputGetGradient{{{1*/
    527 void Penta::ControlInputGetGradient(Vec gradient,int enum_type){
    528 
    529         int doflist1[NUMVERTICES];
    530         Input* input=NULL;
    531 
    532         if(enum_type==MaterialsRheologyBbarEnum){
    533                 if(!IsOnBed()) return;
    534                 input=(Input*)matice->inputs->GetInput(MaterialsRheologyBEnum);
    535         }
    536         else{
    537                 input=inputs->GetInput(enum_type);
    538         }
    539         if (!input) _error_("Input %s not found",EnumToStringx(enum_type));
    540         if (input->Enum()!=ControlInputEnum) _error_("Input %s is not a ControlInput",EnumToStringx(enum_type));
    541 
    542         this->GetDofList1(&doflist1[0]);
    543         ((ControlInput*)input)->GetGradient(gradient,&doflist1[0]);
    544 
    545 }/*}}}*/
    546 /*FUNCTION Penta::ControlInputScaleGradient{{{1*/
    547 void Penta::ControlInputScaleGradient(int enum_type,double scale){
    548 
    549         Input* input=NULL;
    550 
    551         if(enum_type==MaterialsRheologyBbarEnum){
    552                 input=(Input*)matice->inputs->GetInput(MaterialsRheologyBEnum);
    553         }
    554         else{
    555                 input=inputs->GetInput(enum_type);
    556         }
    557         if (!input) _error_("Input %s not found",EnumToStringx(enum_type));
    558         if (input->Enum()!=ControlInputEnum) _error_("Input %s is not a ControlInput",EnumToStringx(enum_type));
    559 
    560         ((ControlInput*)input)->ScaleGradient(scale);
    561 }/*}}}*/
    562 /*FUNCTION Penta::ControlInputSetGradient{{{1*/
    563 void Penta::ControlInputSetGradient(double* gradient,int enum_type){
    564 
    565         int    doflist1[NUMVERTICES];
    566         double grad_list[NUMVERTICES];
    567         Input* grad_input=NULL;
    568         Input* input=NULL;
    569 
    570         if(enum_type==MaterialsRheologyBbarEnum){
    571                 input=(Input*)matice->inputs->GetInput(MaterialsRheologyBEnum);
    572         }
    573         else{
    574                 input=inputs->GetInput(enum_type);
    575         }
    576         if (!input) _error_("Input %s not found",EnumToStringx(enum_type));
    577         if (input->Enum()!=ControlInputEnum) _error_("Input %s is not a ControlInput",EnumToStringx(enum_type));
    578 
    579         this->GetDofList1(&doflist1[0]);
    580         for(int i=0;i<NUMVERTICES;i++) grad_list[i]=gradient[doflist1[i]];
    581         grad_input=new PentaVertexInput(GradientEnum,grad_list);
    582         ((ControlInput*)input)->SetGradient(grad_input);
    583 
    584 }/*}}}*/
    585526/*FUNCTION Penta::CreateDVectorDiagnosticHoriz {{{1*/
    586527ElementVector* Penta::CreateDVectorDiagnosticHoriz(void){
     
    658599                        Ke=CreateKMatrixBalancethickness();
    659600                        break;
     601                #ifdef _HAVE_THERMAL_
    660602                case ThermalAnalysisEnum:
    661603                        Ke=CreateKMatrixThermal();
     
    667609                        Ke=CreateKMatrixMelting();
    668610                        break;
     611                #endif
    669612                default:
    670613                        _error_("analysis %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type));
     
    18171760}
    18181761/*}}}*/
     1762/*FUNCTION Penta::CreateKMatrixPrognostic {{{1*/
     1763ElementMatrix* Penta::CreateKMatrixPrognostic(void){
     1764
     1765        if (!IsOnBed()) return NULL;
     1766
     1767        /*Depth Averaging Vx and Vy*/
     1768        this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);
     1769        this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);
     1770
     1771        Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
     1772        ElementMatrix* Ke=tria->CreateKMatrixPrognostic();
     1773        delete tria->matice; delete tria;
     1774
     1775        /*Delete Vx and Vy averaged*/
     1776        this->inputs->DeleteInput(VxAverageEnum);
     1777        this->inputs->DeleteInput(VyAverageEnum);
     1778
     1779        /*clean up and return*/
     1780        return Ke;
     1781}
     1782/*}}}*/
     1783/*FUNCTION Penta::CreateKMatrixSlope {{{1*/
     1784ElementMatrix* Penta::CreateKMatrixSlope(void){
     1785
     1786        if (!IsOnBed()) return NULL;
     1787
     1788        Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
     1789        ElementMatrix* Ke=tria->CreateKMatrixSlope();
     1790        delete tria->matice; delete tria;
     1791
     1792        /*clean up and return*/
     1793        return Ke;
     1794}
     1795/*}}}*/
     1796
     1797#ifdef _HAVE_THERMAL_
    18191798/*FUNCTION Penta::CreateKMatrixEnthalpy {{{1*/
    18201799ElementMatrix* Penta::CreateKMatrixEnthalpy(void){
     
    20602039}
    20612040/*}}}*/
    2062 /*FUNCTION Penta::CreateKMatrixPrognostic {{{1*/
    2063 ElementMatrix* Penta::CreateKMatrixPrognostic(void){
    2064 
    2065         if (!IsOnBed()) return NULL;
    2066 
    2067         /*Depth Averaging Vx and Vy*/
    2068         this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);
    2069         this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);
    2070 
    2071         Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
    2072         ElementMatrix* Ke=tria->CreateKMatrixPrognostic();
    2073         delete tria->matice; delete tria;
    2074 
    2075         /*Delete Vx and Vy averaged*/
    2076         this->inputs->DeleteInput(VxAverageEnum);
    2077         this->inputs->DeleteInput(VyAverageEnum);
    2078 
    2079         /*clean up and return*/
    2080         return Ke;
    2081 }
    2082 /*}}}*/
    2083 /*FUNCTION Penta::CreateKMatrixSlope {{{1*/
    2084 ElementMatrix* Penta::CreateKMatrixSlope(void){
    2085 
    2086         if (!IsOnBed()) return NULL;
    2087 
    2088         Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
    2089         ElementMatrix* Ke=tria->CreateKMatrixSlope();
    2090         delete tria->matice; delete tria;
    2091 
    2092         /*clean up and return*/
    2093         return Ke;
    2094 }
    2095 /*}}}*/
    20962041/*FUNCTION Penta::CreateKMatrixThermal {{{1*/
    20972042ElementMatrix* Penta::CreateKMatrixThermal(void){
     
    23172262}
    23182263/*}}}*/
    2319 /*FUNCTION Penta::CreatePVector {{{1*/
    2320 void  Penta::CreatePVector(Vec pf){
    2321 
    2322         /*retrive parameters: */
    2323         ElementVector* pe=NULL;
    2324         int analysis_type;
    2325         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    2326 
    2327         /*if debugging mode, check that all pointers exist {{{2*/
    2328         _assert_(this->nodes && this->matice && this->matpar && this->verticalneighbors && this->parameters && this->inputs);
    2329         /*}}}*/
    2330 
    2331         /*Skip if water element*/
    2332         if(IsOnWater()) return;
    2333 
    2334         /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
    2335         switch(analysis_type){
    2336                 case DiagnosticHorizAnalysisEnum:
    2337                         pe=CreatePVectorDiagnosticHoriz();
    2338                         break;
    2339                 case AdjointHorizAnalysisEnum:
    2340                         pe=CreatePVectorAdjointHoriz();
    2341                         break;
    2342                 case DiagnosticHutterAnalysisEnum:
    2343                         pe=CreatePVectorDiagnosticHutter();
    2344                         break;
    2345                 case DiagnosticVertAnalysisEnum:
    2346                         pe=CreatePVectorDiagnosticVert();
    2347                         break;
    2348                 case BedSlopeXAnalysisEnum: case SurfaceSlopeXAnalysisEnum: case BedSlopeYAnalysisEnum: case SurfaceSlopeYAnalysisEnum:
    2349                         pe=CreatePVectorSlope();
    2350                         break;
    2351                 case PrognosticAnalysisEnum:
    2352                         pe=CreatePVectorPrognostic();
    2353                         break;
    2354                 case BalancethicknessAnalysisEnum:
    2355                         pe=CreatePVectorBalancethickness();
    2356                         break;
    2357                 case ThermalAnalysisEnum:
    2358                         pe=CreatePVectorThermal();
    2359                         break;
    2360                 case EnthalpyAnalysisEnum:
    2361                         pe=CreatePVectorEnthalpy();
    2362                         break;
    2363                 case MeltingAnalysisEnum:
    2364                         pe=CreatePVectorMelting();
    2365                         break;
    2366                 default:
    2367                         _error_("analysis %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type));
    2368         }
    2369 
    2370         /*Add to global Vector*/
    2371         if(pe){
    2372                 pe->AddToGlobal(pf);
    2373                 delete pe;
    2374         }
    2375 }
    2376 /*}}}*/
    2377 /*FUNCTION Penta::CreatePVectorAdjointHoriz{{{1*/
    2378 ElementVector* Penta::CreatePVectorAdjointHoriz(void){
    2379 
    2380         int approximation;
    2381         inputs->GetParameterValue(&approximation,ApproximationEnum);
    2382 
    2383         switch(approximation){
    2384                 case MacAyealApproximationEnum:
    2385                         return CreatePVectorAdjointMacAyeal();
    2386                 case PattynApproximationEnum:
    2387                         return CreatePVectorAdjointPattyn();
    2388                 case NoneApproximationEnum:
    2389                         return NULL;
    2390                 case StokesApproximationEnum:
    2391                         return CreatePVectorAdjointStokes();
    2392                 default:
    2393                         _error_("Approximation %s not supported yet",EnumToStringx(approximation));
    2394         }
    2395 }
    2396 /*}}}*/
    2397 /*FUNCTION Penta::CreatePVectorAdjointMacAyeal{{{1*/
    2398 ElementVector* Penta::CreatePVectorAdjointMacAyeal(){
    2399 
    2400         if (!IsOnBed()) return NULL;
    2401 
    2402         /*Call Tria function*/
    2403         Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
    2404         ElementVector* pe=tria->CreatePVectorAdjointHoriz();
    2405         delete tria->matice; delete tria;
    2406 
    2407         /*clean up and return*/
    2408         return pe;
    2409 }
    2410 /*}}}*/
    2411 /*FUNCTION Penta::CreatePVectorAdjointPattyn{{{1*/
    2412 ElementVector* Penta::CreatePVectorAdjointPattyn(void){
    2413 
    2414         if (!IsOnSurface()) return NULL;
    2415 
    2416         /*Call Tria function*/
    2417         Tria* tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
    2418         ElementVector* pe=tria->CreatePVectorAdjointHoriz();
    2419         delete tria->matice; delete tria;
    2420 
    2421         /*clean up and return*/
    2422         return pe;
    2423 }
    2424 /*}}}*/
    2425 /*FUNCTION Penta::CreatePVectorBalancethickness {{{1*/
    2426 ElementVector* Penta::CreatePVectorBalancethickness(void){
    2427 
    2428         if (!IsOnBed()) return NULL;
    2429 
    2430         /*Depth Averaging Vx and Vy*/
    2431         this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);
    2432         this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);
    2433 
    2434         /*Call Tria function*/
    2435         Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
    2436         ElementVector* pe=tria->CreatePVectorBalancethickness();
    2437         delete tria->matice; delete tria;
    2438 
    2439         /*Delete Vx and Vy averaged*/
    2440         this->inputs->DeleteInput(VxAverageEnum);
    2441         this->inputs->DeleteInput(VyAverageEnum);
    2442 
    2443         /*Clean up and return*/
    2444         return pe;
    2445 }
    2446 /*}}}*/
    2447 /*FUNCTION Penta::CreatePVectorCouplingMacAyealStokes {{{1*/
    2448 ElementVector* Penta::CreatePVectorCouplingMacAyealStokes(void){
    2449 
    2450         /*compute all load vectors for this element*/
    2451         ElementVector* pe1=CreatePVectorCouplingMacAyealStokesViscous();
    2452         ElementVector* pe2=CreatePVectorCouplingMacAyealStokesFriction();
    2453         ElementVector* pe =new ElementVector(pe1,pe2);
    2454 
    2455         /*clean-up and return*/
    2456         delete pe1;
    2457         delete pe2;
    2458         return pe;
    2459 }
    2460 /*}}}*/
    2461 /*FUNCTION Penta::CreatePVectorCouplingMacAyealStokesViscous {{{1*/
    2462 ElementVector* Penta::CreatePVectorCouplingMacAyealStokesViscous(void){
    2463 
    2464         /*Constants*/
    2465         const int   numdof=NUMVERTICES*NDOF4;
    2466 
    2467         /*Intermediaries */
    2468         int         i,j,ig;
    2469         int         approximation;
    2470         double      viscosity,Jdet;
    2471         double      stokesreconditioning;
    2472         double      epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
    2473         double      dw[3];
    2474         double      xyz_list[NUMVERTICES][3];
    2475         double      basis[6]; //for the six nodes of the penta
    2476         double      dbasis[3][6]; //for the six nodes of the penta
    2477         GaussPenta *gauss=NULL;
    2478 
    2479         /*Initialize Element vector and return if necessary*/
    2480         inputs->GetParameterValue(&approximation,ApproximationEnum);
    2481         if(approximation!=MacAyealStokesApproximationEnum) return NULL;
    2482         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,StokesApproximationEnum);
    2483 
    2484         /*Retrieve all inputs and parameters*/
    2485         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    2486         this->parameters->FindParam(&stokesreconditioning,DiagnosticStokesreconditioningEnum);
    2487         Input* vx_input=inputs->GetInput(VxEnum);               _assert_(vx_input);
    2488         Input* vy_input=inputs->GetInput(VyEnum);               _assert_(vy_input);
    2489         Input* vz_input=inputs->GetInput(VzEnum);               _assert_(vz_input);
    2490         Input* vzmacayeal_input=inputs->GetInput(VzMacAyealEnum);   _assert_(vzmacayeal_input);
    2491 
    2492         /* Start  looping on the number of gaussian points: */
    2493         gauss=new GaussPenta(5,5);
    2494         for (ig=gauss->begin();ig<gauss->end();ig++){
    2495 
    2496                 gauss->GaussPoint(ig);
    2497 
    2498                 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
    2499                 GetNodalFunctionsP1(&basis[0], gauss);
    2500                 GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);
    2501 
    2502                 vzmacayeal_input->GetParameterDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
    2503 
    2504                 this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
    2505                 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
    2506 
    2507                 for(i=0;i<NUMVERTICES;i++){
    2508                         pe->values[i*NDOF4+0]+=-Jdet*gauss->weight*viscosity*dw[0]*dbasis[2][i];
    2509                         pe->values[i*NDOF4+1]+=-Jdet*gauss->weight*viscosity*dw[1]*dbasis[2][i];
    2510                         pe->values[i*NDOF4+2]+=-Jdet*gauss->weight*viscosity*(dw[0]*dbasis[0][i]+dw[1]*dbasis[1][i]+2*dw[2]*dbasis[2][i]);
    2511                         pe->values[i*NDOF4+3]+=Jdet*gauss->weight*stokesreconditioning*dw[2]*basis[i];
    2512                 }
    2513         }
    2514 
    2515         /*Clean up and return*/
    2516         delete gauss;
    2517         return pe;
    2518 }
    2519 /*}}}*/
    2520 /*FUNCTION Penta::CreatePVectorCouplingMacAyealStokesFriction{{{1*/
    2521 ElementVector* Penta::CreatePVectorCouplingMacAyealStokesFriction(void){
    2522 
    2523         /*Constants*/
    2524         const int numdof=NUMVERTICES*NDOF4;
    2525 
    2526         /*Intermediaries*/
    2527         int         i,j,ig;
    2528         int         approximation,analysis_type;
    2529         double      Jdet,Jdet2d;
    2530         double      stokesreconditioning;
    2531         double     bed_normal[3];
    2532         double      epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
    2533         double      viscosity, w, alpha2_gauss;
    2534         double      dw[3];
    2535         double     xyz_list_tria[NUMVERTICES2D][3];
    2536         double      xyz_list[NUMVERTICES][3];
    2537         double      basis[6]; //for the six nodes of the penta
    2538         Tria*       tria=NULL;
    2539         Friction*   friction=NULL;
    2540         GaussPenta  *gauss=NULL;
    2541 
    2542         /*Initialize Element vector and return if necessary*/
    2543         if(!IsOnBed() || IsOnShelf()) return NULL;
    2544         inputs->GetParameterValue(&approximation,ApproximationEnum);
    2545         if(approximation!=MacAyealStokesApproximationEnum) return NULL;
    2546         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,StokesApproximationEnum);
    2547 
    2548         /*Retrieve all inputs and parameters*/
    2549         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    2550         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    2551         this->parameters->FindParam(&stokesreconditioning,DiagnosticStokesreconditioningEnum);
    2552         Input* vx_input=inputs->GetInput(VxEnum);               _assert_(vx_input);
    2553         Input* vy_input=inputs->GetInput(VyEnum);               _assert_(vy_input);
    2554         Input* vz_input=inputs->GetInput(VzEnum);               _assert_(vz_input);
    2555         Input* vzmacayeal_input=inputs->GetInput(VzMacAyealEnum);   _assert_(vzmacayeal_input);
    2556 
    2557         for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
    2558 
    2559         /*build friction object, used later on: */
    2560         friction=new Friction("3d",inputs,matpar,analysis_type);
    2561 
    2562         /* Start looping on the number of gauss 2d (nodes on the bedrock) */
    2563         gauss=new GaussPenta(0,1,2,2);
    2564         for(ig=gauss->begin();ig<gauss->end();ig++){
    2565 
    2566                 gauss->GaussPoint(ig);
    2567 
    2568                 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
    2569                 GetNodalFunctionsP1(basis, gauss);
    2570 
    2571                 vzmacayeal_input->GetParameterValue(&w, gauss);
    2572                 vzmacayeal_input->GetParameterDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
    2573 
    2574                 BedNormal(&bed_normal[0],xyz_list_tria);
    2575                 this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
    2576                 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
    2577                 friction->GetAlpha2(&alpha2_gauss, gauss,VxEnum,VyEnum,VzEnum);
    2578 
    2579                 for(i=0;i<NUMVERTICES2D;i++){
    2580                         pe->values[i*NDOF4+0]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[0]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[0])*basis[i];
    2581                         pe->values[i*NDOF4+1]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[1]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[1])*basis[i];
    2582                         pe->values[i*NDOF4+2]+=Jdet2d*gauss->weight*2*viscosity*(dw[0]*bed_normal[0]+dw[1]*bed_normal[1]+dw[2]*bed_normal[2])*basis[i];
    2583                 }
    2584         }
    2585 
    2586         /*Clean up and return*/
    2587         delete gauss;
    2588         delete friction;
    2589         return pe;
    2590 }
    2591 /*}}}*/
    2592 /*FUNCTION Penta::CreatePVectorCouplingPattynStokes {{{1*/
    2593 ElementVector* Penta::CreatePVectorCouplingPattynStokes(void){
    2594 
    2595         /*compute all load vectors for this element*/
    2596         ElementVector* pe1=CreatePVectorCouplingPattynStokesViscous();
    2597         ElementVector* pe2=CreatePVectorCouplingPattynStokesFriction();
    2598         ElementVector* pe =new ElementVector(pe1,pe2);
    2599 
    2600         /*clean-up and return*/
    2601         delete pe1;
    2602         delete pe2;
    2603         return pe;
    2604 }
    2605 /*}}}*/
    2606 /*FUNCTION Penta::CreatePVectorCouplingPattynStokesViscous {{{1*/
    2607 ElementVector* Penta::CreatePVectorCouplingPattynStokesViscous(void){
    2608 
    2609         /*Constants*/
    2610         const int   numdof=NUMVERTICES*NDOF4;
    2611 
    2612         /*Intermediaries */
    2613         int         i,j,ig;
    2614         int         approximation;
    2615         double      viscosity,Jdet;
    2616         double      stokesreconditioning;
    2617         double      epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
    2618         double      dw[3];
    2619         double      xyz_list[NUMVERTICES][3];
    2620         double      basis[6]; //for the six nodes of the penta
    2621         double      dbasis[3][6]; //for the six nodes of the penta
    2622         GaussPenta *gauss=NULL;
    2623 
    2624         /*Initialize Element vector and return if necessary*/
    2625         inputs->GetParameterValue(&approximation,ApproximationEnum);
    2626         if(approximation!=PattynStokesApproximationEnum) return NULL;
    2627         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,StokesApproximationEnum);
    2628 
    2629         /*Retrieve all inputs and parameters*/
    2630         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    2631         this->parameters->FindParam(&stokesreconditioning,DiagnosticStokesreconditioningEnum);
    2632         Input* vx_input=inputs->GetInput(VxEnum);               _assert_(vx_input);
    2633         Input* vy_input=inputs->GetInput(VyEnum);               _assert_(vy_input);
    2634         Input* vz_input=inputs->GetInput(VzEnum);               _assert_(vz_input);
    2635         Input* vzpattyn_input=inputs->GetInput(VzPattynEnum);   _assert_(vzpattyn_input);
    2636 
    2637         /* Start  looping on the number of gaussian points: */
    2638         gauss=new GaussPenta(5,5);
    2639         for (ig=gauss->begin();ig<gauss->end();ig++){
    2640 
    2641                 gauss->GaussPoint(ig);
    2642 
    2643                 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
    2644                 GetNodalFunctionsP1(&basis[0], gauss);
    2645                 GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);
    2646 
    2647                 vzpattyn_input->GetParameterDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
    2648 
    2649                 this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
    2650                 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
    2651 
    2652                 for(i=0;i<NUMVERTICES;i++){
    2653                         pe->values[i*NDOF4+0]+=-Jdet*gauss->weight*viscosity*dw[0]*dbasis[2][i];
    2654                         pe->values[i*NDOF4+1]+=-Jdet*gauss->weight*viscosity*dw[1]*dbasis[2][i];
    2655                         pe->values[i*NDOF4+2]+=-Jdet*gauss->weight*viscosity*(dw[0]*dbasis[0][i]+dw[1]*dbasis[1][i]+2*dw[2]*dbasis[2][i]);
    2656                         pe->values[i*NDOF4+3]+=Jdet*gauss->weight*stokesreconditioning*dw[2]*basis[i];
    2657                 }
    2658         }
    2659 
    2660         /*Clean up and return*/
    2661         delete gauss;
    2662         return pe;
    2663 }
    2664 /*}}}*/
    2665 /*FUNCTION Penta::CreatePVectorCouplingPattynStokesFriction{{{1*/
    2666 ElementVector* Penta::CreatePVectorCouplingPattynStokesFriction(void){
    2667 
    2668         /*Constants*/
    2669         const int numdof=NUMVERTICES*NDOF4;
    2670 
    2671         /*Intermediaries*/
    2672         int         i,j,ig;
    2673         int         approximation,analysis_type;
    2674         double      Jdet,Jdet2d;
    2675         double      stokesreconditioning;
    2676         double     bed_normal[3];
    2677         double      epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
    2678         double      viscosity, w, alpha2_gauss;
    2679         double      dw[3];
    2680         double     xyz_list_tria[NUMVERTICES2D][3];
    2681         double      xyz_list[NUMVERTICES][3];
    2682         double      basis[6]; //for the six nodes of the penta
    2683         Tria*       tria=NULL;
    2684         Friction*   friction=NULL;
    2685         GaussPenta  *gauss=NULL;
    2686 
    2687         /*Initialize Element vector and return if necessary*/
    2688         if(!IsOnBed() || IsOnShelf()) return NULL;
    2689         inputs->GetParameterValue(&approximation,ApproximationEnum);
    2690         if(approximation!=PattynStokesApproximationEnum) return NULL;
    2691         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,StokesApproximationEnum);
    2692 
    2693         /*Retrieve all inputs and parameters*/
    2694         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    2695         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    2696         this->parameters->FindParam(&stokesreconditioning,DiagnosticStokesreconditioningEnum);
    2697         Input* vx_input=inputs->GetInput(VxEnum);               _assert_(vx_input);
    2698         Input* vy_input=inputs->GetInput(VyEnum);               _assert_(vy_input);
    2699         Input* vz_input=inputs->GetInput(VzEnum);               _assert_(vz_input);
    2700         Input* vzpattyn_input=inputs->GetInput(VzPattynEnum);   _assert_(vzpattyn_input);
    2701 
    2702         for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
    2703 
    2704         /*build friction object, used later on: */
    2705         friction=new Friction("3d",inputs,matpar,analysis_type);
    2706 
    2707         /* Start looping on the number of gauss 2d (nodes on the bedrock) */
    2708         gauss=new GaussPenta(0,1,2,2);
    2709         for(ig=gauss->begin();ig<gauss->end();ig++){
    2710 
    2711                 gauss->GaussPoint(ig);
    2712 
    2713                 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
    2714                 GetNodalFunctionsP1(basis, gauss);
    2715 
    2716                 vzpattyn_input->GetParameterValue(&w, gauss);
    2717                 vzpattyn_input->GetParameterDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
    2718 
    2719                 BedNormal(&bed_normal[0],xyz_list_tria);
    2720                 this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
    2721                 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
    2722                 friction->GetAlpha2(&alpha2_gauss, gauss,VxEnum,VyEnum,VzEnum);
    2723 
    2724                 for(i=0;i<NUMVERTICES2D;i++){
    2725                         pe->values[i*NDOF4+0]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[0]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[0])*basis[i];
    2726                         pe->values[i*NDOF4+1]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[1]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[1])*basis[i];
    2727                         pe->values[i*NDOF4+2]+=Jdet2d*gauss->weight*2*viscosity*(dw[0]*bed_normal[0]+dw[1]*bed_normal[1]+dw[2]*bed_normal[2])*basis[i];
    2728                 }
    2729         }
    2730 
    2731         /*Clean up and return*/
    2732         delete gauss;
    2733         delete friction;
    2734         return pe;
    2735 }
    2736 /*}}}*/
    2737 /*FUNCTION Penta::CreatePVectorDiagnosticHoriz{{{1*/
    2738 ElementVector* Penta::CreatePVectorDiagnosticHoriz(void){
    2739 
    2740         int approximation;
    2741         inputs->GetParameterValue(&approximation,ApproximationEnum);
    2742 
    2743         switch(approximation){
    2744                 case MacAyealApproximationEnum:
    2745                         return CreatePVectorDiagnosticMacAyeal();
    2746                 case PattynApproximationEnum:
    2747                         return CreatePVectorDiagnosticPattyn();
    2748                 case HutterApproximationEnum:
    2749                         return NULL;
    2750                 case NoneApproximationEnum:
    2751                         return NULL;
    2752                 case StokesApproximationEnum:
    2753                         return CreatePVectorDiagnosticStokes();
    2754                 case MacAyealPattynApproximationEnum:
    2755                         return CreatePVectorDiagnosticMacAyealPattyn();
    2756                 case MacAyealStokesApproximationEnum:
    2757                         return CreatePVectorDiagnosticMacAyealStokes();
    2758                 case PattynStokesApproximationEnum:
    2759                         return CreatePVectorDiagnosticPattynStokes();
    2760                 default:
    2761                         _error_("Approximation %s not supported yet",EnumToStringx(approximation));
    2762         }
    2763 }
    2764 /*}}}*/
    2765 /*FUNCTION Penta::CreatePVectorDiagnosticMacAyealPattyn{{{1*/
    2766 ElementVector* Penta::CreatePVectorDiagnosticMacAyealPattyn(void){
    2767 
    2768         /*compute all load vectors for this element*/
    2769         ElementVector* pe1=CreatePVectorDiagnosticMacAyeal();
    2770         ElementVector* pe2=CreatePVectorDiagnosticPattyn();
    2771         ElementVector* pe =new ElementVector(pe1,pe2);
    2772 
    2773         /*clean-up and return*/
    2774         delete pe1;
    2775         delete pe2;
    2776         return pe;
    2777 }
    2778 /*}}}*/
    2779 /*FUNCTION Penta::CreatePVectorDiagnosticMacAyealStokes{{{1*/
    2780 ElementVector* Penta::CreatePVectorDiagnosticMacAyealStokes(void){
    2781 
    2782         /*compute all load vectors for this element*/
    2783         ElementVector* pe1=CreatePVectorDiagnosticMacAyeal();
    2784         ElementVector* pe2=CreatePVectorDiagnosticStokes();
    2785         ElementVector* pe3=CreatePVectorCouplingMacAyealStokes();
    2786         ElementVector* pe =new ElementVector(pe1,pe2,pe3);
    2787 
    2788         /*clean-up and return*/
    2789         delete pe1;
    2790         delete pe2;
    2791         delete pe3;
    2792         return pe;
    2793 }
    2794 /*}}}*/
    2795 /*FUNCTION Penta::CreatePVectorDiagnosticPattynStokes{{{1*/
    2796 ElementVector* Penta::CreatePVectorDiagnosticPattynStokes(void){
    2797 
    2798         /*compute all load vectors for this element*/
    2799         ElementVector* pe1=CreatePVectorDiagnosticPattyn();
    2800         ElementVector* pe2=CreatePVectorDiagnosticStokes();
    2801         ElementVector* pe3=CreatePVectorCouplingPattynStokes();
    2802         ElementVector* pe =new ElementVector(pe1,pe2,pe3);
    2803 
    2804         /*clean-up and return*/
    2805         delete pe1;
    2806         delete pe2;
    2807         delete pe3;
    2808         return pe;
    2809 }
    2810 /*}}}*/
    2811 /*FUNCTION Penta::CreatePVectorDiagnosticHutter{{{1*/
    2812 ElementVector* Penta::CreatePVectorDiagnosticHutter(void){
    2813 
    2814         /*Constants*/
    2815         const int numdofs=NDOF2*NUMVERTICES;
    2816 
    2817         /*Intermediaries*/
    2818         int          i,j,k,ig;
    2819         int          node0,node1;
    2820         int          connectivity[2];
    2821         double       Jdet;
    2822         double       xyz_list[NUMVERTICES][3];
    2823         double       xyz_list_segment[2][3];
    2824         double       z_list[NUMVERTICES];
    2825         double       z_segment[2],slope[2];
    2826         double       slope2,constant_part;
    2827         double       rho_ice,gravity,n,B;
    2828         double       ub,vb,z_g,surface,thickness;
    2829         GaussPenta*  gauss=NULL;
    2830 
    2831         /*Initialize Element vector*/
    2832         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
    2833 
    2834         /*Retrieve all inputs and parameters*/
    2835         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    2836         rho_ice=matpar->GetRhoIce();
    2837         gravity=matpar->GetG();
    2838         n=matice->GetN();
    2839         B=matice->GetB();
    2840         Input* thickness_input=inputs->GetInput(ThicknessEnum);  _assert_(thickness_input);
    2841         Input* surface_input=inputs->GetInput(SurfaceEnum);      _assert_(surface_input);
    2842         Input* slopex_input=inputs->GetInput(SurfaceSlopeXEnum); _assert_(slopex_input);
    2843         Input* slopey_input=inputs->GetInput(SurfaceSlopeYEnum); _assert_(slopey_input);
    2844         for(i=0;i<NUMVERTICES;i++)z_list[i]=xyz_list[i][2];
    2845 
    2846         /*Loop on the three segments*/
    2847         for(i=0;i<3;i++){
    2848                 node0=i;
    2849                 node1=i+3;
    2850 
    2851                 for(j=0;j<3;j++){
    2852                         xyz_list_segment[0][j]=xyz_list[node0][j];
    2853                         xyz_list_segment[1][j]=xyz_list[node1][j];
    2854                 }
    2855 
    2856                 connectivity[0]=nodes[node0]->GetConnectivity();
    2857                 connectivity[1]=nodes[node1]->GetConnectivity();
    2858 
    2859                 /*Loop on the Gauss points: */
    2860                 gauss=new GaussPenta(node0,node1,3);
    2861                 for(ig=gauss->begin();ig<gauss->end();ig++){
    2862                         gauss->GaussPoint(ig);
    2863 
    2864                         slopex_input->GetParameterValue(&slope[0],gauss);
    2865                         slopey_input->GetParameterValue(&slope[1],gauss);
    2866                         surface_input->GetParameterValue(&surface,gauss);
    2867                         thickness_input->GetParameterValue(&thickness,gauss);
    2868 
    2869                         slope2=pow(slope[0],2)+pow(slope[1],2);
    2870                         constant_part=-2*pow(rho_ice*gravity,n)*pow(slope2,((n-1)/2));
    2871 
    2872                         PentaRef::GetParameterValue(&z_g,&z_list[0],gauss);
    2873                         GetSegmentJacobianDeterminant(&Jdet,&xyz_list_segment[0][0],gauss);
    2874 
    2875                         if (IsOnSurface()){
    2876                                 for(j=0;j<NDOF2;j++) pe->values[2*node1+j]+=constant_part*pow((surface-z_g)/B,n)*slope[j]*Jdet*gauss->weight/(double)connectivity[1];
    2877                         }
    2878                         else{//connectivity is too large, should take only half on it
    2879                                 for(j=0;j<NDOF2;j++) pe->values[2*node1+j]+=constant_part*pow((surface-z_g)/B,n)*slope[j]*Jdet*gauss->weight*2/(double)connectivity[1];
    2880                         }
    2881                 }
    2882                 delete gauss;
    2883 
    2884                 //Deal with lower surface
    2885                 if (IsOnBed()){
    2886                         constant_part=-1.58*pow((double)10.0,-(double)10.0)*rho_ice*gravity*thickness;
    2887                         ub=constant_part*slope[0];
    2888                         vb=constant_part*slope[1];
    2889 
    2890                         pe->values[2*node0]+=ub/(double)connectivity[0];
    2891                         pe->values[2*node0+1]+=vb/(double)connectivity[0];
    2892                 }
    2893         }
    2894 
    2895         /*Clean up and return*/
    2896         return pe;
    2897 }
    2898 /*}}}*/
    2899 /*FUNCTION Penta::CreatePVectorDiagnosticMacAyeal{{{1*/
    2900 ElementVector* Penta::CreatePVectorDiagnosticMacAyeal(void){
    2901 
    2902         if (!IsOnBed()) return NULL;
    2903 
    2904         /*Call Tria function*/
    2905         Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
    2906         ElementVector* pe=tria->CreatePVectorDiagnosticMacAyeal();
    2907         delete tria->matice; delete tria;
    2908 
    2909         /*Clean up and return*/
    2910         return pe;
    2911 }
    2912 /*}}}*/
    2913 /*FUNCTION Penta::CreatePVectorDiagnosticPattyn{{{1*/
    2914 ElementVector* Penta::CreatePVectorDiagnosticPattyn(void){
    2915 
    2916         /*Constants*/
    2917         const int    numdof=NDOF2*NUMVERTICES;
    2918 
    2919         /*Intermediaries*/
    2920         int         i,j,ig;
    2921         double      Jdet;
    2922         double      slope[3]; //do not put 2! this goes into GetParameterDerivativeValue, which addresses slope[3] also!
    2923         double      driving_stress_baseline,thickness;
    2924         double      xyz_list[NUMVERTICES][3];
    2925         double      basis[6];
    2926         GaussPenta  *gauss=NULL;
    2927 
    2928         /*Initialize Element vector*/
    2929         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,PattynApproximationEnum);
    2930 
    2931         /*Retrieve all inputs and parameters*/
    2932         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    2933         Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
    2934         Input* surface_input=inputs->GetInput(SurfaceEnum);     _assert_(surface_input);
    2935 
    2936         /* Start  looping on the number of gaussian points: */
    2937         gauss=new GaussPenta(2,3);
    2938         for (ig=gauss->begin();ig<gauss->end();ig++){
    2939 
    2940                 gauss->GaussPoint(ig);
    2941 
    2942                 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
    2943                 GetNodalFunctionsP1(basis, gauss);
    2944 
    2945                 thickness_input->GetParameterValue(&thickness, gauss);
    2946                 surface_input->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],gauss);
    2947 
    2948                 driving_stress_baseline=matpar->GetRhoIce()*matpar->GetG();
    2949 
    2950                 for(i=0;i<NUMVERTICES;i++) for(j=0;j<NDOF2;j++) pe->values[i*NDOF2+j]+= -driving_stress_baseline*slope[j]*Jdet*gauss->weight*basis[i];
    2951         }
    2952 
    2953         /*Clean up and return*/
    2954         delete gauss;
    2955         return pe;
    2956 }
    2957 /*}}}*/
    2958 /*FUNCTION Penta::CreatePVectorDiagnosticStokes {{{1*/
    2959 ElementVector* Penta::CreatePVectorDiagnosticStokes(void){
    2960 
    2961         /*compute all load vectors for this element*/
    2962         ElementVector* pe1=CreatePVectorDiagnosticStokesViscous();
    2963         ElementVector* pe2=CreatePVectorDiagnosticStokesShelf();
    2964         ElementVector* pe =new ElementVector(pe1,pe2);
    2965 
    2966         /*clean-up and return*/
    2967         delete pe1;
    2968         delete pe2;
    2969         return pe;
    2970 }
    2971 /*}}}*/
    2972 /*FUNCTION Penta::CreatePVectorDiagnosticStokesViscous {{{1*/
    2973 ElementVector* Penta::CreatePVectorDiagnosticStokesViscous(void){
    2974 
    2975         /*Constants*/
    2976         const int numdofbubble=NDOF4*NUMVERTICES+NDOF3*1;
    2977 
    2978         /*Intermediaries*/
    2979         int        i,j,ig;
    2980         int        approximation;
    2981         double     Jdet,viscosity;
    2982         double     gravity,rho_ice,stokesreconditioning;
    2983         double     xyz_list[NUMVERTICES][3];
    2984         double     epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
    2985         double     l1l7[7]; //for the six nodes and the bubble
    2986         double     B[8][numdofbubble];
    2987         double     B_prime[8][numdofbubble];
    2988         double     B_prime_bubble[8][3];
    2989         double     D[8][8]={0.0};
    2990         double     D_scalar;
    2991         double     Pe_gaussian[numdofbubble]={0.0}; //for the six nodes and the bubble
    2992         double     Ke_temp[numdofbubble][3]={0.0}; //for the six nodes and the bubble
    2993         double     Ke_gaussian[numdofbubble][3];
    2994         GaussPenta *gauss=NULL;
    2995 
    2996         /*Initialize Element vector and return if necessary*/
    2997         inputs->GetParameterValue(&approximation,ApproximationEnum);
    2998         if(approximation!=StokesApproximationEnum && approximation!=MacAyealStokesApproximationEnum && approximation!=PattynStokesApproximationEnum) return NULL;
    2999         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,StokesApproximationEnum);
    3000 
    3001         /*Retrieve all inputs and parameters*/
    3002         this->parameters->FindParam(&stokesreconditioning,DiagnosticStokesreconditioningEnum);
    3003         rho_ice=matpar->GetRhoIce();
    3004         gravity=matpar->GetG();
    3005         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    3006         Input* vx_input=inputs->GetInput(VxEnum);   _assert_(vx_input);
    3007         Input* vy_input=inputs->GetInput(VyEnum);   _assert_(vy_input);
    3008         Input* vz_input=inputs->GetInput(VzEnum);   _assert_(vz_input);
    3009 
    3010         /* Start  looping on the number of gaussian points: */
    3011         gauss=new GaussPenta(5,5);
    3012         for (ig=gauss->begin();ig<gauss->end();ig++){
    3013 
    3014                 gauss->GaussPoint(ig);
    3015 
    3016                 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
    3017                 GetBStokes(&B[0][0],&xyz_list[0][0],gauss);
    3018                 GetBprimeStokes(&B_prime[0][0],&xyz_list[0][0], gauss);
    3019                 GetNodalFunctionsMINI(&l1l7[0], gauss);
    3020 
    3021                 this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
    3022                 matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
    3023 
    3024                 for(i=0;i<NUMVERTICES+1;i++){
    3025                         Pe_gaussian[i*NDOF4+2]+=-rho_ice*gravity*Jdet*gauss->weight*l1l7[i];
    3026                 }
    3027 
    3028                 /*Get bubble part of Bprime */
    3029                 for(i=0;i<8;i++) for(j=0;j<3;j++) B_prime_bubble[i][j]=B_prime[i][j+24];
    3030 
    3031                 D_scalar=gauss->weight*Jdet;
    3032                 for (i=0;i<6;i++) D[i][i]=D_scalar*2*viscosity;
    3033                 for (i=6;i<8;i++) D[i][i]=-D_scalar*stokesreconditioning;
    3034 
    3035                 TripleMultiply(&B[0][0],8,numdofbubble,1,
    3036                                         &D[0][0],8,8,0,
    3037                                         &B_prime_bubble[0][0],8,3,0,
    3038                                         &Ke_gaussian[0][0],0);
    3039 
    3040                 for(i=0;i<numdofbubble;i++) for(j=0;j<NDOF3;j++) Ke_temp[i][j]+=Ke_gaussian[i][j];
    3041         }
    3042 
    3043         /*Condensation*/
    3044         ReduceVectorStokes(pe->values, &Ke_temp[0][0], &Pe_gaussian[0]);
    3045 
    3046         /*Clean up and return*/
    3047         delete gauss;
    3048         return pe;
    3049 }
    3050 /*}}}*/
    3051 /*FUNCTION Penta::CreatePVectorDiagnosticStokesShelf{{{1*/
    3052 ElementVector* Penta::CreatePVectorDiagnosticStokesShelf(void){
    3053 
    3054         /*Intermediaries*/
    3055         int         i,j,ig;
    3056         int         approximation,shelf_dampening;
    3057         double      gravity,rho_water,bed,water_pressure;
    3058         double      damper,normal_vel,vx,vy,vz,dt;
    3059         double          xyz_list_tria[NUMVERTICES2D][3];
    3060         double      xyz_list[NUMVERTICES][3];
    3061         double          bed_normal[3];
    3062         double      dz[3];
    3063         double      basis[6]; //for the six nodes of the penta
    3064         double      Jdet2d;
    3065         GaussPenta  *gauss=NULL;
    3066 
    3067         /*Initialize Element vector and return if necessary*/
    3068         if(!IsOnBed() || !IsOnShelf()) return NULL;
    3069         inputs->GetParameterValue(&approximation,ApproximationEnum);
    3070         this->parameters->FindParam(&shelf_dampening,DiagnosticShelfDampeningEnum);
    3071         if(approximation!=StokesApproximationEnum && approximation!=MacAyealStokesApproximationEnum && approximation!=PattynStokesApproximationEnum) return NULL;
    3072         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,StokesApproximationEnum);
    3073 
    3074         /*Retrieve all inputs and parameters*/
    3075         rho_water=matpar->GetRhoWater();
    3076         gravity=matpar->GetG();
    3077         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    3078         Input* bed_input=inputs->GetInput(BedEnum); _assert_(bed_input);
    3079         Input* vx_input=inputs->GetInput(VxEnum);   _assert_(vx_input);
    3080         Input* vy_input=inputs->GetInput(VyEnum);   _assert_(vy_input);
    3081         Input* vz_input=inputs->GetInput(VzEnum);   _assert_(vz_input);
    3082 
    3083         for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
    3084 
    3085         /* Start looping on the number of gauss 2d (nodes on the bedrock) */
    3086         gauss=new GaussPenta(0,1,2,2);
    3087         for(ig=gauss->begin();ig<gauss->end();ig++){
    3088 
    3089                 gauss->GaussPoint(ig);
    3090 
    3091                 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
    3092                 GetNodalFunctionsP1(basis, gauss);
    3093 
    3094                 BedNormal(&bed_normal[0],xyz_list_tria);
    3095                 bed_input->GetParameterValue(&bed, gauss);
    3096                 if(shelf_dampening){ //add dampening to avoid too high vertical velocities when not in hydrostatic equilibrium
    3097                         bed_input->GetParameterDerivativeValue(&dz[0],&xyz_list[0][0],gauss);
    3098                         vx_input->GetParameterValue(&vx, gauss);
    3099                         vy_input->GetParameterValue(&vy, gauss);
    3100                         vz_input->GetParameterValue(&vz, gauss);
    3101                         dt=0;
    3102                         normal_vel=bed_normal[0]*vx+bed_normal[1]*vy+bed_normal[2]*vz;
    3103                         damper=gravity*rho_water*pow(1+pow(dz[0],2)+pow(dz[1],2),0.5)*normal_vel*dt;
    3104                 }
    3105                 else damper=0;
    3106                 water_pressure=gravity*rho_water*bed;
    3107 
    3108                 for(i=0;i<NUMVERTICES;i++) for(j=0;j<3;j++) pe->values[i*NDOF4+j]+=(water_pressure+damper)*gauss->weight*Jdet2d*basis[i]*bed_normal[j];
    3109         }
    3110 
    3111         /*Clean up and return*/
    3112         delete gauss;
    3113         return pe;
    3114 }
    3115 /*}}}*/
    3116 /*FUNCTION Penta::CreatePVectorAdjointStokes{{{1*/
    3117 ElementVector* Penta::CreatePVectorAdjointStokes(void){
    3118 
    3119         if (!IsOnSurface()) return NULL;
    3120 
    3121         /*Call Tria function*/
    3122         Tria* tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
    3123         ElementVector* pe=tria->CreatePVectorAdjointStokes();
    3124         delete tria->matice; delete tria;
    3125 
    3126         /*clean up and return*/
    3127         return pe;
    3128 }
    3129 /*}}}*/
    3130 /*FUNCTION Penta::CreatePVectorDiagnosticVert {{{1*/
    3131 ElementVector* Penta::CreatePVectorDiagnosticVert(void){
    3132 
    3133         /*compute all load vectors for this element*/
    3134         ElementVector* pe1=CreatePVectorDiagnosticVertVolume();
    3135         ElementVector* pe2=CreatePVectorDiagnosticVertBase();
    3136         ElementVector* pe =new ElementVector(pe1,pe2);
    3137 
    3138         /*clean-up and return*/
    3139         delete pe1;
    3140         delete pe2;
    3141         return pe;
    3142 }
    3143 /*}}}*/
    3144 /*FUNCTION Penta::CreatePVectorDiagnosticVertVolume {{{1*/
    3145 ElementVector* Penta::CreatePVectorDiagnosticVertVolume(void){
    3146 
    3147         /*Constants*/
    3148         const int  numdof=NDOF1*NUMVERTICES;
    3149 
    3150         /*Intermediaries*/
    3151         int        i,ig;
    3152         int        approximation;
    3153         double     Jdet;
    3154         double     xyz_list[NUMVERTICES][3];
    3155         double     dudx,dvdy,dwdz;
    3156         double     du[3],dv[3],dw[3];
    3157         double     basis[6];
    3158         GaussPenta *gauss=NULL;
    3159 
    3160         /*Initialize Element vector*/
    3161         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
    3162 
    3163         /*Retrieve all inputs and parameters*/
    3164         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    3165         inputs->GetParameterValue(&approximation,ApproximationEnum);
    3166         Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
    3167         Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
    3168         Input* vzstokes_input=NULL;
    3169         if(approximation==PattynStokesApproximationEnum || approximation==MacAyealStokesApproximationEnum){
    3170                 vzstokes_input=inputs->GetInput(VzStokesEnum); _assert_(vzstokes_input);
    3171         }
    3172 
    3173         /* Start  looping on the number of gaussian points: */
    3174         gauss=new GaussPenta(2,2);
    3175         for (ig=gauss->begin();ig<gauss->end();ig++){
    3176 
    3177                 gauss->GaussPoint(ig);
    3178 
    3179                 GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
    3180                 GetNodalFunctionsP1(basis, gauss);
    3181 
    3182                 vx_input->GetParameterDerivativeValue(&du[0],&xyz_list[0][0],gauss);
    3183                 vy_input->GetParameterDerivativeValue(&dv[0],&xyz_list[0][0],gauss);
    3184                 if(approximation==PattynStokesApproximationEnum || approximation==MacAyealStokesApproximationEnum){
    3185                         vzstokes_input->GetParameterDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
    3186                         dwdz=dw[2];
    3187                 }
    3188                 else dwdz=0;
    3189                 dudx=du[0];
    3190                 dvdy=dv[1];
    3191 
    3192                 for (i=0;i<numdof;i++) pe->values[i] += (dudx+dvdy+dwdz)*Jdet*gauss->weight*basis[i];
    3193         }
    3194 
    3195         /*Clean up and return*/
    3196         delete gauss;
    3197         return pe;
    3198 }
    3199 /*}}}*/
    3200 /*FUNCTION Penta::CreatePVectorDiagnosticVertBase {{{1*/
    3201 ElementVector* Penta::CreatePVectorDiagnosticVertBase(void){
    3202 
    3203 
    3204         /*Constants*/
    3205         const int    numdof=NDOF1*NUMVERTICES;
    3206 
    3207         /*Intermediaries */
    3208         int        i,j,ig;
    3209         int        approximation;
    3210         double     xyz_list[NUMVERTICES][3];
    3211         double     xyz_list_tria[NUMVERTICES2D][3];
    3212         double     Jdet2d;
    3213         double     vx,vy,vz,dbdx,dbdy,basalmeltingvalue;
    3214         double     slope[3];
    3215         double     basis[NUMVERTICES];
    3216         GaussPenta* gauss=NULL;
    3217 
    3218         if (!IsOnBed()) return NULL;
    3219 
    3220         /*Initialize Element vector*/
    3221         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
    3222 
    3223         /*Retrieve all inputs and parameters*/
    3224         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    3225         for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
    3226         inputs->GetParameterValue(&approximation,ApproximationEnum);
    3227         Input* bed_input=inputs->GetInput(BedEnum);                                _assert_(bed_input);
    3228         Input* basal_melting_input=inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(basal_melting_input);
    3229         Input* vx_input=inputs->GetInput(VxEnum);                                  _assert_(vx_input);
    3230         Input* vy_input=inputs->GetInput(VyEnum);                                  _assert_(vy_input);
    3231         Input* vzstokes_input=NULL;
    3232         if(approximation==PattynStokesApproximationEnum || approximation==MacAyealStokesApproximationEnum){
    3233                 vzstokes_input=inputs->GetInput(VzStokesEnum);       _assert_(vzstokes_input);
    3234         }
    3235 
    3236         /* Start  looping on the number of gaussian points: */
    3237         gauss=new GaussPenta(0,1,2,2);
    3238         for(ig=gauss->begin();ig<gauss->end();ig++){
    3239 
    3240                 gauss->GaussPoint(ig);
    3241 
    3242                 basal_melting_input->GetParameterValue(&basalmeltingvalue, gauss);
    3243                 bed_input->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],gauss);
    3244                 vx_input->GetParameterValue(&vx, gauss);
    3245                 vy_input->GetParameterValue(&vy, gauss);
    3246                 if(approximation==PattynStokesApproximationEnum || approximation==MacAyealStokesApproximationEnum){
    3247                         vzstokes_input->GetParameterValue(&vz, gauss);
    3248                 }
    3249                 else vz=0;
    3250 
    3251                 dbdx=slope[0];
    3252                 dbdy=slope[1];
    3253 
    3254                 GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0],gauss);
    3255                 GetNodalFunctionsP1(&basis[0], gauss);
    3256 
    3257                 for(i=0;i<numdof;i++) pe->values[i]+=-Jdet2d*gauss->weight*(vx*dbdx+vy*dbdy-vz-basalmeltingvalue)*basis[i];
    3258         }
    3259 
    3260         /*Clean up and return*/
    3261         delete gauss;
    3262         return pe;
    3263 }
    3264 /*}}}*/
    32652264/*FUNCTION Penta::CreatePVectorEnthalpy {{{1*/
    32662265ElementVector* Penta::CreatePVectorEnthalpy(void){
     
    34942493}
    34952494/*}}}*/
    3496 /*FUNCTION Penta::CreatePVectorPrognostic {{{1*/
    3497 ElementVector* Penta::CreatePVectorPrognostic(void){
    3498 
    3499         if (!IsOnBed()) return NULL;
    3500 
    3501         /*Depth Averaging Vx and Vy*/
    3502         this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);
    3503         this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);
    3504 
    3505         /*Call Tria function*/
    3506         Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
    3507         ElementVector* pe=tria->CreatePVectorPrognostic();
    3508         delete tria->matice; delete tria;
    3509 
    3510         /*Delete Vx and Vy averaged*/
    3511         this->inputs->DeleteInput(VxAverageEnum);
    3512         this->inputs->DeleteInput(VyAverageEnum);
    3513 
    3514         /*Clean up and return*/
    3515         return pe;
    3516 }
    3517 /*}}}*/
    3518 /*FUNCTION Penta::CreatePVectorSlope {{{1*/
    3519 ElementVector* Penta::CreatePVectorSlope(void){
    3520 
    3521         if (!IsOnBed()) return NULL;
    3522 
    3523         /*Call Tria function*/
    3524         Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
    3525         ElementVector* pe=tria->CreatePVectorSlope();
    3526         delete tria->matice; delete tria;
    3527 
    3528         /*clean up and return*/
    3529         return pe;
    3530 }
    3531 /*}}}*/
    35322495/*FUNCTION Penta::CreatePVectorThermal {{{1*/
    35332496ElementVector* Penta::CreatePVectorThermal(void){
     
    37562719}
    37572720/*}}}*/
    3758 /*FUNCTION Penta::DeepEcho{{{1*/
    3759 void Penta::DeepEcho(void){
    3760 
    3761         int i;
    3762        
    3763         printf("Penta:\n");
    3764         printf("   id: %i\n",id);
    3765         nodes[0]->DeepEcho();
    3766         nodes[1]->DeepEcho();
    3767         nodes[2]->DeepEcho();
    3768         nodes[3]->DeepEcho();
    3769         nodes[4]->DeepEcho();
    3770         nodes[5]->DeepEcho();
    3771         matice->DeepEcho();
    3772         matpar->DeepEcho();
    3773         printf("   neighbor ids: %i-%i\n",verticalneighbors[0]->Id(),verticalneighbors[1]->Id());
    3774         printf("   parameters\n");
    3775         parameters->DeepEcho();
    3776         printf("   inputs\n");
    3777         inputs->DeepEcho();
    3778         printf("   results\n");
    3779         results->DeepEcho();
    3780         printf("neighboor sids: \n");
    3781         printf(" %i %i %i\n",horizontalneighborsids[0],horizontalneighborsids[1],horizontalneighborsids[2]);
    3782 
    3783         return;
    3784 }
    3785 /*}}}*/
    3786 /*FUNCTION Penta::DeleteResults {{{1*/
    3787 void  Penta::DeleteResults(void){
    3788 
    3789         /*Delete and reinitialize results*/
    3790         delete this->results;
    3791         this->results=new Results();
    3792 
    3793 }
    3794 /*}}}*/
    3795 /*FUNCTION Penta::DragCoefficientAbsGradient{{{1*/
    3796 double Penta::DragCoefficientAbsGradient(bool process_units,int weight_index){
    3797 
    3798         double J;
    3799         Tria*  tria=NULL;
    3800 
    3801         /*If on water, on shelf or not on bed, skip: */
    3802         if(IsOnWater()|| IsOnShelf() || !IsOnBed()) return 0;
    3803 
    3804         tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria
    3805         J=tria->DragCoefficientAbsGradient(process_units,weight_index);
    3806         delete tria->matice; delete tria;
    3807         return J;
    3808 }
    3809 /*}}}*/
    3810 /*FUNCTION Penta::Echo{{{1*/
    3811 
    3812 void Penta::Echo(void){
    3813         this->DeepEcho();
    3814 }
    3815 /*}}}*/
    3816 /*FUNCTION Penta::Enum {{{1*/
    3817 int Penta::Enum(void){
    3818 
    3819         return PentaEnum;
    3820 
    3821 }
    3822 /*}}}*/
    3823 /*FUNCTION Penta::GetBasalElement{{{1*/
    3824 Penta* Penta::GetBasalElement(void){
    3825 
    3826         /*Output*/
    3827         Penta* penta=NULL;
    3828 
    3829         /*Go through all elements till the bed is reached*/
    3830         penta=this;
    3831         for(;;){
    3832                 /*Stop if we have reached the surface, else, take lower penta*/
    3833                 if (penta->IsOnBed()) break;
    3834 
    3835                 /* get lower Penta*/
    3836                 penta=penta->GetLowerElement();
    3837                 _assert_(penta->Id()!=this->id);
    3838         }
    3839 
    3840         /*return output*/
    3841         return penta;
    3842 }
    3843 /*}}}*/
    3844 /*FUNCTION Penta::GetDofList {{{1*/
    3845 void  Penta::GetDofList(int** pdoflist,int approximation_enum,int setenum){
    3846 
    3847         int  i,j,count=0;
    3848         int  numberofdofs=0;
    3849         int* doflist=NULL;
    3850 
    3851         /*First, figure out size of doflist: */
    3852         for(i=0;i<6;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
    3853 
    3854         /*Allocate: */
    3855         doflist=(int*)xmalloc(numberofdofs*sizeof(int));
    3856 
    3857         /*Populate: */
    3858         count=0;
    3859         for(i=0;i<6;i++){
    3860                 nodes[i]->GetDofList(doflist+count,approximation_enum,setenum);
    3861                 count+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
    3862         }
    3863 
    3864         /*Assign output pointers:*/
    3865         *pdoflist=doflist;
    3866 }
    3867 /*}}}*/
    3868 /*FUNCTION Penta::GetDofList1 {{{1*/
    3869 void  Penta::GetDofList1(int* doflist){
    3870 
    3871         int i;
    3872         for(i=0;i<6;i++) doflist[i]=nodes[i]->GetDofList1();
    3873 
    3874 }
    3875 /*}}}*/
    3876 /*FUNCTION Penta::GetElementType {{{1*/
    3877 int Penta::GetElementType(){
    3878 
    3879         /*return PentaRef field*/
    3880         return this->element_type;
    3881 }
    3882 /*}}}*/
    3883 /*FUNCTION Penta::GetHorizontalNeighboorSids {{{1*/
    3884 int* Penta::GetHorizontalNeighboorSids(){
    3885 
    3886         /*return PentaRef field*/
    3887         return &this->horizontalneighborsids[0];
    3888 
    3889 }
    3890 /*}}}*/
    3891 /*FUNCTION Penta::GetLowerElement{{{1*/
    3892 Penta* Penta::GetLowerElement(void){
    3893 
    3894         Penta* upper_penta=NULL;
    3895 
    3896         upper_penta=(Penta*)verticalneighbors[0]; //first one (0) under, second one (1) above
    3897 
    3898         return upper_penta;
    3899 }
    3900 /*}}}*/
    3901 /*FUNCTION Penta::GetNodeIndex {{{1*/
    3902 int Penta::GetNodeIndex(Node* node){
    3903 
    3904         _assert_(nodes);
    3905         for(int i=0;i<NUMVERTICES;i++){
    3906                 if(node==nodes[i])
    3907                  return i;
    3908         }
    3909         _error_("Node provided not found among element nodes");
    3910 
    3911 }
    3912 /*}}}*/
    3913 /*FUNCTION Penta::GetParameterListOnVertices(double* pvalue,int enumtype) {{{1*/
    3914 void Penta::GetParameterListOnVertices(double* pvalue,int enumtype){
    3915 
    3916         /*Intermediaries*/
    3917         double     value[NUMVERTICES];
    3918         GaussPenta *gauss              = NULL;
    3919 
    3920         /*Recover input*/
    3921         Input* input=inputs->GetInput(enumtype);
    3922         if (!input) _error_("Input %s not found in element",EnumToStringx(enumtype));
    3923 
    3924         /*Checks in debugging mode*/
    3925         _assert_(pvalue);
    3926 
    3927         /* Start looping on the number of vertices: */
    3928         gauss=new GaussPenta();
    3929         for (int iv=0;iv<NUMVERTICES;iv++){
    3930                 gauss->GaussVertex(iv);
    3931                 input->GetParameterValue(&pvalue[iv],gauss);
    3932         }
    3933 
    3934         /*clean-up*/
    3935         delete gauss;
    3936 }
    3937 /*}}}*/
    3938 /*FUNCTION Penta::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue) {{{1*/
    3939 void Penta::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue){
    3940 
    3941         /*Intermediaries*/
    3942         double     value[NUMVERTICES];
    3943         GaussPenta *gauss              = NULL;
    3944 
    3945         /*Recover input*/
    3946         Input* input=inputs->GetInput(enumtype);
    3947 
    3948         /*Checks in debugging mode*/
    3949         _assert_(pvalue);
    3950 
    3951         /* Start looping on the number of vertices: */
    3952         if (input){
    3953                 gauss=new GaussPenta();
    3954                 for (int iv=0;iv<NUMVERTICES;iv++){
    3955                         gauss->GaussVertex(iv);
    3956                         input->GetParameterValue(&pvalue[iv],gauss);
    3957                 }
    3958         }
    3959         else{
    3960                 for (int iv=0;iv<NUMVERTICES;iv++) pvalue[iv]=defaultvalue;
    3961         }
    3962 
    3963         /*clean-up*/
    3964         delete gauss;
    3965 }
    3966 /*}}}*/
    3967 /*FUNCTION Penta::GetParameterValue(double* pvalue,Node* node,int enumtype) {{{1*/
    3968 void Penta::GetParameterValue(double* pvalue,Node* node,int enumtype){
    3969 
    3970         Input* input=inputs->GetInput(enumtype);
    3971         if(!input) _error_("No input of type %s found in tria",EnumToStringx(enumtype));
    3972 
    3973         GaussPenta* gauss=new GaussPenta();
    3974         gauss->GaussVertex(this->GetNodeIndex(node));
    3975 
    3976         input->GetParameterValue(pvalue,gauss);
    3977         delete gauss;
    3978 }
    3979 /*}}}*/
    3980 /*FUNCTION Penta::GetPhi {{{1*/
    3981 void Penta::GetPhi(double* phi, double*  epsilon, double viscosity){
    3982         /*Compute deformational heating from epsilon and viscosity */
    3983 
    3984         double epsilon_matrix[3][3];
    3985         double epsilon_eff;
    3986         double epsilon_sqr[3][3];
    3987 
    3988         /* Build epsilon matrix */
    3989         epsilon_matrix[0][0]=*(epsilon+0);
    3990         epsilon_matrix[1][0]=*(epsilon+3);
    3991         epsilon_matrix[2][0]=*(epsilon+4);
    3992         epsilon_matrix[0][1]=*(epsilon+3);
    3993         epsilon_matrix[1][1]=*(epsilon+1);
    3994         epsilon_matrix[2][1]=*(epsilon+5);
    3995         epsilon_matrix[0][2]=*(epsilon+4);
    3996         epsilon_matrix[1][2]=*(epsilon+5);
    3997         epsilon_matrix[2][2]=*(epsilon+2);
    3998 
    3999         /* Effective value of epsilon_matrix */
    4000         epsilon_sqr[0][0]=pow(epsilon_matrix[0][0],2);
    4001         epsilon_sqr[1][0]=pow(epsilon_matrix[1][0],2);
    4002         epsilon_sqr[2][0]=pow(epsilon_matrix[2][0],2);
    4003         epsilon_sqr[0][1]=pow(epsilon_matrix[0][1],2);
    4004         epsilon_sqr[1][1]=pow(epsilon_matrix[1][1],2);
    4005         epsilon_sqr[2][1]=pow(epsilon_matrix[2][1],2);
    4006         epsilon_sqr[0][2]=pow(epsilon_matrix[0][2],2);
    4007         epsilon_sqr[1][2]=pow(epsilon_matrix[1][2],2);
    4008         epsilon_sqr[2][2]=pow(epsilon_matrix[2][2],2);
    4009         epsilon_eff=1/pow(2,0.5)*pow((epsilon_sqr[0][0]+epsilon_sqr[0][1]+ epsilon_sqr[0][2]+ epsilon_sqr[1][0]+ epsilon_sqr[1][1]+ epsilon_sqr[1][2]+ epsilon_sqr[2][0]+ epsilon_sqr[2][1]+ epsilon_sqr[2][2]),0.5);
    4010 
    4011         /*Phi = Tr(sigma * eps)
    4012          *    = Tr(sigma'* eps)
    4013          *    = 2 * eps_eff * sigma'_eff
    4014          *    = 4 * mu * eps_eff ^2*/
    4015         *phi=4*pow(epsilon_eff,2.0)*viscosity;
    4016 }
    4017 /*}}}*/
    4018 /*FUNCTION Penta::GetSidList{{{1*/
    4019 void  Penta::GetSidList(int* sidlist){
    4020 
    4021         int i;
    4022         for(i=0;i<NUMVERTICES;i++) sidlist[i]=nodes[i]->GetSidList();
    4023 
    4024 }
    4025 /*}}}*/
    4026 /*FUNCTION Penta::GetSolutionFromInputs{{{1*/
    4027 void  Penta::GetSolutionFromInputs(Vec solution){
    4028 
    4029         int analysis_type;
    4030 
    4031         /*retrive parameters: */
    4032         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    4033 
    4034         /*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */
    4035         if (analysis_type==DiagnosticHorizAnalysisEnum){
    4036                 int approximation;
    4037                 inputs->GetParameterValue(&approximation,ApproximationEnum);
    4038                 if(approximation==StokesApproximationEnum || approximation==NoneApproximationEnum){
    4039                         GetSolutionFromInputsDiagnosticStokes(solution);
    4040                 }
    4041                 else if (approximation==MacAyealApproximationEnum || approximation==PattynApproximationEnum || approximation==HutterApproximationEnum){
    4042                         GetSolutionFromInputsDiagnosticHoriz(solution);
    4043                 }
    4044                 else if (approximation==MacAyealPattynApproximationEnum || approximation==PattynStokesApproximationEnum || approximation==MacAyealStokesApproximationEnum){
    4045                         return; //the elements around will create the solution
    4046                 }
    4047         }
    4048         else if(analysis_type==DiagnosticHutterAnalysisEnum){
    4049                 GetSolutionFromInputsDiagnosticHutter(solution);
    4050         }
    4051         else if(analysis_type==DiagnosticVertAnalysisEnum){
    4052                 GetSolutionFromInputsDiagnosticVert(solution);
    4053         }
    4054         else if(analysis_type==ThermalAnalysisEnum){
    4055                 GetSolutionFromInputsThermal(solution);
    4056         }
    4057         else if(analysis_type==EnthalpyAnalysisEnum){
    4058                 GetSolutionFromInputsEnthalpy(solution);
    4059         }
    4060         else{
    4061                 _error_("analysis: %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type));
    4062         }
    4063 }
    4064 /*}}}*/
    4065 /*FUNCTION Penta::GetSolutionFromInputsDiagnosticHoriz{{{1*/
    4066 void  Penta::GetSolutionFromInputsDiagnosticHoriz(Vec solution){
    4067 
    4068         const int    numdof=NDOF2*NUMVERTICES;
    4069 
    4070         int          i;
    4071         int          approximation;
    4072         int*         doflist=NULL;
    4073         double       vx,vy;
    4074         double       values[numdof];
    4075         GaussPenta*  gauss;
    4076 
    4077         /*Get approximation enum and dof list: */
    4078         inputs->GetParameterValue(&approximation,ApproximationEnum);
    4079         Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
    4080         Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
    4081 
    4082         /*If the element is a coupling, do nothing: every node is also on an other elements
    4083          * (as coupling is between MacAyeal and Pattyn) so the other element will take care of it*/
    4084         GetDofList(&doflist,approximation,GsetEnum);
    4085 
    4086         /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
    4087         /*P1 element only for now*/
    4088         gauss=new GaussPenta();
    4089         for(i=0;i<NUMVERTICES;i++){
    4090 
    4091                 /*Recover vx and vy*/
    4092                 gauss->GaussVertex(i);
    4093                 vx_input->GetParameterValue(&vx,gauss);
    4094                 vy_input->GetParameterValue(&vy,gauss);
    4095                 values[i*NDOF2+0]=vx;
    4096                 values[i*NDOF2+1]=vy;
    4097         }
    4098 
    4099         /*Add value to global vector*/
    4100         VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
    4101 
    4102         /*Free ressources:*/
    4103         delete gauss;
    4104         xfree((void**)&doflist);
    4105 }
    4106 /*}}}*/
    4107 /*FUNCTION Penta::GetSolutionFromInputsDiagnosticHutter{{{1*/
    4108 void  Penta::GetSolutionFromInputsDiagnosticHutter(Vec solution){
    4109 
    4110         const int    numdof=NDOF2*NUMVERTICES;
    4111 
    4112         int          i;
    4113         int*         doflist=NULL;
    4114         double       vx,vy;
    4115         double       values[numdof];
    4116         GaussPenta*  gauss=NULL;
    4117 
    4118         /*Get dof list: */
    4119         GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
    4120         Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
    4121         Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
    4122 
    4123         /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
    4124         /*P1 element only for now*/
    4125         gauss=new GaussPenta();
    4126         for(i=0;i<NUMVERTICES;i++){
    4127                 /*Recover vx and vy*/
    4128                 gauss->GaussVertex(i);
    4129                 vx_input->GetParameterValue(&vx,gauss);
    4130                 vy_input->GetParameterValue(&vy,gauss);
    4131                 values[i*NDOF2+0]=vx;
    4132                 values[i*NDOF2+1]=vy;
    4133         }
    4134 
    4135         /*Add value to global vector*/
    4136         VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
    4137 
    4138         /*Free ressources:*/
    4139         delete gauss;
    4140         xfree((void**)&doflist);
    4141 }
    4142 /*}}}*/
    4143 /*FUNCTION Penta::GetSolutionFromInputsDiagnosticVert{{{1*/
    4144 void  Penta::GetSolutionFromInputsDiagnosticVert(Vec solution){
    4145 
    4146         const int    numdof=NDOF1*NUMVERTICES;
    4147 
    4148         int          i;
    4149         int*         doflist=NULL;
    4150         double       vz;
    4151         double       values[numdof];
    4152         GaussPenta*  gauss=NULL;
    4153 
    4154         /*Get dof list: */
    4155         GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
    4156         Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);
    4157 
    4158         /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
    4159         /*P1 element only for now*/
    4160         gauss=new GaussPenta();
    4161         for(i=0;i<NUMVERTICES;i++){
    4162                 /*Recover vz */
    4163                 gauss->GaussVertex(i);
    4164                 vz_input->GetParameterValue(&vz,gauss);
    4165                 values[i]=vz;
    4166         }
    4167 
    4168         /*Add value to global vector*/
    4169         VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
    4170 
    4171         /*Free ressources:*/
    4172         delete gauss;
    4173         xfree((void**)&doflist);
    4174 }
    4175 /*}}}*/
    4176 /*FUNCTION Penta::GetSolutionFromInputsDiagnosticStokes{{{1*/
    4177 void  Penta::GetSolutionFromInputsDiagnosticStokes(Vec solution){
    4178 
    4179         const int    numdof=NDOF4*NUMVERTICES;
    4180 
    4181         int          i;
    4182         int*         doflist=NULL;
    4183         double       vx,vy,vz,p;
    4184         double       stokesreconditioning;
    4185         double       values[numdof];
    4186         GaussPenta   *gauss;
    4187 
    4188         /*Get dof list: */
    4189         GetDofList(&doflist,StokesApproximationEnum,GsetEnum);
    4190         Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
    4191         Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
    4192         Input* vz_input=inputs->GetInput(VzEnum);       _assert_(vz_input);
    4193         Input* p_input =inputs->GetInput(PressureEnum); _assert_(p_input);
    4194 
    4195         /*Recondition pressure: */
    4196         this->parameters->FindParam(&stokesreconditioning,DiagnosticStokesreconditioningEnum);
    4197 
    4198         /*Ok, we have vx vy vz and P in values, fill in vx vy vz P arrays: */
    4199         /*P1 element only for now*/
    4200         gauss=new GaussPenta();
    4201         for(i=0;i<NUMVERTICES;i++){
    4202                 gauss->GaussVertex(i);
    4203                 vx_input->GetParameterValue(&vx,gauss);
    4204                 vy_input->GetParameterValue(&vy,gauss);
    4205                 vz_input->GetParameterValue(&vz,gauss);
    4206                 p_input ->GetParameterValue(&p ,gauss);
    4207                 values[i*NDOF4+0]=vx;
    4208                 values[i*NDOF4+1]=vy;
    4209                 values[i*NDOF4+2]=vz;
    4210                 values[i*NDOF4+3]=p/stokesreconditioning;
    4211         }
    4212 
    4213         /*Add value to global vector*/
    4214         VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
    4215 
    4216         /*Free ressources:*/
    4217         delete gauss;
    4218         xfree((void**)&doflist);
    4219 }
    4220 /*}}}*/
    42212721/*FUNCTION Penta::GetSolutionFromInputsThermal{{{1*/
    42222722void  Penta::GetSolutionFromInputsThermal(Vec solution){
     
    42812781}
    42822782/*}}}*/
    4283 /*FUNCTION Penta::GetStabilizationParameter {{{1*/
    4284 double Penta::GetStabilizationParameter(double u, double v, double w, double diameter, double rho_ice, double heatcapacity, double thermalconductivity){
    4285         /*Compute stabilization parameter*/
    4286 
    4287         double normu;
    4288         double tau_parameter;
    4289 
    4290         normu=pow(pow(u,2)+pow(v,2)+pow(w,2),0.5);
    4291         if(normu*diameter/(3*2*thermalconductivity/(rho_ice*heatcapacity))<1){
    4292                 tau_parameter=pow(diameter,2)/(3*2*2*thermalconductivity/(rho_ice*heatcapacity));
    4293         }
    4294         else tau_parameter=diameter/(2*normu);
    4295 
    4296         return tau_parameter;
    4297 }
    4298 /*}}}*/
    4299 /*FUNCTION Penta::GetStrainRate3dPattyn{{{1*/
    4300 void Penta::GetStrainRate3dPattyn(double* epsilon,double* xyz_list, GaussPenta* gauss, Input* vx_input, Input* vy_input){
    4301         /*Compute the 3d Blatter/PattynStrain Rate (5 components):
    4302          *
    4303          * epsilon=[exx eyy exy exz eyz]
    4304          *
    4305          * with exz=1/2 du/dz
    4306          *      eyz=1/2 dv/dz
    4307          *
    4308          * the contribution of vz is neglected
    4309          */
    4310 
    4311         int i;
    4312         double epsilonvx[5];
    4313         double epsilonvy[5];
    4314 
    4315         /*Check that both inputs have been found*/
    4316         if (!vx_input || !vy_input){
    4317                 _error_("Input missing. Here are the input pointers we have for vx: %p, vy: %p\n",vx_input,vy_input);
    4318         }
    4319 
    4320         /*Get strain rate assuming that epsilon has been allocated*/
    4321         vx_input->GetVxStrainRate3dPattyn(epsilonvx,xyz_list,gauss);
    4322         vy_input->GetVyStrainRate3dPattyn(epsilonvy,xyz_list,gauss);
    4323 
    4324         /*Sum all contributions*/
    4325         for(i=0;i<5;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i];
    4326 }
    4327 /*}}}*/
    4328 /*FUNCTION Penta::GetStrainRate3d{{{1*/
    4329 void Penta::GetStrainRate3d(double* epsilon,double* xyz_list, GaussPenta* gauss, Input* vx_input, Input* vy_input, Input* vz_input){
    4330         /*Compute the 3d Strain Rate (6 components):
    4331          *
    4332          * epsilon=[exx eyy ezz exy exz eyz]
    4333          */
    4334 
    4335         int i;
    4336         double epsilonvx[6];
    4337         double epsilonvy[6];
    4338         double epsilonvz[6];
    4339 
    4340         /*Check that both inputs have been found*/
    4341         if (!vx_input || !vy_input || !vz_input){
    4342                 _error_("Input missing. Here are the input pointers we have for vx: %p, vy: %p, vz: %p\n",vx_input,vy_input,vz_input);
    4343         }
    4344 
    4345         /*Get strain rate assuming that epsilon has been allocated*/
    4346         vx_input->GetVxStrainRate3d(epsilonvx,xyz_list,gauss);
    4347         vy_input->GetVyStrainRate3d(epsilonvy,xyz_list,gauss);
    4348         vz_input->GetVzStrainRate3d(epsilonvz,xyz_list,gauss);
    4349 
    4350         /*Sum all contributions*/
    4351         for(i=0;i<6;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i]+epsilonvz[i];
    4352 }
    4353 /*}}}*/
    4354 /*FUNCTION Penta::GetUpperElement{{{1*/
    4355 Penta* Penta::GetUpperElement(void){
    4356 
    4357         Penta* upper_penta=NULL;
    4358 
    4359         upper_penta=(Penta*)verticalneighbors[1]; //first one under, second one above
    4360 
    4361         return upper_penta;
    4362 }
    4363 /*}}}*/
    4364 /*FUNCTION Penta::GetVectorFromInputs{{{1*/
    4365 void  Penta::GetVectorFromInputs(Vec vector,int input_enum){
     2783/*FUNCTION Penta::InputUpdateFromSolutionThermal {{{1*/
     2784void  Penta::InputUpdateFromSolutionThermal(double* solution){
     2785
     2786        const int    numdof=NDOF1*NUMVERTICES;
     2787
     2788        bool   converged;
     2789        int    i,rheology_law;
     2790        double xyz_list[NUMVERTICES][3];
     2791        double values[numdof];
     2792        double B[numdof];
     2793        double B_average,s_average;
     2794        int*   doflist=NULL;
     2795
     2796        /*Get dof list: */
     2797        GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
     2798
     2799        /*Use the dof list to index into the solution vector: */
     2800        for(i=0;i<numdof;i++){
     2801                values[i]=solution[doflist[i]];
     2802
     2803                /*Check solution*/
     2804                if(isnan(values[i])) _error_("NaN found in solution vector");
     2805                //if(values[i]<0)      printf("temperature < 0°K found in solution vector\n");
     2806                //if(values[i]>275)    printf("temperature > 275°K found in solution vector (Paterson's rheology associated is negative)\n");
     2807        }
     2808
     2809        /*Get all inputs and parameters*/
     2810        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2811        Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);
     2812
     2813        this->inputs->GetParameterValue(&converged,ConvergedEnum);
     2814        if(converged){
     2815                this->inputs->AddInput(new PentaVertexInput(TemperatureEnum,values));
     2816
     2817                /*Update Rheology only if converged (we must make sure that the temperature is below melting point
     2818                 * otherwise the rheology could be negative*/
     2819                this->parameters->FindParam(&rheology_law,MaterialsRheologyLawEnum);
     2820                switch(rheology_law){
     2821                        case NoneEnum:
     2822                                /*Do nothing: B is not temperature dependent*/
     2823                                break;
     2824                        case PatersonEnum:
     2825                                B_average=Paterson((values[0]+values[1]+values[2]+values[3]+values[4]+values[5])/6.0);
     2826                                for(i=0;i<numdof;i++) B[i]=B_average;
     2827                                this->matice->inputs->AddInput(new PentaVertexInput(MaterialsRheologyBEnum,B));
     2828                                break;
     2829                        case ArrheniusEnum:
     2830                                surface_input->GetParameterAverage(&s_average);
     2831                                B_average=Arrhenius((values[0]+values[1]+values[2]+values[3]+values[4]+values[5])/6.0,
     2832                                                        s_average-((xyz_list[0][2]+xyz_list[1][2]+xyz_list[2][2]+xyz_list[3][2]+xyz_list[4][2]+xyz_list[5][2])/6.0),
     2833                                                        matice->GetN());
     2834                                for(i=0;i<numdof;i++) B[i]=B_average;
     2835                                this->matice->inputs->AddInput(new PentaVertexInput(MaterialsRheologyBEnum,B));
     2836                                break;
     2837                        default:
     2838                                _error_("Rheology law %s not supported yet",EnumToStringx(rheology_law));
     2839
     2840                }
     2841        }
     2842        else{
     2843                this->inputs->AddInput(new PentaVertexInput(TemperaturePicardEnum,values));
     2844        }
     2845
     2846        /*Free ressources:*/
     2847        xfree((void**)&doflist);
     2848}
     2849/*}}}*/
     2850/*FUNCTION Penta::InputUpdateFromSolutionEnthalpy {{{1*/
     2851void  Penta::InputUpdateFromSolutionEnthalpy(double* solution){
     2852
     2853        const int    numdof=NDOF1*NUMVERTICES;
     2854
     2855        bool   converged;
     2856        int    i,rheology_law;
     2857        double xyz_list[NUMVERTICES][3];
     2858        double values[numdof];
     2859        double pressure[NUMVERTICES];
     2860        double temperatures[numdof];
     2861        double waterfraction[numdof];
     2862        double B[numdof];
     2863        double B_average,s_average;
     2864        int*   doflist=NULL;
     2865
     2866        /*Get dof list: */
     2867        GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
     2868
     2869        /*Use the dof list to index into the solution vector: */
     2870        for(i=0;i<numdof;i++){
     2871                values[i]=solution[doflist[i]];
     2872
     2873                /*Check solution*/
     2874                if(isnan(values[i])) _error_("NaN found in solution vector");
     2875        }
     2876
     2877        /*Get all inputs and parameters*/
     2878        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2879        GetParameterListOnVertices(&pressure[0],PressureEnum);
     2880        Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);
     2881       
     2882
     2883//      this->inputs->GetParameterValue(&converged,ConvergedEnum);
     2884//      if(converged){
     2885                /*Convert enthalpy into temperature and water fraction*/
     2886                for(i=0;i<numdof;i++) matpar->EnthalpyToThermal(&temperatures[i],&waterfraction[i],values[i],pressure[i]);
     2887                       
     2888                this->inputs->AddInput(new PentaVertexInput(EnthalpyEnum,values));
     2889                this->inputs->AddInput(new PentaVertexInput(WaterfractionEnum,waterfraction));
     2890                this->inputs->AddInput(new PentaVertexInput(TemperatureEnum,temperatures));
     2891
     2892                /*Update Rheology only if converged (we must make sure that the temperature is below melting point
     2893                 * otherwise the rheology could be negative*/
     2894                this->parameters->FindParam(&rheology_law,MaterialsRheologyLawEnum);
     2895                switch(rheology_law){
     2896                        case NoneEnum:
     2897                                /*Do nothing: B is not temperature dependent*/
     2898                                break;
     2899                        case PatersonEnum:
     2900                                B_average=Paterson((temperatures[0]+temperatures[1]+temperatures[2]+temperatures[3]+temperatures[4]+temperatures[5])/6.0);
     2901                                for(i=0;i<numdof;i++) B[i]=B_average;
     2902                                this->matice->inputs->AddInput(new PentaVertexInput(MaterialsRheologyBEnum,B));
     2903                                break;
     2904                        case ArrheniusEnum:
     2905                                surface_input->GetParameterAverage(&s_average);
     2906                                B_average=Arrhenius((temperatures[0]+temperatures[1]+temperatures[2]+temperatures[3]+temperatures[4]+temperatures[5])/6.0,
     2907                                                        s_average-((xyz_list[0][2]+xyz_list[1][2]+xyz_list[2][2]+xyz_list[3][2]+xyz_list[4][2]+xyz_list[5][2])/6.0),
     2908                                                        matice->GetN());
     2909                                for(i=0;i<numdof;i++) B[i]=B_average;
     2910                                this->matice->inputs->AddInput(new PentaVertexInput(MaterialsRheologyBEnum,B));
     2911                                break;
     2912                        default:
     2913                                _error_("Rheology law %s not supported yet",EnumToStringx(rheology_law));
     2914
     2915                }
     2916//      }
     2917//      else{
     2918//              this->inputs->AddInput(new PentaVertexInput(EnthalpyPicardEnum,values));
     2919//      }
     2920
     2921        /*Free ressources:*/
     2922        xfree((void**)&doflist);
     2923}
     2924/*}}}*/
     2925#endif
     2926
     2927#ifdef _HAVE_CONTROL_
     2928/*FUNCTION Penta::ControlInputGetGradient{{{1*/
     2929void Penta::ControlInputGetGradient(Vec gradient,int enum_type){
    43662930
    43672931        int doflist1[NUMVERTICES];
    4368 
    4369         /*Get out if this is not an element input*/
    4370         if (!IsInput(input_enum)) return;
    4371 
    4372         /*Prepare index list*/
     2932        Input* input=NULL;
     2933
     2934        if(enum_type==MaterialsRheologyBbarEnum){
     2935                if(!IsOnBed()) return;
     2936                input=(Input*)matice->inputs->GetInput(MaterialsRheologyBEnum);
     2937        }
     2938        else{
     2939                input=inputs->GetInput(enum_type);
     2940        }
     2941        if (!input) _error_("Input %s not found",EnumToStringx(enum_type));
     2942        if (input->Enum()!=ControlInputEnum) _error_("Input %s is not a ControlInput",EnumToStringx(enum_type));
     2943
    43732944        this->GetDofList1(&doflist1[0]);
    4374 
    4375         /*Get input (either in element or material)*/
    4376         Input* input=inputs->GetInput(input_enum);
    4377         if(!input) _error_("Input %s not found in element",EnumToStringx(input_enum));
    4378 
    4379         /*We found the enum.  Use its values to fill into the vector, using the vertices ids: */
    4380         input->GetVectorFromInputs(vector,&doflist1[0]);
    4381 }
    4382 /*}}}*/
    4383 /*FUNCTION Penta::GetZcoord {{{1*/
    4384 double Penta::GetZcoord(GaussPenta* gauss){
    4385 
    4386         int    i;
    4387         double z;
    4388         double xyz_list[NUMVERTICES][3];
    4389         double z_list[NUMVERTICES];
    4390 
    4391         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    4392         for(i=0;i<NUMVERTICES;i++) z_list[i]=xyz_list[i][2];
    4393         PentaRef::GetParameterValue(&z,z_list,gauss);
    4394 
    4395         return z;
     2945        ((ControlInput*)input)->GetGradient(gradient,&doflist1[0]);
     2946
     2947}/*}}}*/
     2948/*FUNCTION Penta::ControlInputScaleGradient{{{1*/
     2949void Penta::ControlInputScaleGradient(int enum_type,double scale){
     2950
     2951        Input* input=NULL;
     2952
     2953        if(enum_type==MaterialsRheologyBbarEnum){
     2954                input=(Input*)matice->inputs->GetInput(MaterialsRheologyBEnum);
     2955        }
     2956        else{
     2957                input=inputs->GetInput(enum_type);
     2958        }
     2959        if (!input) _error_("Input %s not found",EnumToStringx(enum_type));
     2960        if (input->Enum()!=ControlInputEnum) _error_("Input %s is not a ControlInput",EnumToStringx(enum_type));
     2961
     2962        ((ControlInput*)input)->ScaleGradient(scale);
     2963}/*}}}*/
     2964/*FUNCTION Penta::ControlInputSetGradient{{{1*/
     2965void Penta::ControlInputSetGradient(double* gradient,int enum_type){
     2966
     2967        int    doflist1[NUMVERTICES];
     2968        double grad_list[NUMVERTICES];
     2969        Input* grad_input=NULL;
     2970        Input* input=NULL;
     2971
     2972        if(enum_type==MaterialsRheologyBbarEnum){
     2973                input=(Input*)matice->inputs->GetInput(MaterialsRheologyBEnum);
     2974        }
     2975        else{
     2976                input=inputs->GetInput(enum_type);
     2977        }
     2978        if (!input) _error_("Input %s not found",EnumToStringx(enum_type));
     2979        if (input->Enum()!=ControlInputEnum) _error_("Input %s is not a ControlInput",EnumToStringx(enum_type));
     2980
     2981        this->GetDofList1(&doflist1[0]);
     2982        for(int i=0;i<NUMVERTICES;i++) grad_list[i]=gradient[doflist1[i]];
     2983        grad_input=new PentaVertexInput(GradientEnum,grad_list);
     2984        ((ControlInput*)input)->SetGradient(grad_input);
     2985
     2986}/*}}}*/
     2987/*FUNCTION Penta::CreatePVectorAdjointHoriz{{{1*/
     2988ElementVector* Penta::CreatePVectorAdjointHoriz(void){
     2989
     2990        int approximation;
     2991        inputs->GetParameterValue(&approximation,ApproximationEnum);
     2992
     2993        switch(approximation){
     2994                case MacAyealApproximationEnum:
     2995                        return CreatePVectorAdjointMacAyeal();
     2996                case PattynApproximationEnum:
     2997                        return CreatePVectorAdjointPattyn();
     2998                case NoneApproximationEnum:
     2999                        return NULL;
     3000                case StokesApproximationEnum:
     3001                        return CreatePVectorAdjointStokes();
     3002                default:
     3003                        _error_("Approximation %s not supported yet",EnumToStringx(approximation));
     3004        }
     3005}
     3006/*}}}*/
     3007/*FUNCTION Penta::CreatePVectorAdjointMacAyeal{{{1*/
     3008ElementVector* Penta::CreatePVectorAdjointMacAyeal(){
     3009
     3010        if (!IsOnBed()) return NULL;
     3011
     3012        /*Call Tria function*/
     3013        Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
     3014        ElementVector* pe=tria->CreatePVectorAdjointHoriz();
     3015        delete tria->matice; delete tria;
     3016
     3017        /*clean up and return*/
     3018        return pe;
     3019}
     3020/*}}}*/
     3021/*FUNCTION Penta::CreatePVectorAdjointPattyn{{{1*/
     3022ElementVector* Penta::CreatePVectorAdjointPattyn(void){
     3023
     3024        if (!IsOnSurface()) return NULL;
     3025
     3026        /*Call Tria function*/
     3027        Tria* tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
     3028        ElementVector* pe=tria->CreatePVectorAdjointHoriz();
     3029        delete tria->matice; delete tria;
     3030
     3031        /*clean up and return*/
     3032        return pe;
     3033}
     3034/*}}}*/
     3035/*FUNCTION Penta::CreatePVectorAdjointStokes{{{1*/
     3036ElementVector* Penta::CreatePVectorAdjointStokes(void){
     3037
     3038        if (!IsOnSurface()) return NULL;
     3039
     3040        /*Call Tria function*/
     3041        Tria* tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
     3042        ElementVector* pe=tria->CreatePVectorAdjointStokes();
     3043        delete tria->matice; delete tria;
     3044
     3045        /*clean up and return*/
     3046        return pe;
    43963047}
    43973048/*}}}*/
     
    47143365        this->matice->inputs->DeleteInput(MaterialsRheologyBbarEnum);
    47153366} /*}}}*/
     3367/*FUNCTION Penta::InputControlUpdate{{{1*/
     3368void  Penta::InputControlUpdate(double scalar,bool save_parameter){
     3369
     3370        /*Intermediary*/
     3371        int    num_controls;
     3372        int*   control_type=NULL;
     3373        Input* input=NULL;
     3374
     3375        /*retrieve some parameters: */
     3376        this->parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
     3377        this->parameters->FindParam(&control_type,NULL,InversionControlParametersEnum);
     3378
     3379        for(int i=0;i<num_controls;i++){
     3380
     3381                if(control_type[i]==MaterialsRheologyBbarEnum){
     3382                        if (!IsOnBed()) goto cleanup_and_return;
     3383                        input=(Input*)matice->inputs->GetInput(MaterialsRheologyBEnum); _assert_(input);
     3384                }
     3385                else{
     3386                        input=(Input*)this->inputs->GetInput(control_type[i]); _assert_(input);
     3387                }
     3388
     3389                if (input->Enum()!=ControlInputEnum) _error_("input %s is not a ControlInput",EnumToStringx(control_type[i]));
     3390
     3391                ((ControlInput*)input)->UpdateValue(scalar);
     3392                ((ControlInput*)input)->Constrain();
     3393                if (save_parameter) ((ControlInput*)input)->SaveValue();
     3394
     3395                if(control_type[i]==MaterialsRheologyBbarEnum){
     3396                        this->InputExtrude(MaterialsRheologyBEnum,MaterialsEnum);
     3397                }
     3398        }
     3399
     3400        /*Clean up and return*/
     3401cleanup_and_return:
     3402        xfree((void**)&control_type);
     3403}
     3404/*}}}*/
     3405/*FUNCTION Penta::InputUpdateFromSolutionAdjointStokes {{{1*/
     3406void  Penta::InputUpdateFromSolutionAdjointStokes(double* solution){
     3407
     3408        const int    numdof=NDOF4*NUMVERTICES;
     3409
     3410        int    i;
     3411        double values[numdof];
     3412        double lambdax[NUMVERTICES];
     3413        double lambday[NUMVERTICES];
     3414        double lambdaz[NUMVERTICES];
     3415        double lambdap[NUMVERTICES];
     3416        int*   doflist=NULL;
     3417
     3418        /*Get dof list: */
     3419        GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
     3420
     3421        /*Use the dof list to index into the solution vector: */
     3422        for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
     3423
     3424        /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
     3425        for(i=0;i<NUMVERTICES;i++){
     3426                lambdax[i]=values[i*NDOF4+0];
     3427                lambday[i]=values[i*NDOF4+1];
     3428                lambdaz[i]=values[i*NDOF4+2];
     3429                lambdap[i]=values[i*NDOF4+3];
     3430
     3431                /*Check solution*/
     3432                if(isnan(lambdax[i])) _error_("NaN found in solution vector");
     3433                if(isnan(lambday[i])) _error_("NaN found in solution vector");
     3434                if(isnan(lambdaz[i])) _error_("NaN found in solution vector");
     3435                if(isnan(lambdap[i])) _error_("NaN found in solution vector");
     3436        }
     3437
     3438        /*Add vx and vy as inputs to the tria element: */
     3439        this->inputs->AddInput(new PentaVertexInput(AdjointxEnum,lambdax));
     3440        this->inputs->AddInput(new PentaVertexInput(AdjointyEnum,lambday));
     3441        this->inputs->AddInput(new PentaVertexInput(AdjointzEnum,lambdaz));
     3442        this->inputs->AddInput(new PentaVertexInput(AdjointpEnum,lambdap));
     3443
     3444        /*Free ressources:*/
     3445        xfree((void**)&doflist);
     3446}
     3447/*}}}*/
     3448/*FUNCTION Penta::InputUpdateFromSolutionAdjointHoriz {{{1*/
     3449void  Penta::InputUpdateFromSolutionAdjointHoriz(double* solution){
     3450
     3451        const int numdof=NDOF2*NUMVERTICES;
     3452
     3453        int    i;
     3454        double values[numdof];
     3455        double lambdax[NUMVERTICES];
     3456        double lambday[NUMVERTICES];
     3457        int*   doflist=NULL;
     3458
     3459        /*Get dof list: */
     3460        GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
     3461
     3462        /*Use the dof list to index into the solution vector: */
     3463        for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
     3464
     3465        /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
     3466        for(i=0;i<NUMVERTICES;i++){
     3467                lambdax[i]=values[i*NDOF2+0];
     3468                lambday[i]=values[i*NDOF2+1];
     3469
     3470                /*Check solution*/
     3471                if(isnan(lambdax[i]))       _error_("NaN found in solution vector");
     3472                if(isnan(lambday[i]))       _error_("NaN found in solution vector");
     3473        }
     3474
     3475        /*Add vx and vy as inputs to the tria element: */
     3476        this->inputs->AddInput(new PentaVertexInput(AdjointxEnum,lambdax));
     3477        this->inputs->AddInput(new PentaVertexInput(AdjointyEnum,lambday));
     3478
     3479        /*Free ressources:*/
     3480        xfree((void**)&doflist);
     3481}
     3482/*}}}*/
     3483/*FUNCTION Penta::SurfaceAverageVelMisfit {{{1*/
     3484double Penta::SurfaceAverageVelMisfit(bool process_units,int weight_index){
     3485
     3486        int    approximation;
     3487        double J;
     3488        Tria*  tria=NULL;
     3489
     3490        /*retrieve inputs :*/
     3491        inputs->GetParameterValue(&approximation,ApproximationEnum);
     3492
     3493        /*If on water, return 0: */
     3494        if(IsOnWater())return 0;
     3495
     3496        /*Bail out if this element if:
     3497         * -> Non MacAyeal and not on the surface
     3498         * -> MacAyeal (2d model) and not on bed) */
     3499        if ((approximation!=MacAyealApproximationEnum && !IsOnSurface()) || (approximation==MacAyealApproximationEnum && !IsOnBed())){
     3500                return 0;
     3501        }
     3502        else if (approximation==MacAyealApproximationEnum){
     3503
     3504                /*This element should be collapsed into a tria element at its base. Create this tria element,
     3505                 * and compute SurfaceAverageVelMisfit*/
     3506                tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria (lower face).
     3507                J=tria->SurfaceAverageVelMisfit(process_units,weight_index);
     3508                delete tria->matice; delete tria;
     3509                return J;
     3510        }
     3511        else{
     3512
     3513                tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
     3514                J=tria->SurfaceAverageVelMisfit(process_units,weight_index);
     3515                delete tria->matice; delete tria;
     3516                return J;
     3517        }
     3518}
     3519/*}}}*/
     3520/*FUNCTION Penta::SurfaceAbsVelMisfit {{{1*/
     3521double Penta::SurfaceAbsVelMisfit(bool process_units,int weight_index){
     3522
     3523        int    approximation;
     3524        double J;
     3525        Tria*  tria=NULL;
     3526
     3527        /*retrieve inputs :*/
     3528        inputs->GetParameterValue(&approximation,ApproximationEnum);
     3529
     3530        /*If on water, return 0: */
     3531        if(IsOnWater())return 0;
     3532
     3533        /*Bail out if this element if:
     3534         * -> Non MacAyeal and not on the surface
     3535         * -> MacAyeal (2d model) and not on bed) */
     3536        if ((approximation!=MacAyealApproximationEnum && !IsOnSurface()) || (approximation==MacAyealApproximationEnum && !IsOnBed())){
     3537                return 0;
     3538        }
     3539        else if (approximation==MacAyealApproximationEnum){
     3540
     3541                /*This element should be collapsed into a tria element at its base. Create this tria element,
     3542                 * and compute SurfaceAbsVelMisfit*/
     3543                tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria (lower face).
     3544                J=tria->SurfaceAbsVelMisfit(process_units,weight_index);
     3545                delete tria->matice; delete tria;
     3546                return J;
     3547        }
     3548        else{
     3549
     3550                tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
     3551                J=tria->SurfaceAbsVelMisfit(process_units,weight_index);
     3552                delete tria->matice; delete tria;
     3553                return J;
     3554        }
     3555}
     3556/*}}}*/
     3557/*FUNCTION Penta::SurfaceLogVelMisfit {{{1*/
     3558double Penta::SurfaceLogVelMisfit(bool process_units,int weight_index){
     3559
     3560        int    approximation;
     3561        double J;
     3562        Tria*  tria=NULL;
     3563
     3564        /*retrieve inputs :*/
     3565        inputs->GetParameterValue(&approximation,ApproximationEnum);
     3566
     3567        /*If on water, return 0: */
     3568        if(IsOnWater())return 0;
     3569
     3570        /*Bail out if this element if:
     3571         * -> Non MacAyeal and not on the surface
     3572         * -> MacAyeal (2d model) and not on bed) */
     3573        if ((approximation!=MacAyealApproximationEnum && !IsOnSurface()) || (approximation==MacAyealApproximationEnum && !IsOnBed())){
     3574                return 0;
     3575        }
     3576        else if (approximation==MacAyealApproximationEnum){
     3577
     3578                /*This element should be collapsed into a tria element at its base. Create this tria element,
     3579                 * and compute SurfaceLogVelMisfit*/
     3580                tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria (lower face).
     3581                J=tria->SurfaceLogVelMisfit(process_units,weight_index);
     3582                delete tria->matice; delete tria;
     3583                return J;
     3584        }
     3585        else{
     3586
     3587                tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
     3588                J=tria->SurfaceLogVelMisfit(process_units,weight_index);
     3589                delete tria->matice; delete tria;
     3590                return J;
     3591        }
     3592}
     3593/*}}}*/
     3594/*FUNCTION Penta::SurfaceLogVxVyMisfit {{{1*/
     3595double Penta::SurfaceLogVxVyMisfit(bool process_units,int weight_index){
     3596
     3597        double J;
     3598        Tria* tria=NULL;
     3599
     3600        /*inputs: */
     3601        int  approximation;
     3602
     3603        /*retrieve inputs :*/
     3604        inputs->GetParameterValue(&approximation,ApproximationEnum);
     3605
     3606        /*If on water, return 0: */
     3607        if(IsOnWater())return 0;
     3608
     3609        /*Bail out if this element if:
     3610         * -> Non MacAyeal and not on the surface
     3611         * -> MacAyeal (2d model) and not on bed) */
     3612        if ((approximation!=MacAyealApproximationEnum && !IsOnSurface()) || (approximation==MacAyealApproximationEnum && !IsOnBed())){
     3613                return 0;
     3614        }
     3615        else if (approximation==MacAyealApproximationEnum){
     3616
     3617                /*This element should be collapsed into a tria element at its base. Create this tria element,
     3618                 * and compute SurfaceLogVxVyMisfit*/
     3619                tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria (lower face).
     3620                J=tria->SurfaceLogVxVyMisfit(process_units,weight_index);
     3621                delete tria->matice; delete tria;
     3622                return J;
     3623        }
     3624        else{
     3625
     3626                tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
     3627                J=tria->SurfaceLogVxVyMisfit(process_units,weight_index);
     3628                delete tria->matice; delete tria;
     3629                return J;
     3630        }
     3631}
     3632/*}}}*/
     3633/*FUNCTION Penta::SurfaceRelVelMisfit {{{1*/
     3634double Penta::SurfaceRelVelMisfit(bool process_units,int weight_index){
     3635
     3636        int    approximation;
     3637        double J;
     3638        Tria*  tria=NULL;
     3639
     3640        /*retrieve inputs :*/
     3641        inputs->GetParameterValue(&approximation,ApproximationEnum);
     3642
     3643        /*If on water, return 0: */
     3644        if(IsOnWater())return 0;
     3645
     3646        /*Bail out if this element if:
     3647         * -> Non MacAyeal and not on the surface
     3648         * -> MacAyeal (2d model) and not on bed) */
     3649        if ((approximation!=MacAyealApproximationEnum && !IsOnSurface()) || (approximation==MacAyealApproximationEnum && !IsOnBed())){
     3650                return 0;
     3651        }
     3652        else if (approximation==MacAyealApproximationEnum){
     3653
     3654                /*This element should be collapsed into a tria element at its base. Create this tria element,
     3655                 * and compute SurfaceRelVelMisfit*/
     3656                tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria (lower face).
     3657                J=tria->SurfaceRelVelMisfit(process_units,weight_index);
     3658                delete tria->matice; delete tria;
     3659                return J;
     3660        }
     3661        else{
     3662
     3663                tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
     3664                J=tria->SurfaceRelVelMisfit(process_units,weight_index);
     3665                delete tria->matice; delete tria;
     3666                return J;
     3667        }
     3668}
     3669/*}}}*/
     3670/*FUNCTION Penta::ThicknessAbsGradient{{{1*/
     3671double Penta::ThicknessAbsGradient(bool process_units,int weight_index){
     3672
     3673        _error_("Not implemented yet");
     3674}
     3675/*}}}*/
     3676/*FUNCTION Penta::ThicknessAbsMisfit {{{1*/
     3677double Penta::ThicknessAbsMisfit(bool process_units,int weight_index){
     3678
     3679        int    approximation;
     3680        double J;
     3681        Tria*  tria=NULL;
     3682
     3683        /*retrieve inputs :*/
     3684        inputs->GetParameterValue(&approximation,ApproximationEnum);
     3685
     3686        /*If on water, return 0: */
     3687        if(IsOnWater())return 0;
     3688        _error_("Not implemented yet");
     3689
     3690        tria=(Tria*)SpawnTria(0,1,2);
     3691        J=tria->ThicknessAbsMisfit(process_units,weight_index);
     3692        delete tria->matice; delete tria;
     3693        return J;
     3694}
     3695/*}}}*/
     3696/*FUNCTION Penta::DragCoefficientAbsGradient{{{1*/
     3697double Penta::DragCoefficientAbsGradient(bool process_units,int weight_index){
     3698
     3699        double J;
     3700        Tria*  tria=NULL;
     3701
     3702        /*If on water, on shelf or not on bed, skip: */
     3703        if(IsOnWater()|| IsOnShelf() || !IsOnBed()) return 0;
     3704
     3705        tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria
     3706        J=tria->DragCoefficientAbsGradient(process_units,weight_index);
     3707        delete tria->matice; delete tria;
     3708        return J;
     3709}
     3710/*}}}*/
     3711/*FUNCTION Penta::RheologyBbarAbsGradient{{{1*/
     3712double Penta::RheologyBbarAbsGradient(bool process_units,int weight_index){
     3713
     3714        double J;
     3715        Tria*  tria=NULL;
     3716
     3717        /*If on water, on shelf or not on bed, skip: */
     3718        if(IsOnWater() || !IsOnBed()) return 0;
     3719
     3720        tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria
     3721        J=tria->RheologyBbarAbsGradient(process_units,weight_index);
     3722        delete tria->matice; delete tria;
     3723        return J;
     3724}
     3725/*}}}*/
     3726
     3727#endif
     3728
     3729
     3730#ifdef _HAVE_DAKOTA_
     3731/*FUNCTION Penta::InputUpdateFromVectorDakota(double* vector, int name, int type);{{{1*/
     3732void  Penta::InputUpdateFromVectorDakota(double* vector, int name, int type){
     3733       
     3734        int i,j;
     3735
     3736        /*Check that name is an element input*/
     3737        if (!IsInput(name)) return;
     3738
     3739        switch(type){
     3740
     3741                case VertexEnum:
     3742
     3743                        /*New PentaVertexInput*/
     3744                        double values[6];
     3745
     3746                        /*Get values on the 6 vertices*/
     3747                        for (i=0;i<6;i++){
     3748                                values[i]=vector[this->nodes[i]->GetSidList()]; //careful, vector of values here is not parallel distributed, but serial distributed (from a serial Dakota core!)
     3749                        }
     3750
     3751                        /*Branch on the specified type of update: */
     3752                        switch(name){
     3753                                case ThicknessEnum:
     3754                                        /*Update thickness + surface: assume bed is constant. On ice shelves, takes hydrostatic equilibrium {{{2*/
     3755                                        double  thickness[6];
     3756                                        double  thickness_init[6];
     3757                                        double  hydrostatic_ratio[6];
     3758                                        double  surface[6];
     3759                                        double  bed[6];
     3760                                       
     3761                                        /*retrieve inputs: */
     3762                                        GetParameterListOnVertices(&thickness_init[0],ThicknessEnum);
     3763                                        GetParameterListOnVertices(&hydrostatic_ratio[0],GeometryHydrostaticRatioEnum);
     3764                                        GetParameterListOnVertices(&bed[0],BedEnum);
     3765                                        GetParameterListOnVertices(&surface[0],SurfaceEnum);
     3766
     3767                                        /*build new thickness: */
     3768//                                      for(j=0;j<6;j++)thickness[j]=values[j];
     3769
     3770                                        /*build new bed and surface: */
     3771                                        if (this->IsOnShelf()){
     3772                                                /*hydrostatic equilibrium: */
     3773                                                double rho_ice,rho_water,di;
     3774                                                rho_ice=this->matpar->GetRhoIce();
     3775                                                rho_water=this->matpar->GetRhoWater();
     3776
     3777                                                di=rho_ice/rho_water;
     3778
     3779                                                /*build new thickness: */
     3780                                                for (j=0; j<6; j++) {
     3781                                                /*  for observed/interpolated/hydrostatic thickness, remove scaling from any hydrostatic thickness  */
     3782                                                        if     (hydrostatic_ratio[j] >= 0.)
     3783                                                                thickness[j]=values[j]-(values[j]/thickness_init[j]-1.)*hydrostatic_ratio[j]*surface[j]/(1.-di);
     3784                                                /*  for minimum thickness, don't scale  */
     3785                                                        else
     3786                                                                thickness[j]=thickness_init[j];
     3787
     3788                                                /*  check the computed thickness and update bed  */
     3789                                                        if (thickness[j] < 0.)
     3790                                                                thickness[j]=1./(1.-di);
     3791                                                        bed[j]=surface[j]-thickness[j];
     3792                                                }
     3793
     3794//                                              for(j=0;j<6;j++){
     3795//                                                      surface[j]=(1-di)*thickness[j];
     3796//                                                      bed[j]=-di*thickness[j];
     3797//                                              }
     3798                                        }
     3799                                        else{
     3800                                                /*build new thickness: */
     3801                                                for (j=0; j<6; j++) {
     3802                                                /*  for observed thickness, use scaled value  */
     3803                                                        if(hydrostatic_ratio[j] >= 0.)
     3804                                                                thickness[j]=values[j];
     3805                                                /*  for minimum thickness, don't scale  */
     3806                                                        else
     3807                                                                thickness[j]=thickness_init[j];
     3808                                                }
     3809
     3810                                                /*update bed on grounded ice: */
     3811//                                              for(j=0;j<6;j++)surface[j]=bed[j]+thickness[j];
     3812                                                for(j=0;j<6;j++)bed[j]=surface[j]-thickness[j];
     3813                                        }
     3814
     3815                                        /*Add new inputs: */
     3816                                        this->inputs->AddInput(new PentaVertexInput(ThicknessEnum,thickness));
     3817                                        this->inputs->AddInput(new PentaVertexInput(BedEnum,bed));
     3818                                        this->inputs->AddInput(new PentaVertexInput(SurfaceEnum,surface));
     3819
     3820                                        /*}}}*/
     3821                                        break;
     3822                                default:
     3823                                        this->inputs->AddInput(new PentaVertexInput(name,values));
     3824                        }
     3825                        break;
     3826
     3827                default:
     3828                        _error_("type %i (%s) not implemented yet",type,EnumToStringx(type));
     3829        }
     3830
     3831}
     3832/*}}}*/
     3833/*FUNCTION Penta::InputUpdateFromVectorDakota(int* vector, int name, int type);{{{1*/
     3834void  Penta::InputUpdateFromVectorDakota(int* vector, int name, int type){
     3835        _error_(" not supported yet!");
     3836}
     3837/*}}}*/
     3838/*FUNCTION Penta::InputUpdateFromVectorDakota(bool* vector, int name, int type);{{{1*/
     3839void  Penta::InputUpdateFromVectorDakota(bool* vector, int name, int type){
     3840        _error_(" not supported yet!");
     3841}
     3842/*}}}*/
     3843#endif
     3844
     3845/*FUNCTION Penta::CreatePVector {{{1*/
     3846void  Penta::CreatePVector(Vec pf){
     3847
     3848        /*retrive parameters: */
     3849        ElementVector* pe=NULL;
     3850        int analysis_type;
     3851        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     3852
     3853        /*if debugging mode, check that all pointers exist {{{2*/
     3854        _assert_(this->nodes && this->matice && this->matpar && this->verticalneighbors && this->parameters && this->inputs);
     3855        /*}}}*/
     3856
     3857        /*Skip if water element*/
     3858        if(IsOnWater()) return;
     3859
     3860        /*Just branch to the correct element stiffness matrix generator, according to the type of analysis we are carrying out: */
     3861        switch(analysis_type){
     3862                case DiagnosticHorizAnalysisEnum:
     3863                        pe=CreatePVectorDiagnosticHoriz();
     3864                        break;
     3865                #ifdef _HAVE_CONTROL_
     3866                case AdjointHorizAnalysisEnum:
     3867                        pe=CreatePVectorAdjointHoriz();
     3868                        break;
     3869                #endif
     3870                case DiagnosticHutterAnalysisEnum:
     3871                        pe=CreatePVectorDiagnosticHutter();
     3872                        break;
     3873                case DiagnosticVertAnalysisEnum:
     3874                        pe=CreatePVectorDiagnosticVert();
     3875                        break;
     3876                case BedSlopeXAnalysisEnum: case SurfaceSlopeXAnalysisEnum: case BedSlopeYAnalysisEnum: case SurfaceSlopeYAnalysisEnum:
     3877                        pe=CreatePVectorSlope();
     3878                        break;
     3879                case PrognosticAnalysisEnum:
     3880                        pe=CreatePVectorPrognostic();
     3881                        break;
     3882                case BalancethicknessAnalysisEnum:
     3883                        pe=CreatePVectorBalancethickness();
     3884                        break;
     3885                #ifdef _HAVE_THERMAL_
     3886                case ThermalAnalysisEnum:
     3887                        pe=CreatePVectorThermal();
     3888                        break;
     3889                case EnthalpyAnalysisEnum:
     3890                        pe=CreatePVectorEnthalpy();
     3891                        break;
     3892                case MeltingAnalysisEnum:
     3893                        pe=CreatePVectorMelting();
     3894                        break;
     3895                #endif
     3896                default:
     3897                        _error_("analysis %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type));
     3898        }
     3899
     3900        /*Add to global Vector*/
     3901        if(pe){
     3902                pe->AddToGlobal(pf);
     3903                delete pe;
     3904        }
     3905}
     3906/*}}}*/
     3907/*FUNCTION Penta::CreatePVectorBalancethickness {{{1*/
     3908ElementVector* Penta::CreatePVectorBalancethickness(void){
     3909
     3910        if (!IsOnBed()) return NULL;
     3911
     3912        /*Depth Averaging Vx and Vy*/
     3913        this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);
     3914        this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);
     3915
     3916        /*Call Tria function*/
     3917        Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
     3918        ElementVector* pe=tria->CreatePVectorBalancethickness();
     3919        delete tria->matice; delete tria;
     3920
     3921        /*Delete Vx and Vy averaged*/
     3922        this->inputs->DeleteInput(VxAverageEnum);
     3923        this->inputs->DeleteInput(VyAverageEnum);
     3924
     3925        /*Clean up and return*/
     3926        return pe;
     3927}
     3928/*}}}*/
     3929/*FUNCTION Penta::CreatePVectorCouplingMacAyealStokes {{{1*/
     3930ElementVector* Penta::CreatePVectorCouplingMacAyealStokes(void){
     3931
     3932        /*compute all load vectors for this element*/
     3933        ElementVector* pe1=CreatePVectorCouplingMacAyealStokesViscous();
     3934        ElementVector* pe2=CreatePVectorCouplingMacAyealStokesFriction();
     3935        ElementVector* pe =new ElementVector(pe1,pe2);
     3936
     3937        /*clean-up and return*/
     3938        delete pe1;
     3939        delete pe2;
     3940        return pe;
     3941}
     3942/*}}}*/
     3943/*FUNCTION Penta::CreatePVectorCouplingMacAyealStokesViscous {{{1*/
     3944ElementVector* Penta::CreatePVectorCouplingMacAyealStokesViscous(void){
     3945
     3946        /*Constants*/
     3947        const int   numdof=NUMVERTICES*NDOF4;
     3948
     3949        /*Intermediaries */
     3950        int         i,j,ig;
     3951        int         approximation;
     3952        double      viscosity,Jdet;
     3953        double      stokesreconditioning;
     3954        double      epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
     3955        double      dw[3];
     3956        double      xyz_list[NUMVERTICES][3];
     3957        double      basis[6]; //for the six nodes of the penta
     3958        double      dbasis[3][6]; //for the six nodes of the penta
     3959        GaussPenta *gauss=NULL;
     3960
     3961        /*Initialize Element vector and return if necessary*/
     3962        inputs->GetParameterValue(&approximation,ApproximationEnum);
     3963        if(approximation!=MacAyealStokesApproximationEnum) return NULL;
     3964        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,StokesApproximationEnum);
     3965
     3966        /*Retrieve all inputs and parameters*/
     3967        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     3968        this->parameters->FindParam(&stokesreconditioning,DiagnosticStokesreconditioningEnum);
     3969        Input* vx_input=inputs->GetInput(VxEnum);               _assert_(vx_input);
     3970        Input* vy_input=inputs->GetInput(VyEnum);               _assert_(vy_input);
     3971        Input* vz_input=inputs->GetInput(VzEnum);               _assert_(vz_input);
     3972        Input* vzmacayeal_input=inputs->GetInput(VzMacAyealEnum);   _assert_(vzmacayeal_input);
     3973
     3974        /* Start  looping on the number of gaussian points: */
     3975        gauss=new GaussPenta(5,5);
     3976        for (ig=gauss->begin();ig<gauss->end();ig++){
     3977
     3978                gauss->GaussPoint(ig);
     3979
     3980                GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
     3981                GetNodalFunctionsP1(&basis[0], gauss);
     3982                GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);
     3983
     3984                vzmacayeal_input->GetParameterDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
     3985
     3986                this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
     3987                matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
     3988
     3989                for(i=0;i<NUMVERTICES;i++){
     3990                        pe->values[i*NDOF4+0]+=-Jdet*gauss->weight*viscosity*dw[0]*dbasis[2][i];
     3991                        pe->values[i*NDOF4+1]+=-Jdet*gauss->weight*viscosity*dw[1]*dbasis[2][i];
     3992                        pe->values[i*NDOF4+2]+=-Jdet*gauss->weight*viscosity*(dw[0]*dbasis[0][i]+dw[1]*dbasis[1][i]+2*dw[2]*dbasis[2][i]);
     3993                        pe->values[i*NDOF4+3]+=Jdet*gauss->weight*stokesreconditioning*dw[2]*basis[i];
     3994                }
     3995        }
     3996
     3997        /*Clean up and return*/
     3998        delete gauss;
     3999        return pe;
     4000}
     4001/*}}}*/
     4002/*FUNCTION Penta::CreatePVectorCouplingMacAyealStokesFriction{{{1*/
     4003ElementVector* Penta::CreatePVectorCouplingMacAyealStokesFriction(void){
     4004
     4005        /*Constants*/
     4006        const int numdof=NUMVERTICES*NDOF4;
     4007
     4008        /*Intermediaries*/
     4009        int         i,j,ig;
     4010        int         approximation,analysis_type;
     4011        double      Jdet,Jdet2d;
     4012        double      stokesreconditioning;
     4013        double     bed_normal[3];
     4014        double      epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
     4015        double      viscosity, w, alpha2_gauss;
     4016        double      dw[3];
     4017        double     xyz_list_tria[NUMVERTICES2D][3];
     4018        double      xyz_list[NUMVERTICES][3];
     4019        double      basis[6]; //for the six nodes of the penta
     4020        Tria*       tria=NULL;
     4021        Friction*   friction=NULL;
     4022        GaussPenta  *gauss=NULL;
     4023
     4024        /*Initialize Element vector and return if necessary*/
     4025        if(!IsOnBed() || IsOnShelf()) return NULL;
     4026        inputs->GetParameterValue(&approximation,ApproximationEnum);
     4027        if(approximation!=MacAyealStokesApproximationEnum) return NULL;
     4028        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,StokesApproximationEnum);
     4029
     4030        /*Retrieve all inputs and parameters*/
     4031        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     4032        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     4033        this->parameters->FindParam(&stokesreconditioning,DiagnosticStokesreconditioningEnum);
     4034        Input* vx_input=inputs->GetInput(VxEnum);               _assert_(vx_input);
     4035        Input* vy_input=inputs->GetInput(VyEnum);               _assert_(vy_input);
     4036        Input* vz_input=inputs->GetInput(VzEnum);               _assert_(vz_input);
     4037        Input* vzmacayeal_input=inputs->GetInput(VzMacAyealEnum);   _assert_(vzmacayeal_input);
     4038
     4039        for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
     4040
     4041        /*build friction object, used later on: */
     4042        friction=new Friction("3d",inputs,matpar,analysis_type);
     4043
     4044        /* Start looping on the number of gauss 2d (nodes on the bedrock) */
     4045        gauss=new GaussPenta(0,1,2,2);
     4046        for(ig=gauss->begin();ig<gauss->end();ig++){
     4047
     4048                gauss->GaussPoint(ig);
     4049
     4050                GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
     4051                GetNodalFunctionsP1(basis, gauss);
     4052
     4053                vzmacayeal_input->GetParameterValue(&w, gauss);
     4054                vzmacayeal_input->GetParameterDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
     4055
     4056                BedNormal(&bed_normal[0],xyz_list_tria);
     4057                this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
     4058                matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
     4059                friction->GetAlpha2(&alpha2_gauss, gauss,VxEnum,VyEnum,VzEnum);
     4060
     4061                for(i=0;i<NUMVERTICES2D;i++){
     4062                        pe->values[i*NDOF4+0]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[0]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[0])*basis[i];
     4063                        pe->values[i*NDOF4+1]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[1]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[1])*basis[i];
     4064                        pe->values[i*NDOF4+2]+=Jdet2d*gauss->weight*2*viscosity*(dw[0]*bed_normal[0]+dw[1]*bed_normal[1]+dw[2]*bed_normal[2])*basis[i];
     4065                }
     4066        }
     4067
     4068        /*Clean up and return*/
     4069        delete gauss;
     4070        delete friction;
     4071        return pe;
     4072}
     4073/*}}}*/
     4074/*FUNCTION Penta::CreatePVectorCouplingPattynStokes {{{1*/
     4075ElementVector* Penta::CreatePVectorCouplingPattynStokes(void){
     4076
     4077        /*compute all load vectors for this element*/
     4078        ElementVector* pe1=CreatePVectorCouplingPattynStokesViscous();
     4079        ElementVector* pe2=CreatePVectorCouplingPattynStokesFriction();
     4080        ElementVector* pe =new ElementVector(pe1,pe2);
     4081
     4082        /*clean-up and return*/
     4083        delete pe1;
     4084        delete pe2;
     4085        return pe;
     4086}
     4087/*}}}*/
     4088/*FUNCTION Penta::CreatePVectorCouplingPattynStokesViscous {{{1*/
     4089ElementVector* Penta::CreatePVectorCouplingPattynStokesViscous(void){
     4090
     4091        /*Constants*/
     4092        const int   numdof=NUMVERTICES*NDOF4;
     4093
     4094        /*Intermediaries */
     4095        int         i,j,ig;
     4096        int         approximation;
     4097        double      viscosity,Jdet;
     4098        double      stokesreconditioning;
     4099        double      epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
     4100        double      dw[3];
     4101        double      xyz_list[NUMVERTICES][3];
     4102        double      basis[6]; //for the six nodes of the penta
     4103        double      dbasis[3][6]; //for the six nodes of the penta
     4104        GaussPenta *gauss=NULL;
     4105
     4106        /*Initialize Element vector and return if necessary*/
     4107        inputs->GetParameterValue(&approximation,ApproximationEnum);
     4108        if(approximation!=PattynStokesApproximationEnum) return NULL;
     4109        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,StokesApproximationEnum);
     4110
     4111        /*Retrieve all inputs and parameters*/
     4112        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     4113        this->parameters->FindParam(&stokesreconditioning,DiagnosticStokesreconditioningEnum);
     4114        Input* vx_input=inputs->GetInput(VxEnum);               _assert_(vx_input);
     4115        Input* vy_input=inputs->GetInput(VyEnum);               _assert_(vy_input);
     4116        Input* vz_input=inputs->GetInput(VzEnum);               _assert_(vz_input);
     4117        Input* vzpattyn_input=inputs->GetInput(VzPattynEnum);   _assert_(vzpattyn_input);
     4118
     4119        /* Start  looping on the number of gaussian points: */
     4120        gauss=new GaussPenta(5,5);
     4121        for (ig=gauss->begin();ig<gauss->end();ig++){
     4122
     4123                gauss->GaussPoint(ig);
     4124
     4125                GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
     4126                GetNodalFunctionsP1(&basis[0], gauss);
     4127                GetNodalFunctionsP1Derivatives(&dbasis[0][0],&xyz_list[0][0], gauss);
     4128
     4129                vzpattyn_input->GetParameterDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
     4130
     4131                this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
     4132                matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
     4133
     4134                for(i=0;i<NUMVERTICES;i++){
     4135                        pe->values[i*NDOF4+0]+=-Jdet*gauss->weight*viscosity*dw[0]*dbasis[2][i];
     4136                        pe->values[i*NDOF4+1]+=-Jdet*gauss->weight*viscosity*dw[1]*dbasis[2][i];
     4137                        pe->values[i*NDOF4+2]+=-Jdet*gauss->weight*viscosity*(dw[0]*dbasis[0][i]+dw[1]*dbasis[1][i]+2*dw[2]*dbasis[2][i]);
     4138                        pe->values[i*NDOF4+3]+=Jdet*gauss->weight*stokesreconditioning*dw[2]*basis[i];
     4139                }
     4140        }
     4141
     4142        /*Clean up and return*/
     4143        delete gauss;
     4144        return pe;
     4145}
     4146/*}}}*/
     4147/*FUNCTION Penta::CreatePVectorCouplingPattynStokesFriction{{{1*/
     4148ElementVector* Penta::CreatePVectorCouplingPattynStokesFriction(void){
     4149
     4150        /*Constants*/
     4151        const int numdof=NUMVERTICES*NDOF4;
     4152
     4153        /*Intermediaries*/
     4154        int         i,j,ig;
     4155        int         approximation,analysis_type;
     4156        double      Jdet,Jdet2d;
     4157        double      stokesreconditioning;
     4158        double     bed_normal[3];
     4159        double      epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
     4160        double      viscosity, w, alpha2_gauss;
     4161        double      dw[3];
     4162        double     xyz_list_tria[NUMVERTICES2D][3];
     4163        double      xyz_list[NUMVERTICES][3];
     4164        double      basis[6]; //for the six nodes of the penta
     4165        Tria*       tria=NULL;
     4166        Friction*   friction=NULL;
     4167        GaussPenta  *gauss=NULL;
     4168
     4169        /*Initialize Element vector and return if necessary*/
     4170        if(!IsOnBed() || IsOnShelf()) return NULL;
     4171        inputs->GetParameterValue(&approximation,ApproximationEnum);
     4172        if(approximation!=PattynStokesApproximationEnum) return NULL;
     4173        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,StokesApproximationEnum);
     4174
     4175        /*Retrieve all inputs and parameters*/
     4176        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     4177        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     4178        this->parameters->FindParam(&stokesreconditioning,DiagnosticStokesreconditioningEnum);
     4179        Input* vx_input=inputs->GetInput(VxEnum);               _assert_(vx_input);
     4180        Input* vy_input=inputs->GetInput(VyEnum);               _assert_(vy_input);
     4181        Input* vz_input=inputs->GetInput(VzEnum);               _assert_(vz_input);
     4182        Input* vzpattyn_input=inputs->GetInput(VzPattynEnum);   _assert_(vzpattyn_input);
     4183
     4184        for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
     4185
     4186        /*build friction object, used later on: */
     4187        friction=new Friction("3d",inputs,matpar,analysis_type);
     4188
     4189        /* Start looping on the number of gauss 2d (nodes on the bedrock) */
     4190        gauss=new GaussPenta(0,1,2,2);
     4191        for(ig=gauss->begin();ig<gauss->end();ig++){
     4192
     4193                gauss->GaussPoint(ig);
     4194
     4195                GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
     4196                GetNodalFunctionsP1(basis, gauss);
     4197
     4198                vzpattyn_input->GetParameterValue(&w, gauss);
     4199                vzpattyn_input->GetParameterDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
     4200
     4201                BedNormal(&bed_normal[0],xyz_list_tria);
     4202                this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
     4203                matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
     4204                friction->GetAlpha2(&alpha2_gauss, gauss,VxEnum,VyEnum,VzEnum);
     4205
     4206                for(i=0;i<NUMVERTICES2D;i++){
     4207                        pe->values[i*NDOF4+0]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[0]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[0])*basis[i];
     4208                        pe->values[i*NDOF4+1]+=Jdet2d*gauss->weight*(alpha2_gauss*w*bed_normal[1]*bed_normal[2]+2*viscosity*dw[2]*bed_normal[1])*basis[i];
     4209                        pe->values[i*NDOF4+2]+=Jdet2d*gauss->weight*2*viscosity*(dw[0]*bed_normal[0]+dw[1]*bed_normal[1]+dw[2]*bed_normal[2])*basis[i];
     4210                }
     4211        }
     4212
     4213        /*Clean up and return*/
     4214        delete gauss;
     4215        delete friction;
     4216        return pe;
     4217}
     4218/*}}}*/
     4219/*FUNCTION Penta::CreatePVectorDiagnosticHoriz{{{1*/
     4220ElementVector* Penta::CreatePVectorDiagnosticHoriz(void){
     4221
     4222        int approximation;
     4223        inputs->GetParameterValue(&approximation,ApproximationEnum);
     4224
     4225        switch(approximation){
     4226                case MacAyealApproximationEnum:
     4227                        return CreatePVectorDiagnosticMacAyeal();
     4228                case PattynApproximationEnum:
     4229                        return CreatePVectorDiagnosticPattyn();
     4230                case HutterApproximationEnum:
     4231                        return NULL;
     4232                case NoneApproximationEnum:
     4233                        return NULL;
     4234                case StokesApproximationEnum:
     4235                        return CreatePVectorDiagnosticStokes();
     4236                case MacAyealPattynApproximationEnum:
     4237                        return CreatePVectorDiagnosticMacAyealPattyn();
     4238                case MacAyealStokesApproximationEnum:
     4239                        return CreatePVectorDiagnosticMacAyealStokes();
     4240                case PattynStokesApproximationEnum:
     4241                        return CreatePVectorDiagnosticPattynStokes();
     4242                default:
     4243                        _error_("Approximation %s not supported yet",EnumToStringx(approximation));
     4244        }
     4245}
     4246/*}}}*/
     4247/*FUNCTION Penta::CreatePVectorDiagnosticMacAyealPattyn{{{1*/
     4248ElementVector* Penta::CreatePVectorDiagnosticMacAyealPattyn(void){
     4249
     4250        /*compute all load vectors for this element*/
     4251        ElementVector* pe1=CreatePVectorDiagnosticMacAyeal();
     4252        ElementVector* pe2=CreatePVectorDiagnosticPattyn();
     4253        ElementVector* pe =new ElementVector(pe1,pe2);
     4254
     4255        /*clean-up and return*/
     4256        delete pe1;
     4257        delete pe2;
     4258        return pe;
     4259}
     4260/*}}}*/
     4261/*FUNCTION Penta::CreatePVectorDiagnosticMacAyealStokes{{{1*/
     4262ElementVector* Penta::CreatePVectorDiagnosticMacAyealStokes(void){
     4263
     4264        /*compute all load vectors for this element*/
     4265        ElementVector* pe1=CreatePVectorDiagnosticMacAyeal();
     4266        ElementVector* pe2=CreatePVectorDiagnosticStokes();
     4267        ElementVector* pe3=CreatePVectorCouplingMacAyealStokes();
     4268        ElementVector* pe =new ElementVector(pe1,pe2,pe3);
     4269
     4270        /*clean-up and return*/
     4271        delete pe1;
     4272        delete pe2;
     4273        delete pe3;
     4274        return pe;
     4275}
     4276/*}}}*/
     4277/*FUNCTION Penta::CreatePVectorDiagnosticPattynStokes{{{1*/
     4278ElementVector* Penta::CreatePVectorDiagnosticPattynStokes(void){
     4279
     4280        /*compute all load vectors for this element*/
     4281        ElementVector* pe1=CreatePVectorDiagnosticPattyn();
     4282        ElementVector* pe2=CreatePVectorDiagnosticStokes();
     4283        ElementVector* pe3=CreatePVectorCouplingPattynStokes();
     4284        ElementVector* pe =new ElementVector(pe1,pe2,pe3);
     4285
     4286        /*clean-up and return*/
     4287        delete pe1;
     4288        delete pe2;
     4289        delete pe3;
     4290        return pe;
     4291}
     4292/*}}}*/
     4293/*FUNCTION Penta::CreatePVectorDiagnosticHutter{{{1*/
     4294ElementVector* Penta::CreatePVectorDiagnosticHutter(void){
     4295
     4296        /*Constants*/
     4297        const int numdofs=NDOF2*NUMVERTICES;
     4298
     4299        /*Intermediaries*/
     4300        int          i,j,k,ig;
     4301        int          node0,node1;
     4302        int          connectivity[2];
     4303        double       Jdet;
     4304        double       xyz_list[NUMVERTICES][3];
     4305        double       xyz_list_segment[2][3];
     4306        double       z_list[NUMVERTICES];
     4307        double       z_segment[2],slope[2];
     4308        double       slope2,constant_part;
     4309        double       rho_ice,gravity,n,B;
     4310        double       ub,vb,z_g,surface,thickness;
     4311        GaussPenta*  gauss=NULL;
     4312
     4313        /*Initialize Element vector*/
     4314        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
     4315
     4316        /*Retrieve all inputs and parameters*/
     4317        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     4318        rho_ice=matpar->GetRhoIce();
     4319        gravity=matpar->GetG();
     4320        n=matice->GetN();
     4321        B=matice->GetB();
     4322        Input* thickness_input=inputs->GetInput(ThicknessEnum);  _assert_(thickness_input);
     4323        Input* surface_input=inputs->GetInput(SurfaceEnum);      _assert_(surface_input);
     4324        Input* slopex_input=inputs->GetInput(SurfaceSlopeXEnum); _assert_(slopex_input);
     4325        Input* slopey_input=inputs->GetInput(SurfaceSlopeYEnum); _assert_(slopey_input);
     4326        for(i=0;i<NUMVERTICES;i++)z_list[i]=xyz_list[i][2];
     4327
     4328        /*Loop on the three segments*/
     4329        for(i=0;i<3;i++){
     4330                node0=i;
     4331                node1=i+3;
     4332
     4333                for(j=0;j<3;j++){
     4334                        xyz_list_segment[0][j]=xyz_list[node0][j];
     4335                        xyz_list_segment[1][j]=xyz_list[node1][j];
     4336                }
     4337
     4338                connectivity[0]=nodes[node0]->GetConnectivity();
     4339                connectivity[1]=nodes[node1]->GetConnectivity();
     4340
     4341                /*Loop on the Gauss points: */
     4342                gauss=new GaussPenta(node0,node1,3);
     4343                for(ig=gauss->begin();ig<gauss->end();ig++){
     4344                        gauss->GaussPoint(ig);
     4345
     4346                        slopex_input->GetParameterValue(&slope[0],gauss);
     4347                        slopey_input->GetParameterValue(&slope[1],gauss);
     4348                        surface_input->GetParameterValue(&surface,gauss);
     4349                        thickness_input->GetParameterValue(&thickness,gauss);
     4350
     4351                        slope2=pow(slope[0],2)+pow(slope[1],2);
     4352                        constant_part=-2*pow(rho_ice*gravity,n)*pow(slope2,((n-1)/2));
     4353
     4354                        PentaRef::GetParameterValue(&z_g,&z_list[0],gauss);
     4355                        GetSegmentJacobianDeterminant(&Jdet,&xyz_list_segment[0][0],gauss);
     4356
     4357                        if (IsOnSurface()){
     4358                                for(j=0;j<NDOF2;j++) pe->values[2*node1+j]+=constant_part*pow((surface-z_g)/B,n)*slope[j]*Jdet*gauss->weight/(double)connectivity[1];
     4359                        }
     4360                        else{//connectivity is too large, should take only half on it
     4361                                for(j=0;j<NDOF2;j++) pe->values[2*node1+j]+=constant_part*pow((surface-z_g)/B,n)*slope[j]*Jdet*gauss->weight*2/(double)connectivity[1];
     4362                        }
     4363                }
     4364                delete gauss;
     4365
     4366                //Deal with lower surface
     4367                if (IsOnBed()){
     4368                        constant_part=-1.58*pow((double)10.0,-(double)10.0)*rho_ice*gravity*thickness;
     4369                        ub=constant_part*slope[0];
     4370                        vb=constant_part*slope[1];
     4371
     4372                        pe->values[2*node0]+=ub/(double)connectivity[0];
     4373                        pe->values[2*node0+1]+=vb/(double)connectivity[0];
     4374                }
     4375        }
     4376
     4377        /*Clean up and return*/
     4378        return pe;
     4379}
     4380/*}}}*/
     4381/*FUNCTION Penta::CreatePVectorDiagnosticMacAyeal{{{1*/
     4382ElementVector* Penta::CreatePVectorDiagnosticMacAyeal(void){
     4383
     4384        if (!IsOnBed()) return NULL;
     4385
     4386        /*Call Tria function*/
     4387        Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
     4388        ElementVector* pe=tria->CreatePVectorDiagnosticMacAyeal();
     4389        delete tria->matice; delete tria;
     4390
     4391        /*Clean up and return*/
     4392        return pe;
     4393}
     4394/*}}}*/
     4395/*FUNCTION Penta::CreatePVectorDiagnosticPattyn{{{1*/
     4396ElementVector* Penta::CreatePVectorDiagnosticPattyn(void){
     4397
     4398        /*Constants*/
     4399        const int    numdof=NDOF2*NUMVERTICES;
     4400
     4401        /*Intermediaries*/
     4402        int         i,j,ig;
     4403        double      Jdet;
     4404        double      slope[3]; //do not put 2! this goes into GetParameterDerivativeValue, which addresses slope[3] also!
     4405        double      driving_stress_baseline,thickness;
     4406        double      xyz_list[NUMVERTICES][3];
     4407        double      basis[6];
     4408        GaussPenta  *gauss=NULL;
     4409
     4410        /*Initialize Element vector*/
     4411        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,PattynApproximationEnum);
     4412
     4413        /*Retrieve all inputs and parameters*/
     4414        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     4415        Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
     4416        Input* surface_input=inputs->GetInput(SurfaceEnum);     _assert_(surface_input);
     4417
     4418        /* Start  looping on the number of gaussian points: */
     4419        gauss=new GaussPenta(2,3);
     4420        for (ig=gauss->begin();ig<gauss->end();ig++){
     4421
     4422                gauss->GaussPoint(ig);
     4423
     4424                GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
     4425                GetNodalFunctionsP1(basis, gauss);
     4426
     4427                thickness_input->GetParameterValue(&thickness, gauss);
     4428                surface_input->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],gauss);
     4429
     4430                driving_stress_baseline=matpar->GetRhoIce()*matpar->GetG();
     4431
     4432                for(i=0;i<NUMVERTICES;i++) for(j=0;j<NDOF2;j++) pe->values[i*NDOF2+j]+= -driving_stress_baseline*slope[j]*Jdet*gauss->weight*basis[i];
     4433        }
     4434
     4435        /*Clean up and return*/
     4436        delete gauss;
     4437        return pe;
     4438}
     4439/*}}}*/
     4440/*FUNCTION Penta::CreatePVectorDiagnosticStokes {{{1*/
     4441ElementVector* Penta::CreatePVectorDiagnosticStokes(void){
     4442
     4443        /*compute all load vectors for this element*/
     4444        ElementVector* pe1=CreatePVectorDiagnosticStokesViscous();
     4445        ElementVector* pe2=CreatePVectorDiagnosticStokesShelf();
     4446        ElementVector* pe =new ElementVector(pe1,pe2);
     4447
     4448        /*clean-up and return*/
     4449        delete pe1;
     4450        delete pe2;
     4451        return pe;
     4452}
     4453/*}}}*/
     4454/*FUNCTION Penta::CreatePVectorDiagnosticStokesViscous {{{1*/
     4455ElementVector* Penta::CreatePVectorDiagnosticStokesViscous(void){
     4456
     4457        /*Constants*/
     4458        const int numdofbubble=NDOF4*NUMVERTICES+NDOF3*1;
     4459
     4460        /*Intermediaries*/
     4461        int        i,j,ig;
     4462        int        approximation;
     4463        double     Jdet,viscosity;
     4464        double     gravity,rho_ice,stokesreconditioning;
     4465        double     xyz_list[NUMVERTICES][3];
     4466        double     epsilon[6]; /* epsilon=[exx,eyy,ezz,exy,exz,eyz];*/
     4467        double     l1l7[7]; //for the six nodes and the bubble
     4468        double     B[8][numdofbubble];
     4469        double     B_prime[8][numdofbubble];
     4470        double     B_prime_bubble[8][3];
     4471        double     D[8][8]={0.0};
     4472        double     D_scalar;
     4473        double     Pe_gaussian[numdofbubble]={0.0}; //for the six nodes and the bubble
     4474        double     Ke_temp[numdofbubble][3]={0.0}; //for the six nodes and the bubble
     4475        double     Ke_gaussian[numdofbubble][3];
     4476        GaussPenta *gauss=NULL;
     4477
     4478        /*Initialize Element vector and return if necessary*/
     4479        inputs->GetParameterValue(&approximation,ApproximationEnum);
     4480        if(approximation!=StokesApproximationEnum && approximation!=MacAyealStokesApproximationEnum && approximation!=PattynStokesApproximationEnum) return NULL;
     4481        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,StokesApproximationEnum);
     4482
     4483        /*Retrieve all inputs and parameters*/
     4484        this->parameters->FindParam(&stokesreconditioning,DiagnosticStokesreconditioningEnum);
     4485        rho_ice=matpar->GetRhoIce();
     4486        gravity=matpar->GetG();
     4487        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     4488        Input* vx_input=inputs->GetInput(VxEnum);   _assert_(vx_input);
     4489        Input* vy_input=inputs->GetInput(VyEnum);   _assert_(vy_input);
     4490        Input* vz_input=inputs->GetInput(VzEnum);   _assert_(vz_input);
     4491
     4492        /* Start  looping on the number of gaussian points: */
     4493        gauss=new GaussPenta(5,5);
     4494        for (ig=gauss->begin();ig<gauss->end();ig++){
     4495
     4496                gauss->GaussPoint(ig);
     4497
     4498                GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
     4499                GetBStokes(&B[0][0],&xyz_list[0][0],gauss);
     4500                GetBprimeStokes(&B_prime[0][0],&xyz_list[0][0], gauss);
     4501                GetNodalFunctionsMINI(&l1l7[0], gauss);
     4502
     4503                this->GetStrainRate3d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input,vz_input);
     4504                matice->GetViscosity3dStokes(&viscosity,&epsilon[0]);
     4505
     4506                for(i=0;i<NUMVERTICES+1;i++){
     4507                        Pe_gaussian[i*NDOF4+2]+=-rho_ice*gravity*Jdet*gauss->weight*l1l7[i];
     4508                }
     4509
     4510                /*Get bubble part of Bprime */
     4511                for(i=0;i<8;i++) for(j=0;j<3;j++) B_prime_bubble[i][j]=B_prime[i][j+24];
     4512
     4513                D_scalar=gauss->weight*Jdet;
     4514                for (i=0;i<6;i++) D[i][i]=D_scalar*2*viscosity;
     4515                for (i=6;i<8;i++) D[i][i]=-D_scalar*stokesreconditioning;
     4516
     4517                TripleMultiply(&B[0][0],8,numdofbubble,1,
     4518                                        &D[0][0],8,8,0,
     4519                                        &B_prime_bubble[0][0],8,3,0,
     4520                                        &Ke_gaussian[0][0],0);
     4521
     4522                for(i=0;i<numdofbubble;i++) for(j=0;j<NDOF3;j++) Ke_temp[i][j]+=Ke_gaussian[i][j];
     4523        }
     4524
     4525        /*Condensation*/
     4526        ReduceVectorStokes(pe->values, &Ke_temp[0][0], &Pe_gaussian[0]);
     4527
     4528        /*Clean up and return*/
     4529        delete gauss;
     4530        return pe;
     4531}
     4532/*}}}*/
     4533/*FUNCTION Penta::CreatePVectorDiagnosticStokesShelf{{{1*/
     4534ElementVector* Penta::CreatePVectorDiagnosticStokesShelf(void){
     4535
     4536        /*Intermediaries*/
     4537        int         i,j,ig;
     4538        int         approximation,shelf_dampening;
     4539        double      gravity,rho_water,bed,water_pressure;
     4540        double      damper,normal_vel,vx,vy,vz,dt;
     4541        double          xyz_list_tria[NUMVERTICES2D][3];
     4542        double      xyz_list[NUMVERTICES][3];
     4543        double          bed_normal[3];
     4544        double      dz[3];
     4545        double      basis[6]; //for the six nodes of the penta
     4546        double      Jdet2d;
     4547        GaussPenta  *gauss=NULL;
     4548
     4549        /*Initialize Element vector and return if necessary*/
     4550        if(!IsOnBed() || !IsOnShelf()) return NULL;
     4551        inputs->GetParameterValue(&approximation,ApproximationEnum);
     4552        this->parameters->FindParam(&shelf_dampening,DiagnosticShelfDampeningEnum);
     4553        if(approximation!=StokesApproximationEnum && approximation!=MacAyealStokesApproximationEnum && approximation!=PattynStokesApproximationEnum) return NULL;
     4554        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters,StokesApproximationEnum);
     4555
     4556        /*Retrieve all inputs and parameters*/
     4557        rho_water=matpar->GetRhoWater();
     4558        gravity=matpar->GetG();
     4559        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     4560        Input* bed_input=inputs->GetInput(BedEnum); _assert_(bed_input);
     4561        Input* vx_input=inputs->GetInput(VxEnum);   _assert_(vx_input);
     4562        Input* vy_input=inputs->GetInput(VyEnum);   _assert_(vy_input);
     4563        Input* vz_input=inputs->GetInput(VzEnum);   _assert_(vz_input);
     4564
     4565        for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
     4566
     4567        /* Start looping on the number of gauss 2d (nodes on the bedrock) */
     4568        gauss=new GaussPenta(0,1,2,2);
     4569        for(ig=gauss->begin();ig<gauss->end();ig++){
     4570
     4571                gauss->GaussPoint(ig);
     4572
     4573                GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0], gauss);
     4574                GetNodalFunctionsP1(basis, gauss);
     4575
     4576                BedNormal(&bed_normal[0],xyz_list_tria);
     4577                bed_input->GetParameterValue(&bed, gauss);
     4578                if(shelf_dampening){ //add dampening to avoid too high vertical velocities when not in hydrostatic equilibrium
     4579                        bed_input->GetParameterDerivativeValue(&dz[0],&xyz_list[0][0],gauss);
     4580                        vx_input->GetParameterValue(&vx, gauss);
     4581                        vy_input->GetParameterValue(&vy, gauss);
     4582                        vz_input->GetParameterValue(&vz, gauss);
     4583                        dt=0;
     4584                        normal_vel=bed_normal[0]*vx+bed_normal[1]*vy+bed_normal[2]*vz;
     4585                        damper=gravity*rho_water*pow(1+pow(dz[0],2)+pow(dz[1],2),0.5)*normal_vel*dt;
     4586                }
     4587                else damper=0;
     4588                water_pressure=gravity*rho_water*bed;
     4589
     4590                for(i=0;i<NUMVERTICES;i++) for(j=0;j<3;j++) pe->values[i*NDOF4+j]+=(water_pressure+damper)*gauss->weight*Jdet2d*basis[i]*bed_normal[j];
     4591        }
     4592
     4593        /*Clean up and return*/
     4594        delete gauss;
     4595        return pe;
     4596}
     4597/*}}}*/
     4598/*FUNCTION Penta::CreatePVectorDiagnosticVert {{{1*/
     4599ElementVector* Penta::CreatePVectorDiagnosticVert(void){
     4600
     4601        /*compute all load vectors for this element*/
     4602        ElementVector* pe1=CreatePVectorDiagnosticVertVolume();
     4603        ElementVector* pe2=CreatePVectorDiagnosticVertBase();
     4604        ElementVector* pe =new ElementVector(pe1,pe2);
     4605
     4606        /*clean-up and return*/
     4607        delete pe1;
     4608        delete pe2;
     4609        return pe;
     4610}
     4611/*}}}*/
     4612/*FUNCTION Penta::CreatePVectorDiagnosticVertVolume {{{1*/
     4613ElementVector* Penta::CreatePVectorDiagnosticVertVolume(void){
     4614
     4615        /*Constants*/
     4616        const int  numdof=NDOF1*NUMVERTICES;
     4617
     4618        /*Intermediaries*/
     4619        int        i,ig;
     4620        int        approximation;
     4621        double     Jdet;
     4622        double     xyz_list[NUMVERTICES][3];
     4623        double     dudx,dvdy,dwdz;
     4624        double     du[3],dv[3],dw[3];
     4625        double     basis[6];
     4626        GaussPenta *gauss=NULL;
     4627
     4628        /*Initialize Element vector*/
     4629        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
     4630
     4631        /*Retrieve all inputs and parameters*/
     4632        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     4633        inputs->GetParameterValue(&approximation,ApproximationEnum);
     4634        Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
     4635        Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
     4636        Input* vzstokes_input=NULL;
     4637        if(approximation==PattynStokesApproximationEnum || approximation==MacAyealStokesApproximationEnum){
     4638                vzstokes_input=inputs->GetInput(VzStokesEnum); _assert_(vzstokes_input);
     4639        }
     4640
     4641        /* Start  looping on the number of gaussian points: */
     4642        gauss=new GaussPenta(2,2);
     4643        for (ig=gauss->begin();ig<gauss->end();ig++){
     4644
     4645                gauss->GaussPoint(ig);
     4646
     4647                GetJacobianDeterminant(&Jdet, &xyz_list[0][0],gauss);
     4648                GetNodalFunctionsP1(basis, gauss);
     4649
     4650                vx_input->GetParameterDerivativeValue(&du[0],&xyz_list[0][0],gauss);
     4651                vy_input->GetParameterDerivativeValue(&dv[0],&xyz_list[0][0],gauss);
     4652                if(approximation==PattynStokesApproximationEnum || approximation==MacAyealStokesApproximationEnum){
     4653                        vzstokes_input->GetParameterDerivativeValue(&dw[0],&xyz_list[0][0],gauss);
     4654                        dwdz=dw[2];
     4655                }
     4656                else dwdz=0;
     4657                dudx=du[0];
     4658                dvdy=dv[1];
     4659
     4660                for (i=0;i<numdof;i++) pe->values[i] += (dudx+dvdy+dwdz)*Jdet*gauss->weight*basis[i];
     4661        }
     4662
     4663        /*Clean up and return*/
     4664        delete gauss;
     4665        return pe;
     4666}
     4667/*}}}*/
     4668/*FUNCTION Penta::CreatePVectorDiagnosticVertBase {{{1*/
     4669ElementVector* Penta::CreatePVectorDiagnosticVertBase(void){
     4670
     4671
     4672        /*Constants*/
     4673        const int    numdof=NDOF1*NUMVERTICES;
     4674
     4675        /*Intermediaries */
     4676        int        i,j,ig;
     4677        int        approximation;
     4678        double     xyz_list[NUMVERTICES][3];
     4679        double     xyz_list_tria[NUMVERTICES2D][3];
     4680        double     Jdet2d;
     4681        double     vx,vy,vz,dbdx,dbdy,basalmeltingvalue;
     4682        double     slope[3];
     4683        double     basis[NUMVERTICES];
     4684        GaussPenta* gauss=NULL;
     4685
     4686        if (!IsOnBed()) return NULL;
     4687
     4688        /*Initialize Element vector*/
     4689        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
     4690
     4691        /*Retrieve all inputs and parameters*/
     4692        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     4693        for(i=0;i<NUMVERTICES2D;i++) for(j=0;j<3;j++) xyz_list_tria[i][j]=xyz_list[i][j];
     4694        inputs->GetParameterValue(&approximation,ApproximationEnum);
     4695        Input* bed_input=inputs->GetInput(BedEnum);                                _assert_(bed_input);
     4696        Input* basal_melting_input=inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(basal_melting_input);
     4697        Input* vx_input=inputs->GetInput(VxEnum);                                  _assert_(vx_input);
     4698        Input* vy_input=inputs->GetInput(VyEnum);                                  _assert_(vy_input);
     4699        Input* vzstokes_input=NULL;
     4700        if(approximation==PattynStokesApproximationEnum || approximation==MacAyealStokesApproximationEnum){
     4701                vzstokes_input=inputs->GetInput(VzStokesEnum);       _assert_(vzstokes_input);
     4702        }
     4703
     4704        /* Start  looping on the number of gaussian points: */
     4705        gauss=new GaussPenta(0,1,2,2);
     4706        for(ig=gauss->begin();ig<gauss->end();ig++){
     4707
     4708                gauss->GaussPoint(ig);
     4709
     4710                basal_melting_input->GetParameterValue(&basalmeltingvalue, gauss);
     4711                bed_input->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],gauss);
     4712                vx_input->GetParameterValue(&vx, gauss);
     4713                vy_input->GetParameterValue(&vy, gauss);
     4714                if(approximation==PattynStokesApproximationEnum || approximation==MacAyealStokesApproximationEnum){
     4715                        vzstokes_input->GetParameterValue(&vz, gauss);
     4716                }
     4717                else vz=0;
     4718
     4719                dbdx=slope[0];
     4720                dbdy=slope[1];
     4721
     4722                GetTriaJacobianDeterminant(&Jdet2d, &xyz_list_tria[0][0],gauss);
     4723                GetNodalFunctionsP1(&basis[0], gauss);
     4724
     4725                for(i=0;i<numdof;i++) pe->values[i]+=-Jdet2d*gauss->weight*(vx*dbdx+vy*dbdy-vz-basalmeltingvalue)*basis[i];
     4726        }
     4727
     4728        /*Clean up and return*/
     4729        delete gauss;
     4730        return pe;
     4731}
     4732/*}}}*/
     4733/*FUNCTION Penta::CreatePVectorPrognostic {{{1*/
     4734ElementVector* Penta::CreatePVectorPrognostic(void){
     4735
     4736        if (!IsOnBed()) return NULL;
     4737
     4738        /*Depth Averaging Vx and Vy*/
     4739        this->InputDepthAverageAtBase(VxEnum,VxAverageEnum);
     4740        this->InputDepthAverageAtBase(VyEnum,VyAverageEnum);
     4741
     4742        /*Call Tria function*/
     4743        Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
     4744        ElementVector* pe=tria->CreatePVectorPrognostic();
     4745        delete tria->matice; delete tria;
     4746
     4747        /*Delete Vx and Vy averaged*/
     4748        this->inputs->DeleteInput(VxAverageEnum);
     4749        this->inputs->DeleteInput(VyAverageEnum);
     4750
     4751        /*Clean up and return*/
     4752        return pe;
     4753}
     4754/*}}}*/
     4755/*FUNCTION Penta::CreatePVectorSlope {{{1*/
     4756ElementVector* Penta::CreatePVectorSlope(void){
     4757
     4758        if (!IsOnBed()) return NULL;
     4759
     4760        /*Call Tria function*/
     4761        Tria* tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria.
     4762        ElementVector* pe=tria->CreatePVectorSlope();
     4763        delete tria->matice; delete tria;
     4764
     4765        /*clean up and return*/
     4766        return pe;
     4767}
     4768/*}}}*/
     4769/*FUNCTION Penta::DeepEcho{{{1*/
     4770void Penta::DeepEcho(void){
     4771
     4772        int i;
     4773       
     4774        printf("Penta:\n");
     4775        printf("   id: %i\n",id);
     4776        nodes[0]->DeepEcho();
     4777        nodes[1]->DeepEcho();
     4778        nodes[2]->DeepEcho();
     4779        nodes[3]->DeepEcho();
     4780        nodes[4]->DeepEcho();
     4781        nodes[5]->DeepEcho();
     4782        matice->DeepEcho();
     4783        matpar->DeepEcho();
     4784        printf("   neighbor ids: %i-%i\n",verticalneighbors[0]->Id(),verticalneighbors[1]->Id());
     4785        printf("   parameters\n");
     4786        parameters->DeepEcho();
     4787        printf("   inputs\n");
     4788        inputs->DeepEcho();
     4789        printf("   results\n");
     4790        results->DeepEcho();
     4791        printf("neighboor sids: \n");
     4792        printf(" %i %i %i\n",horizontalneighborsids[0],horizontalneighborsids[1],horizontalneighborsids[2]);
     4793
     4794        return;
     4795}
     4796/*}}}*/
     4797/*FUNCTION Penta::DeleteResults {{{1*/
     4798void  Penta::DeleteResults(void){
     4799
     4800        /*Delete and reinitialize results*/
     4801        delete this->results;
     4802        this->results=new Results();
     4803
     4804}
     4805/*}}}*/
     4806/*FUNCTION Penta::Echo{{{1*/
     4807
     4808void Penta::Echo(void){
     4809        this->DeepEcho();
     4810}
     4811/*}}}*/
     4812/*FUNCTION Penta::Enum {{{1*/
     4813int Penta::Enum(void){
     4814
     4815        return PentaEnum;
     4816
     4817}
     4818/*}}}*/
     4819/*FUNCTION Penta::GetBasalElement{{{1*/
     4820Penta* Penta::GetBasalElement(void){
     4821
     4822        /*Output*/
     4823        Penta* penta=NULL;
     4824
     4825        /*Go through all elements till the bed is reached*/
     4826        penta=this;
     4827        for(;;){
     4828                /*Stop if we have reached the surface, else, take lower penta*/
     4829                if (penta->IsOnBed()) break;
     4830
     4831                /* get lower Penta*/
     4832                penta=penta->GetLowerElement();
     4833                _assert_(penta->Id()!=this->id);
     4834        }
     4835
     4836        /*return output*/
     4837        return penta;
     4838}
     4839/*}}}*/
     4840/*FUNCTION Penta::GetDofList {{{1*/
     4841void  Penta::GetDofList(int** pdoflist,int approximation_enum,int setenum){
     4842
     4843        int  i,j,count=0;
     4844        int  numberofdofs=0;
     4845        int* doflist=NULL;
     4846
     4847        /*First, figure out size of doflist: */
     4848        for(i=0;i<6;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
     4849
     4850        /*Allocate: */
     4851        doflist=(int*)xmalloc(numberofdofs*sizeof(int));
     4852
     4853        /*Populate: */
     4854        count=0;
     4855        for(i=0;i<6;i++){
     4856                nodes[i]->GetDofList(doflist+count,approximation_enum,setenum);
     4857                count+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
     4858        }
     4859
     4860        /*Assign output pointers:*/
     4861        *pdoflist=doflist;
     4862}
     4863/*}}}*/
     4864/*FUNCTION Penta::GetDofList1 {{{1*/
     4865void  Penta::GetDofList1(int* doflist){
     4866
     4867        int i;
     4868        for(i=0;i<6;i++) doflist[i]=nodes[i]->GetDofList1();
     4869
     4870}
     4871/*}}}*/
     4872/*FUNCTION Penta::GetElementType {{{1*/
     4873int Penta::GetElementType(){
     4874
     4875        /*return PentaRef field*/
     4876        return this->element_type;
     4877}
     4878/*}}}*/
     4879/*FUNCTION Penta::GetHorizontalNeighboorSids {{{1*/
     4880int* Penta::GetHorizontalNeighboorSids(){
     4881
     4882        /*return PentaRef field*/
     4883        return &this->horizontalneighborsids[0];
     4884
     4885}
     4886/*}}}*/
     4887/*FUNCTION Penta::GetLowerElement{{{1*/
     4888Penta* Penta::GetLowerElement(void){
     4889
     4890        Penta* upper_penta=NULL;
     4891
     4892        upper_penta=(Penta*)verticalneighbors[0]; //first one (0) under, second one (1) above
     4893
     4894        return upper_penta;
     4895}
     4896/*}}}*/
     4897/*FUNCTION Penta::GetNodeIndex {{{1*/
     4898int Penta::GetNodeIndex(Node* node){
     4899
     4900        _assert_(nodes);
     4901        for(int i=0;i<NUMVERTICES;i++){
     4902                if(node==nodes[i])
     4903                 return i;
     4904        }
     4905        _error_("Node provided not found among element nodes");
     4906
     4907}
     4908/*}}}*/
     4909/*FUNCTION Penta::GetParameterListOnVertices(double* pvalue,int enumtype) {{{1*/
     4910void Penta::GetParameterListOnVertices(double* pvalue,int enumtype){
     4911
     4912        /*Intermediaries*/
     4913        double     value[NUMVERTICES];
     4914        GaussPenta *gauss              = NULL;
     4915
     4916        /*Recover input*/
     4917        Input* input=inputs->GetInput(enumtype);
     4918        if (!input) _error_("Input %s not found in element",EnumToStringx(enumtype));
     4919
     4920        /*Checks in debugging mode*/
     4921        _assert_(pvalue);
     4922
     4923        /* Start looping on the number of vertices: */
     4924        gauss=new GaussPenta();
     4925        for (int iv=0;iv<NUMVERTICES;iv++){
     4926                gauss->GaussVertex(iv);
     4927                input->GetParameterValue(&pvalue[iv],gauss);
     4928        }
     4929
     4930        /*clean-up*/
     4931        delete gauss;
     4932}
     4933/*}}}*/
     4934/*FUNCTION Penta::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue) {{{1*/
     4935void Penta::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue){
     4936
     4937        /*Intermediaries*/
     4938        double     value[NUMVERTICES];
     4939        GaussPenta *gauss              = NULL;
     4940
     4941        /*Recover input*/
     4942        Input* input=inputs->GetInput(enumtype);
     4943
     4944        /*Checks in debugging mode*/
     4945        _assert_(pvalue);
     4946
     4947        /* Start looping on the number of vertices: */
     4948        if (input){
     4949                gauss=new GaussPenta();
     4950                for (int iv=0;iv<NUMVERTICES;iv++){
     4951                        gauss->GaussVertex(iv);
     4952                        input->GetParameterValue(&pvalue[iv],gauss);
     4953                }
     4954        }
     4955        else{
     4956                for (int iv=0;iv<NUMVERTICES;iv++) pvalue[iv]=defaultvalue;
     4957        }
     4958
     4959        /*clean-up*/
     4960        delete gauss;
     4961}
     4962/*}}}*/
     4963/*FUNCTION Penta::GetParameterValue(double* pvalue,Node* node,int enumtype) {{{1*/
     4964void Penta::GetParameterValue(double* pvalue,Node* node,int enumtype){
     4965
     4966        Input* input=inputs->GetInput(enumtype);
     4967        if(!input) _error_("No input of type %s found in tria",EnumToStringx(enumtype));
     4968
     4969        GaussPenta* gauss=new GaussPenta();
     4970        gauss->GaussVertex(this->GetNodeIndex(node));
     4971
     4972        input->GetParameterValue(pvalue,gauss);
     4973        delete gauss;
     4974}
     4975/*}}}*/
     4976/*FUNCTION Penta::GetPhi {{{1*/
     4977void Penta::GetPhi(double* phi, double*  epsilon, double viscosity){
     4978        /*Compute deformational heating from epsilon and viscosity */
     4979
     4980        double epsilon_matrix[3][3];
     4981        double epsilon_eff;
     4982        double epsilon_sqr[3][3];
     4983
     4984        /* Build epsilon matrix */
     4985        epsilon_matrix[0][0]=*(epsilon+0);
     4986        epsilon_matrix[1][0]=*(epsilon+3);
     4987        epsilon_matrix[2][0]=*(epsilon+4);
     4988        epsilon_matrix[0][1]=*(epsilon+3);
     4989        epsilon_matrix[1][1]=*(epsilon+1);
     4990        epsilon_matrix[2][1]=*(epsilon+5);
     4991        epsilon_matrix[0][2]=*(epsilon+4);
     4992        epsilon_matrix[1][2]=*(epsilon+5);
     4993        epsilon_matrix[2][2]=*(epsilon+2);
     4994
     4995        /* Effective value of epsilon_matrix */
     4996        epsilon_sqr[0][0]=pow(epsilon_matrix[0][0],2);
     4997        epsilon_sqr[1][0]=pow(epsilon_matrix[1][0],2);
     4998        epsilon_sqr[2][0]=pow(epsilon_matrix[2][0],2);
     4999        epsilon_sqr[0][1]=pow(epsilon_matrix[0][1],2);
     5000        epsilon_sqr[1][1]=pow(epsilon_matrix[1][1],2);
     5001        epsilon_sqr[2][1]=pow(epsilon_matrix[2][1],2);
     5002        epsilon_sqr[0][2]=pow(epsilon_matrix[0][2],2);
     5003        epsilon_sqr[1][2]=pow(epsilon_matrix[1][2],2);
     5004        epsilon_sqr[2][2]=pow(epsilon_matrix[2][2],2);
     5005        epsilon_eff=1/pow(2,0.5)*pow((epsilon_sqr[0][0]+epsilon_sqr[0][1]+ epsilon_sqr[0][2]+ epsilon_sqr[1][0]+ epsilon_sqr[1][1]+ epsilon_sqr[1][2]+ epsilon_sqr[2][0]+ epsilon_sqr[2][1]+ epsilon_sqr[2][2]),0.5);
     5006
     5007        /*Phi = Tr(sigma * eps)
     5008         *    = Tr(sigma'* eps)
     5009         *    = 2 * eps_eff * sigma'_eff
     5010         *    = 4 * mu * eps_eff ^2*/
     5011        *phi=4*pow(epsilon_eff,2.0)*viscosity;
     5012}
     5013/*}}}*/
     5014/*FUNCTION Penta::GetSidList{{{1*/
     5015void  Penta::GetSidList(int* sidlist){
     5016
     5017        int i;
     5018        for(i=0;i<NUMVERTICES;i++) sidlist[i]=nodes[i]->GetSidList();
     5019
     5020}
     5021/*}}}*/
     5022/*FUNCTION Penta::GetSolutionFromInputs{{{1*/
     5023void  Penta::GetSolutionFromInputs(Vec solution){
     5024
     5025        int analysis_type;
     5026
     5027        /*retrive parameters: */
     5028        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     5029
     5030        /*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */
     5031        if (analysis_type==DiagnosticHorizAnalysisEnum){
     5032                int approximation;
     5033                inputs->GetParameterValue(&approximation,ApproximationEnum);
     5034                if(approximation==StokesApproximationEnum || approximation==NoneApproximationEnum){
     5035                        GetSolutionFromInputsDiagnosticStokes(solution);
     5036                }
     5037                else if (approximation==MacAyealApproximationEnum || approximation==PattynApproximationEnum || approximation==HutterApproximationEnum){
     5038                        GetSolutionFromInputsDiagnosticHoriz(solution);
     5039                }
     5040                else if (approximation==MacAyealPattynApproximationEnum || approximation==PattynStokesApproximationEnum || approximation==MacAyealStokesApproximationEnum){
     5041                        return; //the elements around will create the solution
     5042                }
     5043        }
     5044        else if(analysis_type==DiagnosticHutterAnalysisEnum){
     5045                GetSolutionFromInputsDiagnosticHutter(solution);
     5046        }
     5047        else if(analysis_type==DiagnosticVertAnalysisEnum){
     5048                GetSolutionFromInputsDiagnosticVert(solution);
     5049        }
     5050        #ifdef _HAVE_THERMAL_
     5051        else if(analysis_type==ThermalAnalysisEnum){
     5052                GetSolutionFromInputsThermal(solution);
     5053        }
     5054        else if(analysis_type==EnthalpyAnalysisEnum){
     5055                GetSolutionFromInputsEnthalpy(solution);
     5056        }
     5057        #endif
     5058        else{
     5059                _error_("analysis: %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type));
     5060        }
     5061}
     5062/*}}}*/
     5063/*FUNCTION Penta::GetSolutionFromInputsDiagnosticHoriz{{{1*/
     5064void  Penta::GetSolutionFromInputsDiagnosticHoriz(Vec solution){
     5065
     5066        const int    numdof=NDOF2*NUMVERTICES;
     5067
     5068        int          i;
     5069        int          approximation;
     5070        int*         doflist=NULL;
     5071        double       vx,vy;
     5072        double       values[numdof];
     5073        GaussPenta*  gauss;
     5074
     5075        /*Get approximation enum and dof list: */
     5076        inputs->GetParameterValue(&approximation,ApproximationEnum);
     5077        Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
     5078        Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
     5079
     5080        /*If the element is a coupling, do nothing: every node is also on an other elements
     5081         * (as coupling is between MacAyeal and Pattyn) so the other element will take care of it*/
     5082        GetDofList(&doflist,approximation,GsetEnum);
     5083
     5084        /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
     5085        /*P1 element only for now*/
     5086        gauss=new GaussPenta();
     5087        for(i=0;i<NUMVERTICES;i++){
     5088
     5089                /*Recover vx and vy*/
     5090                gauss->GaussVertex(i);
     5091                vx_input->GetParameterValue(&vx,gauss);
     5092                vy_input->GetParameterValue(&vy,gauss);
     5093                values[i*NDOF2+0]=vx;
     5094                values[i*NDOF2+1]=vy;
     5095        }
     5096
     5097        /*Add value to global vector*/
     5098        VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
     5099
     5100        /*Free ressources:*/
     5101        delete gauss;
     5102        xfree((void**)&doflist);
     5103}
     5104/*}}}*/
     5105/*FUNCTION Penta::GetSolutionFromInputsDiagnosticHutter{{{1*/
     5106void  Penta::GetSolutionFromInputsDiagnosticHutter(Vec solution){
     5107
     5108        const int    numdof=NDOF2*NUMVERTICES;
     5109
     5110        int          i;
     5111        int*         doflist=NULL;
     5112        double       vx,vy;
     5113        double       values[numdof];
     5114        GaussPenta*  gauss=NULL;
     5115
     5116        /*Get dof list: */
     5117        GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
     5118        Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
     5119        Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
     5120
     5121        /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
     5122        /*P1 element only for now*/
     5123        gauss=new GaussPenta();
     5124        for(i=0;i<NUMVERTICES;i++){
     5125                /*Recover vx and vy*/
     5126                gauss->GaussVertex(i);
     5127                vx_input->GetParameterValue(&vx,gauss);
     5128                vy_input->GetParameterValue(&vy,gauss);
     5129                values[i*NDOF2+0]=vx;
     5130                values[i*NDOF2+1]=vy;
     5131        }
     5132
     5133        /*Add value to global vector*/
     5134        VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
     5135
     5136        /*Free ressources:*/
     5137        delete gauss;
     5138        xfree((void**)&doflist);
     5139}
     5140/*}}}*/
     5141/*FUNCTION Penta::GetSolutionFromInputsDiagnosticVert{{{1*/
     5142void  Penta::GetSolutionFromInputsDiagnosticVert(Vec solution){
     5143
     5144        const int    numdof=NDOF1*NUMVERTICES;
     5145
     5146        int          i;
     5147        int*         doflist=NULL;
     5148        double       vz;
     5149        double       values[numdof];
     5150        GaussPenta*  gauss=NULL;
     5151
     5152        /*Get dof list: */
     5153        GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
     5154        Input* vz_input=inputs->GetInput(VzEnum); _assert_(vz_input);
     5155
     5156        /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
     5157        /*P1 element only for now*/
     5158        gauss=new GaussPenta();
     5159        for(i=0;i<NUMVERTICES;i++){
     5160                /*Recover vz */
     5161                gauss->GaussVertex(i);
     5162                vz_input->GetParameterValue(&vz,gauss);
     5163                values[i]=vz;
     5164        }
     5165
     5166        /*Add value to global vector*/
     5167        VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
     5168
     5169        /*Free ressources:*/
     5170        delete gauss;
     5171        xfree((void**)&doflist);
     5172}
     5173/*}}}*/
     5174/*FUNCTION Penta::GetSolutionFromInputsDiagnosticStokes{{{1*/
     5175void  Penta::GetSolutionFromInputsDiagnosticStokes(Vec solution){
     5176
     5177        const int    numdof=NDOF4*NUMVERTICES;
     5178
     5179        int          i;
     5180        int*         doflist=NULL;
     5181        double       vx,vy,vz,p;
     5182        double       stokesreconditioning;
     5183        double       values[numdof];
     5184        GaussPenta   *gauss;
     5185
     5186        /*Get dof list: */
     5187        GetDofList(&doflist,StokesApproximationEnum,GsetEnum);
     5188        Input* vx_input=inputs->GetInput(VxEnum);       _assert_(vx_input);
     5189        Input* vy_input=inputs->GetInput(VyEnum);       _assert_(vy_input);
     5190        Input* vz_input=inputs->GetInput(VzEnum);       _assert_(vz_input);
     5191        Input* p_input =inputs->GetInput(PressureEnum); _assert_(p_input);
     5192
     5193        /*Recondition pressure: */
     5194        this->parameters->FindParam(&stokesreconditioning,DiagnosticStokesreconditioningEnum);
     5195
     5196        /*Ok, we have vx vy vz and P in values, fill in vx vy vz P arrays: */
     5197        /*P1 element only for now*/
     5198        gauss=new GaussPenta();
     5199        for(i=0;i<NUMVERTICES;i++){
     5200                gauss->GaussVertex(i);
     5201                vx_input->GetParameterValue(&vx,gauss);
     5202                vy_input->GetParameterValue(&vy,gauss);
     5203                vz_input->GetParameterValue(&vz,gauss);
     5204                p_input ->GetParameterValue(&p ,gauss);
     5205                values[i*NDOF4+0]=vx;
     5206                values[i*NDOF4+1]=vy;
     5207                values[i*NDOF4+2]=vz;
     5208                values[i*NDOF4+3]=p/stokesreconditioning;
     5209        }
     5210
     5211        /*Add value to global vector*/
     5212        VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
     5213
     5214        /*Free ressources:*/
     5215        delete gauss;
     5216        xfree((void**)&doflist);
     5217}
     5218/*}}}*/
     5219/*FUNCTION Penta::GetStabilizationParameter {{{1*/
     5220double Penta::GetStabilizationParameter(double u, double v, double w, double diameter, double rho_ice, double heatcapacity, double thermalconductivity){
     5221        /*Compute stabilization parameter*/
     5222
     5223        double normu;
     5224        double tau_parameter;
     5225
     5226        normu=pow(pow(u,2)+pow(v,2)+pow(w,2),0.5);
     5227        if(normu*diameter/(3*2*thermalconductivity/(rho_ice*heatcapacity))<1){
     5228                tau_parameter=pow(diameter,2)/(3*2*2*thermalconductivity/(rho_ice*heatcapacity));
     5229        }
     5230        else tau_parameter=diameter/(2*normu);
     5231
     5232        return tau_parameter;
     5233}
     5234/*}}}*/
     5235/*FUNCTION Penta::GetStrainRate3dPattyn{{{1*/
     5236void Penta::GetStrainRate3dPattyn(double* epsilon,double* xyz_list, GaussPenta* gauss, Input* vx_input, Input* vy_input){
     5237        /*Compute the 3d Blatter/PattynStrain Rate (5 components):
     5238         *
     5239         * epsilon=[exx eyy exy exz eyz]
     5240         *
     5241         * with exz=1/2 du/dz
     5242         *      eyz=1/2 dv/dz
     5243         *
     5244         * the contribution of vz is neglected
     5245         */
     5246
     5247        int i;
     5248        double epsilonvx[5];
     5249        double epsilonvy[5];
     5250
     5251        /*Check that both inputs have been found*/
     5252        if (!vx_input || !vy_input){
     5253                _error_("Input missing. Here are the input pointers we have for vx: %p, vy: %p\n",vx_input,vy_input);
     5254        }
     5255
     5256        /*Get strain rate assuming that epsilon has been allocated*/
     5257        vx_input->GetVxStrainRate3dPattyn(epsilonvx,xyz_list,gauss);
     5258        vy_input->GetVyStrainRate3dPattyn(epsilonvy,xyz_list,gauss);
     5259
     5260        /*Sum all contributions*/
     5261        for(i=0;i<5;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i];
     5262}
     5263/*}}}*/
     5264/*FUNCTION Penta::GetStrainRate3d{{{1*/
     5265void Penta::GetStrainRate3d(double* epsilon,double* xyz_list, GaussPenta* gauss, Input* vx_input, Input* vy_input, Input* vz_input){
     5266        /*Compute the 3d Strain Rate (6 components):
     5267         *
     5268         * epsilon=[exx eyy ezz exy exz eyz]
     5269         */
     5270
     5271        int i;
     5272        double epsilonvx[6];
     5273        double epsilonvy[6];
     5274        double epsilonvz[6];
     5275
     5276        /*Check that both inputs have been found*/
     5277        if (!vx_input || !vy_input || !vz_input){
     5278                _error_("Input missing. Here are the input pointers we have for vx: %p, vy: %p, vz: %p\n",vx_input,vy_input,vz_input);
     5279        }
     5280
     5281        /*Get strain rate assuming that epsilon has been allocated*/
     5282        vx_input->GetVxStrainRate3d(epsilonvx,xyz_list,gauss);
     5283        vy_input->GetVyStrainRate3d(epsilonvy,xyz_list,gauss);
     5284        vz_input->GetVzStrainRate3d(epsilonvz,xyz_list,gauss);
     5285
     5286        /*Sum all contributions*/
     5287        for(i=0;i<6;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i]+epsilonvz[i];
     5288}
     5289/*}}}*/
     5290/*FUNCTION Penta::GetUpperElement{{{1*/
     5291Penta* Penta::GetUpperElement(void){
     5292
     5293        Penta* upper_penta=NULL;
     5294
     5295        upper_penta=(Penta*)verticalneighbors[1]; //first one under, second one above
     5296
     5297        return upper_penta;
     5298}
     5299/*}}}*/
     5300/*FUNCTION Penta::GetVectorFromInputs{{{1*/
     5301void  Penta::GetVectorFromInputs(Vec vector,int input_enum){
     5302
     5303        int doflist1[NUMVERTICES];
     5304
     5305        /*Get out if this is not an element input*/
     5306        if (!IsInput(input_enum)) return;
     5307
     5308        /*Prepare index list*/
     5309        this->GetDofList1(&doflist1[0]);
     5310
     5311        /*Get input (either in element or material)*/
     5312        Input* input=inputs->GetInput(input_enum);
     5313        if(!input) _error_("Input %s not found in element",EnumToStringx(input_enum));
     5314
     5315        /*We found the enum.  Use its values to fill into the vector, using the vertices ids: */
     5316        input->GetVectorFromInputs(vector,&doflist1[0]);
     5317}
     5318/*}}}*/
     5319/*FUNCTION Penta::GetZcoord {{{1*/
     5320double Penta::GetZcoord(GaussPenta* gauss){
     5321
     5322        int    i;
     5323        double z;
     5324        double xyz_list[NUMVERTICES][3];
     5325        double z_list[NUMVERTICES];
     5326
     5327        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     5328        for(i=0;i<NUMVERTICES;i++) z_list[i]=xyz_list[i][2];
     5329        PentaRef::GetParameterValue(&z,z_list,gauss);
     5330
     5331        return z;
     5332}
     5333/*}}}*/
    47165334/*FUNCTION Penta::Sid {{{1*/
    47175335int    Penta::Sid(){
     
    47695387        /*Return output*/
    47705388        return converged;
    4771 }
    4772 /*}}}*/
    4773 /*FUNCTION Penta::InputControlUpdate{{{1*/
    4774 void  Penta::InputControlUpdate(double scalar,bool save_parameter){
    4775 
    4776         /*Intermediary*/
    4777         int    num_controls;
    4778         int*   control_type=NULL;
    4779         Input* input=NULL;
    4780 
    4781         /*retrieve some parameters: */
    4782         this->parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
    4783         this->parameters->FindParam(&control_type,NULL,InversionControlParametersEnum);
    4784 
    4785         for(int i=0;i<num_controls;i++){
    4786 
    4787                 if(control_type[i]==MaterialsRheologyBbarEnum){
    4788                         if (!IsOnBed()) goto cleanup_and_return;
    4789                         input=(Input*)matice->inputs->GetInput(MaterialsRheologyBEnum); _assert_(input);
    4790                 }
    4791                 else{
    4792                         input=(Input*)this->inputs->GetInput(control_type[i]); _assert_(input);
    4793                 }
    4794 
    4795                 if (input->Enum()!=ControlInputEnum) _error_("input %s is not a ControlInput",EnumToStringx(control_type[i]));
    4796 
    4797                 ((ControlInput*)input)->UpdateValue(scalar);
    4798                 ((ControlInput*)input)->Constrain();
    4799                 if (save_parameter) ((ControlInput*)input)->SaveValue();
    4800 
    4801                 if(control_type[i]==MaterialsRheologyBbarEnum){
    4802                         this->InputExtrude(MaterialsRheologyBEnum,MaterialsEnum);
    4803                 }
    4804         }
    4805 
    4806         /*Clean up and return*/
    4807 cleanup_and_return:
    4808         xfree((void**)&control_type);
    48095389}
    48105390/*}}}*/
     
    51055685         * object out of the input, with the additional step and time information: */
    51065686        this->results->AddObject((Object*)input->SpawnResult(step,time));
     5687        #ifdef _HAVE_CONTROL_
    51075688        if(input->Enum()==ControlInputEnum) this->results->AddObject((Object*)((ControlInput*)input)->SpawnGradient(step,time));
     5689        #endif
    51085690
    51095691}
     
    51695751
    51705752        /*Control Inputs*/
     5753        #ifdef _HAVE_CONTROL_
    51715754        if (control_analysis && iomodel->Data(InversionControlParametersEnum)){
    51725755                for(i=0;i<num_control_type;i++){
     
    52115794                }
    52125795        }
     5796        #endif
    52135797
    52145798        //Need to know the type of approximation for this element
     
    52765860                InputUpdateFromSolutionDiagnosticVert( solution);
    52775861        }
     5862        #ifdef _HAVE_CONTROL_
    52785863        else if (analysis_type==AdjointHorizAnalysisEnum){
    52795864                int approximation;
     
    52865871                }
    52875872        }
     5873        #endif
    52885874        else if (analysis_type==BedSlopeXAnalysisEnum){
    52895875                InputUpdateFromSolutionOneDofCollapsed(solution,BedSlopeXEnum);
     
    53045890                InputUpdateFromSolutionOneDofCollapsed(solution,ThicknessEnum);
    53055891        }
     5892        #ifdef _HAVE_THERMAL_
    53065893        else if (analysis_type==ThermalAnalysisEnum){
    53075894                InputUpdateFromSolutionThermal( solution);
     
    53135900                InputUpdateFromSolutionOneDof(solution,BasalforcingsMeltingRateEnum);
    53145901        }
     5902        #endif
    53155903        else{
    53165904                _error_("analysis %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type));
     
    60506638}
    60516639/*}}}*/
    6052 /*FUNCTION Penta::InputUpdateFromSolutionAdjointStokes {{{1*/
    6053 void  Penta::InputUpdateFromSolutionAdjointStokes(double* solution){
    6054 
    6055         const int    numdof=NDOF4*NUMVERTICES;
    6056 
    6057         int    i;
    6058         double values[numdof];
    6059         double lambdax[NUMVERTICES];
    6060         double lambday[NUMVERTICES];
    6061         double lambdaz[NUMVERTICES];
    6062         double lambdap[NUMVERTICES];
    6063         int*   doflist=NULL;
    6064 
    6065         /*Get dof list: */
    6066         GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
    6067 
    6068         /*Use the dof list to index into the solution vector: */
    6069         for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
    6070 
    6071         /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
    6072         for(i=0;i<NUMVERTICES;i++){
    6073                 lambdax[i]=values[i*NDOF4+0];
    6074                 lambday[i]=values[i*NDOF4+1];
    6075                 lambdaz[i]=values[i*NDOF4+2];
    6076                 lambdap[i]=values[i*NDOF4+3];
    6077 
    6078                 /*Check solution*/
    6079                 if(isnan(lambdax[i])) _error_("NaN found in solution vector");
    6080                 if(isnan(lambday[i])) _error_("NaN found in solution vector");
    6081                 if(isnan(lambdaz[i])) _error_("NaN found in solution vector");
    6082                 if(isnan(lambdap[i])) _error_("NaN found in solution vector");
    6083         }
    6084 
    6085         /*Add vx and vy as inputs to the tria element: */
    6086         this->inputs->AddInput(new PentaVertexInput(AdjointxEnum,lambdax));
    6087         this->inputs->AddInput(new PentaVertexInput(AdjointyEnum,lambday));
    6088         this->inputs->AddInput(new PentaVertexInput(AdjointzEnum,lambdaz));
    6089         this->inputs->AddInput(new PentaVertexInput(AdjointpEnum,lambdap));
    6090 
    6091         /*Free ressources:*/
    6092         xfree((void**)&doflist);
    6093 }
    6094 /*}}}*/
    6095 /*FUNCTION Penta::InputUpdateFromSolutionAdjointHoriz {{{1*/
    6096 void  Penta::InputUpdateFromSolutionAdjointHoriz(double* solution){
    6097 
    6098         const int numdof=NDOF2*NUMVERTICES;
    6099 
    6100         int    i;
    6101         double values[numdof];
    6102         double lambdax[NUMVERTICES];
    6103         double lambday[NUMVERTICES];
    6104         int*   doflist=NULL;
    6105 
    6106         /*Get dof list: */
    6107         GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
    6108 
    6109         /*Use the dof list to index into the solution vector: */
    6110         for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
    6111 
    6112         /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
    6113         for(i=0;i<NUMVERTICES;i++){
    6114                 lambdax[i]=values[i*NDOF2+0];
    6115                 lambday[i]=values[i*NDOF2+1];
    6116 
    6117                 /*Check solution*/
    6118                 if(isnan(lambdax[i]))       _error_("NaN found in solution vector");
    6119                 if(isnan(lambday[i]))       _error_("NaN found in solution vector");
    6120         }
    6121 
    6122         /*Add vx and vy as inputs to the tria element: */
    6123         this->inputs->AddInput(new PentaVertexInput(AdjointxEnum,lambdax));
    6124         this->inputs->AddInput(new PentaVertexInput(AdjointyEnum,lambday));
    6125 
    6126         /*Free ressources:*/
    6127         xfree((void**)&doflist);
    6128 }
    6129 /*}}}*/
    61306640/*FUNCTION Penta::InputUpdateFromSolutionPrognostic{{{1*/
    61316641void  Penta::InputUpdateFromSolutionPrognostic(double* solution){
     
    62136723}
    62146724/*}}}*/
    6215 /*FUNCTION Penta::InputUpdateFromSolutionThermal {{{1*/
    6216 void  Penta::InputUpdateFromSolutionThermal(double* solution){
    6217 
    6218         const int    numdof=NDOF1*NUMVERTICES;
    6219 
    6220         bool   converged;
    6221         int    i,rheology_law;
    6222         double xyz_list[NUMVERTICES][3];
    6223         double values[numdof];
    6224         double B[numdof];
    6225         double B_average,s_average;
    6226         int*   doflist=NULL;
    6227 
    6228         /*Get dof list: */
    6229         GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
    6230 
    6231         /*Use the dof list to index into the solution vector: */
    6232         for(i=0;i<numdof;i++){
    6233                 values[i]=solution[doflist[i]];
    6234 
    6235                 /*Check solution*/
    6236                 if(isnan(values[i])) _error_("NaN found in solution vector");
    6237                 //if(values[i]<0)      printf("temperature < 0°K found in solution vector\n");
    6238                 //if(values[i]>275)    printf("temperature > 275°K found in solution vector (Paterson's rheology associated is negative)\n");
    6239         }
    6240 
    6241         /*Get all inputs and parameters*/
    6242         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    6243         Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);
    6244 
    6245         this->inputs->GetParameterValue(&converged,ConvergedEnum);
    6246         if(converged){
    6247                 this->inputs->AddInput(new PentaVertexInput(TemperatureEnum,values));
    6248 
    6249                 /*Update Rheology only if converged (we must make sure that the temperature is below melting point
    6250                  * otherwise the rheology could be negative*/
    6251                 this->parameters->FindParam(&rheology_law,MaterialsRheologyLawEnum);
    6252                 switch(rheology_law){
    6253                         case NoneEnum:
    6254                                 /*Do nothing: B is not temperature dependent*/
    6255                                 break;
    6256                         case PatersonEnum:
    6257                                 B_average=Paterson((values[0]+values[1]+values[2]+values[3]+values[4]+values[5])/6.0);
    6258                                 for(i=0;i<numdof;i++) B[i]=B_average;
    6259                                 this->matice->inputs->AddInput(new PentaVertexInput(MaterialsRheologyBEnum,B));
    6260                                 break;
    6261                         case ArrheniusEnum:
    6262                                 surface_input->GetParameterAverage(&s_average);
    6263                                 B_average=Arrhenius((values[0]+values[1]+values[2]+values[3]+values[4]+values[5])/6.0,
    6264                                                         s_average-((xyz_list[0][2]+xyz_list[1][2]+xyz_list[2][2]+xyz_list[3][2]+xyz_list[4][2]+xyz_list[5][2])/6.0),
    6265                                                         matice->GetN());
    6266                                 for(i=0;i<numdof;i++) B[i]=B_average;
    6267                                 this->matice->inputs->AddInput(new PentaVertexInput(MaterialsRheologyBEnum,B));
    6268                                 break;
    6269                         default:
    6270                                 _error_("Rheology law %s not supported yet",EnumToStringx(rheology_law));
    6271 
    6272                 }
    6273         }
    6274         else{
    6275                 this->inputs->AddInput(new PentaVertexInput(TemperaturePicardEnum,values));
    6276         }
    6277 
    6278         /*Free ressources:*/
    6279         xfree((void**)&doflist);
    6280 }
    6281 /*}}}*/
    6282 /*FUNCTION Penta::InputUpdateFromSolutionEnthalpy {{{1*/
    6283 void  Penta::InputUpdateFromSolutionEnthalpy(double* solution){
    6284 
    6285         const int    numdof=NDOF1*NUMVERTICES;
    6286 
    6287         bool   converged;
    6288         int    i,rheology_law;
    6289         double xyz_list[NUMVERTICES][3];
    6290         double values[numdof];
    6291         double pressure[NUMVERTICES];
    6292         double temperatures[numdof];
    6293         double waterfraction[numdof];
    6294         double B[numdof];
    6295         double B_average,s_average;
    6296         int*   doflist=NULL;
    6297 
    6298         /*Get dof list: */
    6299         GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
    6300 
    6301         /*Use the dof list to index into the solution vector: */
    6302         for(i=0;i<numdof;i++){
    6303                 values[i]=solution[doflist[i]];
    6304 
    6305                 /*Check solution*/
    6306                 if(isnan(values[i])) _error_("NaN found in solution vector");
    6307         }
    6308 
    6309         /*Get all inputs and parameters*/
    6310         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    6311         GetParameterListOnVertices(&pressure[0],PressureEnum);
    6312         Input* surface_input=inputs->GetInput(SurfaceEnum); _assert_(surface_input);
    6313        
    6314 
    6315 //      this->inputs->GetParameterValue(&converged,ConvergedEnum);
    6316 //      if(converged){
    6317                 /*Convert enthalpy into temperature and water fraction*/
    6318                 for(i=0;i<numdof;i++) matpar->EnthalpyToThermal(&temperatures[i],&waterfraction[i],values[i],pressure[i]);
    6319                        
    6320                 this->inputs->AddInput(new PentaVertexInput(EnthalpyEnum,values));
    6321                 this->inputs->AddInput(new PentaVertexInput(WaterfractionEnum,waterfraction));
    6322                 this->inputs->AddInput(new PentaVertexInput(TemperatureEnum,temperatures));
    6323 
    6324                 /*Update Rheology only if converged (we must make sure that the temperature is below melting point
    6325                  * otherwise the rheology could be negative*/
    6326                 this->parameters->FindParam(&rheology_law,MaterialsRheologyLawEnum);
    6327                 switch(rheology_law){
    6328                         case NoneEnum:
    6329                                 /*Do nothing: B is not temperature dependent*/
    6330                                 break;
    6331                         case PatersonEnum:
    6332                                 B_average=Paterson((temperatures[0]+temperatures[1]+temperatures[2]+temperatures[3]+temperatures[4]+temperatures[5])/6.0);
    6333                                 for(i=0;i<numdof;i++) B[i]=B_average;
    6334                                 this->matice->inputs->AddInput(new PentaVertexInput(MaterialsRheologyBEnum,B));
    6335                                 break;
    6336                         case ArrheniusEnum:
    6337                                 surface_input->GetParameterAverage(&s_average);
    6338                                 B_average=Arrhenius((temperatures[0]+temperatures[1]+temperatures[2]+temperatures[3]+temperatures[4]+temperatures[5])/6.0,
    6339                                                         s_average-((xyz_list[0][2]+xyz_list[1][2]+xyz_list[2][2]+xyz_list[3][2]+xyz_list[4][2]+xyz_list[5][2])/6.0),
    6340                                                         matice->GetN());
    6341                                 for(i=0;i<numdof;i++) B[i]=B_average;
    6342                                 this->matice->inputs->AddInput(new PentaVertexInput(MaterialsRheologyBEnum,B));
    6343                                 break;
    6344                         default:
    6345                                 _error_("Rheology law %s not supported yet",EnumToStringx(rheology_law));
    6346 
    6347                 }
    6348 //      }
    6349 //      else{
    6350 //              this->inputs->AddInput(new PentaVertexInput(EnthalpyPicardEnum,values));
    6351 //      }
    6352 
    6353         /*Free ressources:*/
    6354         xfree((void**)&doflist);
    6355 }
    6356 /*}}}*/
    63576725/*FUNCTION Penta::InputUpdateFromSolutionOneDof{{{1*/
    63586726void  Penta::InputUpdateFromSolutionOneDof(double* solution,int enum_type){
     
    64566824/*FUNCTION Penta::InputUpdateFromVector(bool* vector, int name, int type);{{{1*/
    64576825void  Penta::InputUpdateFromVector(bool* vector, int name, int type){
    6458         _error_(" not supported yet!");
    6459 }
    6460 /*}}}*/
    6461 /*FUNCTION Penta::InputUpdateFromVectorDakota(double* vector, int name, int type);{{{1*/
    6462 void  Penta::InputUpdateFromVectorDakota(double* vector, int name, int type){
    6463        
    6464         int i,j;
    6465 
    6466         /*Check that name is an element input*/
    6467         if (!IsInput(name)) return;
    6468 
    6469         switch(type){
    6470 
    6471                 case VertexEnum:
    6472 
    6473                         /*New PentaVertexInput*/
    6474                         double values[6];
    6475 
    6476                         /*Get values on the 6 vertices*/
    6477                         for (i=0;i<6;i++){
    6478                                 values[i]=vector[this->nodes[i]->GetSidList()]; //careful, vector of values here is not parallel distributed, but serial distributed (from a serial Dakota core!)
    6479                         }
    6480 
    6481                         /*Branch on the specified type of update: */
    6482                         switch(name){
    6483                                 case ThicknessEnum:
    6484                                         /*Update thickness + surface: assume bed is constant. On ice shelves, takes hydrostatic equilibrium {{{2*/
    6485                                         double  thickness[6];
    6486                                         double  thickness_init[6];
    6487                                         double  hydrostatic_ratio[6];
    6488                                         double  surface[6];
    6489                                         double  bed[6];
    6490                                        
    6491                                         /*retrieve inputs: */
    6492                                         GetParameterListOnVertices(&thickness_init[0],ThicknessEnum);
    6493                                         GetParameterListOnVertices(&hydrostatic_ratio[0],GeometryHydrostaticRatioEnum);
    6494                                         GetParameterListOnVertices(&bed[0],BedEnum);
    6495                                         GetParameterListOnVertices(&surface[0],SurfaceEnum);
    6496 
    6497                                         /*build new thickness: */
    6498 //                                      for(j=0;j<6;j++)thickness[j]=values[j];
    6499 
    6500                                         /*build new bed and surface: */
    6501                                         if (this->IsOnShelf()){
    6502                                                 /*hydrostatic equilibrium: */
    6503                                                 double rho_ice,rho_water,di;
    6504                                                 rho_ice=this->matpar->GetRhoIce();
    6505                                                 rho_water=this->matpar->GetRhoWater();
    6506 
    6507                                                 di=rho_ice/rho_water;
    6508 
    6509                                                 /*build new thickness: */
    6510                                                 for (j=0; j<6; j++) {
    6511                                                 /*  for observed/interpolated/hydrostatic thickness, remove scaling from any hydrostatic thickness  */
    6512                                                         if     (hydrostatic_ratio[j] >= 0.)
    6513                                                                 thickness[j]=values[j]-(values[j]/thickness_init[j]-1.)*hydrostatic_ratio[j]*surface[j]/(1.-di);
    6514                                                 /*  for minimum thickness, don't scale  */
    6515                                                         else
    6516                                                                 thickness[j]=thickness_init[j];
    6517 
    6518                                                 /*  check the computed thickness and update bed  */
    6519                                                         if (thickness[j] < 0.)
    6520                                                                 thickness[j]=1./(1.-di);
    6521                                                         bed[j]=surface[j]-thickness[j];
    6522                                                 }
    6523 
    6524 //                                              for(j=0;j<6;j++){
    6525 //                                                      surface[j]=(1-di)*thickness[j];
    6526 //                                                      bed[j]=-di*thickness[j];
    6527 //                                              }
    6528                                         }
    6529                                         else{
    6530                                                 /*build new thickness: */
    6531                                                 for (j=0; j<6; j++) {
    6532                                                 /*  for observed thickness, use scaled value  */
    6533                                                         if(hydrostatic_ratio[j] >= 0.)
    6534                                                                 thickness[j]=values[j];
    6535                                                 /*  for minimum thickness, don't scale  */
    6536                                                         else
    6537                                                                 thickness[j]=thickness_init[j];
    6538                                                 }
    6539 
    6540                                                 /*update bed on grounded ice: */
    6541 //                                              for(j=0;j<6;j++)surface[j]=bed[j]+thickness[j];
    6542                                                 for(j=0;j<6;j++)bed[j]=surface[j]-thickness[j];
    6543                                         }
    6544 
    6545                                         /*Add new inputs: */
    6546                                         this->inputs->AddInput(new PentaVertexInput(ThicknessEnum,thickness));
    6547                                         this->inputs->AddInput(new PentaVertexInput(BedEnum,bed));
    6548                                         this->inputs->AddInput(new PentaVertexInput(SurfaceEnum,surface));
    6549 
    6550                                         /*}}}*/
    6551                                         break;
    6552                                 default:
    6553                                         this->inputs->AddInput(new PentaVertexInput(name,values));
    6554                         }
    6555                         break;
    6556 
    6557                 default:
    6558                         _error_("type %i (%s) not implemented yet",type,EnumToStringx(type));
    6559         }
    6560 
    6561 }
    6562 /*}}}*/
    6563 /*FUNCTION Penta::InputUpdateFromVectorDakota(int* vector, int name, int type);{{{1*/
    6564 void  Penta::InputUpdateFromVectorDakota(int* vector, int name, int type){
    6565         _error_(" not supported yet!");
    6566 }
    6567 /*}}}*/
    6568 /*FUNCTION Penta::InputUpdateFromVectorDakota(bool* vector, int name, int type);{{{1*/
    6569 void  Penta::InputUpdateFromVectorDakota(bool* vector, int name, int type){
    65706826        _error_(" not supported yet!");
    65716827}
     
    70897345}
    70907346/*}}}*/
    7091 /*FUNCTION Penta::RheologyBbarAbsGradient{{{1*/
    7092 double Penta::RheologyBbarAbsGradient(bool process_units,int weight_index){
    7093 
    7094         double J;
    7095         Tria*  tria=NULL;
    7096 
    7097         /*If on water, on shelf or not on bed, skip: */
    7098         if(IsOnWater() || !IsOnBed()) return 0;
    7099 
    7100         tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria
    7101         J=tria->RheologyBbarAbsGradient(process_units,weight_index);
    7102         delete tria->matice; delete tria;
    7103         return J;
    7104 }
    7105 /*}}}*/
    71067347/*FUNCTION Penta::SetClone {{{1*/
    71077348void  Penta::SetClone(int* minranks){
     
    72067447}
    72077448/*}}}*/
    7208 /*FUNCTION Penta::SurfaceAverageVelMisfit {{{1*/
    7209 double Penta::SurfaceAverageVelMisfit(bool process_units,int weight_index){
    7210 
    7211         int    approximation;
    7212         double J;
    7213         Tria*  tria=NULL;
    7214 
    7215         /*retrieve inputs :*/
    7216         inputs->GetParameterValue(&approximation,ApproximationEnum);
    7217 
    7218         /*If on water, return 0: */
    7219         if(IsOnWater())return 0;
    7220 
    7221         /*Bail out if this element if:
    7222          * -> Non MacAyeal and not on the surface
    7223          * -> MacAyeal (2d model) and not on bed) */
    7224         if ((approximation!=MacAyealApproximationEnum && !IsOnSurface()) || (approximation==MacAyealApproximationEnum && !IsOnBed())){
    7225                 return 0;
    7226         }
    7227         else if (approximation==MacAyealApproximationEnum){
    7228 
    7229                 /*This element should be collapsed into a tria element at its base. Create this tria element,
    7230                  * and compute SurfaceAverageVelMisfit*/
    7231                 tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria (lower face).
    7232                 J=tria->SurfaceAverageVelMisfit(process_units,weight_index);
    7233                 delete tria->matice; delete tria;
    7234                 return J;
    7235         }
    7236         else{
    7237 
    7238                 tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
    7239                 J=tria->SurfaceAverageVelMisfit(process_units,weight_index);
    7240                 delete tria->matice; delete tria;
    7241                 return J;
    7242         }
    7243 }
    7244 /*}}}*/
    7245 /*FUNCTION Penta::SurfaceAbsVelMisfit {{{1*/
    7246 double Penta::SurfaceAbsVelMisfit(bool process_units,int weight_index){
    7247 
    7248         int    approximation;
    7249         double J;
    7250         Tria*  tria=NULL;
    7251 
    7252         /*retrieve inputs :*/
    7253         inputs->GetParameterValue(&approximation,ApproximationEnum);
    7254 
    7255         /*If on water, return 0: */
    7256         if(IsOnWater())return 0;
    7257 
    7258         /*Bail out if this element if:
    7259          * -> Non MacAyeal and not on the surface
    7260          * -> MacAyeal (2d model) and not on bed) */
    7261         if ((approximation!=MacAyealApproximationEnum && !IsOnSurface()) || (approximation==MacAyealApproximationEnum && !IsOnBed())){
    7262                 return 0;
    7263         }
    7264         else if (approximation==MacAyealApproximationEnum){
    7265 
    7266                 /*This element should be collapsed into a tria element at its base. Create this tria element,
    7267                  * and compute SurfaceAbsVelMisfit*/
    7268                 tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria (lower face).
    7269                 J=tria->SurfaceAbsVelMisfit(process_units,weight_index);
    7270                 delete tria->matice; delete tria;
    7271                 return J;
    7272         }
    7273         else{
    7274 
    7275                 tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
    7276                 J=tria->SurfaceAbsVelMisfit(process_units,weight_index);
    7277                 delete tria->matice; delete tria;
    7278                 return J;
    7279         }
    7280 }
    7281 /*}}}*/
    7282 /*FUNCTION Penta::SurfaceLogVelMisfit {{{1*/
    7283 double Penta::SurfaceLogVelMisfit(bool process_units,int weight_index){
    7284 
    7285         int    approximation;
    7286         double J;
    7287         Tria*  tria=NULL;
    7288 
    7289         /*retrieve inputs :*/
    7290         inputs->GetParameterValue(&approximation,ApproximationEnum);
    7291 
    7292         /*If on water, return 0: */
    7293         if(IsOnWater())return 0;
    7294 
    7295         /*Bail out if this element if:
    7296          * -> Non MacAyeal and not on the surface
    7297          * -> MacAyeal (2d model) and not on bed) */
    7298         if ((approximation!=MacAyealApproximationEnum && !IsOnSurface()) || (approximation==MacAyealApproximationEnum && !IsOnBed())){
    7299                 return 0;
    7300         }
    7301         else if (approximation==MacAyealApproximationEnum){
    7302 
    7303                 /*This element should be collapsed into a tria element at its base. Create this tria element,
    7304                  * and compute SurfaceLogVelMisfit*/
    7305                 tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria (lower face).
    7306                 J=tria->SurfaceLogVelMisfit(process_units,weight_index);
    7307                 delete tria->matice; delete tria;
    7308                 return J;
    7309         }
    7310         else{
    7311 
    7312                 tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
    7313                 J=tria->SurfaceLogVelMisfit(process_units,weight_index);
    7314                 delete tria->matice; delete tria;
    7315                 return J;
    7316         }
    7317 }
    7318 /*}}}*/
    7319 /*FUNCTION Penta::SurfaceLogVxVyMisfit {{{1*/
    7320 double Penta::SurfaceLogVxVyMisfit(bool process_units,int weight_index){
    7321 
    7322         double J;
    7323         Tria* tria=NULL;
    7324 
    7325         /*inputs: */
    7326         int  approximation;
    7327 
    7328         /*retrieve inputs :*/
    7329         inputs->GetParameterValue(&approximation,ApproximationEnum);
    7330 
    7331         /*If on water, return 0: */
    7332         if(IsOnWater())return 0;
    7333 
    7334         /*Bail out if this element if:
    7335          * -> Non MacAyeal and not on the surface
    7336          * -> MacAyeal (2d model) and not on bed) */
    7337         if ((approximation!=MacAyealApproximationEnum && !IsOnSurface()) || (approximation==MacAyealApproximationEnum && !IsOnBed())){
    7338                 return 0;
    7339         }
    7340         else if (approximation==MacAyealApproximationEnum){
    7341 
    7342                 /*This element should be collapsed into a tria element at its base. Create this tria element,
    7343                  * and compute SurfaceLogVxVyMisfit*/
    7344                 tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria (lower face).
    7345                 J=tria->SurfaceLogVxVyMisfit(process_units,weight_index);
    7346                 delete tria->matice; delete tria;
    7347                 return J;
    7348         }
    7349         else{
    7350 
    7351                 tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
    7352                 J=tria->SurfaceLogVxVyMisfit(process_units,weight_index);
    7353                 delete tria->matice; delete tria;
    7354                 return J;
    7355         }
    7356 }
    7357 /*}}}*/
    73587449/*FUNCTION Penta::SurfaceNormal {{{1*/
    73597450void Penta::SurfaceNormal(double* surface_normal, double xyz_list[3][3]){
     
    73787469        *(surface_normal+1)=normal[1]/normal_norm;
    73797470        *(surface_normal+2)=normal[2]/normal_norm;
    7380 }
    7381 /*}}}*/
    7382 /*FUNCTION Penta::SurfaceRelVelMisfit {{{1*/
    7383 double Penta::SurfaceRelVelMisfit(bool process_units,int weight_index){
    7384 
    7385         int    approximation;
    7386         double J;
    7387         Tria*  tria=NULL;
    7388 
    7389         /*retrieve inputs :*/
    7390         inputs->GetParameterValue(&approximation,ApproximationEnum);
    7391 
    7392         /*If on water, return 0: */
    7393         if(IsOnWater())return 0;
    7394 
    7395         /*Bail out if this element if:
    7396          * -> Non MacAyeal and not on the surface
    7397          * -> MacAyeal (2d model) and not on bed) */
    7398         if ((approximation!=MacAyealApproximationEnum && !IsOnSurface()) || (approximation==MacAyealApproximationEnum && !IsOnBed())){
    7399                 return 0;
    7400         }
    7401         else if (approximation==MacAyealApproximationEnum){
    7402 
    7403                 /*This element should be collapsed into a tria element at its base. Create this tria element,
    7404                  * and compute SurfaceRelVelMisfit*/
    7405                 tria=(Tria*)SpawnTria(0,1,2); //nodes 0, 1 and 2 make the new tria (lower face).
    7406                 J=tria->SurfaceRelVelMisfit(process_units,weight_index);
    7407                 delete tria->matice; delete tria;
    7408                 return J;
    7409         }
    7410         else{
    7411 
    7412                 tria=(Tria*)SpawnTria(3,4,5); //nodes 3, 4 and 5 make the new tria (upper face).
    7413                 J=tria->SurfaceRelVelMisfit(process_units,weight_index);
    7414                 delete tria->matice; delete tria;
    7415                 return J;
    7416         }
    7417 }
    7418 /*}}}*/
    7419 /*FUNCTION Penta::ThicknessAbsGradient{{{1*/
    7420 double Penta::ThicknessAbsGradient(bool process_units,int weight_index){
    7421 
    7422         _error_("Not implemented yet");
    74237471}
    74247472/*}}}*/
     
    74677515        return dt;
    74687516}
    7469 /*FUNCTION Penta::ThicknessAbsMisfit {{{1*/
    7470 double Penta::ThicknessAbsMisfit(bool process_units,int weight_index){
    7471 
    7472         int    approximation;
    7473         double J;
    7474         Tria*  tria=NULL;
    7475 
    7476         /*retrieve inputs :*/
    7477         inputs->GetParameterValue(&approximation,ApproximationEnum);
    7478 
    7479         /*If on water, return 0: */
    7480         if(IsOnWater())return 0;
    7481         _error_("Not implemented yet");
    7482 
    7483         tria=(Tria*)SpawnTria(0,1,2);
    7484         J=tria->ThicknessAbsMisfit(process_units,weight_index);
    7485         delete tria->matice; delete tria;
    7486         return J;
    7487 }
    7488 /*}}}*/
    74897517/*FUNCTION Penta::Update(int index,IoModel* iomodel,int analysis_counter,int analysis_type) {{{1*/
    74907518void Penta::Update(int index,IoModel* iomodel,int analysis_counter,int analysis_type){
  • issm/trunk/src/c/objects/Elements/Penta.h

    r9733 r9761  
    6868                void  InputUpdateFromVector(double* vector, int name, int type);
    6969                void  InputUpdateFromVector(int* vector, int name, int type);
     70                #ifdef _HAVE_DAKOTA_
    7071                void  InputUpdateFromVectorDakota(bool* vector, int name, int type);
    7172                void  InputUpdateFromVectorDakota(double* vector, int name, int type);
    7273                void  InputUpdateFromVectorDakota(int* vector, int name, int type);
     74                #endif
    7375                void  InputUpdateFromIoModel(int index, IoModel* iomodel);
    7476                /*}}}*/
     
    8385                void   CreatePVector(Vec pf);
    8486                void   DeleteResults(void);
    85                 double DragCoefficientAbsGradient(bool process_units,int weight_index);
    8687                int    GetNodeIndex(Node* node);
    8788                void   GetSolutionFromInputs(Vec solution);
    8889                double GetZcoord(GaussPenta* gauss);
    8990                void   GetVectorFromInputs(Vec vector,int NameEnum);
     91                #ifdef _HAVE_CONTROL_
     92                double DragCoefficientAbsGradient(bool process_units,int weight_index);
    9093                void   Gradj(Vec gradient,int control_type);
    9194                void   GradjDragMacAyeal(Vec gradient);
     
    9598                void   GradjBbarPattyn(Vec gradient);
    9699                void   GradjBbarStokes(Vec gradient);
     100                void   ControlInputGetGradient(Vec gradient,int enum_type);
     101                void   ControlInputScaleGradient(int enum_type,double scale);
     102                void   ControlInputSetGradient(double* gradient,int enum_type);
     103                double RheologyBbarAbsGradient(bool process_units,int weight_index);
     104                double ThicknessAbsMisfit(     bool process_units,int weight_index);
     105                double SurfaceAbsVelMisfit(    bool process_units,int weight_index);
     106                double SurfaceRelVelMisfit(    bool process_units,int weight_index);
     107                double SurfaceLogVelMisfit(    bool process_units,int weight_index);
     108                double SurfaceLogVxVyMisfit(   bool process_units,int weight_index);
     109                double SurfaceAverageVelMisfit(bool process_units,int weight_index);
     110                double ThicknessAbsGradient(bool process_units,int weight_index);
     111                void   InputControlUpdate(double scalar,bool save_parameter);
     112                #endif
    97113                int    Sid();
    98114                void   InputArtificialNoise(int enum_type,double min, double max);
    99                 void   InputControlUpdate(double scalar,bool save_parameter);
    100115                bool   InputConvergence(double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums);
    101116                void   InputCreate(double scalar,int name,int code);
     
    104119                void   InputDuplicate(int original_enum,int new_enum);
    105120                void   InputScale(int enum_type,double scale_factor);
    106                 void   ControlInputGetGradient(Vec gradient,int enum_type);
    107                 void   ControlInputScaleGradient(int enum_type,double scale);
    108                 void   ControlInputSetGradient(double* gradient,int enum_type);
     121               
    109122                void   InputToResult(int enum_type,int step,double time);
    110123                double MassFlux(double* segment,bool process_units);
     
    120133                void   PotentialSheetUngrounding(Vec potential_sheet_ungrounding);
    121134                void   ShelfSync();
    122                 double RheologyBbarAbsGradient(bool process_units,int weight_index);
    123135                void   RequestedOutput(int output_enum,int step,double time);
    124                 double ThicknessAbsGradient(bool process_units,int weight_index);
    125136                void   MigrateGroundingLine();
    126137                void   MinVel(double* pminvel, bool process_units);
     
    128139                void   MinVy(double* pminvy, bool process_units);
    129140                void   MinVz(double* pminvz, bool process_units);
    130                 double ThicknessAbsMisfit(     bool process_units,int weight_index);
    131                 double SurfaceAbsVelMisfit(    bool process_units,int weight_index);
    132                 double SurfaceRelVelMisfit(    bool process_units,int weight_index);
    133                 double SurfaceLogVelMisfit(    bool process_units,int weight_index);
    134                 double SurfaceLogVxVyMisfit(   bool process_units,int weight_index);
    135                 double SurfaceAverageVelMisfit(bool process_units,int weight_index);
    136141                void   PatchFill(int* pcount, Patch* patch);
    137142                void   PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes);
  • issm/trunk/src/c/objects/Elements/Tria.cpp

    r9740 r9761  
    12501250                        pe=CreatePVectorDiagnosticMacAyeal();
    12511251                        break;
    1252                 case AdjointHorizAnalysisEnum:
    1253                         pe=CreatePVectorAdjointHoriz();
    1254                         break;
    12551252                case DiagnosticHutterAnalysisEnum:
    12561253                        pe=CreatePVectorDiagnosticHutter();
     
    12681265                        pe=CreatePVectorBalancethickness();
    12691266                        break;
     1267                #ifdef _HAVE_CONTROL_
    12701268                case AdjointBalancethicknessAnalysisEnum:
    12711269                        pe=CreatePVectorAdjointBalancethickness();
    12721270                        break;
     1271                case AdjointHorizAnalysisEnum:
     1272                        pe=CreatePVectorAdjointHoriz();
     1273                        break;
     1274                #endif
    12731275                default:
    12741276                        _error_("analysis %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type));
     
    14311433        delete gauss;
    14321434        return pe;
     1435}
     1436/*}}}*/
     1437/*FUNCTION Tria::CreatePVectorDiagnosticHutter{{{1*/
     1438ElementVector* Tria::CreatePVectorDiagnosticHutter(void){
     1439
     1440        /*Intermediaries */
     1441        int        i,connectivity;
     1442        double     constant_part,ub,vb;
     1443        double     rho_ice,gravity,n,B;
     1444        double     slope2,thickness;
     1445        double     slope[2];
     1446        GaussTria* gauss=NULL;
     1447
     1448        /*Initialize Element vector*/
     1449        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
     1450
     1451        /*Retrieve all inputs and parameters*/
     1452        rho_ice=matpar->GetRhoIce();
     1453        gravity=matpar->GetG();
     1454        n=matice->GetN();
     1455        B=matice->GetBbar();
     1456        Input* slopex_input=inputs->GetInput(SurfaceSlopeXEnum); _assert_(slopex_input);
     1457        Input* slopey_input=inputs->GetInput(SurfaceSlopeYEnum); _assert_(slopey_input);
     1458        Input* thickness_input=inputs->GetInput(ThicknessEnum);  _assert_(thickness_input);
     1459
     1460        /*Spawn 3 sing elements: */
     1461        gauss=new GaussTria();
     1462        for(i=0;i<NUMVERTICES;i++){
     1463
     1464                gauss->GaussVertex(i);
     1465
     1466                connectivity=nodes[i]->GetConnectivity();
     1467
     1468                thickness_input->GetParameterValue(&thickness,gauss);
     1469                slopex_input->GetParameterValue(&slope[0],gauss);
     1470                slopey_input->GetParameterValue(&slope[1],gauss);
     1471                slope2=pow(slope[0],2)+pow(slope[1],2);
     1472
     1473                constant_part=-2*pow(rho_ice*gravity,n)*pow(slope2,((n-1)/2));
     1474
     1475                ub=-1.58*pow((double)10.0,(double)-10.0)*rho_ice*gravity*thickness*slope[0];
     1476                vb=-1.58*pow((double)10.0,(double)-10.0)*rho_ice*gravity*thickness*slope[1];
     1477
     1478                pe->values[2*i]  =(ub-2.0*pow(rho_ice*gravity,n)*pow(slope2,((n-1)/2.0))*pow(thickness,n)/(pow(B,n)*(n+1))*slope[0])/(double)connectivity;
     1479                pe->values[2*i+1]=(vb-2.0*pow(rho_ice*gravity,n)*pow(slope2,((n-1)/2.0))*pow(thickness,n)/(pow(B,n)*(n+1))*slope[1])/(double)connectivity;
     1480        }
     1481
     1482        /*Clean up and return*/
     1483        delete gauss;
     1484        return pe;
     1485}
     1486/*}}}*/
     1487/*FUNCTION Tria::CreatePVectorPrognostic{{{1*/
     1488ElementVector* Tria::CreatePVectorPrognostic(void){
     1489
     1490        switch(GetElementType()){
     1491                case P1Enum:
     1492                        return CreatePVectorPrognostic_CG();
     1493                case P1DGEnum:
     1494                        return CreatePVectorPrognostic_DG();
     1495                default:
     1496                        _error_("Element type %s not supported yet",EnumToStringx(GetElementType()));
     1497        }
     1498}
     1499/*}}}*/
     1500/*FUNCTION Tria::CreatePVectorHydrology {{{1*/
     1501ElementVector* Tria::CreatePVectorHydrology(void){
     1502
     1503        /*Constants*/
     1504        const int    numdof=NDOF1*NUMVERTICES;
     1505
     1506        /*Intermediaries */
     1507        int        i,j,ig;
     1508        double     Jdettria,dt;
     1509        double     basal_melting_g;
     1510        double     old_watercolumn_g;
     1511        double     xyz_list[NUMVERTICES][3];
     1512        double     basis[numdof];
     1513        GaussTria* gauss=NULL;
     1514
     1515        /*Initialize Element vector*/
     1516        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
     1517
     1518        /*Retrieve all inputs and parameters*/
     1519        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     1520        this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
     1521        Input* basal_melting_input=inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(basal_melting_input);
     1522        Input* old_watercolumn_input=inputs->GetInput(WaterColumnOldEnum);         _assert_(old_watercolumn_input);
     1523
     1524        /*Initialize basal_melting_correction_g to 0, do not forget!:*/
     1525        /* Start  looping on the number of gaussian points: */
     1526        gauss=new GaussTria(2);
     1527        for(ig=gauss->begin();ig<gauss->end();ig++){
     1528
     1529                gauss->GaussPoint(ig);
     1530
     1531                GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss);
     1532                GetNodalFunctions(basis, gauss);
     1533
     1534                basal_melting_input->GetParameterValue(&basal_melting_g,gauss);
     1535                old_watercolumn_input->GetParameterValue(&old_watercolumn_g,gauss);
     1536
     1537                if(dt)for(i=0;i<numdof;i++) pe->values[i]+=Jdettria*gauss->weight*(old_watercolumn_g+dt*basal_melting_g)*basis[i];
     1538                else  for(i=0;i<numdof;i++) pe->values[i]+=Jdettria*gauss->weight*basal_melting_g*basis[i];
     1539        }
     1540               
     1541        /*Clean up and return*/
     1542        delete gauss;
     1543        return pe;
     1544}
     1545/*}}}*/
     1546/*FUNCTION Tria::CreatePVectorPrognostic_CG {{{1*/
     1547ElementVector* Tria::CreatePVectorPrognostic_CG(void){
     1548
     1549        /*Constants*/
     1550        const int    numdof=NDOF1*NUMVERTICES;
     1551
     1552        /*Intermediaries */
     1553        int        i,j,ig;
     1554        double     Jdettria,dt;
     1555        double     surface_mass_balance_g,basal_melting_g,basal_melting_correction_g,thickness_g;
     1556        double     xyz_list[NUMVERTICES][3];
     1557        double     L[NUMVERTICES];
     1558        GaussTria* gauss=NULL;
     1559
     1560        /*Initialize Element vector*/
     1561        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
     1562
     1563        /*Retrieve all inputs and parameters*/
     1564        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     1565        this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
     1566        Input* surface_mass_balance_input=inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(surface_mass_balance_input);
     1567        Input* basal_melting_input=inputs->GetInput(BasalforcingsMeltingRateEnum);          _assert_(basal_melting_input);
     1568        Input* basal_melting_correction_input=inputs->GetInput(BasalforcingsMeltingRateCorrectionEnum);
     1569        Input* thickness_input=inputs->GetInput(ThicknessEnum);                             _assert_(thickness_input);
     1570
     1571        /*Initialize basal_melting_correction_g to 0, do not forget!:*/
     1572        /* Start  looping on the number of gaussian points: */
     1573        gauss=new GaussTria(2);
     1574        for(ig=gauss->begin();ig<gauss->end();ig++){
     1575
     1576                gauss->GaussPoint(ig);
     1577
     1578                GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss);
     1579                GetL(&L[0], &xyz_list[0][0], gauss,NDOF1);
     1580
     1581                surface_mass_balance_input->GetParameterValue(&surface_mass_balance_g,gauss);
     1582                basal_melting_input->GetParameterValue(&basal_melting_g,gauss);
     1583                thickness_input->GetParameterValue(&thickness_g,gauss);
     1584                if(basal_melting_correction_input) basal_melting_correction_input->GetParameterValue(&basal_melting_correction_g,gauss);
     1585
     1586                for(i=0;i<numdof;i++) pe->values[i]+=Jdettria*gauss->weight*(thickness_g+dt*(surface_mass_balance_g-basal_melting_g-basal_melting_correction_g))*L[i];
     1587        }
     1588
     1589        /*Clean up and return*/
     1590        delete gauss;
     1591        return pe;
     1592}
     1593/*}}}*/
     1594/*FUNCTION Tria::CreatePVectorPrognostic_DG {{{1*/
     1595ElementVector* Tria::CreatePVectorPrognostic_DG(void){
     1596
     1597        /*Constants*/
     1598        const int    numdof=NDOF1*NUMVERTICES;
     1599
     1600        /*Intermediaries */
     1601        int        i,j,ig;
     1602        double     Jdettria,dt;
     1603        double     surface_mass_balance_g,basal_melting_g,thickness_g;
     1604        double     xyz_list[NUMVERTICES][3];
     1605        double     L[NUMVERTICES];
     1606        GaussTria* gauss=NULL;
     1607
     1608        /*Initialize Element vector*/
     1609        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
     1610
     1611        /*Retrieve all inputs and parameters*/
     1612        this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
     1613        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     1614        Input* surface_mass_balance_input=inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(surface_mass_balance_input);
     1615        Input* basal_melting_input=inputs->GetInput(BasalforcingsMeltingRateEnum);          _assert_(basal_melting_input);
     1616        Input* thickness_input=inputs->GetInput(ThicknessEnum);                             _assert_(thickness_input);
     1617
     1618        /* Start  looping on the number of gaussian points: */
     1619        gauss=new GaussTria(2);
     1620        for(ig=gauss->begin();ig<gauss->end();ig++){
     1621
     1622                gauss->GaussPoint(ig);
     1623
     1624                GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss);
     1625                GetL(&L[0], &xyz_list[0][0], gauss,NDOF1);
     1626
     1627                surface_mass_balance_input->GetParameterValue(&surface_mass_balance_g,gauss);
     1628                basal_melting_input->GetParameterValue(&basal_melting_g,gauss);
     1629                thickness_input->GetParameterValue(&thickness_g,gauss);
     1630
     1631                for(i=0;i<numdof;i++) pe->values[i]+=Jdettria*gauss->weight*(thickness_g+dt*(surface_mass_balance_g-basal_melting_g))*L[i];
     1632        }
     1633
     1634        /*Clean up and return*/
     1635        delete gauss;
     1636        return pe;
     1637}
     1638/*}}}*/
     1639/*FUNCTION Tria::CreatePVectorSlope {{{1*/
     1640ElementVector* Tria::CreatePVectorSlope(void){
     1641
     1642        /*Constants*/
     1643        const int    numdof=NDOF1*NUMVERTICES;
     1644       
     1645        /*Intermediaries */
     1646        int        i,j,ig;
     1647        int        analysis_type;
     1648        double     Jdet;
     1649        double     xyz_list[NUMVERTICES][3];
     1650        double     slope[2];
     1651        double     basis[3];
     1652        GaussTria* gauss=NULL;
     1653
     1654        /*Initialize Element vector*/
     1655        ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
     1656
     1657        /*Retrieve all inputs and parameters*/
     1658        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     1659        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     1660        Input* slope_input=NULL;
     1661        if ( (analysis_type==SurfaceSlopeXAnalysisEnum) || (analysis_type==SurfaceSlopeYAnalysisEnum)){
     1662                slope_input=inputs->GetInput(SurfaceEnum); _assert_(slope_input);
     1663        }
     1664        if ( (analysis_type==BedSlopeXAnalysisEnum) || (analysis_type==BedSlopeYAnalysisEnum)){
     1665                slope_input=inputs->GetInput(BedEnum);     _assert_(slope_input);
     1666        }
     1667               
     1668        /* Start  looping on the number of gaussian points: */
     1669        gauss=new GaussTria(2);
     1670        for(ig=gauss->begin();ig<gauss->end();ig++){
     1671
     1672                gauss->GaussPoint(ig);
     1673
     1674                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     1675                GetNodalFunctions(basis, gauss);
     1676
     1677                slope_input->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],gauss);
     1678
     1679                if ( (analysis_type==SurfaceSlopeXAnalysisEnum) || (analysis_type==BedSlopeXAnalysisEnum)){
     1680                        for(i=0;i<numdof;i++) pe->values[i]+=Jdet*gauss->weight*slope[0]*basis[i];
     1681                }
     1682                if ( (analysis_type==SurfaceSlopeYAnalysisEnum) || (analysis_type==BedSlopeYAnalysisEnum)){
     1683                        for(i=0;i<numdof;i++) pe->values[i]+=Jdet*gauss->weight*slope[1]*basis[i];
     1684                }
     1685        }
     1686
     1687        /*Clean up and return*/
     1688        delete gauss;
     1689        return pe;
     1690}
     1691/*}}}*/
     1692/*FUNCTION Tria::ComputeBasalStress {{{1*/
     1693void  Tria::ComputeBasalStress(Vec eps){
     1694        _error_("Not Implemented yet");
     1695}
     1696/*}}}*/
     1697/*FUNCTION Tria::ComputeStrainRate {{{1*/
     1698void  Tria::ComputeStrainRate(Vec eps){
     1699        _error_("Not Implemented yet");
     1700}
     1701/*}}}*/
     1702/*FUNCTION Tria::Configure {{{1*/
     1703void  Tria::Configure(Elements* elementsin, Loads* loadsin, DataSet* nodesin, Materials* materialsin, Parameters* parametersin){
     1704       
     1705        /*go into parameters and get the analysis_counter: */
     1706        int analysis_counter;
     1707        parametersin->FindParam(&analysis_counter,AnalysisCounterEnum);
     1708
     1709        /*Get Element type*/
     1710        this->element_type=this->element_type_list[analysis_counter];
     1711
     1712        /*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective
     1713         * datasets, using internal ids and offsets hidden in hooks: */
     1714        if(this->hnodes[analysis_counter]) this->hnodes[analysis_counter]->configure(nodesin);
     1715        this->hmatice->configure(materialsin);
     1716        this->hmatpar->configure(materialsin);
     1717
     1718        /*Now, go pick up the objects inside the hooks: */
     1719        if(this->hnodes[analysis_counter]) this->nodes=(Node**)this->hnodes[analysis_counter]->deliverp();
     1720        else this->nodes=NULL;
     1721        this->matice=(Matice*)this->hmatice->delivers();
     1722        this->matpar=(Matpar*)this->hmatpar->delivers();
     1723
     1724        /*point parameters to real dataset: */
     1725        this->parameters=parametersin;
     1726
     1727        /*get inputs configured too: */
     1728        this->inputs->Configure(parameters);
     1729
     1730}
     1731/*}}}*/
     1732/*FUNCTION Tria::DeepEcho{{{1*/
     1733void Tria::DeepEcho(void){
     1734
     1735        printf("Tria:\n");
     1736        printf("   id: %i\n",id);
     1737        if(nodes){
     1738                nodes[0]->DeepEcho();
     1739                nodes[1]->DeepEcho();
     1740                nodes[2]->DeepEcho();
     1741        }
     1742        else printf("nodes = NULL\n");
     1743
     1744        if (matice) matice->DeepEcho();
     1745        else printf("matice = NULL\n");
     1746
     1747        if (matpar) matpar->DeepEcho();
     1748        else printf("matpar = NULL\n");
     1749
     1750        printf("   parameters\n");
     1751        if (parameters) parameters->DeepEcho();
     1752        else printf("parameters = NULL\n");
     1753
     1754        printf("   inputs\n");
     1755        if (inputs) inputs->DeepEcho();
     1756        else printf("inputs=NULL\n");
     1757
     1758        if (results) results->DeepEcho();
     1759        else printf("results=NULL\n");
     1760
     1761        printf("neighboor sids: \n");
     1762        printf(" %i %i %i\n",horizontalneighborsids[0],horizontalneighborsids[1],horizontalneighborsids[2]);
     1763       
     1764        return;
     1765}
     1766/*}}}*/
     1767/*FUNCTION Tria::DeleteResults {{{1*/
     1768void  Tria::DeleteResults(void){
     1769
     1770        /*Delete and reinitialize results*/
     1771        delete this->results;
     1772        this->results=new Results();
     1773
     1774}
     1775/*}}}*/
     1776/*FUNCTION Tria::Echo{{{1*/
     1777void Tria::Echo(void){
     1778        printf("Tria:\n");
     1779        printf("   id: %i\n",id);
     1780        if(nodes){
     1781                nodes[0]->Echo();
     1782                nodes[1]->Echo();
     1783                nodes[2]->Echo();
     1784        }
     1785        else printf("nodes = NULL\n");
     1786
     1787        if (matice) matice->Echo();
     1788        else printf("matice = NULL\n");
     1789
     1790        if (matpar) matpar->Echo();
     1791        else printf("matpar = NULL\n");
     1792
     1793        printf("   parameters\n");
     1794        if (parameters) parameters->Echo();
     1795        else printf("parameters = NULL\n");
     1796
     1797        printf("   inputs\n");
     1798        if (inputs) inputs->Echo();
     1799        else printf("inputs=NULL\n");
     1800
     1801        if (results) results->Echo();
     1802        else printf("results=NULL\n");
     1803
     1804        printf("neighboor sids: \n");
     1805        printf(" %i %i %i\n",horizontalneighborsids[0],horizontalneighborsids[1],horizontalneighborsids[2]);
     1806}
     1807/*}}}*/
     1808/*FUNCTION Tria::Enum {{{1*/
     1809int Tria::Enum(void){
     1810
     1811        return TriaEnum;
     1812
     1813}
     1814/*}}}*/
     1815/*FUNCTION Tria::GetArea {{{1*/
     1816double Tria::GetArea(void){
     1817
     1818        double area=0;
     1819        double xyz_list[NUMVERTICES][3];
     1820        double x1,y1,x2,y2,x3,y3;
     1821
     1822        /*Get xyz list: */
     1823        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     1824        x1=xyz_list[0][0]; y1=xyz_list[0][1];
     1825        x2=xyz_list[1][0]; y2=xyz_list[1][1];
     1826        x3=xyz_list[2][0]; y3=xyz_list[2][1];
     1827 
     1828        return (x2*y3 - y2*x3 + x1*y2 - y1*x2 + x3*y1 - y3*x1)/2;
     1829}
     1830/*}}}*/
     1831/*FUNCTION Tria::GetDofList {{{1*/
     1832void  Tria::GetDofList(int** pdoflist, int approximation_enum,int setenum){
     1833
     1834        int i,j;
     1835        int count=0;
     1836        int numberofdofs=0;
     1837        int* doflist=NULL;
     1838
     1839        /*First, figure out size of doflist and create it: */
     1840        for(i=0;i<3;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
     1841        doflist=(int*)xmalloc(numberofdofs*sizeof(int));
     1842
     1843        /*Populate: */
     1844        count=0;
     1845        for(i=0;i<3;i++){
     1846                nodes[i]->GetDofList(doflist+count,approximation_enum,setenum);
     1847                count+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
     1848        }
     1849
     1850        /*Assign output pointers:*/
     1851        *pdoflist=doflist;
     1852}
     1853/*}}}*/
     1854/*FUNCTION Tria::GetDofList1 {{{1*/
     1855void  Tria::GetDofList1(int* doflist){
     1856
     1857        int i;
     1858        for(i=0;i<3;i++) doflist[i]=nodes[i]->GetDofList1();
     1859
     1860}
     1861/*}}}*/
     1862/*FUNCTION Tria::GetElementType {{{1*/
     1863int Tria::GetElementType(){
     1864
     1865        /*return TriaRef field*/
     1866        return this->element_type;
     1867
     1868}
     1869/*}}}*/
     1870/*FUNCTION Tria::GetHorizontalNeighboorSids {{{1*/
     1871int* Tria::GetHorizontalNeighboorSids(){
     1872
     1873        /*return TriaRef field*/
     1874        return &this->horizontalneighborsids[0];
     1875
     1876}
     1877/*}}}*/
     1878/*FUNCTION Tria::GetNodeIndex {{{1*/
     1879int Tria::GetNodeIndex(Node* node){
     1880
     1881        _assert_(nodes);
     1882        for(int i=0;i<NUMVERTICES;i++){
     1883                if(node==nodes[i])
     1884                 return i;
     1885        }
     1886        _error_("Node provided not found among element nodes");
     1887}
     1888/*}}}*/
     1889/*FUNCTION Tria::GetParameterListOnVertices(double* pvalue,int enumtype) {{{1*/
     1890void Tria::GetParameterListOnVertices(double* pvalue,int enumtype){
     1891
     1892        /*Intermediaries*/
     1893        double     value[NUMVERTICES];
     1894        GaussTria *gauss              = NULL;
     1895
     1896        /*Recover input*/
     1897        Input* input=inputs->GetInput(enumtype);
     1898        if (!input) _error_("Input %s not found in element",EnumToStringx(enumtype));
     1899
     1900        /*Checks in debugging mode*/
     1901        _assert_(pvalue);
     1902
     1903        /* Start looping on the number of vertices: */
     1904        gauss=new GaussTria();
     1905        for (int iv=0;iv<NUMVERTICES;iv++){
     1906                gauss->GaussVertex(iv);
     1907                input->GetParameterValue(&pvalue[iv],gauss);
     1908        }
     1909
     1910        /*clean-up*/
     1911        delete gauss;
     1912}
     1913/*}}}*/
     1914/*FUNCTION Tria::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue) {{{1*/
     1915void Tria::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue){
     1916
     1917        double     value[NUMVERTICES];
     1918        GaussTria *gauss = NULL;
     1919        Input     *input = inputs->GetInput(enumtype);
     1920
     1921        /*Checks in debugging mode*/
     1922        _assert_(pvalue);
     1923
     1924        /* Start looping on the number of vertices: */
     1925        if (input){
     1926                gauss=new GaussTria();
     1927                for (int iv=0;iv<NUMVERTICES;iv++){
     1928                        gauss->GaussVertex(iv);
     1929                        input->GetParameterValue(&pvalue[iv],gauss);
     1930                }
     1931        }
     1932        else{
     1933                for (int iv=0;iv<NUMVERTICES;iv++) pvalue[iv]=defaultvalue;
     1934        }
     1935
     1936        /*clean-up*/
     1937        delete gauss;
     1938}
     1939/*}}}*/
     1940/*FUNCTION Tria::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue,int index) TO BE REMOVED{{{1*/
     1941void Tria::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue,int index){
     1942
     1943        double     value[NUMVERTICES];
     1944        GaussTria *gauss = NULL;
     1945        Input     *input = inputs->GetInput(enumtype);
     1946
     1947        /*Checks in debugging mode*/
     1948        _assert_(pvalue);
     1949
     1950        /* Start looping on the number of vertices: */
     1951        if (input){
     1952                gauss=new GaussTria();
     1953                for (int iv=0;iv<NUMVERTICES;iv++){
     1954                        gauss->GaussVertex(iv);
     1955                        input->GetParameterValue(&pvalue[iv],gauss,index);
     1956                }
     1957        }
     1958        else{
     1959                for (int iv=0;iv<NUMVERTICES;iv++) pvalue[iv]=defaultvalue;
     1960        }
     1961
     1962        /*clean-up*/
     1963        delete gauss;
     1964}
     1965/*}}}*/
     1966/*FUNCTION Tria::GetParameterValue(double* pvalue,Node* node,int enumtype) {{{1*/
     1967void Tria::GetParameterValue(double* pvalue,Node* node,int enumtype){
     1968
     1969        Input* input=inputs->GetInput(enumtype);
     1970        if(!input) _error_("No input of type %s found in tria",EnumToStringx(enumtype));
     1971
     1972        GaussTria* gauss=new GaussTria();
     1973        gauss->GaussVertex(this->GetNodeIndex(node));
     1974
     1975        input->GetParameterValue(pvalue,gauss);
     1976        delete gauss;
     1977}
     1978/*}}}*/
     1979/*FUNCTION Tria::GetSidList {{{1*/
     1980void  Tria::GetSidList(int* sidlist){
     1981
     1982        int i;
     1983        for(i=0;i<NUMVERTICES;i++) sidlist[i]=nodes[i]->GetSidList();
     1984
     1985}
     1986/*}}}*/
     1987/*FUNCTION Tria::GetSolutionFromInputs{{{1*/
     1988void  Tria::GetSolutionFromInputs(Vec solution){
     1989
     1990        /*retrive parameters: */
     1991        int analysis_type;
     1992        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     1993
     1994        /*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */
     1995        if (analysis_type==DiagnosticHorizAnalysisEnum)
     1996         GetSolutionFromInputsDiagnosticHoriz(solution);
     1997        else if (analysis_type==DiagnosticHutterAnalysisEnum)
     1998         GetSolutionFromInputsDiagnosticHutter(solution);
     1999        else if (analysis_type==HydrologyAnalysisEnum)
     2000         GetSolutionFromInputsHydrology(solution);
     2001        else
     2002         _error_("analysis: %s not supported yet",EnumToStringx(analysis_type));
     2003
     2004}
     2005/*}}}*/
     2006/*FUNCTION Tria::GetSolutionFromInputsDiagnosticHoriz{{{1*/
     2007void  Tria::GetSolutionFromInputsDiagnosticHoriz(Vec solution){
     2008
     2009        const int    numdof=NDOF2*NUMVERTICES;
     2010
     2011        int          i;
     2012        int*         doflist=NULL;
     2013        double       vx,vy;
     2014        double       values[numdof];
     2015        GaussTria*   gauss=NULL;
     2016
     2017        /*Get dof list: */
     2018        GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
     2019
     2020        /*Get inputs*/
     2021        Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
     2022        Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
     2023
     2024        /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
     2025        /*P1 element only for now*/
     2026        gauss=new GaussTria();
     2027        for(i=0;i<NUMVERTICES;i++){
     2028
     2029                gauss->GaussVertex(i);
     2030
     2031                /*Recover vx and vy*/
     2032                vx_input->GetParameterValue(&vx,gauss);
     2033                vy_input->GetParameterValue(&vy,gauss);
     2034                values[i*NDOF2+0]=vx;
     2035                values[i*NDOF2+1]=vy;
     2036        }
     2037
     2038        VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
     2039
     2040        /*Free ressources:*/
     2041        delete gauss;
     2042        xfree((void**)&doflist);
     2043}
     2044/*}}}*/
     2045/*FUNCTION Tria::GetSolutionFromInputsDiagnosticHutter{{{1*/
     2046void  Tria::GetSolutionFromInputsDiagnosticHutter(Vec solution){
     2047
     2048        const int    numdof=NDOF2*NUMVERTICES;
     2049
     2050        int i,dummy;
     2051        int*         doflist=NULL;
     2052        double       vx,vy;
     2053        double       values[numdof];
     2054        GaussTria*   gauss=NULL;
     2055
     2056        /*Get dof list: */
     2057        GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
     2058
     2059        /*Get inputs*/
     2060        Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
     2061        Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
     2062
     2063        /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
     2064        /*P1 element only for now*/
     2065        gauss=new GaussTria();
     2066        for(i=0;i<NUMVERTICES;i++){
     2067
     2068                gauss->GaussVertex(i);
     2069
     2070                /*Recover vx and vy*/
     2071                vx_input->GetParameterValue(&vx,gauss);
     2072                vy_input->GetParameterValue(&vy,gauss);
     2073                values[i*NDOF2+0]=vx;
     2074                values[i*NDOF2+1]=vy;
     2075        }
     2076
     2077        VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
     2078
     2079        /*Free ressources:*/
     2080        delete gauss;
     2081        xfree((void**)&doflist);
     2082}
     2083/*}}}*/
     2084/*FUNCTION Tria::GetSolutionFromInputsHydrology{{{1*/
     2085void  Tria::GetSolutionFromInputsHydrology(Vec solution){
     2086
     2087        const int    numdof=NDOF1*NUMVERTICES;
     2088
     2089        int i,dummy;
     2090        int*         doflist=NULL;
     2091        double       watercolumn;
     2092        double       values[numdof];
     2093        GaussTria*   gauss=NULL;
     2094
     2095        /*Get dof list: */
     2096        GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
     2097
     2098        /*Get inputs*/
     2099        Input* watercolumn_input=inputs->GetInput(WatercolumnEnum); _assert_(watercolumn_input);
     2100
     2101        /*Ok, we have watercolumn values, fill in watercolumn array: */
     2102        /*P1 element only for now*/
     2103        gauss=new GaussTria();
     2104        for(i=0;i<NUMVERTICES;i++){
     2105
     2106                gauss->GaussVertex(i);
     2107
     2108                /*Recover watercolumn*/
     2109                watercolumn_input->GetParameterValue(&watercolumn,gauss);
     2110                values[i]=watercolumn;
     2111        }
     2112
     2113        VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
     2114
     2115        /*Free ressources:*/
     2116        delete gauss;
     2117        xfree((void**)&doflist);
     2118}
     2119/*}}}*/
     2120/*FUNCTION Tria::GetStrainRate2d(double* epsilon,double* xyz_list, GaussTria* gauss, Input* vx_input, Input* vy_input){{{1*/
     2121void Tria::GetStrainRate2d(double* epsilon,double* xyz_list, GaussTria* gauss, Input* vx_input, Input* vy_input){
     2122        /*Compute the 2d Strain Rate (3 components):
     2123         * epsilon=[exx eyy exy] */
     2124
     2125        int i;
     2126        double epsilonvx[3];
     2127        double epsilonvy[3];
     2128
     2129        /*Check that both inputs have been found*/
     2130        if (!vx_input || !vy_input){
     2131                _error_("Input missing. Here are the input pointers we have for vx: %p, vy: %p\n",vx_input,vy_input);
     2132        }
     2133
     2134        /*Get strain rate assuming that epsilon has been allocated*/
     2135        vx_input->GetVxStrainRate2d(epsilonvx,xyz_list,gauss);
     2136        vy_input->GetVyStrainRate2d(epsilonvy,xyz_list,gauss);
     2137
     2138        /*Sum all contributions*/
     2139        for(i=0;i<3;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i];
     2140}
     2141/*}}}*/
     2142/*FUNCTION Tria::GetVectorFromInputs{{{1*/
     2143void  Tria::GetVectorFromInputs(Vec vector,int input_enum){
     2144
     2145        int doflist1[NUMVERTICES];
     2146
     2147        /*Get out if this is not an element input*/
     2148        if (!IsInput(input_enum)) return;
     2149
     2150        /*Prepare index list*/
     2151        this->GetDofList1(&doflist1[0]);
     2152
     2153        /*Get input (either in element or material)*/
     2154        Input* input=inputs->GetInput(input_enum);
     2155        if(!input) _error_("Input %s not found in element",EnumToStringx(input_enum));
     2156
     2157        /*We found the enum.  Use its values to fill into the vector, using the vertices ids: */
     2158        input->GetVectorFromInputs(vector,&doflist1[0]);
     2159}
     2160/*}}}*/
     2161/*FUNCTION Tria::Id {{{1*/
     2162int    Tria::Id(){
     2163       
     2164        return id;
     2165
     2166}
     2167/*}}}*/
     2168/*FUNCTION Tria::Sid {{{1*/
     2169int    Tria::Sid(){
     2170       
     2171        return sid;
     2172
     2173}
     2174/*}}}*/
     2175/*FUNCTION Tria::InputArtificialNoise{{{1*/
     2176void  Tria::InputArtificialNoise(int enum_type,double min,double max){
     2177
     2178        Input* input=NULL;
     2179
     2180        /*Make a copy of the original input: */
     2181        input=(Input*)this->inputs->GetInput(enum_type);
     2182        if(!input)_error_(" could not find old input with enum: %s",EnumToStringx(enum_type));
     2183
     2184        /*ArtificialNoise: */
     2185        input->ArtificialNoise(min,max);
     2186}
     2187/*}}}*/
     2188
     2189#ifdef _HAVE_CONTROL_
     2190/*FUNCTION Tria::InputControlUpdate{{{1*/
     2191void  Tria::InputControlUpdate(double scalar,bool save_parameter){
     2192
     2193        /*Intermediary*/
     2194        int    num_controls;
     2195        int*   control_type=NULL;
     2196        Input* input=NULL;
     2197
     2198        /*retrieve some parameters: */
     2199        this->parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
     2200        this->parameters->FindParam(&control_type,NULL,InversionControlParametersEnum);
     2201
     2202        for(int i=0;i<num_controls;i++){
     2203
     2204                if(control_type[i]==MaterialsRheologyBbarEnum){
     2205                        input=(Input*)matice->inputs->GetInput(control_type[i]); _assert_(input);
     2206                }
     2207                else{
     2208                        input=(Input*)this->inputs->GetInput(control_type[i]);   _assert_(input);
     2209                }
     2210
     2211                if (input->Enum()!=ControlInputEnum){
     2212                        _error_("input %s is not a ControlInput",EnumToStringx(control_type[i]));
     2213                }
     2214
     2215                ((ControlInput*)input)->UpdateValue(scalar);
     2216                ((ControlInput*)input)->Constrain();
     2217                if (save_parameter) ((ControlInput*)input)->SaveValue();
     2218
     2219        }
     2220
     2221        /*Clean up and return*/
     2222        xfree((void**)&control_type);
     2223}
     2224/*}}}*/
     2225/*FUNCTION Tria::ControlInputGetGradient{{{1*/
     2226void Tria::ControlInputGetGradient(Vec gradient,int enum_type){
     2227
     2228        int doflist1[NUMVERTICES];
     2229        Input* input=NULL;
     2230
     2231        if(enum_type==MaterialsRheologyBbarEnum){
     2232                input=(Input*)matice->inputs->GetInput(enum_type);
     2233        }
     2234        else{
     2235                input=inputs->GetInput(enum_type);
     2236        }
     2237        if (!input) _error_("Input %s not found",EnumToStringx(enum_type));
     2238        if (input->Enum()!=ControlInputEnum) _error_("Input %s is not a ControlInput",EnumToStringx(enum_type));
     2239
     2240        this->GetDofList1(&doflist1[0]);
     2241        ((ControlInput*)input)->GetGradient(gradient,&doflist1[0]);
     2242
     2243}/*}}}*/
     2244/*FUNCTION Tria::ControlInputScaleGradient{{{1*/
     2245void Tria::ControlInputScaleGradient(int enum_type,double scale){
     2246
     2247        Input* input=NULL;
     2248
     2249        if(enum_type==MaterialsRheologyBbarEnum){
     2250                input=(Input*)matice->inputs->GetInput(enum_type);
     2251        }
     2252        else{
     2253                input=inputs->GetInput(enum_type);
     2254        }
     2255        if (!input) _error_("Input %s not found",EnumToStringx(enum_type));
     2256        if (input->Enum()!=ControlInputEnum) _error_("Input %s is not a ControlInput",EnumToStringx(enum_type));
     2257
     2258        ((ControlInput*)input)->ScaleGradient(scale);
     2259}/*}}}*/
     2260/*FUNCTION Tria::ControlInputSetGradient{{{1*/
     2261void Tria::ControlInputSetGradient(double* gradient,int enum_type){
     2262
     2263        int    doflist1[NUMVERTICES];
     2264        double grad_list[NUMVERTICES];
     2265        Input* grad_input=NULL;
     2266        Input* input=NULL;
     2267
     2268        if(enum_type==MaterialsRheologyBbarEnum){
     2269                input=(Input*)matice->inputs->GetInput(enum_type);
     2270        }
     2271        else{
     2272                input=inputs->GetInput(enum_type);
     2273        }
     2274        if (!input) _error_("Input %s not found",EnumToStringx(enum_type));
     2275        if (input->Enum()!=ControlInputEnum) _error_("Input %s is not a ControlInput",EnumToStringx(enum_type));
     2276
     2277        this->GetDofList1(&doflist1[0]);
     2278        for(int i=0;i<NUMVERTICES;i++) grad_list[i]=gradient[doflist1[i]];
     2279        grad_input=new TriaVertexInput(GradientEnum,grad_list);
     2280
     2281        ((ControlInput*)input)->SetGradient(grad_input);
     2282
     2283}/*}}}*/
     2284/*FUNCTION Tria::Gradj {{{1*/
     2285void  Tria::Gradj(Vec gradient,int control_type){
     2286        /*dJ/dalpha = ∂L/∂alpha = ∂J/∂alpha + ∂/∂alpha(KU-F)*/
     2287
     2288        /*If on water, grad = 0: */
     2289        if(IsOnWater()) return;
     2290
     2291        /*First deal with ∂/∂alpha(KU-F)*/
     2292        switch(control_type){
     2293                case FrictionCoefficientEnum:
     2294                        GradjDragMacAyeal(gradient);
     2295                        break;
     2296                case MaterialsRheologyBbarEnum:
     2297                        GradjBMacAyeal(gradient);
     2298                        break;
     2299                case BalancethicknessThickeningRateEnum:
     2300                        GradjDhDtBalancedthickness(gradient);
     2301                        break;
     2302                case VxEnum:
     2303                        GradjVxBalancedthickness(gradient);
     2304                        break;
     2305                case VyEnum:
     2306                        GradjVyBalancedthickness(gradient);
     2307                        break;
     2308                default:
     2309                        _error_("%s%i","control type not supported yet: ",control_type);
     2310        }
     2311
     2312        /*Now deal with ∂J/∂alpha*/
     2313        int        *responses = NULL;
     2314        int         num_responses,resp;
     2315        this->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);
     2316        this->parameters->FindParam(&responses,NULL,NULL,StepResponsesEnum);
     2317
     2318        for(resp=0;resp<num_responses;resp++) switch(responses[resp]){
     2319                //FIXME: the control type should be checked somewhere (with respect to what variable are we taking the gradient!)
     2320
     2321                case ThicknessAbsMisfitEnum:
     2322                case ThicknessAbsGradientEnum:
     2323                case SurfaceAbsVelMisfitEnum:
     2324                case SurfaceRelVelMisfitEnum:
     2325                case SurfaceLogVelMisfitEnum:
     2326                case SurfaceLogVxVyMisfitEnum:
     2327                case SurfaceAverageVelMisfitEnum:
     2328                        /*Nothing, J does not depends on the parameter being inverted for*/
     2329                        break;
     2330                case DragCoefficientAbsGradientEnum:
     2331                        GradjDragGradient(gradient,resp);
     2332                        break;
     2333                case RheologyBbarAbsGradientEnum:
     2334                        GradjBGradient(gradient,resp);
     2335                        break;
     2336                default:
     2337                        _error_("response %s not supported yet",EnumToStringx(responses[resp]));
     2338        }
     2339
     2340        xfree((void**)&responses);
     2341}
     2342/*}}}*/
     2343/*FUNCTION Tria::GradjBGradient{{{1*/
     2344void  Tria::GradjBGradient(Vec gradient, int weight_index){
     2345
     2346        int        i,ig;
     2347        int        doflist1[NUMVERTICES];
     2348        double     Jdet,weight;
     2349        double     xyz_list[NUMVERTICES][3];
     2350        double     dbasis[NDOF2][NUMVERTICES];
     2351        double     dk[NDOF2];
     2352        double     grade_g[NUMVERTICES]={0.0};
     2353        GaussTria  *gauss=NULL;
     2354
     2355        /*Retrieve all inputs we will be needing: */
     2356        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2357        GetDofList1(&doflist1[0]);
     2358        Input* rheologyb_input=matice->inputs->GetInput(MaterialsRheologyBbarEnum); _assert_(rheologyb_input);
     2359        Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);                _assert_(weights_input);
     2360
     2361        /* Start  looping on the number of gaussian points: */
     2362        gauss=new GaussTria(2);
     2363        for (ig=gauss->begin();ig<gauss->end();ig++){
     2364
     2365                gauss->GaussPoint(ig);
     2366
     2367                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     2368                GetNodalFunctionsDerivatives(&dbasis[0][0],&xyz_list[0][0],gauss);
     2369                weights_input->GetParameterValue(&weight,gauss,weight_index);
     2370
     2371                /*Build alpha_complement_list: */
     2372                rheologyb_input->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],gauss);
     2373
     2374                /*Build gradje_g_gaussian vector (actually -dJ/ddrag): */
     2375                for (i=0;i<NUMVERTICES;i++) grade_g[i]+=-weight*Jdet*gauss->weight*(dbasis[0][i]*dk[0]+dbasis[1][i]*dk[1]);
     2376        }
     2377        VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES);
     2378
     2379        /*Clean up and return*/
     2380        delete gauss;
     2381}
     2382/*}}}*/
     2383/*FUNCTION Tria::GradjBMacAyeal{{{1*/
     2384void  Tria::GradjBMacAyeal(Vec gradient){
     2385
     2386        /*Intermediaries*/
     2387        int        i,ig;
     2388        int        doflist[NUMVERTICES];
     2389        double     vx,vy,lambda,mu,thickness,Jdet;
     2390        double     viscosity_complement;
     2391        double     dvx[NDOF2],dvy[NDOF2],dadjx[NDOF2],dadjy[NDOF2],dB[NDOF2];
     2392        double     xyz_list[NUMVERTICES][3];
     2393        double     basis[3],epsilon[3];
     2394        double     grad[NUMVERTICES]={0.0};
     2395        GaussTria *gauss = NULL;
     2396
     2397        /* Get node coordinates and dof list: */
     2398        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2399        GetDofList1(&doflist[0]);
     2400
     2401        /*Retrieve all inputs*/
     2402        Input* thickness_input=inputs->GetInput(ThicknessEnum);            _assert_(thickness_input);
     2403        Input* vx_input=inputs->GetInput(VxEnum);                          _assert_(vx_input);
     2404        Input* vy_input=inputs->GetInput(VyEnum);                          _assert_(vy_input);
     2405        Input* adjointx_input=inputs->GetInput(AdjointxEnum);              _assert_(adjointx_input);
     2406        Input* adjointy_input=inputs->GetInput(AdjointyEnum);              _assert_(adjointy_input);
     2407        Input* rheologyb_input=matice->inputs->GetInput(MaterialsRheologyBbarEnum); _assert_(rheologyb_input);
     2408
     2409        /* Start  looping on the number of gaussian points: */
     2410        gauss=new GaussTria(4);
     2411        for (ig=gauss->begin();ig<gauss->end();ig++){
     2412
     2413                gauss->GaussPoint(ig);
     2414
     2415                thickness_input->GetParameterValue(&thickness,gauss);
     2416                rheologyb_input->GetParameterDerivativeValue(&dB[0],&xyz_list[0][0],gauss);
     2417                vx_input->GetParameterDerivativeValue(&dvx[0],&xyz_list[0][0],gauss);
     2418                vy_input->GetParameterDerivativeValue(&dvy[0],&xyz_list[0][0],gauss);
     2419                adjointx_input->GetParameterDerivativeValue(&dadjx[0],&xyz_list[0][0],gauss);
     2420                adjointy_input->GetParameterDerivativeValue(&dadjy[0],&xyz_list[0][0],gauss);
     2421
     2422                this->GetStrainRate2d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
     2423                matice->GetViscosityComplement(&viscosity_complement,&epsilon[0]);
     2424
     2425                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     2426                GetNodalFunctions(basis,gauss);
     2427
     2428                /*standard gradient dJ/dki*/
     2429                for (i=0;i<NUMVERTICES;i++) grad[i]+=-viscosity_complement*thickness*(
     2430                                        (2*dvx[0]+dvy[1])*2*dadjx[0]+(dvx[1]+dvy[0])*(dadjx[1]+dadjy[0])+(2*dvy[1]+dvx[0])*2*dadjy[1]
     2431                                        )*Jdet*gauss->weight*basis[i];
     2432        }
     2433
     2434        VecSetValues(gradient,NUMVERTICES,doflist,(const double*)grad,ADD_VALUES);
     2435
     2436        /*clean-up*/
     2437        delete gauss;
     2438}
     2439/*}}}*/
     2440/*FUNCTION Tria::GradjDragMacAyeal {{{1*/
     2441void  Tria::GradjDragMacAyeal(Vec gradient){
     2442
     2443        int        i,ig;
     2444        int        analysis_type;
     2445        int        doflist1[NUMVERTICES];
     2446        double     vx,vy,lambda,mu,alpha_complement,Jdet;
     2447        double     bed,thickness,Neff,drag;
     2448        double     xyz_list[NUMVERTICES][3];
     2449        double     dk[NDOF2];
     2450        double     grade_g[NUMVERTICES]={0.0};
     2451        double     grade_g_gaussian[NUMVERTICES];
     2452        double     basis[3];
     2453        double     epsilon[3]; /* epsilon=[exx,eyy,exy];*/
     2454        Friction*  friction=NULL;
     2455        GaussTria  *gauss=NULL;
     2456
     2457        if(IsOnShelf())return;
     2458
     2459        /*retrive parameters: */
     2460        parameters->FindParam(&analysis_type,AnalysisTypeEnum);
     2461        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2462        GetDofList1(&doflist1[0]);
     2463
     2464        /*Build frictoin element, needed later: */
     2465        friction=new Friction("2d",inputs,matpar,analysis_type);
     2466
     2467        /*Retrieve all inputs we will be needing: */
     2468        Input* adjointx_input=inputs->GetInput(AdjointxEnum);               _assert_(adjointx_input);
     2469        Input* adjointy_input=inputs->GetInput(AdjointyEnum);               _assert_(adjointy_input);
     2470        Input* vx_input=inputs->GetInput(VxEnum);                           _assert_(vx_input);
     2471        Input* vy_input=inputs->GetInput(VyEnum);                           _assert_(vy_input);
     2472        Input* dragcoefficient_input=inputs->GetInput(FrictionCoefficientEnum); _assert_(dragcoefficient_input);
     2473
     2474        /* Start  looping on the number of gaussian points: */
     2475        gauss=new GaussTria(4);
     2476        for (ig=gauss->begin();ig<gauss->end();ig++){
     2477
     2478                gauss->GaussPoint(ig);
     2479
     2480                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     2481                GetNodalFunctions(basis, gauss);
     2482
     2483                /*Build alpha_complement_list: */
     2484                friction->GetAlphaComplement(&alpha_complement, gauss,VxEnum,VyEnum,VzEnum);
     2485       
     2486                dragcoefficient_input->GetParameterValue(&drag, gauss);
     2487                adjointx_input->GetParameterValue(&lambda, gauss);
     2488                adjointy_input->GetParameterValue(&mu, gauss);
     2489                vx_input->GetParameterValue(&vx,gauss);
     2490                vy_input->GetParameterValue(&vy,gauss);
     2491                dragcoefficient_input->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],gauss);
     2492
     2493                /*Build gradje_g_gaussian vector (actually -dJ/ddrag): */
     2494                for (i=0;i<NUMVERTICES;i++){
     2495                        grade_g_gaussian[i]=-2*drag*alpha_complement*((lambda*vx+mu*vy))*Jdet*gauss->weight*basis[i];
     2496                }
     2497               
     2498                /*Add gradje_g_gaussian vector to gradje_g: */
     2499                for(i=0;i<NUMVERTICES;i++){
     2500                        _assert_(!isnan(grade_g[i]));
     2501                        grade_g[i]+=grade_g_gaussian[i];
     2502                }
     2503        }
     2504        /*Analytical gradient*/
     2505        //delete gauss;
     2506        //gauss=new GaussTria();
     2507        //for (int iv=0;iv<NUMVERTICES;iv++){
     2508        //      gauss->GaussVertex(iv);
     2509        //      friction->GetAlphaComplement(&alpha_complement, gauss,VxEnum,VyEnum,VzEnum);
     2510        //      dragcoefficient_input->GetParameterValue(&drag, gauss);
     2511        //      adjointx_input->GetParameterValue(&lambda, gauss);
     2512        //      adjointy_input->GetParameterValue(&mu, gauss);
     2513        //      vx_input->GetParameterValue(&vx,gauss);
     2514        //      vy_input->GetParameterValue(&vy,gauss);
     2515        //      grade_g[iv]=-2*drag*alpha_complement*((lambda*vx+mu*vy));
     2516        //      VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,INSERT_VALUES);
     2517        //}
     2518        /*End Analytical gradient*/
     2519
     2520        VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES);
     2521
     2522        /*Clean up and return*/
     2523        delete gauss;
     2524        delete friction;
     2525}
     2526/*}}}*/
     2527/*FUNCTION Tria::GradjDragGradient{{{1*/
     2528void  Tria::GradjDragGradient(Vec gradient, int weight_index){
     2529
     2530        int        i,ig;
     2531        int        doflist1[NUMVERTICES];
     2532        double     Jdet,weight;
     2533        double     xyz_list[NUMVERTICES][3];
     2534        double     dbasis[NDOF2][NUMVERTICES];
     2535        double     dk[NDOF2];
     2536        double     grade_g[NUMVERTICES]={0.0};
     2537        GaussTria  *gauss=NULL;
     2538
     2539        /*Retrieve all inputs we will be needing: */
     2540        if(IsOnShelf())return;
     2541        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2542        GetDofList1(&doflist1[0]);
     2543        Input* dragcoefficient_input=inputs->GetInput(FrictionCoefficientEnum); _assert_(dragcoefficient_input);
     2544        Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);                 _assert_(weights_input);
     2545
     2546        /* Start  looping on the number of gaussian points: */
     2547        gauss=new GaussTria(2);
     2548        for (ig=gauss->begin();ig<gauss->end();ig++){
     2549
     2550                gauss->GaussPoint(ig);
     2551
     2552                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     2553                GetNodalFunctionsDerivatives(&dbasis[0][0],&xyz_list[0][0],gauss);
     2554                weights_input->GetParameterValue(&weight,gauss,weight_index);
     2555
     2556                /*Build alpha_complement_list: */
     2557                dragcoefficient_input->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],gauss);
     2558
     2559                /*Build gradje_g_gaussian vector (actually -dJ/ddrag): */
     2560                for (i=0;i<NUMVERTICES;i++){
     2561                        grade_g[i]+=-weight*Jdet*gauss->weight*(dbasis[0][i]*dk[0]+dbasis[1][i]*dk[1]);
     2562                        _assert_(!isnan(grade_g[i]));
     2563                }
     2564        }
     2565        VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES);
     2566
     2567        /*Clean up and return*/
     2568        delete gauss;
     2569}
     2570/*}}}*/
     2571/*FUNCTION Tria::GradjDhDtBalancedthickness{{{1*/
     2572void  Tria::GradjDhDtBalancedthickness(Vec gradient){
     2573
     2574        /*Intermediaries*/
     2575        int    doflist1[NUMVERTICES];
     2576        double lambda[NUMVERTICES];
     2577        double gradient_g[NUMVERTICES];
     2578
     2579        GetDofList1(&doflist1[0]);
     2580
     2581        /*Compute Gradient*/
     2582        GetParameterListOnVertices(&lambda[0],AdjointEnum);
     2583        for(int i=0;i<NUMVERTICES;i++) gradient_g[i]=-lambda[i];
     2584
     2585        VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)gradient_g,INSERT_VALUES);
     2586}
     2587/*}}}*/
     2588/*FUNCTION Tria::GradjVxBalancedthickness{{{1*/
     2589void  Tria::GradjVxBalancedthickness(Vec gradient){
     2590
     2591        /*Intermediaries*/
     2592        int        i,ig;
     2593        int        doflist1[NUMVERTICES];
     2594        double     thickness,Jdet;
     2595        double     basis[3];
     2596        double     Dlambda[2],dp[2];
     2597        double     xyz_list[NUMVERTICES][3];
     2598        double     grade_g[NUMVERTICES] = {0.0};
     2599        GaussTria *gauss                = NULL;
     2600
     2601        /* Get node coordinates and dof list: */
     2602        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2603        GetDofList1(&doflist1[0]);
     2604
     2605        /*Retrieve all inputs we will be needing: */
     2606        Input* adjoint_input=inputs->GetInput(AdjointEnum);     _assert_(adjoint_input);
     2607        Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
     2608
     2609        /* Start  looping on the number of gaussian points: */
     2610        gauss=new GaussTria(2);
     2611        for (ig=gauss->begin();ig<gauss->end();ig++){
     2612
     2613                gauss->GaussPoint(ig);
     2614
     2615                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     2616                GetNodalFunctions(basis, gauss);
     2617               
     2618                adjoint_input->GetParameterDerivativeValue(&Dlambda[0],&xyz_list[0][0],gauss);
     2619                thickness_input->GetParameterValue(&thickness, gauss);
     2620                thickness_input->GetParameterDerivativeValue(&dp[0],&xyz_list[0][0],gauss);
     2621
     2622                for(i=0;i<NUMVERTICES;i++) grade_g[i]+=thickness*Dlambda[0]*Jdet*gauss->weight*basis[i];
     2623        }
     2624
     2625        VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES);
     2626
     2627        /*Clean up and return*/
     2628        delete gauss;
     2629}
     2630/*}}}*/
     2631/*FUNCTION Tria::GradjVyBalancedthickness{{{1*/
     2632void  Tria::GradjVyBalancedthickness(Vec gradient){
     2633
     2634        /*Intermediaries*/
     2635        int        i,ig;
     2636        int        doflist1[NUMVERTICES];
     2637        double     thickness,Jdet;
     2638        double     basis[3];
     2639        double     Dlambda[2],dp[2];
     2640        double     xyz_list[NUMVERTICES][3];
     2641        double     grade_g[NUMVERTICES] = {0.0};
     2642        GaussTria *gauss                = NULL;
     2643
     2644        /* Get node coordinates and dof list: */
     2645        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2646        GetDofList1(&doflist1[0]);
     2647
     2648        /*Retrieve all inputs we will be needing: */
     2649        Input* adjoint_input=inputs->GetInput(AdjointEnum);     _assert_(adjoint_input);
     2650        Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
     2651
     2652        /* Start  looping on the number of gaussian points: */
     2653        gauss=new GaussTria(2);
     2654        for (ig=gauss->begin();ig<gauss->end();ig++){
     2655
     2656                gauss->GaussPoint(ig);
     2657
     2658                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     2659                GetNodalFunctions(basis, gauss);
     2660
     2661                adjoint_input->GetParameterDerivativeValue(&Dlambda[0],&xyz_list[0][0],gauss);
     2662                thickness_input->GetParameterValue(&thickness, gauss);
     2663                thickness_input->GetParameterDerivativeValue(&dp[0],&xyz_list[0][0],gauss);
     2664
     2665                for(i=0;i<NUMVERTICES;i++) grade_g[i]+=thickness*Dlambda[1]*Jdet*gauss->weight*basis[i];
     2666        }
     2667        VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES);
     2668
     2669        /*Clean up and return*/
     2670        delete gauss;
     2671}
     2672/*}}}*/
     2673/*FUNCTION Tria::RheologyBbarAbsGradient{{{1*/
     2674double Tria::RheologyBbarAbsGradient(bool process_units,int weight_index){
     2675
     2676        /* Intermediaries */
     2677        int        ig;
     2678        double     Jelem = 0;
     2679        double     weight;
     2680        double     Jdet;
     2681        double     xyz_list[NUMVERTICES][3];
     2682        double     dp[NDOF2];
     2683        GaussTria *gauss = NULL;
     2684
     2685        /*retrieve parameters and inputs*/
     2686
     2687        /*If on water, return 0: */
     2688        if(IsOnWater()) return 0;
     2689
     2690        /*Retrieve all inputs we will be needing: */
     2691        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2692        Input* weights_input  =inputs->GetInput(InversionCostFunctionsCoefficientsEnum);              _assert_(weights_input);
     2693        Input* rheologyb_input=matice->inputs->GetInput(MaterialsRheologyBbarEnum); _assert_(rheologyb_input);
     2694
     2695        /* Start looping on the number of gaussian points: */
     2696        gauss=new GaussTria(2);
     2697        for (ig=gauss->begin();ig<gauss->end();ig++){
     2698
     2699                gauss->GaussPoint(ig);
     2700
     2701                /* Get Jacobian determinant: */
     2702                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     2703
     2704                /*Get all parameters at gaussian point*/
     2705                weights_input->GetParameterValue(&weight,gauss,weight_index);
     2706                rheologyb_input->GetParameterDerivativeValue(&dp[0],&xyz_list[0][0],gauss);
     2707
     2708                /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */
     2709                //Jelem+=weight*1/2*(pow(dp[0],2.)+pow(dp[1],2.))*Jdet*gauss->weight;
     2710        }
     2711
     2712        /*Clean up and return*/
     2713        delete gauss;
     2714        return Jelem;
     2715}
     2716/*}}}*/
     2717/*FUNCTION Tria::SurfaceAverageVelMisfit {{{1*/
     2718double Tria::SurfaceAverageVelMisfit(bool process_units,int weight_index){
     2719
     2720        const int    numdof=2*NUMVERTICES;
     2721
     2722        int        i,ig;
     2723        double     Jelem=0,S,Jdet;
     2724        double     misfit;
     2725        double     vx,vy,vxobs,vyobs,weight;
     2726        double     xyz_list[NUMVERTICES][3];
     2727        GaussTria *gauss=NULL;
     2728
     2729        /*If on water, return 0: */
     2730        if(IsOnWater())return 0;
     2731
     2732        /* Get node coordinates and dof list: */
     2733        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2734
     2735        /*Retrieve all inputs we will be needing: */
     2736        inputs->GetParameterValue(&S,SurfaceAreaEnum);
     2737        Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
     2738        Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
     2739        Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
     2740        Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
     2741        Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
     2742
     2743        /* Start  looping on the number of gaussian points: */
     2744        gauss=new GaussTria(3);
     2745        for (ig=gauss->begin();ig<gauss->end();ig++){
     2746
     2747                gauss->GaussPoint(ig);
     2748
     2749                /* Get Jacobian determinant: */
     2750                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     2751
     2752                /*Get all parameters at gaussian point*/
     2753                weights_input->GetParameterValue(&weight,gauss,weight_index);
     2754                vx_input->GetParameterValue(&vx,gauss);
     2755                vy_input->GetParameterValue(&vy,gauss);
     2756                vxobs_input->GetParameterValue(&vxobs,gauss);
     2757                vyobs_input->GetParameterValue(&vyobs,gauss);
     2758
     2759                /*Compute SurfaceAverageVelMisfitEnum:
     2760                 *
     2761                 *      1                    2              2
     2762                 * J = ---  sqrt(  (u - u   )  +  (v - v   )  )
     2763                 *      S                obs            obs
     2764                 */
     2765                misfit=1/S*pow( pow(vx-vxobs,2.) + pow(vy-vyobs,2.) ,0.5);
     2766
     2767                if(process_units)UnitConversion(misfit,IuToExtEnum,SurfaceAverageVelMisfitEnum);
     2768
     2769                /*Add to cost function*/
     2770                Jelem+=misfit*weight*Jdet*gauss->weight;
     2771        }
     2772
     2773        /*clean-up and Return: */
     2774        delete gauss;
     2775        return Jelem;
     2776}
     2777/*}}}*/
     2778/*FUNCTION Tria::SurfaceLogVelMisfit {{{1*/
     2779double Tria::SurfaceLogVelMisfit(bool process_units,int weight_index){
     2780
     2781        const int    numdof=NDOF2*NUMVERTICES;
     2782
     2783        int        i,ig;
     2784        double     Jelem=0;
     2785        double     misfit,Jdet;
     2786        double     epsvel=2.220446049250313e-16;
     2787        double     meanvel=3.170979198376458e-05; /*1000 m/yr*/
     2788        double     velocity_mag,obs_velocity_mag;
     2789        double     xyz_list[NUMVERTICES][3];
     2790        double     vx,vy,vxobs,vyobs,weight;
     2791        GaussTria *gauss=NULL;
     2792
     2793        /*If on water, return 0: */
     2794        if(IsOnWater())return 0;
     2795
     2796        /* Get node coordinates and dof list: */
     2797        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2798
     2799        /*Retrieve all inputs we will be needing: */
     2800        Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
     2801        Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
     2802        Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
     2803        Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
     2804        Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
     2805
     2806        /* Start  looping on the number of gaussian points: */
     2807        gauss=new GaussTria(4);
     2808        for (ig=gauss->begin();ig<gauss->end();ig++){
     2809
     2810                gauss->GaussPoint(ig);
     2811
     2812                /* Get Jacobian determinant: */
     2813                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     2814
     2815                /*Get all parameters at gaussian point*/
     2816                weights_input->GetParameterValue(&weight,gauss,weight_index);
     2817                vx_input->GetParameterValue(&vx,gauss);
     2818                vy_input->GetParameterValue(&vy,gauss);
     2819                vxobs_input->GetParameterValue(&vxobs,gauss);
     2820                vyobs_input->GetParameterValue(&vyobs,gauss);
     2821
     2822                /*Compute SurfaceLogVelMisfit:
     2823                 *                 [        vel + eps     ] 2
     2824                 * J = 4 \bar{v}^2 | log ( -----------  ) | 
     2825                 *                 [       vel   + eps    ]
     2826                 *                            obs
     2827                 */
     2828                velocity_mag    =sqrt(pow(vx,   2.)+pow(vy,   2.))+epsvel;
     2829                obs_velocity_mag=sqrt(pow(vxobs,2.)+pow(vyobs,2.))+epsvel;
     2830                misfit=4*pow(meanvel,2.)*pow(log(velocity_mag/obs_velocity_mag),2.);
     2831
     2832                if(process_units)UnitConversion(misfit,IuToExtEnum,SurfaceLogVelMisfitEnum);
     2833
     2834                /*Add to cost function*/
     2835                Jelem+=misfit*weight*Jdet*gauss->weight;
     2836        }
     2837
     2838        /*clean-up and Return: */
     2839        delete gauss;
     2840        return Jelem;
     2841}
     2842/*}}}*/
     2843/*FUNCTION Tria::SurfaceLogVxVyMisfit {{{1*/
     2844double Tria::SurfaceLogVxVyMisfit(bool process_units,int weight_index){
     2845
     2846        const int    numdof=NDOF2*NUMVERTICES;
     2847
     2848        int        i,ig;
     2849        int        fit=-1;
     2850        double     Jelem=0, S=0;
     2851        double     epsvel=2.220446049250313e-16;
     2852        double     meanvel=3.170979198376458e-05; /*1000 m/yr*/
     2853        double     misfit, Jdet;
     2854        double     vx,vy,vxobs,vyobs,weight;
     2855        double     xyz_list[NUMVERTICES][3];
     2856        GaussTria *gauss=NULL;
     2857
     2858        /*If on water, return 0: */
     2859        if(IsOnWater())return 0;
     2860
     2861        /* Get node coordinates and dof list: */
     2862        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2863
     2864        /*Retrieve all inputs we will be needing: */
     2865        Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
     2866        Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
     2867        Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
     2868        Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
     2869        Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
     2870       
     2871        /* Start  looping on the number of gaussian points: */
     2872        gauss=new GaussTria(4);
     2873        for (ig=gauss->begin();ig<gauss->end();ig++){
     2874
     2875                gauss->GaussPoint(ig);
     2876
     2877                /* Get Jacobian determinant: */
     2878                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     2879
     2880                /*Get all parameters at gaussian point*/
     2881                weights_input->GetParameterValue(&weight,gauss,weight_index);
     2882                vx_input->GetParameterValue(&vx,gauss);
     2883                vy_input->GetParameterValue(&vy,gauss);
     2884                vxobs_input->GetParameterValue(&vxobs,gauss);
     2885                vyobs_input->GetParameterValue(&vyobs,gauss);
     2886
     2887                /*Compute SurfaceRelVelMisfit:
     2888                 *
     2889                 *      1            [        |u| + eps     2          |v| + eps     2  ]
     2890                 * J = --- \bar{v}^2 | log ( -----------  )   +  log ( -----------  )   | 
     2891                 *      2            [       |u    |+ eps              |v    |+ eps     ]
     2892                 *                              obs                       obs
     2893                 */
     2894                misfit=0.5*pow(meanvel,2.)*(
     2895                                        pow(log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)),2.) +
     2896                                        pow(log((fabs(vy)+epsvel)/(fabs(vyobs)+epsvel)),2.) );
     2897
     2898                if(process_units)UnitConversion(misfit,IuToExtEnum,SurfaceLogVxVyMisfitEnum);
     2899
     2900                /*Add to cost function*/
     2901                Jelem+=misfit*weight*Jdet*gauss->weight;
     2902        }
     2903
     2904        /*clean-up and Return: */
     2905        delete gauss;
     2906        return Jelem;
     2907}
     2908/*}}}*/
     2909/*FUNCTION Tria::SurfaceAbsVelMisfit {{{1*/
     2910double Tria::SurfaceAbsVelMisfit(bool process_units,int weight_index){
     2911
     2912        const int    numdof=NDOF2*NUMVERTICES;
     2913
     2914        int        i,ig;
     2915        double     Jelem=0;
     2916        double     misfit,Jdet;
     2917        double     vx,vy,vxobs,vyobs,weight;
     2918        double     xyz_list[NUMVERTICES][3];
     2919        GaussTria *gauss=NULL;
     2920
     2921        /*If on water, return 0: */
     2922        if(IsOnWater())return 0;
     2923
     2924        /* Get node coordinates and dof list: */
     2925        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2926
     2927        /*Retrieve all inputs we will be needing: */
     2928        Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
     2929        Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
     2930        Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
     2931        Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
     2932        Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
     2933
     2934        /* Start  looping on the number of gaussian points: */
     2935        gauss=new GaussTria(2);
     2936        for (ig=gauss->begin();ig<gauss->end();ig++){
     2937
     2938                gauss->GaussPoint(ig);
     2939
     2940                /* Get Jacobian determinant: */
     2941                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     2942
     2943                /*Get all parameters at gaussian point*/
     2944                weights_input->GetParameterValue(&weight,gauss,weight_index);
     2945                vx_input->GetParameterValue(&vx,gauss);
     2946                vy_input->GetParameterValue(&vy,gauss);
     2947                vxobs_input->GetParameterValue(&vxobs,gauss);
     2948                vyobs_input->GetParameterValue(&vyobs,gauss);
     2949
     2950                /*Compute SurfaceAbsVelMisfitEnum:
     2951                 *
     2952                 *      1  [           2              2 ]
     2953                 * J = --- | (u - u   )  +  (v - v   )  |
     2954                 *      2  [       obs            obs   ]
     2955                 *
     2956                 */
     2957                misfit=0.5*( pow(vx-vxobs,2.) + pow(vy-vyobs,2.) );
     2958
     2959                if(process_units)UnitConversion(misfit,IuToExtEnum,SurfaceAverageVelMisfitEnum);
     2960
     2961                /*Add to cost function*/
     2962                Jelem+=misfit*weight*Jdet*gauss->weight;
     2963        }
     2964
     2965        /*clean up and Return: */
     2966        delete gauss;
     2967        return Jelem;
     2968}
     2969/*}}}*/
     2970/*FUNCTION Tria::SurfaceRelVelMisfit {{{1*/
     2971double Tria::SurfaceRelVelMisfit(bool process_units,int weight_index){
     2972        const int  numdof=2*NUMVERTICES;
     2973
     2974        int        i,ig;
     2975        double     Jelem=0;
     2976        double     scalex=1,scaley=1;
     2977        double     misfit,Jdet;
     2978        double     epsvel=2.220446049250313e-16;
     2979        double     meanvel=3.170979198376458e-05; /*1000 m/yr*/
     2980        double     vx,vy,vxobs,vyobs,weight;
     2981        double     xyz_list[NUMVERTICES][3];
     2982        GaussTria *gauss=NULL;
     2983
     2984        /*If on water, return 0: */
     2985        if(IsOnWater())return 0;
     2986
     2987        /* Get node coordinates and dof list: */
     2988        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     2989
     2990        /*Retrieve all inputs we will be needing: */
     2991        Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
     2992        Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
     2993        Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
     2994        Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
     2995        Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
     2996
     2997        /* Start  looping on the number of gaussian points: */
     2998        gauss=new GaussTria(4);
     2999        for (ig=gauss->begin();ig<gauss->end();ig++){
     3000
     3001                gauss->GaussPoint(ig);
     3002
     3003                /* Get Jacobian determinant: */
     3004                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     3005
     3006                /*Get all parameters at gaussian point*/
     3007                weights_input->GetParameterValue(&weight,gauss,weight_index);
     3008                vx_input->GetParameterValue(&vx,gauss);
     3009                vy_input->GetParameterValue(&vy,gauss);
     3010                vxobs_input->GetParameterValue(&vxobs,gauss);
     3011                vyobs_input->GetParameterValue(&vyobs,gauss);
     3012
     3013                /*Compute SurfaceRelVelMisfit:
     3014                 *                       
     3015                 *      1  [     \bar{v}^2             2   \bar{v}^2              2 ]
     3016                 * J = --- | -------------  (u - u   ) + -------------  (v - v   )  |
     3017                 *      2  [  (u   + eps)^2       obs    (v   + eps)^2       obs    ]
     3018                 *              obs                        obs                     
     3019                 */
     3020                scalex=pow(meanvel/(vxobs+epsvel),2.); if(vxobs==0)scalex=0;
     3021                scaley=pow(meanvel/(vyobs+epsvel),2.); if(vyobs==0)scaley=0;
     3022                misfit=0.5*(scalex*pow((vx-vxobs),2.)+scaley*pow((vy-vyobs),2.));
     3023                if(process_units)UnitConversion(misfit,IuToExtEnum,SurfaceRelVelMisfitEnum);
     3024
     3025                /*Add to cost function*/
     3026                Jelem+=misfit*weight*Jdet*gauss->weight;
     3027        }
     3028
     3029        /*clean up and Return: */
     3030        delete gauss;
     3031        return Jelem;
     3032}
     3033/*}}}*/
     3034/*FUNCTION Tria::ThicknessAbsGradient{{{1*/
     3035double Tria::ThicknessAbsGradient(bool process_units,int weight_index){
     3036
     3037        /* Intermediaries */
     3038        int        ig;
     3039        double     Jelem = 0;
     3040        double     weight;
     3041        double     Jdet;
     3042        double     xyz_list[NUMVERTICES][3];
     3043        double     dp[NDOF2];
     3044        GaussTria *gauss = NULL;
     3045
     3046        /*retrieve parameters and inputs*/
     3047
     3048        /*If on water, return 0: */
     3049        if(IsOnWater()) return 0;
     3050
     3051        /*Retrieve all inputs we will be needing: */
     3052        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     3053        Input* weights_input  =inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
     3054        Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
     3055
     3056        /* Start looping on the number of gaussian points: */
     3057        gauss=new GaussTria(2);
     3058        for (ig=gauss->begin();ig<gauss->end();ig++){
     3059
     3060                gauss->GaussPoint(ig);
     3061
     3062                /* Get Jacobian determinant: */
     3063                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     3064
     3065                /*Get all parameters at gaussian point*/
     3066                weights_input->GetParameterValue(&weight,gauss,weight_index);
     3067                thickness_input->GetParameterDerivativeValue(&dp[0],&xyz_list[0][0],gauss);
     3068
     3069                /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */
     3070                Jelem+=weight*1/2*(pow(dp[0],2.)+pow(dp[1],2.))*Jdet*gauss->weight;
     3071        }
     3072
     3073        /*Clean up and return*/
     3074        delete gauss;
     3075        return Jelem;
     3076}
     3077/*}}}*/
     3078/*FUNCTION Tria::ThicknessAbsMisfit {{{1*/
     3079double Tria::ThicknessAbsMisfit(bool process_units,int weight_index){
     3080
     3081        /*Intermediaries*/
     3082        int        i,ig;
     3083        double     thickness,thicknessobs,weight;
     3084        double     Jdet;
     3085        double     Jelem = 0;
     3086        double     xyz_list[NUMVERTICES][3];
     3087        GaussTria *gauss = NULL;
     3088        double     dH[2];
     3089
     3090        /*If on water, return 0: */
     3091        if(IsOnWater())return 0;
     3092
     3093        /*Retrieve all inputs we will be needing: */
     3094        GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
     3095        Input* thickness_input   =inputs->GetInput(ThicknessEnum);   _assert_(thickness_input);
     3096        Input* thicknessobs_input=inputs->GetInput(InversionThicknessObsEnum);_assert_(thicknessobs_input);
     3097        Input* weights_input     =inputs->GetInput(InversionCostFunctionsCoefficientsEnum);     _assert_(weights_input);
     3098
     3099        /* Start  looping on the number of gaussian points: */
     3100        gauss=new GaussTria(2);
     3101        for (ig=gauss->begin();ig<gauss->end();ig++){
     3102
     3103                gauss->GaussPoint(ig);
     3104
     3105                /* Get Jacobian determinant: */
     3106                GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
     3107
     3108                /*Get parameters at gauss point*/
     3109                thickness_input->GetParameterValue(&thickness,gauss);
     3110                thickness_input->GetParameterDerivativeValue(&dH[0],&xyz_list[0][0],gauss);
     3111                thicknessobs_input->GetParameterValue(&thicknessobs,gauss);
     3112                weights_input->GetParameterValue(&weight,gauss,weight_index);
     3113
     3114                /*compute ThicknessAbsMisfit*/
     3115                Jelem+=0.5*pow(thickness-thicknessobs,2.0)*weight*Jdet*gauss->weight;
     3116        }
     3117
     3118        /* clean up and Return: */
     3119        delete gauss;
     3120        return Jelem;
    14333121}
    14343122/*}}}*/
     
    18543542}
    18553543/*}}}*/
    1856 /*FUNCTION Tria::CreatePVectorDiagnosticHutter{{{1*/
    1857 ElementVector* Tria::CreatePVectorDiagnosticHutter(void){
    1858 
    1859         /*Intermediaries */
    1860         int        i,connectivity;
    1861         double     constant_part,ub,vb;
    1862         double     rho_ice,gravity,n,B;
    1863         double     slope2,thickness;
    1864         double     slope[2];
    1865         GaussTria* gauss=NULL;
    1866 
    1867         /*Initialize Element vector*/
    1868         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
    1869 
    1870         /*Retrieve all inputs and parameters*/
    1871         rho_ice=matpar->GetRhoIce();
    1872         gravity=matpar->GetG();
    1873         n=matice->GetN();
    1874         B=matice->GetBbar();
    1875         Input* slopex_input=inputs->GetInput(SurfaceSlopeXEnum); _assert_(slopex_input);
    1876         Input* slopey_input=inputs->GetInput(SurfaceSlopeYEnum); _assert_(slopey_input);
    1877         Input* thickness_input=inputs->GetInput(ThicknessEnum);  _assert_(thickness_input);
    1878 
    1879         /*Spawn 3 sing elements: */
    1880         gauss=new GaussTria();
    1881         for(i=0;i<NUMVERTICES;i++){
    1882 
    1883                 gauss->GaussVertex(i);
    1884 
    1885                 connectivity=nodes[i]->GetConnectivity();
    1886 
    1887                 thickness_input->GetParameterValue(&thickness,gauss);
    1888                 slopex_input->GetParameterValue(&slope[0],gauss);
    1889                 slopey_input->GetParameterValue(&slope[1],gauss);
    1890                 slope2=pow(slope[0],2)+pow(slope[1],2);
    1891 
    1892                 constant_part=-2*pow(rho_ice*gravity,n)*pow(slope2,((n-1)/2));
    1893 
    1894                 ub=-1.58*pow((double)10.0,(double)-10.0)*rho_ice*gravity*thickness*slope[0];
    1895                 vb=-1.58*pow((double)10.0,(double)-10.0)*rho_ice*gravity*thickness*slope[1];
    1896 
    1897                 pe->values[2*i]  =(ub-2.0*pow(rho_ice*gravity,n)*pow(slope2,((n-1)/2.0))*pow(thickness,n)/(pow(B,n)*(n+1))*slope[0])/(double)connectivity;
    1898                 pe->values[2*i+1]=(vb-2.0*pow(rho_ice*gravity,n)*pow(slope2,((n-1)/2.0))*pow(thickness,n)/(pow(B,n)*(n+1))*slope[1])/(double)connectivity;
    1899         }
    1900 
    1901         /*Clean up and return*/
    1902         delete gauss;
    1903         return pe;
    1904 }
    1905 /*}}}*/
    1906 /*FUNCTION Tria::CreatePVectorPrognostic{{{1*/
    1907 ElementVector* Tria::CreatePVectorPrognostic(void){
    1908 
    1909         switch(GetElementType()){
    1910                 case P1Enum:
    1911                         return CreatePVectorPrognostic_CG();
    1912                 case P1DGEnum:
    1913                         return CreatePVectorPrognostic_DG();
    1914                 default:
    1915                         _error_("Element type %s not supported yet",EnumToStringx(GetElementType()));
    1916         }
    1917 }
    1918 /*}}}*/
    1919 /*FUNCTION Tria::CreatePVectorHydrology {{{1*/
    1920 ElementVector* Tria::CreatePVectorHydrology(void){
    1921 
    1922         /*Constants*/
    1923         const int    numdof=NDOF1*NUMVERTICES;
    1924 
    1925         /*Intermediaries */
    1926         int        i,j,ig;
    1927         double     Jdettria,dt;
    1928         double     basal_melting_g;
    1929         double     old_watercolumn_g;
    1930         double     xyz_list[NUMVERTICES][3];
    1931         double     basis[numdof];
    1932         GaussTria* gauss=NULL;
    1933 
    1934         /*Initialize Element vector*/
    1935         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
    1936 
    1937         /*Retrieve all inputs and parameters*/
    1938         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    1939         this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
    1940         Input* basal_melting_input=inputs->GetInput(BasalforcingsMeltingRateEnum); _assert_(basal_melting_input);
    1941         Input* old_watercolumn_input=inputs->GetInput(WaterColumnOldEnum);         _assert_(old_watercolumn_input);
    1942 
    1943         /*Initialize basal_melting_correction_g to 0, do not forget!:*/
    1944         /* Start  looping on the number of gaussian points: */
    1945         gauss=new GaussTria(2);
    1946         for(ig=gauss->begin();ig<gauss->end();ig++){
    1947 
    1948                 gauss->GaussPoint(ig);
    1949 
    1950                 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss);
    1951                 GetNodalFunctions(basis, gauss);
    1952 
    1953                 basal_melting_input->GetParameterValue(&basal_melting_g,gauss);
    1954                 old_watercolumn_input->GetParameterValue(&old_watercolumn_g,gauss);
    1955 
    1956                 if(dt)for(i=0;i<numdof;i++) pe->values[i]+=Jdettria*gauss->weight*(old_watercolumn_g+dt*basal_melting_g)*basis[i];
    1957                 else  for(i=0;i<numdof;i++) pe->values[i]+=Jdettria*gauss->weight*basal_melting_g*basis[i];
    1958         }
    1959                
    1960         /*Clean up and return*/
    1961         delete gauss;
    1962         return pe;
    1963 }
    1964 /*}}}*/
    1965 /*FUNCTION Tria::CreatePVectorPrognostic_CG {{{1*/
    1966 ElementVector* Tria::CreatePVectorPrognostic_CG(void){
    1967 
    1968         /*Constants*/
    1969         const int    numdof=NDOF1*NUMVERTICES;
    1970 
    1971         /*Intermediaries */
    1972         int        i,j,ig;
    1973         double     Jdettria,dt;
    1974         double     surface_mass_balance_g,basal_melting_g,basal_melting_correction_g,thickness_g;
    1975         double     xyz_list[NUMVERTICES][3];
    1976         double     L[NUMVERTICES];
    1977         GaussTria* gauss=NULL;
    1978 
    1979         /*Initialize Element vector*/
    1980         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
    1981 
    1982         /*Retrieve all inputs and parameters*/
    1983         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    1984         this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
    1985         Input* surface_mass_balance_input=inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(surface_mass_balance_input);
    1986         Input* basal_melting_input=inputs->GetInput(BasalforcingsMeltingRateEnum);          _assert_(basal_melting_input);
    1987         Input* basal_melting_correction_input=inputs->GetInput(BasalforcingsMeltingRateCorrectionEnum);
    1988         Input* thickness_input=inputs->GetInput(ThicknessEnum);                             _assert_(thickness_input);
    1989 
    1990         /*Initialize basal_melting_correction_g to 0, do not forget!:*/
    1991         /* Start  looping on the number of gaussian points: */
    1992         gauss=new GaussTria(2);
    1993         for(ig=gauss->begin();ig<gauss->end();ig++){
    1994 
    1995                 gauss->GaussPoint(ig);
    1996 
    1997                 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss);
    1998                 GetL(&L[0], &xyz_list[0][0], gauss,NDOF1);
    1999 
    2000                 surface_mass_balance_input->GetParameterValue(&surface_mass_balance_g,gauss);
    2001                 basal_melting_input->GetParameterValue(&basal_melting_g,gauss);
    2002                 thickness_input->GetParameterValue(&thickness_g,gauss);
    2003                 if(basal_melting_correction_input) basal_melting_correction_input->GetParameterValue(&basal_melting_correction_g,gauss);
    2004 
    2005                 for(i=0;i<numdof;i++) pe->values[i]+=Jdettria*gauss->weight*(thickness_g+dt*(surface_mass_balance_g-basal_melting_g-basal_melting_correction_g))*L[i];
    2006         }
    2007 
    2008         /*Clean up and return*/
    2009         delete gauss;
    2010         return pe;
    2011 }
    2012 /*}}}*/
    2013 /*FUNCTION Tria::CreatePVectorPrognostic_DG {{{1*/
    2014 ElementVector* Tria::CreatePVectorPrognostic_DG(void){
    2015 
    2016         /*Constants*/
    2017         const int    numdof=NDOF1*NUMVERTICES;
    2018 
    2019         /*Intermediaries */
    2020         int        i,j,ig;
    2021         double     Jdettria,dt;
    2022         double     surface_mass_balance_g,basal_melting_g,thickness_g;
    2023         double     xyz_list[NUMVERTICES][3];
    2024         double     L[NUMVERTICES];
    2025         GaussTria* gauss=NULL;
    2026 
    2027         /*Initialize Element vector*/
    2028         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
    2029 
    2030         /*Retrieve all inputs and parameters*/
    2031         this->parameters->FindParam(&dt,TimesteppingTimeStepEnum);
    2032         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    2033         Input* surface_mass_balance_input=inputs->GetInput(SurfaceforcingsMassBalanceEnum); _assert_(surface_mass_balance_input);
    2034         Input* basal_melting_input=inputs->GetInput(BasalforcingsMeltingRateEnum);          _assert_(basal_melting_input);
    2035         Input* thickness_input=inputs->GetInput(ThicknessEnum);                             _assert_(thickness_input);
    2036 
    2037         /* Start  looping on the number of gaussian points: */
    2038         gauss=new GaussTria(2);
    2039         for(ig=gauss->begin();ig<gauss->end();ig++){
    2040 
    2041                 gauss->GaussPoint(ig);
    2042 
    2043                 GetJacobianDeterminant2d(&Jdettria, &xyz_list[0][0],gauss);
    2044                 GetL(&L[0], &xyz_list[0][0], gauss,NDOF1);
    2045 
    2046                 surface_mass_balance_input->GetParameterValue(&surface_mass_balance_g,gauss);
    2047                 basal_melting_input->GetParameterValue(&basal_melting_g,gauss);
    2048                 thickness_input->GetParameterValue(&thickness_g,gauss);
    2049 
    2050                 for(i=0;i<numdof;i++) pe->values[i]+=Jdettria*gauss->weight*(thickness_g+dt*(surface_mass_balance_g-basal_melting_g))*L[i];
    2051         }
    2052 
    2053         /*Clean up and return*/
    2054         delete gauss;
    2055         return pe;
    2056 }
    2057 /*}}}*/
    2058 /*FUNCTION Tria::CreatePVectorSlope {{{1*/
    2059 ElementVector* Tria::CreatePVectorSlope(void){
    2060 
    2061         /*Constants*/
    2062         const int    numdof=NDOF1*NUMVERTICES;
    2063        
    2064         /*Intermediaries */
    2065         int        i,j,ig;
    2066         int        analysis_type;
    2067         double     Jdet;
    2068         double     xyz_list[NUMVERTICES][3];
    2069         double     slope[2];
    2070         double     basis[3];
    2071         GaussTria* gauss=NULL;
    2072 
    2073         /*Initialize Element vector*/
    2074         ElementVector* pe=new ElementVector(nodes,NUMVERTICES,this->parameters);
    2075 
    2076         /*Retrieve all inputs and parameters*/
    2077         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    2078         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    2079         Input* slope_input=NULL;
    2080         if ( (analysis_type==SurfaceSlopeXAnalysisEnum) || (analysis_type==SurfaceSlopeYAnalysisEnum)){
    2081                 slope_input=inputs->GetInput(SurfaceEnum); _assert_(slope_input);
    2082         }
    2083         if ( (analysis_type==BedSlopeXAnalysisEnum) || (analysis_type==BedSlopeYAnalysisEnum)){
    2084                 slope_input=inputs->GetInput(BedEnum);     _assert_(slope_input);
    2085         }
    2086                
    2087         /* Start  looping on the number of gaussian points: */
    2088         gauss=new GaussTria(2);
    2089         for(ig=gauss->begin();ig<gauss->end();ig++){
    2090 
    2091                 gauss->GaussPoint(ig);
    2092 
    2093                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    2094                 GetNodalFunctions(basis, gauss);
    2095 
    2096                 slope_input->GetParameterDerivativeValue(&slope[0],&xyz_list[0][0],gauss);
    2097 
    2098                 if ( (analysis_type==SurfaceSlopeXAnalysisEnum) || (analysis_type==BedSlopeXAnalysisEnum)){
    2099                         for(i=0;i<numdof;i++) pe->values[i]+=Jdet*gauss->weight*slope[0]*basis[i];
    2100                 }
    2101                 if ( (analysis_type==SurfaceSlopeYAnalysisEnum) || (analysis_type==BedSlopeYAnalysisEnum)){
    2102                         for(i=0;i<numdof;i++) pe->values[i]+=Jdet*gauss->weight*slope[1]*basis[i];
    2103                 }
    2104         }
    2105 
    2106         /*Clean up and return*/
    2107         delete gauss;
    2108         return pe;
    2109 }
    2110 /*}}}*/
    2111 /*FUNCTION Tria::ComputeBasalStress {{{1*/
    2112 void  Tria::ComputeBasalStress(Vec eps){
    2113         _error_("Not Implemented yet");
    2114 }
    2115 /*}}}*/
    2116 /*FUNCTION Tria::ComputeStrainRate {{{1*/
    2117 void  Tria::ComputeStrainRate(Vec eps){
    2118         _error_("Not Implemented yet");
    2119 }
    2120 /*}}}*/
    2121 /*FUNCTION Tria::Configure {{{1*/
    2122 void  Tria::Configure(Elements* elementsin, Loads* loadsin, DataSet* nodesin, Materials* materialsin, Parameters* parametersin){
    2123        
    2124         /*go into parameters and get the analysis_counter: */
    2125         int analysis_counter;
    2126         parametersin->FindParam(&analysis_counter,AnalysisCounterEnum);
    2127 
    2128         /*Get Element type*/
    2129         this->element_type=this->element_type_list[analysis_counter];
    2130 
    2131         /*Take care of hooking up all objects for this element, ie links the objects in the hooks to their respective
    2132          * datasets, using internal ids and offsets hidden in hooks: */
    2133         if(this->hnodes[analysis_counter]) this->hnodes[analysis_counter]->configure(nodesin);
    2134         this->hmatice->configure(materialsin);
    2135         this->hmatpar->configure(materialsin);
    2136 
    2137         /*Now, go pick up the objects inside the hooks: */
    2138         if(this->hnodes[analysis_counter]) this->nodes=(Node**)this->hnodes[analysis_counter]->deliverp();
    2139         else this->nodes=NULL;
    2140         this->matice=(Matice*)this->hmatice->delivers();
    2141         this->matpar=(Matpar*)this->hmatpar->delivers();
    2142 
    2143         /*point parameters to real dataset: */
    2144         this->parameters=parametersin;
    2145 
    2146         /*get inputs configured too: */
    2147         this->inputs->Configure(parameters);
    2148 
    2149 }
    2150 /*}}}*/
    2151 /*FUNCTION Tria::ControlInputGetGradient{{{1*/
    2152 void Tria::ControlInputGetGradient(Vec gradient,int enum_type){
    2153 
    2154         int doflist1[NUMVERTICES];
    2155         Input* input=NULL;
    2156 
    2157         if(enum_type==MaterialsRheologyBbarEnum){
    2158                 input=(Input*)matice->inputs->GetInput(enum_type);
    2159         }
    2160         else{
    2161                 input=inputs->GetInput(enum_type);
    2162         }
    2163         if (!input) _error_("Input %s not found",EnumToStringx(enum_type));
    2164         if (input->Enum()!=ControlInputEnum) _error_("Input %s is not a ControlInput",EnumToStringx(enum_type));
    2165 
    2166         this->GetDofList1(&doflist1[0]);
    2167         ((ControlInput*)input)->GetGradient(gradient,&doflist1[0]);
    2168 
    2169 }/*}}}*/
    2170 /*FUNCTION Tria::ControlInputScaleGradient{{{1*/
    2171 void Tria::ControlInputScaleGradient(int enum_type,double scale){
    2172 
    2173         Input* input=NULL;
    2174 
    2175         if(enum_type==MaterialsRheologyBbarEnum){
    2176                 input=(Input*)matice->inputs->GetInput(enum_type);
    2177         }
    2178         else{
    2179                 input=inputs->GetInput(enum_type);
    2180         }
    2181         if (!input) _error_("Input %s not found",EnumToStringx(enum_type));
    2182         if (input->Enum()!=ControlInputEnum) _error_("Input %s is not a ControlInput",EnumToStringx(enum_type));
    2183 
    2184         ((ControlInput*)input)->ScaleGradient(scale);
    2185 }/*}}}*/
    2186 /*FUNCTION Tria::ControlInputSetGradient{{{1*/
    2187 void Tria::ControlInputSetGradient(double* gradient,int enum_type){
    2188 
    2189         int    doflist1[NUMVERTICES];
    2190         double grad_list[NUMVERTICES];
    2191         Input* grad_input=NULL;
    2192         Input* input=NULL;
    2193 
    2194         if(enum_type==MaterialsRheologyBbarEnum){
    2195                 input=(Input*)matice->inputs->GetInput(enum_type);
    2196         }
    2197         else{
    2198                 input=inputs->GetInput(enum_type);
    2199         }
    2200         if (!input) _error_("Input %s not found",EnumToStringx(enum_type));
    2201         if (input->Enum()!=ControlInputEnum) _error_("Input %s is not a ControlInput",EnumToStringx(enum_type));
    2202 
    2203         this->GetDofList1(&doflist1[0]);
    2204         for(int i=0;i<NUMVERTICES;i++) grad_list[i]=gradient[doflist1[i]];
    2205         grad_input=new TriaVertexInput(GradientEnum,grad_list);
    2206 
    2207         ((ControlInput*)input)->SetGradient(grad_input);
    2208 
    2209 }/*}}}*/
    2210 /*FUNCTION Tria::DeepEcho{{{1*/
    2211 void Tria::DeepEcho(void){
    2212 
    2213         printf("Tria:\n");
    2214         printf("   id: %i\n",id);
    2215         if(nodes){
    2216                 nodes[0]->DeepEcho();
    2217                 nodes[1]->DeepEcho();
    2218                 nodes[2]->DeepEcho();
    2219         }
    2220         else printf("nodes = NULL\n");
    2221 
    2222         if (matice) matice->DeepEcho();
    2223         else printf("matice = NULL\n");
    2224 
    2225         if (matpar) matpar->DeepEcho();
    2226         else printf("matpar = NULL\n");
    2227 
    2228         printf("   parameters\n");
    2229         if (parameters) parameters->DeepEcho();
    2230         else printf("parameters = NULL\n");
    2231 
    2232         printf("   inputs\n");
    2233         if (inputs) inputs->DeepEcho();
    2234         else printf("inputs=NULL\n");
    2235 
    2236         if (results) results->DeepEcho();
    2237         else printf("results=NULL\n");
    2238 
    2239         printf("neighboor sids: \n");
    2240         printf(" %i %i %i\n",horizontalneighborsids[0],horizontalneighborsids[1],horizontalneighborsids[2]);
    2241        
    2242         return;
    2243 }
    2244 /*}}}*/
    2245 /*FUNCTION Tria::DeleteResults {{{1*/
    2246 void  Tria::DeleteResults(void){
    2247 
    2248         /*Delete and reinitialize results*/
    2249         delete this->results;
    2250         this->results=new Results();
    2251 
    2252 }
    2253 /*}}}*/
    22543544/*FUNCTION Tria::DragCoefficientAbsGradient{{{1*/
    22553545double Tria::DragCoefficientAbsGradient(bool process_units,int weight_index){
     
    22963586}
    22973587/*}}}*/
    2298 /*FUNCTION Tria::Echo{{{1*/
    2299 void Tria::Echo(void){
    2300         printf("Tria:\n");
    2301         printf("   id: %i\n",id);
    2302         if(nodes){
    2303                 nodes[0]->Echo();
    2304                 nodes[1]->Echo();
    2305                 nodes[2]->Echo();
    2306         }
    2307         else printf("nodes = NULL\n");
    2308 
    2309         if (matice) matice->Echo();
    2310         else printf("matice = NULL\n");
    2311 
    2312         if (matpar) matpar->Echo();
    2313         else printf("matpar = NULL\n");
    2314 
    2315         printf("   parameters\n");
    2316         if (parameters) parameters->Echo();
    2317         else printf("parameters = NULL\n");
    2318 
    2319         printf("   inputs\n");
    2320         if (inputs) inputs->Echo();
    2321         else printf("inputs=NULL\n");
    2322 
    2323         if (results) results->Echo();
    2324         else printf("results=NULL\n");
    2325 
    2326         printf("neighboor sids: \n");
    2327         printf(" %i %i %i\n",horizontalneighborsids[0],horizontalneighborsids[1],horizontalneighborsids[2]);
    2328 }
    2329 /*}}}*/
    2330 /*FUNCTION Tria::Enum {{{1*/
    2331 int Tria::Enum(void){
    2332 
    2333         return TriaEnum;
    2334 
    2335 }
    2336 /*}}}*/
    2337 /*FUNCTION Tria::GetArea {{{1*/
    2338 double Tria::GetArea(void){
    2339 
    2340         double area=0;
    2341         double xyz_list[NUMVERTICES][3];
    2342         double x1,y1,x2,y2,x3,y3;
    2343 
    2344         /*Get xyz list: */
    2345         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    2346         x1=xyz_list[0][0]; y1=xyz_list[0][1];
    2347         x2=xyz_list[1][0]; y2=xyz_list[1][1];
    2348         x3=xyz_list[2][0]; y3=xyz_list[2][1];
    2349  
    2350         return (x2*y3 - y2*x3 + x1*y2 - y1*x2 + x3*y1 - y3*x1)/2;
    2351 }
    2352 /*}}}*/
    2353 /*FUNCTION Tria::GetDofList {{{1*/
    2354 void  Tria::GetDofList(int** pdoflist, int approximation_enum,int setenum){
    2355 
    2356         int i,j;
    2357         int count=0;
    2358         int numberofdofs=0;
    2359         int* doflist=NULL;
    2360 
    2361         /*First, figure out size of doflist and create it: */
    2362         for(i=0;i<3;i++) numberofdofs+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
    2363         doflist=(int*)xmalloc(numberofdofs*sizeof(int));
    2364 
    2365         /*Populate: */
    2366         count=0;
    2367         for(i=0;i<3;i++){
    2368                 nodes[i]->GetDofList(doflist+count,approximation_enum,setenum);
    2369                 count+=nodes[i]->GetNumberOfDofs(approximation_enum,setenum);
    2370         }
    2371 
    2372         /*Assign output pointers:*/
    2373         *pdoflist=doflist;
    2374 }
    2375 /*}}}*/
    2376 /*FUNCTION Tria::GetDofList1 {{{1*/
    2377 void  Tria::GetDofList1(int* doflist){
    2378 
    2379         int i;
    2380         for(i=0;i<3;i++) doflist[i]=nodes[i]->GetDofList1();
    2381 
    2382 }
    2383 /*}}}*/
    2384 /*FUNCTION Tria::GetElementType {{{1*/
    2385 int Tria::GetElementType(){
    2386 
    2387         /*return TriaRef field*/
    2388         return this->element_type;
    2389 
    2390 }
    2391 /*}}}*/
    2392 /*FUNCTION Tria::GetHorizontalNeighboorSids {{{1*/
    2393 int* Tria::GetHorizontalNeighboorSids(){
    2394 
    2395         /*return TriaRef field*/
    2396         return &this->horizontalneighborsids[0];
    2397 
    2398 }
    2399 /*}}}*/
    2400 /*FUNCTION Tria::GetNodeIndex {{{1*/
    2401 int Tria::GetNodeIndex(Node* node){
    2402 
    2403         _assert_(nodes);
    2404         for(int i=0;i<NUMVERTICES;i++){
    2405                 if(node==nodes[i])
    2406                  return i;
    2407         }
    2408         _error_("Node provided not found among element nodes");
    2409 }
    2410 /*}}}*/
    2411 /*FUNCTION Tria::GetParameterListOnVertices(double* pvalue,int enumtype) {{{1*/
    2412 void Tria::GetParameterListOnVertices(double* pvalue,int enumtype){
    2413 
    2414         /*Intermediaries*/
    2415         double     value[NUMVERTICES];
    2416         GaussTria *gauss              = NULL;
    2417 
    2418         /*Recover input*/
    2419         Input* input=inputs->GetInput(enumtype);
    2420         if (!input) _error_("Input %s not found in element",EnumToStringx(enumtype));
    2421 
    2422         /*Checks in debugging mode*/
    2423         _assert_(pvalue);
    2424 
    2425         /* Start looping on the number of vertices: */
    2426         gauss=new GaussTria();
    2427         for (int iv=0;iv<NUMVERTICES;iv++){
    2428                 gauss->GaussVertex(iv);
    2429                 input->GetParameterValue(&pvalue[iv],gauss);
    2430         }
    2431 
    2432         /*clean-up*/
    2433         delete gauss;
    2434 }
    2435 /*}}}*/
    2436 /*FUNCTION Tria::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue) {{{1*/
    2437 void Tria::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue){
    2438 
    2439         double     value[NUMVERTICES];
    2440         GaussTria *gauss = NULL;
    2441         Input     *input = inputs->GetInput(enumtype);
    2442 
    2443         /*Checks in debugging mode*/
    2444         _assert_(pvalue);
    2445 
    2446         /* Start looping on the number of vertices: */
    2447         if (input){
    2448                 gauss=new GaussTria();
    2449                 for (int iv=0;iv<NUMVERTICES;iv++){
    2450                         gauss->GaussVertex(iv);
    2451                         input->GetParameterValue(&pvalue[iv],gauss);
    2452                 }
    2453         }
    2454         else{
    2455                 for (int iv=0;iv<NUMVERTICES;iv++) pvalue[iv]=defaultvalue;
    2456         }
    2457 
    2458         /*clean-up*/
    2459         delete gauss;
    2460 }
    2461 /*}}}*/
    2462 /*FUNCTION Tria::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue,int index) TO BE REMOVED{{{1*/
    2463 void Tria::GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue,int index){
    2464 
    2465         double     value[NUMVERTICES];
    2466         GaussTria *gauss = NULL;
    2467         Input     *input = inputs->GetInput(enumtype);
    2468 
    2469         /*Checks in debugging mode*/
    2470         _assert_(pvalue);
    2471 
    2472         /* Start looping on the number of vertices: */
    2473         if (input){
    2474                 gauss=new GaussTria();
    2475                 for (int iv=0;iv<NUMVERTICES;iv++){
    2476                         gauss->GaussVertex(iv);
    2477                         input->GetParameterValue(&pvalue[iv],gauss,index);
    2478                 }
    2479         }
    2480         else{
    2481                 for (int iv=0;iv<NUMVERTICES;iv++) pvalue[iv]=defaultvalue;
    2482         }
    2483 
    2484         /*clean-up*/
    2485         delete gauss;
    2486 }
    2487 /*}}}*/
    2488 /*FUNCTION Tria::GetParameterValue(double* pvalue,Node* node,int enumtype) {{{1*/
    2489 void Tria::GetParameterValue(double* pvalue,Node* node,int enumtype){
    2490 
    2491         Input* input=inputs->GetInput(enumtype);
    2492         if(!input) _error_("No input of type %s found in tria",EnumToStringx(enumtype));
    2493 
    2494         GaussTria* gauss=new GaussTria();
    2495         gauss->GaussVertex(this->GetNodeIndex(node));
    2496 
    2497         input->GetParameterValue(pvalue,gauss);
    2498         delete gauss;
    2499 }
    2500 /*}}}*/
    2501 /*FUNCTION Tria::GetSidList {{{1*/
    2502 void  Tria::GetSidList(int* sidlist){
    2503 
    2504         int i;
    2505         for(i=0;i<NUMVERTICES;i++) sidlist[i]=nodes[i]->GetSidList();
    2506 
    2507 }
    2508 /*}}}*/
    2509 /*FUNCTION Tria::GetSolutionFromInputs{{{1*/
    2510 void  Tria::GetSolutionFromInputs(Vec solution){
    2511 
    2512         /*retrive parameters: */
    2513         int analysis_type;
    2514         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    2515 
    2516         /*Just branch to the correct InputUpdateFromSolution generator, according to the type of analysis we are carrying out: */
    2517         if (analysis_type==DiagnosticHorizAnalysisEnum)
    2518          GetSolutionFromInputsDiagnosticHoriz(solution);
    2519         else if (analysis_type==DiagnosticHutterAnalysisEnum)
    2520          GetSolutionFromInputsDiagnosticHutter(solution);
    2521         else if (analysis_type==HydrologyAnalysisEnum)
    2522          GetSolutionFromInputsHydrology(solution);
    2523         else
    2524          _error_("analysis: %s not supported yet",EnumToStringx(analysis_type));
    2525 
    2526 }
    2527 /*}}}*/
    2528 /*FUNCTION Tria::GetSolutionFromInputsDiagnosticHoriz{{{1*/
    2529 void  Tria::GetSolutionFromInputsDiagnosticHoriz(Vec solution){
    2530 
    2531         const int    numdof=NDOF2*NUMVERTICES;
    2532 
    2533         int          i;
    2534         int*         doflist=NULL;
    2535         double       vx,vy;
    2536         double       values[numdof];
    2537         GaussTria*   gauss=NULL;
    2538 
    2539         /*Get dof list: */
    2540         GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
    2541 
    2542         /*Get inputs*/
    2543         Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
    2544         Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
    2545 
    2546         /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
    2547         /*P1 element only for now*/
    2548         gauss=new GaussTria();
    2549         for(i=0;i<NUMVERTICES;i++){
    2550 
    2551                 gauss->GaussVertex(i);
    2552 
    2553                 /*Recover vx and vy*/
    2554                 vx_input->GetParameterValue(&vx,gauss);
    2555                 vy_input->GetParameterValue(&vy,gauss);
    2556                 values[i*NDOF2+0]=vx;
    2557                 values[i*NDOF2+1]=vy;
    2558         }
    2559 
    2560         VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
    2561 
    2562         /*Free ressources:*/
    2563         delete gauss;
    2564         xfree((void**)&doflist);
    2565 }
    2566 /*}}}*/
    2567 /*FUNCTION Tria::GetSolutionFromInputsDiagnosticHutter{{{1*/
    2568 void  Tria::GetSolutionFromInputsDiagnosticHutter(Vec solution){
    2569 
    2570         const int    numdof=NDOF2*NUMVERTICES;
    2571 
    2572         int i,dummy;
    2573         int*         doflist=NULL;
    2574         double       vx,vy;
    2575         double       values[numdof];
    2576         GaussTria*   gauss=NULL;
    2577 
    2578         /*Get dof list: */
    2579         GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
    2580 
    2581         /*Get inputs*/
    2582         Input* vx_input=inputs->GetInput(VxEnum); _assert_(vx_input);
    2583         Input* vy_input=inputs->GetInput(VyEnum); _assert_(vy_input);
    2584 
    2585         /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
    2586         /*P1 element only for now*/
    2587         gauss=new GaussTria();
    2588         for(i=0;i<NUMVERTICES;i++){
    2589 
    2590                 gauss->GaussVertex(i);
    2591 
    2592                 /*Recover vx and vy*/
    2593                 vx_input->GetParameterValue(&vx,gauss);
    2594                 vy_input->GetParameterValue(&vy,gauss);
    2595                 values[i*NDOF2+0]=vx;
    2596                 values[i*NDOF2+1]=vy;
    2597         }
    2598 
    2599         VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
    2600 
    2601         /*Free ressources:*/
    2602         delete gauss;
    2603         xfree((void**)&doflist);
    2604 }
    2605 /*}}}*/
    2606 /*FUNCTION Tria::GetSolutionFromInputsHydrology{{{1*/
    2607 void  Tria::GetSolutionFromInputsHydrology(Vec solution){
    2608 
    2609         const int    numdof=NDOF1*NUMVERTICES;
    2610 
    2611         int i,dummy;
    2612         int*         doflist=NULL;
    2613         double       watercolumn;
    2614         double       values[numdof];
    2615         GaussTria*   gauss=NULL;
    2616 
    2617         /*Get dof list: */
    2618         GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
    2619 
    2620         /*Get inputs*/
    2621         Input* watercolumn_input=inputs->GetInput(WatercolumnEnum); _assert_(watercolumn_input);
    2622 
    2623         /*Ok, we have watercolumn values, fill in watercolumn array: */
    2624         /*P1 element only for now*/
    2625         gauss=new GaussTria();
    2626         for(i=0;i<NUMVERTICES;i++){
    2627 
    2628                 gauss->GaussVertex(i);
    2629 
    2630                 /*Recover watercolumn*/
    2631                 watercolumn_input->GetParameterValue(&watercolumn,gauss);
    2632                 values[i]=watercolumn;
    2633         }
    2634 
    2635         VecSetValues(solution,numdof,doflist,(const double*)values,INSERT_VALUES);
    2636 
    2637         /*Free ressources:*/
    2638         delete gauss;
    2639         xfree((void**)&doflist);
    2640 }
    2641 /*}}}*/
    2642 /*FUNCTION Tria::GetStrainRate2d(double* epsilon,double* xyz_list, GaussTria* gauss, Input* vx_input, Input* vy_input){{{1*/
    2643 void Tria::GetStrainRate2d(double* epsilon,double* xyz_list, GaussTria* gauss, Input* vx_input, Input* vy_input){
    2644         /*Compute the 2d Strain Rate (3 components):
    2645          * epsilon=[exx eyy exy] */
    2646 
    2647         int i;
    2648         double epsilonvx[3];
    2649         double epsilonvy[3];
    2650 
    2651         /*Check that both inputs have been found*/
    2652         if (!vx_input || !vy_input){
    2653                 _error_("Input missing. Here are the input pointers we have for vx: %p, vy: %p\n",vx_input,vy_input);
    2654         }
    2655 
    2656         /*Get strain rate assuming that epsilon has been allocated*/
    2657         vx_input->GetVxStrainRate2d(epsilonvx,xyz_list,gauss);
    2658         vy_input->GetVyStrainRate2d(epsilonvy,xyz_list,gauss);
    2659 
    2660         /*Sum all contributions*/
    2661         for(i=0;i<3;i++) epsilon[i]=epsilonvx[i]+epsilonvy[i];
    2662 }
    2663 /*}}}*/
    2664 /*FUNCTION Tria::GetVectorFromInputs{{{1*/
    2665 void  Tria::GetVectorFromInputs(Vec vector,int input_enum){
    2666 
    2667         int doflist1[NUMVERTICES];
    2668 
    2669         /*Get out if this is not an element input*/
    2670         if (!IsInput(input_enum)) return;
    2671 
    2672         /*Prepare index list*/
    2673         this->GetDofList1(&doflist1[0]);
    2674 
    2675         /*Get input (either in element or material)*/
    2676         Input* input=inputs->GetInput(input_enum);
    2677         if(!input) _error_("Input %s not found in element",EnumToStringx(input_enum));
    2678 
    2679         /*We found the enum.  Use its values to fill into the vector, using the vertices ids: */
    2680         input->GetVectorFromInputs(vector,&doflist1[0]);
    2681 }
    2682 /*}}}*/
    2683 /*FUNCTION Tria::Gradj {{{1*/
    2684 void  Tria::Gradj(Vec gradient,int control_type){
    2685         /*dJ/dalpha = ∂L/∂alpha = ∂J/∂alpha + ∂/∂alpha(KU-F)*/
    2686 
    2687         /*If on water, grad = 0: */
    2688         if(IsOnWater()) return;
    2689 
    2690         /*First deal with ∂/∂alpha(KU-F)*/
    2691         switch(control_type){
    2692                 case FrictionCoefficientEnum:
    2693                         GradjDragMacAyeal(gradient);
    2694                         break;
    2695                 case MaterialsRheologyBbarEnum:
    2696                         GradjBMacAyeal(gradient);
    2697                         break;
    2698                 case BalancethicknessThickeningRateEnum:
    2699                         GradjDhDtBalancedthickness(gradient);
    2700                         break;
    2701                 case VxEnum:
    2702                         GradjVxBalancedthickness(gradient);
    2703                         break;
    2704                 case VyEnum:
    2705                         GradjVyBalancedthickness(gradient);
    2706                         break;
    2707                 default:
    2708                         _error_("%s%i","control type not supported yet: ",control_type);
    2709         }
    2710 
    2711         /*Now deal with ∂J/∂alpha*/
    2712         int        *responses = NULL;
    2713         int         num_responses,resp;
    2714         this->parameters->FindParam(&num_responses,InversionNumCostFunctionsEnum);
    2715         this->parameters->FindParam(&responses,NULL,NULL,StepResponsesEnum);
    2716 
    2717         for(resp=0;resp<num_responses;resp++) switch(responses[resp]){
    2718                 //FIXME: the control type should be checked somewhere (with respect to what variable are we taking the gradient!)
    2719 
    2720                 case ThicknessAbsMisfitEnum:
    2721                 case ThicknessAbsGradientEnum:
    2722                 case SurfaceAbsVelMisfitEnum:
    2723                 case SurfaceRelVelMisfitEnum:
    2724                 case SurfaceLogVelMisfitEnum:
    2725                 case SurfaceLogVxVyMisfitEnum:
    2726                 case SurfaceAverageVelMisfitEnum:
    2727                         /*Nothing, J does not depends on the parameter being inverted for*/
    2728                         break;
    2729                 case DragCoefficientAbsGradientEnum:
    2730                         GradjDragGradient(gradient,resp);
    2731                         break;
    2732                 case RheologyBbarAbsGradientEnum:
    2733                         GradjBGradient(gradient,resp);
    2734                         break;
    2735                 default:
    2736                         _error_("response %s not supported yet",EnumToStringx(responses[resp]));
    2737         }
    2738 
    2739         xfree((void**)&responses);
    2740 }
    2741 /*}}}*/
    2742 /*FUNCTION Tria::GradjBGradient{{{1*/
    2743 void  Tria::GradjBGradient(Vec gradient, int weight_index){
    2744 
    2745         int        i,ig;
    2746         int        doflist1[NUMVERTICES];
    2747         double     Jdet,weight;
    2748         double     xyz_list[NUMVERTICES][3];
    2749         double     dbasis[NDOF2][NUMVERTICES];
    2750         double     dk[NDOF2];
    2751         double     grade_g[NUMVERTICES]={0.0};
    2752         GaussTria  *gauss=NULL;
    2753 
    2754         /*Retrieve all inputs we will be needing: */
    2755         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    2756         GetDofList1(&doflist1[0]);
    2757         Input* rheologyb_input=matice->inputs->GetInput(MaterialsRheologyBbarEnum); _assert_(rheologyb_input);
    2758         Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);                _assert_(weights_input);
    2759 
    2760         /* Start  looping on the number of gaussian points: */
    2761         gauss=new GaussTria(2);
    2762         for (ig=gauss->begin();ig<gauss->end();ig++){
    2763 
    2764                 gauss->GaussPoint(ig);
    2765 
    2766                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    2767                 GetNodalFunctionsDerivatives(&dbasis[0][0],&xyz_list[0][0],gauss);
    2768                 weights_input->GetParameterValue(&weight,gauss,weight_index);
    2769 
    2770                 /*Build alpha_complement_list: */
    2771                 rheologyb_input->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],gauss);
    2772 
    2773                 /*Build gradje_g_gaussian vector (actually -dJ/ddrag): */
    2774                 for (i=0;i<NUMVERTICES;i++) grade_g[i]+=-weight*Jdet*gauss->weight*(dbasis[0][i]*dk[0]+dbasis[1][i]*dk[1]);
    2775         }
    2776         VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES);
    2777 
    2778         /*Clean up and return*/
    2779         delete gauss;
    2780 }
    2781 /*}}}*/
    2782 /*FUNCTION Tria::GradjBMacAyeal{{{1*/
    2783 void  Tria::GradjBMacAyeal(Vec gradient){
    2784 
    2785         /*Intermediaries*/
    2786         int        i,ig;
    2787         int        doflist[NUMVERTICES];
    2788         double     vx,vy,lambda,mu,thickness,Jdet;
    2789         double     viscosity_complement;
    2790         double     dvx[NDOF2],dvy[NDOF2],dadjx[NDOF2],dadjy[NDOF2],dB[NDOF2];
    2791         double     xyz_list[NUMVERTICES][3];
    2792         double     basis[3],epsilon[3];
    2793         double     grad[NUMVERTICES]={0.0};
    2794         GaussTria *gauss = NULL;
    2795 
    2796         /* Get node coordinates and dof list: */
    2797         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    2798         GetDofList1(&doflist[0]);
    2799 
    2800         /*Retrieve all inputs*/
    2801         Input* thickness_input=inputs->GetInput(ThicknessEnum);            _assert_(thickness_input);
    2802         Input* vx_input=inputs->GetInput(VxEnum);                          _assert_(vx_input);
    2803         Input* vy_input=inputs->GetInput(VyEnum);                          _assert_(vy_input);
    2804         Input* adjointx_input=inputs->GetInput(AdjointxEnum);              _assert_(adjointx_input);
    2805         Input* adjointy_input=inputs->GetInput(AdjointyEnum);              _assert_(adjointy_input);
    2806         Input* rheologyb_input=matice->inputs->GetInput(MaterialsRheologyBbarEnum); _assert_(rheologyb_input);
    2807 
    2808         /* Start  looping on the number of gaussian points: */
    2809         gauss=new GaussTria(4);
    2810         for (ig=gauss->begin();ig<gauss->end();ig++){
    2811 
    2812                 gauss->GaussPoint(ig);
    2813 
    2814                 thickness_input->GetParameterValue(&thickness,gauss);
    2815                 rheologyb_input->GetParameterDerivativeValue(&dB[0],&xyz_list[0][0],gauss);
    2816                 vx_input->GetParameterDerivativeValue(&dvx[0],&xyz_list[0][0],gauss);
    2817                 vy_input->GetParameterDerivativeValue(&dvy[0],&xyz_list[0][0],gauss);
    2818                 adjointx_input->GetParameterDerivativeValue(&dadjx[0],&xyz_list[0][0],gauss);
    2819                 adjointy_input->GetParameterDerivativeValue(&dadjy[0],&xyz_list[0][0],gauss);
    2820 
    2821                 this->GetStrainRate2d(&epsilon[0],&xyz_list[0][0],gauss,vx_input,vy_input);
    2822                 matice->GetViscosityComplement(&viscosity_complement,&epsilon[0]);
    2823 
    2824                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    2825                 GetNodalFunctions(basis,gauss);
    2826 
    2827                 /*standard gradient dJ/dki*/
    2828                 for (i=0;i<NUMVERTICES;i++) grad[i]+=-viscosity_complement*thickness*(
    2829                                         (2*dvx[0]+dvy[1])*2*dadjx[0]+(dvx[1]+dvy[0])*(dadjx[1]+dadjy[0])+(2*dvy[1]+dvx[0])*2*dadjy[1]
    2830                                         )*Jdet*gauss->weight*basis[i];
    2831         }
    2832 
    2833         VecSetValues(gradient,NUMVERTICES,doflist,(const double*)grad,ADD_VALUES);
    2834 
    2835         /*clean-up*/
    2836         delete gauss;
    2837 }
    2838 /*}}}*/
    2839 /*FUNCTION Tria::GradjDragMacAyeal {{{1*/
    2840 void  Tria::GradjDragMacAyeal(Vec gradient){
    2841 
    2842         int        i,ig;
    2843         int        analysis_type;
    2844         int        doflist1[NUMVERTICES];
    2845         double     vx,vy,lambda,mu,alpha_complement,Jdet;
    2846         double     bed,thickness,Neff,drag;
    2847         double     xyz_list[NUMVERTICES][3];
    2848         double     dk[NDOF2];
    2849         double     grade_g[NUMVERTICES]={0.0};
    2850         double     grade_g_gaussian[NUMVERTICES];
    2851         double     basis[3];
    2852         double     epsilon[3]; /* epsilon=[exx,eyy,exy];*/
    2853         Friction*  friction=NULL;
    2854         GaussTria  *gauss=NULL;
    2855 
    2856         if(IsOnShelf())return;
    2857 
    2858         /*retrive parameters: */
    2859         parameters->FindParam(&analysis_type,AnalysisTypeEnum);
    2860         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    2861         GetDofList1(&doflist1[0]);
    2862 
    2863         /*Build frictoin element, needed later: */
    2864         friction=new Friction("2d",inputs,matpar,analysis_type);
    2865 
    2866         /*Retrieve all inputs we will be needing: */
    2867         Input* adjointx_input=inputs->GetInput(AdjointxEnum);               _assert_(adjointx_input);
    2868         Input* adjointy_input=inputs->GetInput(AdjointyEnum);               _assert_(adjointy_input);
    2869         Input* vx_input=inputs->GetInput(VxEnum);                           _assert_(vx_input);
    2870         Input* vy_input=inputs->GetInput(VyEnum);                           _assert_(vy_input);
    2871         Input* dragcoefficient_input=inputs->GetInput(FrictionCoefficientEnum); _assert_(dragcoefficient_input);
    2872 
    2873         /* Start  looping on the number of gaussian points: */
    2874         gauss=new GaussTria(4);
    2875         for (ig=gauss->begin();ig<gauss->end();ig++){
    2876 
    2877                 gauss->GaussPoint(ig);
    2878 
    2879                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    2880                 GetNodalFunctions(basis, gauss);
    2881 
    2882                 /*Build alpha_complement_list: */
    2883                 friction->GetAlphaComplement(&alpha_complement, gauss,VxEnum,VyEnum,VzEnum);
    2884        
    2885                 dragcoefficient_input->GetParameterValue(&drag, gauss);
    2886                 adjointx_input->GetParameterValue(&lambda, gauss);
    2887                 adjointy_input->GetParameterValue(&mu, gauss);
    2888                 vx_input->GetParameterValue(&vx,gauss);
    2889                 vy_input->GetParameterValue(&vy,gauss);
    2890                 dragcoefficient_input->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],gauss);
    2891 
    2892                 /*Build gradje_g_gaussian vector (actually -dJ/ddrag): */
    2893                 for (i=0;i<NUMVERTICES;i++){
    2894                         grade_g_gaussian[i]=-2*drag*alpha_complement*((lambda*vx+mu*vy))*Jdet*gauss->weight*basis[i];
    2895                 }
    2896                
    2897                 /*Add gradje_g_gaussian vector to gradje_g: */
    2898                 for(i=0;i<NUMVERTICES;i++){
    2899                         _assert_(!isnan(grade_g[i]));
    2900                         grade_g[i]+=grade_g_gaussian[i];
    2901                 }
    2902         }
    2903         /*Analytical gradient*/
    2904         //delete gauss;
    2905         //gauss=new GaussTria();
    2906         //for (int iv=0;iv<NUMVERTICES;iv++){
    2907         //      gauss->GaussVertex(iv);
    2908         //      friction->GetAlphaComplement(&alpha_complement, gauss,VxEnum,VyEnum,VzEnum);
    2909         //      dragcoefficient_input->GetParameterValue(&drag, gauss);
    2910         //      adjointx_input->GetParameterValue(&lambda, gauss);
    2911         //      adjointy_input->GetParameterValue(&mu, gauss);
    2912         //      vx_input->GetParameterValue(&vx,gauss);
    2913         //      vy_input->GetParameterValue(&vy,gauss);
    2914         //      grade_g[iv]=-2*drag*alpha_complement*((lambda*vx+mu*vy));
    2915         //      VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,INSERT_VALUES);
    2916         //}
    2917         /*End Analytical gradient*/
    2918 
    2919         VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES);
    2920 
    2921         /*Clean up and return*/
    2922         delete gauss;
    2923         delete friction;
    2924 }
    2925 /*}}}*/
    2926 /*FUNCTION Tria::GradjDragGradient{{{1*/
    2927 void  Tria::GradjDragGradient(Vec gradient, int weight_index){
    2928 
    2929         int        i,ig;
    2930         int        doflist1[NUMVERTICES];
    2931         double     Jdet,weight;
    2932         double     xyz_list[NUMVERTICES][3];
    2933         double     dbasis[NDOF2][NUMVERTICES];
    2934         double     dk[NDOF2];
    2935         double     grade_g[NUMVERTICES]={0.0};
    2936         GaussTria  *gauss=NULL;
    2937 
    2938         /*Retrieve all inputs we will be needing: */
    2939         if(IsOnShelf())return;
    2940         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    2941         GetDofList1(&doflist1[0]);
    2942         Input* dragcoefficient_input=inputs->GetInput(FrictionCoefficientEnum); _assert_(dragcoefficient_input);
    2943         Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);                 _assert_(weights_input);
    2944 
    2945         /* Start  looping on the number of gaussian points: */
    2946         gauss=new GaussTria(2);
    2947         for (ig=gauss->begin();ig<gauss->end();ig++){
    2948 
    2949                 gauss->GaussPoint(ig);
    2950 
    2951                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    2952                 GetNodalFunctionsDerivatives(&dbasis[0][0],&xyz_list[0][0],gauss);
    2953                 weights_input->GetParameterValue(&weight,gauss,weight_index);
    2954 
    2955                 /*Build alpha_complement_list: */
    2956                 dragcoefficient_input->GetParameterDerivativeValue(&dk[0],&xyz_list[0][0],gauss);
    2957 
    2958                 /*Build gradje_g_gaussian vector (actually -dJ/ddrag): */
    2959                 for (i=0;i<NUMVERTICES;i++){
    2960                         grade_g[i]+=-weight*Jdet*gauss->weight*(dbasis[0][i]*dk[0]+dbasis[1][i]*dk[1]);
    2961                         _assert_(!isnan(grade_g[i]));
    2962                 }
    2963         }
    2964         VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES);
    2965 
    2966         /*Clean up and return*/
    2967         delete gauss;
    2968 }
    2969 /*}}}*/
    2970 /*FUNCTION Tria::GradjDhDtBalancedthickness{{{1*/
    2971 void  Tria::GradjDhDtBalancedthickness(Vec gradient){
    2972 
    2973         /*Intermediaries*/
    2974         int    doflist1[NUMVERTICES];
    2975         double lambda[NUMVERTICES];
    2976         double gradient_g[NUMVERTICES];
    2977 
    2978         GetDofList1(&doflist1[0]);
    2979 
    2980         /*Compute Gradient*/
    2981         GetParameterListOnVertices(&lambda[0],AdjointEnum);
    2982         for(int i=0;i<NUMVERTICES;i++) gradient_g[i]=-lambda[i];
    2983 
    2984         VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)gradient_g,INSERT_VALUES);
    2985 }
    2986 /*}}}*/
    2987 /*FUNCTION Tria::GradjVxBalancedthickness{{{1*/
    2988 void  Tria::GradjVxBalancedthickness(Vec gradient){
    2989 
    2990         /*Intermediaries*/
    2991         int        i,ig;
    2992         int        doflist1[NUMVERTICES];
    2993         double     thickness,Jdet;
    2994         double     basis[3];
    2995         double     Dlambda[2],dp[2];
    2996         double     xyz_list[NUMVERTICES][3];
    2997         double     grade_g[NUMVERTICES] = {0.0};
    2998         GaussTria *gauss                = NULL;
    2999 
    3000         /* Get node coordinates and dof list: */
    3001         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    3002         GetDofList1(&doflist1[0]);
    3003 
    3004         /*Retrieve all inputs we will be needing: */
    3005         Input* adjoint_input=inputs->GetInput(AdjointEnum);     _assert_(adjoint_input);
    3006         Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
    3007 
    3008         /* Start  looping on the number of gaussian points: */
    3009         gauss=new GaussTria(2);
    3010         for (ig=gauss->begin();ig<gauss->end();ig++){
    3011 
    3012                 gauss->GaussPoint(ig);
    3013 
    3014                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    3015                 GetNodalFunctions(basis, gauss);
    3016                
    3017                 adjoint_input->GetParameterDerivativeValue(&Dlambda[0],&xyz_list[0][0],gauss);
    3018                 thickness_input->GetParameterValue(&thickness, gauss);
    3019                 thickness_input->GetParameterDerivativeValue(&dp[0],&xyz_list[0][0],gauss);
    3020 
    3021                 for(i=0;i<NUMVERTICES;i++) grade_g[i]+=thickness*Dlambda[0]*Jdet*gauss->weight*basis[i];
    3022         }
    3023 
    3024         VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES);
    3025 
    3026         /*Clean up and return*/
    3027         delete gauss;
    3028 }
    3029 /*}}}*/
    3030 /*FUNCTION Tria::GradjVyBalancedthickness{{{1*/
    3031 void  Tria::GradjVyBalancedthickness(Vec gradient){
    3032 
    3033         /*Intermediaries*/
    3034         int        i,ig;
    3035         int        doflist1[NUMVERTICES];
    3036         double     thickness,Jdet;
    3037         double     basis[3];
    3038         double     Dlambda[2],dp[2];
    3039         double     xyz_list[NUMVERTICES][3];
    3040         double     grade_g[NUMVERTICES] = {0.0};
    3041         GaussTria *gauss                = NULL;
    3042 
    3043         /* Get node coordinates and dof list: */
    3044         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    3045         GetDofList1(&doflist1[0]);
    3046 
    3047         /*Retrieve all inputs we will be needing: */
    3048         Input* adjoint_input=inputs->GetInput(AdjointEnum);     _assert_(adjoint_input);
    3049         Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
    3050 
    3051         /* Start  looping on the number of gaussian points: */
    3052         gauss=new GaussTria(2);
    3053         for (ig=gauss->begin();ig<gauss->end();ig++){
    3054 
    3055                 gauss->GaussPoint(ig);
    3056 
    3057                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    3058                 GetNodalFunctions(basis, gauss);
    3059 
    3060                 adjoint_input->GetParameterDerivativeValue(&Dlambda[0],&xyz_list[0][0],gauss);
    3061                 thickness_input->GetParameterValue(&thickness, gauss);
    3062                 thickness_input->GetParameterDerivativeValue(&dp[0],&xyz_list[0][0],gauss);
    3063 
    3064                 for(i=0;i<NUMVERTICES;i++) grade_g[i]+=thickness*Dlambda[1]*Jdet*gauss->weight*basis[i];
    3065         }
    3066         VecSetValues(gradient,NUMVERTICES,doflist1,(const double*)grade_g,ADD_VALUES);
    3067 
    3068         /*Clean up and return*/
    3069         delete gauss;
    3070 }
    3071 /*}}}*/
    3072 /*FUNCTION Tria::Id {{{1*/
    3073 int    Tria::Id(){
    3074        
    3075         return id;
    3076 
    3077 }
    3078 /*}}}*/
    3079 /*FUNCTION Tria::Sid {{{1*/
    3080 int    Tria::Sid(){
    3081        
    3082         return sid;
    3083 
    3084 }
    3085 /*}}}*/
    3086 /*FUNCTION Tria::InputArtificialNoise{{{1*/
    3087 void  Tria::InputArtificialNoise(int enum_type,double min,double max){
    3088 
    3089         Input* input=NULL;
    3090 
    3091         /*Make a copy of the original input: */
    3092         input=(Input*)this->inputs->GetInput(enum_type);
    3093         if(!input)_error_(" could not find old input with enum: %s",EnumToStringx(enum_type));
    3094 
    3095         /*ArtificialNoise: */
    3096         input->ArtificialNoise(min,max);
    3097 }
    3098 /*}}}*/
    3099 /*FUNCTION Tria::InputControlUpdate{{{1*/
    3100 void  Tria::InputControlUpdate(double scalar,bool save_parameter){
    3101 
    3102         /*Intermediary*/
    3103         int    num_controls;
    3104         int*   control_type=NULL;
    3105         Input* input=NULL;
    3106 
    3107         /*retrieve some parameters: */
    3108         this->parameters->FindParam(&num_controls,InversionNumControlParametersEnum);
    3109         this->parameters->FindParam(&control_type,NULL,InversionControlParametersEnum);
    3110 
    3111         for(int i=0;i<num_controls;i++){
    3112 
    3113                 if(control_type[i]==MaterialsRheologyBbarEnum){
    3114                         input=(Input*)matice->inputs->GetInput(control_type[i]); _assert_(input);
    3115                 }
    3116                 else{
    3117                         input=(Input*)this->inputs->GetInput(control_type[i]);   _assert_(input);
    3118                 }
    3119 
    3120                 if (input->Enum()!=ControlInputEnum){
    3121                         _error_("input %s is not a ControlInput",EnumToStringx(control_type[i]));
    3122                 }
    3123 
    3124                 ((ControlInput*)input)->UpdateValue(scalar);
    3125                 ((ControlInput*)input)->Constrain();
    3126                 if (save_parameter) ((ControlInput*)input)->SaveValue();
    3127 
    3128         }
    3129 
    3130         /*Clean up and return*/
    3131         xfree((void**)&control_type);
    3132 }
    3133 /*}}}*/
     3588#endif
     3589
    31343590/*FUNCTION Tria::InputConvergence{{{1*/
    31353591bool Tria::InputConvergence(double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){
     
    32263682         * object out of the input, with the additional step and time information: */
    32273683        this->results->AddObject((Object*)input->SpawnResult(step,time));
     3684        #ifdef _HAVE_CONTROL_
    32283685        if(input->Enum()==ControlInputEnum) this->results->AddObject((Object*)((ControlInput*)input)->SpawnGradient(step,time));
     3686        #endif
    32293687}
    32303688/*}}}*/
     
    32823740
    32833741        /*Control Inputs*/
     3742        #ifdef _HAVE_CONTROL_
    32843743        if (control_analysis && iomodel->Data(InversionControlParametersEnum)){
    32853744                for(i=0;i<num_control_type;i++){
     
    33243783                }
    33253784        }
     3785        #endif
    33263786
    33273787        /*DatasetInputs*/
     
    33553815                        InputUpdateFromSolutionDiagnosticHoriz( solution);
    33563816                        break;
     3817                #ifdef _HAVE_CONTROL_
    33573818                case AdjointHorizAnalysisEnum:
    33583819                        InputUpdateFromSolutionAdjointHoriz( solution);
    33593820                        break;
     3821                case AdjointBalancethicknessAnalysisEnum:
     3822                        InputUpdateFromSolutionAdjointBalancethickness( solution);
     3823                        break;
     3824                #endif
    33603825                case BedSlopeXAnalysisEnum:
    33613826                        InputUpdateFromSolutionOneDof(solution,BedSlopeXEnum);
     
    33793844                        InputUpdateFromSolutionOneDof(solution,ThicknessEnum);
    33803845                        break;
    3381                 case AdjointBalancethicknessAnalysisEnum:
    3382                         InputUpdateFromSolutionAdjointBalancethickness( solution);
    3383                         break;
    33843846                default:
    33853847                        _error_("analysis %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type));
    33863848        }
    3387 }
    3388 /*}}}*/
    3389 /*FUNCTION Tria::InputUpdateFromSolutionAdjointBalancethickness {{{1*/
    3390 void  Tria::InputUpdateFromSolutionAdjointBalancethickness(double* solution){
    3391 
    3392         const int numdof=NDOF1*NUMVERTICES;
    3393 
    3394         int       i;
    3395         int*      doflist=NULL;
    3396         double    values[numdof];
    3397         double    lambda[NUMVERTICES];
    3398 
    3399         /*Get dof list: */
    3400         GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
    3401 
    3402         /*Use the dof list to index into the solution vector: */
    3403         for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
    3404 
    3405         /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
    3406         for(i=0;i<numdof;i++){
    3407                 lambda[i]=values[i];
    3408                 if(isnan(lambda[i])) _error_("NaN found in solution vector");
    3409         }
    3410 
    3411         /*Add vx and vy as inputs to the tria element: */
    3412         this->inputs->AddInput(new TriaVertexInput(AdjointEnum,lambda));
    3413 
    3414         /*Free ressources:*/
    3415         xfree((void**)&doflist);
    3416 }
    3417 /*}}}*/
    3418 /*FUNCTION Tria::InputUpdateFromSolutionAdjointHoriz {{{1*/
    3419 void  Tria::InputUpdateFromSolutionAdjointHoriz(double* solution){
    3420 
    3421         const int numdof=NDOF2*NUMVERTICES;
    3422 
    3423         int       i;
    3424         int*      doflist=NULL;
    3425         double    values[numdof];
    3426         double    lambdax[NUMVERTICES];
    3427         double    lambday[NUMVERTICES];
    3428 
    3429         /*Get dof list: */
    3430         GetDofList(&doflist,NoneApproximationEnum,GsetEnum);
    3431 
    3432         /*Use the dof list to index into the solution vector: */
    3433         for(i=0;i<numdof;i++) values[i]=solution[doflist[i]];
    3434 
    3435         /*Ok, we have vx and vy in values, fill in vx and vy arrays: */
    3436         for(i=0;i<NUMVERTICES;i++){
    3437                 lambdax[i]=values[i*NDOF2+0];
    3438                 lambday[i]=values[i*NDOF2+1];
    3439 
    3440                 /*Check solution*/
    3441                 if(isnan(lambdax[i])) _error_("NaN found in solution vector");
    3442                 if(isnan(lambday[i])) _error_("NaN found in solution vector");
    3443         }
    3444 
    3445         /*Add vx and vy as inputs to the tria element: */
    3446         this->inputs->AddInput(new TriaVertexInput(AdjointxEnum,lambdax));
    3447         this->inputs->AddInput(new TriaVertexInput(AdjointyEnum,lambday));
    3448 
    3449         /*Free ressources:*/
    3450         xfree((void**)&doflist);
    34513849}
    34523850/*}}}*/
     
    37514149}
    37524150/*}}}*/
     4151
     4152
     4153#ifdef _HAVE_DAKOTA_
    37534154/*FUNCTION Tria::InputUpdateFromVectorDakota(double* vector, int name, int type);{{{1*/
    37544155void  Tria::InputUpdateFromVectorDakota(double* vector, int name, int type){
     
    38634264}
    38644265/*}}}*/
     4266#endif
    38654267/*FUNCTION Tria::InputCreate(double scalar,int enum,int code);{{{1*/
    38664268void Tria::InputCreate(double scalar,int name,int code){
     
    44804882}
    44814883/*}}}*/
    4482 /*FUNCTION Tria::RheologyBbarAbsGradient{{{1*/
    4483 double Tria::RheologyBbarAbsGradient(bool process_units,int weight_index){
    4484 
    4485         /* Intermediaries */
    4486         int        ig;
    4487         double     Jelem = 0;
    4488         double     weight;
    4489         double     Jdet;
    4490         double     xyz_list[NUMVERTICES][3];
    4491         double     dp[NDOF2];
    4492         GaussTria *gauss = NULL;
    4493 
    4494         /*retrieve parameters and inputs*/
    4495 
    4496         /*If on water, return 0: */
    4497         if(IsOnWater()) return 0;
    4498 
    4499         /*Retrieve all inputs we will be needing: */
    4500         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    4501         Input* weights_input  =inputs->GetInput(InversionCostFunctionsCoefficientsEnum);              _assert_(weights_input);
    4502         Input* rheologyb_input=matice->inputs->GetInput(MaterialsRheologyBbarEnum); _assert_(rheologyb_input);
    4503 
    4504         /* Start looping on the number of gaussian points: */
    4505         gauss=new GaussTria(2);
    4506         for (ig=gauss->begin();ig<gauss->end();ig++){
    4507 
    4508                 gauss->GaussPoint(ig);
    4509 
    4510                 /* Get Jacobian determinant: */
    4511                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    4512 
    4513                 /*Get all parameters at gaussian point*/
    4514                 weights_input->GetParameterValue(&weight,gauss,weight_index);
    4515                 rheologyb_input->GetParameterDerivativeValue(&dp[0],&xyz_list[0][0],gauss);
    4516 
    4517                 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */
    4518                 //Jelem+=weight*1/2*(pow(dp[0],2.)+pow(dp[1],2.))*Jdet*gauss->weight;
    4519         }
    4520 
    4521         /*Clean up and return*/
    4522         delete gauss;
    4523         return Jelem;
    4524 }
    4525 /*}}}*/
    45264884/*FUNCTION Tria::RequestedOutput{{{1*/
    45274885void Tria::RequestedOutput(int output_enum,int step,double time){
     
    46985056        }
    46995057/*}}}*/
    4700 /*FUNCTION Tria::SurfaceAbsVelMisfit {{{1*/
    4701 double Tria::SurfaceAbsVelMisfit(bool process_units,int weight_index){
    4702 
    4703         const int    numdof=NDOF2*NUMVERTICES;
    4704 
    4705         int        i,ig;
    4706         double     Jelem=0;
    4707         double     misfit,Jdet;
    4708         double     vx,vy,vxobs,vyobs,weight;
    4709         double     xyz_list[NUMVERTICES][3];
    4710         GaussTria *gauss=NULL;
    4711 
    4712         /*If on water, return 0: */
    4713         if(IsOnWater())return 0;
    4714 
    4715         /* Get node coordinates and dof list: */
    4716         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    4717 
    4718         /*Retrieve all inputs we will be needing: */
    4719         Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
    4720         Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
    4721         Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
    4722         Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
    4723         Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
    4724 
    4725         /* Start  looping on the number of gaussian points: */
    4726         gauss=new GaussTria(2);
    4727         for (ig=gauss->begin();ig<gauss->end();ig++){
    4728 
    4729                 gauss->GaussPoint(ig);
    4730 
    4731                 /* Get Jacobian determinant: */
    4732                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    4733 
    4734                 /*Get all parameters at gaussian point*/
    4735                 weights_input->GetParameterValue(&weight,gauss,weight_index);
    4736                 vx_input->GetParameterValue(&vx,gauss);
    4737                 vy_input->GetParameterValue(&vy,gauss);
    4738                 vxobs_input->GetParameterValue(&vxobs,gauss);
    4739                 vyobs_input->GetParameterValue(&vyobs,gauss);
    4740 
    4741                 /*Compute SurfaceAbsVelMisfitEnum:
    4742                  *
    4743                  *      1  [           2              2 ]
    4744                  * J = --- | (u - u   )  +  (v - v   )  |
    4745                  *      2  [       obs            obs   ]
    4746                  *
    4747                  */
    4748                 misfit=0.5*( pow(vx-vxobs,2.) + pow(vy-vyobs,2.) );
    4749 
    4750                 if(process_units)UnitConversion(misfit,IuToExtEnum,SurfaceAverageVelMisfitEnum);
    4751 
    4752                 /*Add to cost function*/
    4753                 Jelem+=misfit*weight*Jdet*gauss->weight;
    4754         }
    4755 
    4756         /*clean up and Return: */
    4757         delete gauss;
    4758         return Jelem;
    4759 }
    4760 /*}}}*/
    47615058/*FUNCTION Tria::SurfaceArea {{{1*/
    47625059double Tria::SurfaceArea(void){
     
    47885085}
    47895086/*}}}*/
    4790 /*FUNCTION Tria::SurfaceAverageVelMisfit {{{1*/
    4791 double Tria::SurfaceAverageVelMisfit(bool process_units,int weight_index){
    4792 
    4793         const int    numdof=2*NUMVERTICES;
    4794 
    4795         int        i,ig;
    4796         double     Jelem=0,S,Jdet;
    4797         double     misfit;
    4798         double     vx,vy,vxobs,vyobs,weight;
    4799         double     xyz_list[NUMVERTICES][3];
    4800         GaussTria *gauss=NULL;
    4801 
    4802         /*If on water, return 0: */
    4803         if(IsOnWater())return 0;
    4804 
    4805         /* Get node coordinates and dof list: */
    4806         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    4807 
    4808         /*Retrieve all inputs we will be needing: */
    4809         inputs->GetParameterValue(&S,SurfaceAreaEnum);
    4810         Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
    4811         Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
    4812         Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
    4813         Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
    4814         Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
    4815 
    4816         /* Start  looping on the number of gaussian points: */
    4817         gauss=new GaussTria(3);
    4818         for (ig=gauss->begin();ig<gauss->end();ig++){
    4819 
    4820                 gauss->GaussPoint(ig);
    4821 
    4822                 /* Get Jacobian determinant: */
    4823                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    4824 
    4825                 /*Get all parameters at gaussian point*/
    4826                 weights_input->GetParameterValue(&weight,gauss,weight_index);
    4827                 vx_input->GetParameterValue(&vx,gauss);
    4828                 vy_input->GetParameterValue(&vy,gauss);
    4829                 vxobs_input->GetParameterValue(&vxobs,gauss);
    4830                 vyobs_input->GetParameterValue(&vyobs,gauss);
    4831 
    4832                 /*Compute SurfaceAverageVelMisfitEnum:
    4833                  *
    4834                  *      1                    2              2
    4835                  * J = ---  sqrt(  (u - u   )  +  (v - v   )  )
    4836                  *      S                obs            obs
    4837                  */
    4838                 misfit=1/S*pow( pow(vx-vxobs,2.) + pow(vy-vyobs,2.) ,0.5);
    4839 
    4840                 if(process_units)UnitConversion(misfit,IuToExtEnum,SurfaceAverageVelMisfitEnum);
    4841 
    4842                 /*Add to cost function*/
    4843                 Jelem+=misfit*weight*Jdet*gauss->weight;
    4844         }
    4845 
    4846         /*clean-up and Return: */
    4847         delete gauss;
    4848         return Jelem;
    4849 }
    4850 /*}}}*/
    4851 /*FUNCTION Tria::SurfaceLogVelMisfit {{{1*/
    4852 double Tria::SurfaceLogVelMisfit(bool process_units,int weight_index){
    4853 
    4854         const int    numdof=NDOF2*NUMVERTICES;
    4855 
    4856         int        i,ig;
    4857         double     Jelem=0;
    4858         double     misfit,Jdet;
    4859         double     epsvel=2.220446049250313e-16;
    4860         double     meanvel=3.170979198376458e-05; /*1000 m/yr*/
    4861         double     velocity_mag,obs_velocity_mag;
    4862         double     xyz_list[NUMVERTICES][3];
    4863         double     vx,vy,vxobs,vyobs,weight;
    4864         GaussTria *gauss=NULL;
    4865 
    4866         /*If on water, return 0: */
    4867         if(IsOnWater())return 0;
    4868 
    4869         /* Get node coordinates and dof list: */
    4870         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    4871 
    4872         /*Retrieve all inputs we will be needing: */
    4873         Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
    4874         Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
    4875         Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
    4876         Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
    4877         Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
    4878 
    4879         /* Start  looping on the number of gaussian points: */
    4880         gauss=new GaussTria(4);
    4881         for (ig=gauss->begin();ig<gauss->end();ig++){
    4882 
    4883                 gauss->GaussPoint(ig);
    4884 
    4885                 /* Get Jacobian determinant: */
    4886                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    4887 
    4888                 /*Get all parameters at gaussian point*/
    4889                 weights_input->GetParameterValue(&weight,gauss,weight_index);
    4890                 vx_input->GetParameterValue(&vx,gauss);
    4891                 vy_input->GetParameterValue(&vy,gauss);
    4892                 vxobs_input->GetParameterValue(&vxobs,gauss);
    4893                 vyobs_input->GetParameterValue(&vyobs,gauss);
    4894 
    4895                 /*Compute SurfaceLogVelMisfit:
    4896                  *                 [        vel + eps     ] 2
    4897                  * J = 4 \bar{v}^2 | log ( -----------  ) | 
    4898                  *                 [       vel   + eps    ]
    4899                  *                            obs
    4900                  */
    4901                 velocity_mag    =sqrt(pow(vx,   2.)+pow(vy,   2.))+epsvel;
    4902                 obs_velocity_mag=sqrt(pow(vxobs,2.)+pow(vyobs,2.))+epsvel;
    4903                 misfit=4*pow(meanvel,2.)*pow(log(velocity_mag/obs_velocity_mag),2.);
    4904 
    4905                 if(process_units)UnitConversion(misfit,IuToExtEnum,SurfaceLogVelMisfitEnum);
    4906 
    4907                 /*Add to cost function*/
    4908                 Jelem+=misfit*weight*Jdet*gauss->weight;
    4909         }
    4910 
    4911         /*clean-up and Return: */
    4912         delete gauss;
    4913         return Jelem;
    4914 }
    4915 /*}}}*/
    4916 /*FUNCTION Tria::SurfaceLogVxVyMisfit {{{1*/
    4917 double Tria::SurfaceLogVxVyMisfit(bool process_units,int weight_index){
    4918 
    4919         const int    numdof=NDOF2*NUMVERTICES;
    4920 
    4921         int        i,ig;
    4922         int        fit=-1;
    4923         double     Jelem=0, S=0;
    4924         double     epsvel=2.220446049250313e-16;
    4925         double     meanvel=3.170979198376458e-05; /*1000 m/yr*/
    4926         double     misfit, Jdet;
    4927         double     vx,vy,vxobs,vyobs,weight;
    4928         double     xyz_list[NUMVERTICES][3];
    4929         GaussTria *gauss=NULL;
    4930 
    4931         /*If on water, return 0: */
    4932         if(IsOnWater())return 0;
    4933 
    4934         /* Get node coordinates and dof list: */
    4935         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    4936 
    4937         /*Retrieve all inputs we will be needing: */
    4938         Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
    4939         Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
    4940         Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
    4941         Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
    4942         Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
    4943        
    4944         /* Start  looping on the number of gaussian points: */
    4945         gauss=new GaussTria(4);
    4946         for (ig=gauss->begin();ig<gauss->end();ig++){
    4947 
    4948                 gauss->GaussPoint(ig);
    4949 
    4950                 /* Get Jacobian determinant: */
    4951                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    4952 
    4953                 /*Get all parameters at gaussian point*/
    4954                 weights_input->GetParameterValue(&weight,gauss,weight_index);
    4955                 vx_input->GetParameterValue(&vx,gauss);
    4956                 vy_input->GetParameterValue(&vy,gauss);
    4957                 vxobs_input->GetParameterValue(&vxobs,gauss);
    4958                 vyobs_input->GetParameterValue(&vyobs,gauss);
    4959 
    4960                 /*Compute SurfaceRelVelMisfit:
    4961                  *
    4962                  *      1            [        |u| + eps     2          |v| + eps     2  ]
    4963                  * J = --- \bar{v}^2 | log ( -----------  )   +  log ( -----------  )   | 
    4964                  *      2            [       |u    |+ eps              |v    |+ eps     ]
    4965                  *                              obs                       obs
    4966                  */
    4967                 misfit=0.5*pow(meanvel,2.)*(
    4968                                         pow(log((fabs(vx)+epsvel)/(fabs(vxobs)+epsvel)),2.) +
    4969                                         pow(log((fabs(vy)+epsvel)/(fabs(vyobs)+epsvel)),2.) );
    4970 
    4971                 if(process_units)UnitConversion(misfit,IuToExtEnum,SurfaceLogVxVyMisfitEnum);
    4972 
    4973                 /*Add to cost function*/
    4974                 Jelem+=misfit*weight*Jdet*gauss->weight;
    4975         }
    4976 
    4977         /*clean-up and Return: */
    4978         delete gauss;
    4979         return Jelem;
    4980 }
    4981 /*}}}*/
    49825087/*FUNCTION Tria::SurfaceNormal{{{1*/
    49835088void Tria::SurfaceNormal(double* surface_normal, double xyz_list[3][3]){
     
    50025107        *(surface_normal+1)=normal[1]/normal_norm;
    50035108        *(surface_normal+2)=normal[2]/normal_norm;
    5004 }
    5005 /*}}}*/
    5006 /*FUNCTION Tria::SurfaceRelVelMisfit {{{1*/
    5007 double Tria::SurfaceRelVelMisfit(bool process_units,int weight_index){
    5008         const int  numdof=2*NUMVERTICES;
    5009 
    5010         int        i,ig;
    5011         double     Jelem=0;
    5012         double     scalex=1,scaley=1;
    5013         double     misfit,Jdet;
    5014         double     epsvel=2.220446049250313e-16;
    5015         double     meanvel=3.170979198376458e-05; /*1000 m/yr*/
    5016         double     vx,vy,vxobs,vyobs,weight;
    5017         double     xyz_list[NUMVERTICES][3];
    5018         GaussTria *gauss=NULL;
    5019 
    5020         /*If on water, return 0: */
    5021         if(IsOnWater())return 0;
    5022 
    5023         /* Get node coordinates and dof list: */
    5024         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    5025 
    5026         /*Retrieve all inputs we will be needing: */
    5027         Input* weights_input=inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
    5028         Input* vx_input     =inputs->GetInput(VxEnum);        _assert_(vx_input);
    5029         Input* vy_input     =inputs->GetInput(VyEnum);        _assert_(vy_input);
    5030         Input* vxobs_input  =inputs->GetInput(InversionVxObsEnum);     _assert_(vxobs_input);
    5031         Input* vyobs_input  =inputs->GetInput(InversionVyObsEnum);     _assert_(vyobs_input);
    5032 
    5033         /* Start  looping on the number of gaussian points: */
    5034         gauss=new GaussTria(4);
    5035         for (ig=gauss->begin();ig<gauss->end();ig++){
    5036 
    5037                 gauss->GaussPoint(ig);
    5038 
    5039                 /* Get Jacobian determinant: */
    5040                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    5041 
    5042                 /*Get all parameters at gaussian point*/
    5043                 weights_input->GetParameterValue(&weight,gauss,weight_index);
    5044                 vx_input->GetParameterValue(&vx,gauss);
    5045                 vy_input->GetParameterValue(&vy,gauss);
    5046                 vxobs_input->GetParameterValue(&vxobs,gauss);
    5047                 vyobs_input->GetParameterValue(&vyobs,gauss);
    5048 
    5049                 /*Compute SurfaceRelVelMisfit:
    5050                  *                       
    5051                  *      1  [     \bar{v}^2             2   \bar{v}^2              2 ]
    5052                  * J = --- | -------------  (u - u   ) + -------------  (v - v   )  |
    5053                  *      2  [  (u   + eps)^2       obs    (v   + eps)^2       obs    ]
    5054                  *              obs                        obs                     
    5055                  */
    5056                 scalex=pow(meanvel/(vxobs+epsvel),2.); if(vxobs==0)scalex=0;
    5057                 scaley=pow(meanvel/(vyobs+epsvel),2.); if(vyobs==0)scaley=0;
    5058                 misfit=0.5*(scalex*pow((vx-vxobs),2.)+scaley*pow((vy-vyobs),2.));
    5059                 if(process_units)UnitConversion(misfit,IuToExtEnum,SurfaceRelVelMisfitEnum);
    5060 
    5061                 /*Add to cost function*/
    5062                 Jelem+=misfit*weight*Jdet*gauss->weight;
    5063         }
    5064 
    5065         /*clean up and Return: */
    5066         delete gauss;
    5067         return Jelem;
    5068 }
    5069 /*}}}*/
    5070 /*FUNCTION Tria::ThicknessAbsGradient{{{1*/
    5071 double Tria::ThicknessAbsGradient(bool process_units,int weight_index){
    5072 
    5073         /* Intermediaries */
    5074         int        ig;
    5075         double     Jelem = 0;
    5076         double     weight;
    5077         double     Jdet;
    5078         double     xyz_list[NUMVERTICES][3];
    5079         double     dp[NDOF2];
    5080         GaussTria *gauss = NULL;
    5081 
    5082         /*retrieve parameters and inputs*/
    5083 
    5084         /*If on water, return 0: */
    5085         if(IsOnWater()) return 0;
    5086 
    5087         /*Retrieve all inputs we will be needing: */
    5088         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    5089         Input* weights_input  =inputs->GetInput(InversionCostFunctionsCoefficientsEnum);   _assert_(weights_input);
    5090         Input* thickness_input=inputs->GetInput(ThicknessEnum); _assert_(thickness_input);
    5091 
    5092         /* Start looping on the number of gaussian points: */
    5093         gauss=new GaussTria(2);
    5094         for (ig=gauss->begin();ig<gauss->end();ig++){
    5095 
    5096                 gauss->GaussPoint(ig);
    5097 
    5098                 /* Get Jacobian determinant: */
    5099                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    5100 
    5101                 /*Get all parameters at gaussian point*/
    5102                 weights_input->GetParameterValue(&weight,gauss,weight_index);
    5103                 thickness_input->GetParameterDerivativeValue(&dp[0],&xyz_list[0][0],gauss);
    5104 
    5105                 /*Tikhonov regularization: J = 1/2 ((dp/dx)^2 + (dp/dy)^2) */
    5106                 Jelem+=weight*1/2*(pow(dp[0],2.)+pow(dp[1],2.))*Jdet*gauss->weight;
    5107         }
    5108 
    5109         /*Clean up and return*/
    5110         delete gauss;
    5111         return Jelem;
    5112 }
    5113 /*}}}*/
    5114 /*FUNCTION Tria::ThicknessAbsMisfit {{{1*/
    5115 double Tria::ThicknessAbsMisfit(bool process_units,int weight_index){
    5116 
    5117         /*Intermediaries*/
    5118         int        i,ig;
    5119         double     thickness,thicknessobs,weight;
    5120         double     Jdet;
    5121         double     Jelem = 0;
    5122         double     xyz_list[NUMVERTICES][3];
    5123         GaussTria *gauss = NULL;
    5124         double     dH[2];
    5125 
    5126         /*If on water, return 0: */
    5127         if(IsOnWater())return 0;
    5128 
    5129         /*Retrieve all inputs we will be needing: */
    5130         GetVerticesCoordinates(&xyz_list[0][0], nodes, NUMVERTICES);
    5131         Input* thickness_input   =inputs->GetInput(ThicknessEnum);   _assert_(thickness_input);
    5132         Input* thicknessobs_input=inputs->GetInput(InversionThicknessObsEnum);_assert_(thicknessobs_input);
    5133         Input* weights_input     =inputs->GetInput(InversionCostFunctionsCoefficientsEnum);     _assert_(weights_input);
    5134 
    5135         /* Start  looping on the number of gaussian points: */
    5136         gauss=new GaussTria(2);
    5137         for (ig=gauss->begin();ig<gauss->end();ig++){
    5138 
    5139                 gauss->GaussPoint(ig);
    5140 
    5141                 /* Get Jacobian determinant: */
    5142                 GetJacobianDeterminant2d(&Jdet, &xyz_list[0][0],gauss);
    5143 
    5144                 /*Get parameters at gauss point*/
    5145                 thickness_input->GetParameterValue(&thickness,gauss);
    5146                 thickness_input->GetParameterDerivativeValue(&dH[0],&xyz_list[0][0],gauss);
    5147                 thicknessobs_input->GetParameterValue(&thicknessobs,gauss);
    5148                 weights_input->GetParameterValue(&weight,gauss,weight_index);
    5149 
    5150                 /*compute ThicknessAbsMisfit*/
    5151                 Jelem+=0.5*pow(thickness-thicknessobs,2.0)*weight*Jdet*gauss->weight;
    5152         }
    5153 
    5154         /* clean up and Return: */
    5155         delete gauss;
    5156         return Jelem;
    51575109}
    51585110/*}}}*/
  • issm/trunk/src/c/objects/Elements/Tria.h

    r9733 r9761  
    6262                void  InputUpdateFromVector(int* vector, int name, int type);
    6363                void  InputUpdateFromVector(bool* vector, int name, int type);
     64                #ifdef _HAVE_DAKOTA_
    6465                void  InputUpdateFromVectorDakota(double* vector, int name, int type);
    6566                void  InputUpdateFromVectorDakota(int* vector, int name, int type);
    6667                void  InputUpdateFromVectorDakota(bool* vector, int name, int type);
     68                #endif
    6769                void  InputUpdateFromConstant(double constant, int name);
    6870                void  InputUpdateFromConstant(int constant, int name);
     
    7880                void   CreateKMatrix(Mat Kff, Mat Kfs,Vec df);
    7981                void   CreatePVector(Vec pf);
    80                 double DragCoefficientAbsGradient(bool process_units,int weight_index);
    8182                int    GetNodeIndex(Node* node);
    8283                int    Sid();
     
    8889                void   GetSolutionFromInputs(Vec solution);
    8990                void   GetVectorFromInputs(Vec vector,int NameEnum);
     91                #ifdef _HAVE_CONTROL_
     92                double DragCoefficientAbsGradient(bool process_units,int weight_index);
    9093                void   Gradj(Vec gradient,int control_type);
    9194                void   GradjBGradient(Vec gradient,int weight_index);
     
    97100                void   GradjVxBalancedthickness(Vec gradient);
    98101                void   GradjVyBalancedthickness(Vec gradient);
     102                void   ControlInputGetGradient(Vec gradient,int enum_type);
     103                void   ControlInputScaleGradient(int enum_type,double scale);
     104                void   ControlInputSetGradient(double* gradient,int enum_type);
     105                double RheologyBbarAbsGradient(bool process_units,int weight_index);
     106                double ThicknessAbsMisfit(     bool process_units,int weight_index);
     107                double SurfaceAbsVelMisfit(    bool process_units,int weight_index);
     108                double ThicknessAbsGradient(bool process_units,int weight_index);
     109                double SurfaceRelVelMisfit(    bool process_units,int weight_index);
     110                double SurfaceLogVelMisfit(    bool process_units,int weight_index);
     111                double SurfaceLogVxVyMisfit(   bool process_units,int weight_index);
     112                double SurfaceAverageVelMisfit(bool process_units,int weight_index);
     113                void   InputControlUpdate(double scalar,bool save_parameter);
     114                #endif
     115
    99116                void   InputArtificialNoise(int enum_type,double min, double max);
    100                 void   InputControlUpdate(double scalar,bool save_parameter);
    101117                bool   InputConvergence(double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums);
    102118                void   InputCreate(double scalar,int name,int code);
     
    105121                void   InputDuplicate(int original_enum,int new_enum);
    106122                void   InputScale(int enum_type,double scale_factor);
    107                 void   ControlInputGetGradient(Vec gradient,int enum_type);
    108                 void   ControlInputScaleGradient(int enum_type,double scale);
    109                 void   ControlInputSetGradient(double* gradient,int enum_type);
    110                 void   InputToResult(int enum_type,int step,double time);
     123                                void   InputToResult(int enum_type,int step,double time);
    111124                void   DeleteResults(void);
    112125                void   MaterialUpdateFromTemperature(void){_error_("not implemented yet");};
     
    129142                void   MinVz(double* pminvz, bool process_units);
    130143                void   RequestedOutput(int output_enum,int step,double time);
    131                 double RheologyBbarAbsGradient(bool process_units,int weight_index);
    132                 double ThicknessAbsMisfit(     bool process_units,int weight_index);
    133                 double SurfaceAbsVelMisfit(    bool process_units,int weight_index);
    134                 double ThicknessAbsGradient(bool process_units,int weight_index);
    135                 double SurfaceRelVelMisfit(    bool process_units,int weight_index);
    136                 double SurfaceLogVelMisfit(    bool process_units,int weight_index);
    137                 double SurfaceLogVxVyMisfit(   bool process_units,int weight_index);
    138                 double SurfaceAverageVelMisfit(bool process_units,int weight_index);
    139144                void   PatchFill(int* pcount, Patch* patch);
    140145                void   PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes);
  • issm/trunk/src/c/objects/ExternalResults/PetscVecExternalResult.cpp

    r9320 r9761  
    206206        char   *name      = NULL;
    207207        double *serialvec = NULL;
     208        extern int my_rank;
    208209
    209210        /*serialize: */
  • issm/trunk/src/c/objects/FemModel.cpp

    r9320 r9761  
    1313#include "../Container/Container.h"
    1414#include "../modules/ModelProcessorx/ModelProcessorx.h"
     15#include "../io/io.h"
    1516#include "./objects.h"
    1617#include "../include/include.h"
     
    2728        int analysis_type;
    2829        FILE* IOMODEL;
     30        extern int my_rank;
    2931
    3032        /*Open input file on cpu 0: */
  • issm/trunk/src/c/objects/IoModel.cpp

    r9725 r9761  
    1616
    1717#include "./objects.h"
     18#include "../io/io.h"
    1819#include "./Container/Parameters.h"
    1920#include "../shared/shared.h"
  • issm/trunk/src/c/objects/KML/KMLFileReadUtils.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_Attribute.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_ColorStyle.cpp

    r9320 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_Container.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_Document.cpp

    r9320 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_Feature.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_File.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_Folder.cpp

    r9320 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_GroundOverlay.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_Icon.cpp

    r9320 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_LatLonBox.cpp

    r9320 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_LineString.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_LineStyle.cpp

    r9320 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_LinearRing.cpp

    r9336 r9761  
    1717#include "../../Container/Container.h"
    1818#include "../../include/include.h"
     19#include "../../io/io.h"
    1920#include "../../modules/Ll2xyx/Ll2xyx.h"
    2021/*}}}*/
  • issm/trunk/src/c/objects/KML/KML_MultiGeometry.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_Object.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_Overlay.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_Placemark.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_PolyStyle.cpp

    r9320 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_Polygon.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/KML/KML_Style.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/Materials/Matice.cpp

    r9733 r9761  
    686686
    687687                /*Control Inputs*/
     688                #ifdef _HAVE_CONTROL_
    688689                if (control_analysis && iomodel->Data(InversionControlParametersEnum)){
    689690                        for(i=0;i<num_control_type;i++){
     
    701702                        }
    702703                }
     704                #endif
    703705        }
    704706
     
    725727
    726728                /*Control Inputs*/
     729                #ifdef _HAVE_CONTROL_
    727730                if (control_analysis && iomodel->Data(InversionControlParametersEnum)){
    728731                        for(i=0;i<num_control_type;i++){
     
    740743                        }
    741744                }
     745                #endif
    742746        }
    743747        else{
  • issm/trunk/src/c/objects/Options/Option.cpp

    r9320 r9761  
    1616#include "../../shared/shared.h"
    1717#include "../../Container/Container.h"
     18#include "../../io/io.h"
    1819#include "../../include/include.h"
    1920/*}}}*/
  • issm/trunk/src/c/objects/Options/OptionCell.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/Options/OptionChar.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/Options/OptionDouble.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/Options/OptionLogical.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/Options/OptionStruct.cpp

    r9336 r9761  
    1515#include "../objects.h"
    1616#include "../../shared/shared.h"
     17#include "../../io/io.h"
    1718#include "../../Container/Container.h"
    1819#include "../../include/include.h"
  • issm/trunk/src/c/objects/Update.h

    r6216 r9761  
    1717                virtual void  InputUpdateFromVector(double* vector, int name, int type)=0;
    1818                virtual void  InputUpdateFromVector(int* vector, int name, int type)=0;
    19                 virtual void  InputUpdateFromVector(bool* vector, int name, int type)=0;
     19                virtual void  InputUpdateFromVector(bool* vector, int name, int type)=0;
     20                #ifdef _HAVE_DAKOTA_
    2021                virtual void  InputUpdateFromVectorDakota(double* vector, int name, int type)=0;
    2122                virtual void  InputUpdateFromVectorDakota(int* vector, int name, int type)=0;
    2223                virtual void  InputUpdateFromVectorDakota(bool* vector, int name, int type)=0;
     24                #endif
    2325                virtual void  InputUpdateFromConstant(double constant, int name)=0;
    2426                virtual void  InputUpdateFromConstant(int constant, int name)=0;
  • issm/trunk/src/c/shared/Exceptions/Exceptions.cpp

    r9388 r9761  
    88#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
    99#endif
     10
    1011#include "../shared.h"
    1112#include "../../include/include.h"
  • issm/trunk/src/c/shared/Matlab/matlabshared.h

    r8 r9761  
    88#include "../../objects/objects.h"
    99
    10 /*printf: */
    11 int PrintfFunction(char* format,...);
    12 int ModuleBoot(void);
    1310
    1411#ifdef _SERIAL_
    1512#include "mex.h"
     13        int ModuleBoot(void);
    1614        mxArray* mxGetAssignedField(const mxArray* pmxa_array,int number, char* field);
    1715        int CheckNumMatlabArguments(int nlhs,int NLHS, int nrhs,int NRHS, char* THISFUNCTION, void (*function)( void ));
  • issm/trunk/src/c/shared/Matrix/MatrixUtils.cpp

    r6412 r9761  
    1414#include <float.h>    /*  DBL_EPSILON  */
    1515#include "../../include/include.h"
     16#include "../../io/io.h"
    1617/*}}}*/
    1718
  • issm/trunk/src/c/shared/Numerics/BrentSearch.cpp

    r9563 r9761  
    1212#include "../../objects/objects.h"
    1313#include "../../include/include.h"
     14#include "../../io/io.h"
    1415#include "../../shared/shared.h"
    1516#include <float.h>
  • issm/trunk/src/c/shared/Numerics/GaussPoints.cpp

    r6412 r9761  
    55#include "../Alloc/alloc.h"
    66#include "../../include/include.h"
     7#include "../../io/io.h"
    78#include "../Exceptions/exceptions.h"
    89#include <math.h>
  • issm/trunk/src/c/shared/Numerics/OptimalSearch.cpp

    r9563 r9761  
    1111#include "./numerics.h"
    1212#include "../../objects/objects.h"
     13#include "../../io/io.h"
    1314#include "../../include/include.h"
    1415#include "../../shared/shared.h"
  • issm/trunk/src/c/shared/shared.h

    r6273 r9761  
    66#define _SHARED_H_
    77
     8
    89#include "Alloc/alloc.h"
    9 #include "Matlab/matlabshared.h"
    1010#include "Exceptions/exceptions.h"
    1111#include "Exp/exp.h"
     
    1616#include "Numerics/numerics.h"
    1717#include "Dofs/dofs.h"
    18 #include "String/sharedstring.h" //to avoid confusion with <string.h> standard header file
    1918#include "Threads/issm_threads.h"
    2019#include "Bamg/shared.h"
     20#include "Matlab/matlabshared.h"
    2121
    2222#endif
  • issm/trunk/src/c/solutions/CorePointerFromSolutionEnum.cpp

    r9725 r9761  
    2020void CorePointerFromSolutionEnum(void (**psolutioncore)(FemModel*),Parameters* parameters,int solutiontype){
    2121
    22         /*intermediary: */
    23         bool control_analysis=false;
    24         bool dakota_analysis=false;
    25        
    2622        /*output: */
    2723        void (*solutioncore)(FemModel*)=NULL;
    28 
    29         /*retrieve some parameters: */
    30         parameters->FindParam(&control_analysis,InversionIscontrolEnum);
    31         parameters->FindParam(&dakota_analysis,QmuIsdakotaEnum);
    3224
    3325        switch(solutiontype){
     
    4032                        break;
    4133                case ThermalSolutionEnum:
     34                        #ifdef _HAVE_THERMAL_
    4235                        solutioncore=&thermal_core;
     36                        #else
     37                        _error_("ISSM was not compiled with thermal capabilities. Exiting");
     38                        #endif
    4339                        break;
    4440                case EnthalpySolutionEnum:
     41                        #ifdef _HAVE_THERMAL_
    4542                        solutioncore=&enthalpy_core;
     43                        #else
     44                        _error_("ISSM was not compiled with thermal capabilities. Exiting");
     45                        #endif
    4646                        break;
    4747                case PrognosticSolutionEnum:
  • issm/trunk/src/c/solutions/ResetBoundaryConditions.cpp

    r9298 r9761  
    55#include "../objects/objects.h"
    66#include "../modules/modules.h"
     7#include "../io/io.h"
    78#include "../EnumDefinitions/EnumDefinitions.h"
    89
  • issm/trunk/src/c/solutions/adjointbalancethickness_core.cpp

    r9681 r9761  
    66#include "../objects/objects.h"
    77#include "../shared/shared.h"
     8#include "../io/io.h"
    89#include "../EnumDefinitions/EnumDefinitions.h"
    910#include "./solutions.h"
  • issm/trunk/src/c/solutions/adjointdiagnostic_core.cpp

    r9681 r9761  
    66#include "../objects/objects.h"
    77#include "../shared/shared.h"
     8#include "../io/io.h"
    89#include "../EnumDefinitions/EnumDefinitions.h"
    910#include "./solutions.h"
  • issm/trunk/src/c/solutions/balancethickness_core.cpp

    r9719 r9761  
    66#include "../objects/objects.h"
    77#include "../shared/shared.h"
     8#include "../io/io.h"
    89#include "../include/include.h"
    910#include "../EnumDefinitions/EnumDefinitions.h"
  • issm/trunk/src/c/solutions/bedslope_core.cpp

    r9719 r9761  
    66#include "../toolkits/toolkits.h"
    77#include "../objects/objects.h"
     8#include "../io/io.h"
    89#include "../EnumDefinitions/EnumDefinitions.h"
    910#include "../modules/modules.h"
  • issm/trunk/src/c/solutions/control_core.cpp

    r9719 r9761  
    66#include "../objects/objects.h"
    77#include "../shared/shared.h"
     8#include "../io/io.h"
    89#include "../EnumDefinitions/EnumDefinitions.h"
    910#include "./solutions.h"
  • issm/trunk/src/c/solutions/controlconvergence.cpp

    r9320 r9761  
    1010#include "../objects/objects.h"
    1111#include "../shared/shared.h"
     12#include "../io/io.h"
    1213#include "../Container/Container.h"
    1314#include "../EnumDefinitions/EnumDefinitions.h"
  • issm/trunk/src/c/solutions/controltao_core.cpp

    r9681 r9761  
    22 * \brief: core of the control solution
    33 */
    4 #include "../issm.h"
     4#include "../toolkits/toolkits.h"
     5#include "../objects/objects.h"
     6#include "../shared/shared.h"
     7#include "../io/io.h"
     8#include "../EnumDefinitions/EnumDefinitions.h"
     9#include "./solutions.h"
     10#include "../modules/modules.h"
     11#include "../include/include.h"
     12#include "../solvers/solvers.h"
     13
    514
    615#ifdef _HAVE_TAO_
  • issm/trunk/src/c/solutions/convergence.cpp

    r9679 r9761  
    55#include "../objects/objects.h"
    66#include "../modules/modules.h"
     7#include "../io/io.h"
    78#include "../EnumDefinitions/EnumDefinitions.h"
    89
  • issm/trunk/src/c/solutions/diagnostic_core.cpp

    r9719 r9761  
    66#include "../objects/objects.h"
    77#include "../shared/shared.h"
     8#include "../io/io.h"
    89#include "../EnumDefinitions/EnumDefinitions.h"
    910#include "./solutions.h"
  • issm/trunk/src/c/solutions/enthalpy_core.cpp

    r9681 r9761  
    1010#include "../modules/modules.h"
    1111#include "../include/include.h"
     12#include "../io/io.h"
    1213#include "../solvers/solvers.h"
    1314
  • issm/trunk/src/c/solutions/gradient_core.cpp

    r9681 r9761  
    66#include "../objects/objects.h"
    77#include "../shared/shared.h"
     8#include "../io/io.h"
    89#include "../EnumDefinitions/EnumDefinitions.h"
    910#include "./solutions.h"
  • issm/trunk/src/c/solutions/groundinglinemigration2d_core.cpp

    r9725 r9761  
    66#include "../objects/objects.h"
    77#include "../shared/shared.h"
     8#include "../io/io.h"
    89#include "../EnumDefinitions/EnumDefinitions.h"
    910#include "./solutions.h"
  • issm/trunk/src/c/solutions/hydrology_core.cpp

    r9681 r9761  
    66#include "../objects/objects.h"
    77#include "../shared/shared.h"
     8#include "../io/io.h"
    89#include "../EnumDefinitions/EnumDefinitions.h"
    910#include "./solutions.h"
  • issm/trunk/src/c/solutions/hydrology_core_step.cpp

    r9291 r9761  
    66#include "../objects/objects.h"
    77#include "../shared/shared.h"
     8#include "../io/io.h"
    89#include "../EnumDefinitions/EnumDefinitions.h"
    910#include "./solutions.h"
  • issm/trunk/src/c/solutions/issm.cpp

    r9702 r9761  
    33 */
    44
    5 #include "./issm.h"
     5#include "../issm.h"
     6#include "../include/globals.h"
    67
    78int main(int argc,char  **argv){
     
    9798        MPI_Barrier(MPI_COMM_WORLD); start_core=MPI_Wtime( );
    9899        if(dakota_analysis){
     100                #ifdef _HAVE_DAKOTA_
    99101                Dakotax(femmodel);
     102                #else
     103                _error_("ISSM was not compiled with dakota support, cannot carry out dakota analysis!");
     104                #endif
    100105        }
    101106        else if(control_analysis){
     107                #ifdef _HAVE_CONTROL_
    102108                #ifdef _HAVE_TAO_
    103                 //controltao_core(femmodel);
    104                 control_core(femmodel);
     109                controltao_core(femmodel);
    105110                #else
    106111                control_core(femmodel);
     112                #endif
     113                #else
     114                _error_("ISSM was not compiled with control support, cannot carry out dakota analysis!");
    107115                #endif
    108116        }
  • issm/trunk/src/c/solutions/prognostic_core.cpp

    r9681 r9761  
    66#include "../objects/objects.h"
    77#include "../shared/shared.h"
     8#include "../io/io.h"
    89#include "../EnumDefinitions/EnumDefinitions.h"
    910#include "./solutions.h"
  • issm/trunk/src/c/solutions/steadystate_core.cpp

    r9719 r9761  
    33 */
    44
     5#ifdef HAVE_CONFIG_H
     6        #include <config.h>
     7#else
     8#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
     9#endif
     10
    511#include "../toolkits/toolkits.h"
    612#include "../objects/objects.h"
    713#include "../shared/shared.h"
     14#include "../io/io.h"
    815#include "../EnumDefinitions/EnumDefinitions.h"
    916#include "./solutions.h"
     
    3946       
    4047                _printf_(VerboseSolution(),"%s%i\n","   computing temperature and velocity for step: ",step);
     48                #ifdef _HAVE_THERMAL_
    4149                thermal_core(femmodel);
     50                #else
     51                _error_("ISSM was not compiled with thermal capabilities. Exiting");
     52                #endif
    4253
    4354                _printf_(VerboseSolution(),"%s\n","   computing new velocity");
  • issm/trunk/src/c/solutions/surfaceslope_core.cpp

    r9719 r9761  
    66#include "../toolkits/toolkits.h"
    77#include "../objects/objects.h"
     8#include "../io/io.h"
    89#include "../EnumDefinitions/EnumDefinitions.h"
    910#include "../solvers/solvers.h"
  • issm/trunk/src/c/solutions/thermal_core.cpp

    r9681 r9761  
    66#include "../objects/objects.h"
    77#include "../shared/shared.h"
     8#include "../io/io.h"
    89#include "../EnumDefinitions/EnumDefinitions.h"
    910#include "./solutions.h"
  • issm/trunk/src/c/solutions/thermal_core_step.cpp

    r6412 r9761  
    66#include "../objects/objects.h"
    77#include "../shared/shared.h"
     8#include "../io/io.h"
    89#include "../EnumDefinitions/EnumDefinitions.h"
    910#include "./solutions.h"
  • issm/trunk/src/c/solutions/transient_core.cpp

    r9719 r9761  
    33 */
    44
     5#ifdef HAVE_CONFIG_H
     6        #include <config.h>
     7#else
     8#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
     9#endif
     10
    511#include "../toolkits/toolkits.h"
    612#include "../objects/objects.h"
    713#include "../shared/shared.h"
     14#include "../io/io.h"
    815#include "../EnumDefinitions/EnumDefinitions.h"
    916#include "./solutions.h"
     
    6572                if(isthermal && dim==3){
    6673                        _printf_(VerboseSolution(),"   computing temperatures:\n");
     74                        #ifdef _HAVE_THERMAL_
    6775                        thermal_core_step(femmodel,step,time);
     76                        #else
     77                        _error_("ISSM was not compiled with thermal capabilities. Exiting");
     78                        #endif
    6879                }
    6980
  • issm/trunk/src/c/solvers/solver_nonlinear.cpp

    r9679 r9761  
    55#include "../toolkits/toolkits.h"
    66#include "../objects/objects.h"
     7#include "../io/io.h"
    78#include "../EnumDefinitions/EnumDefinitions.h"
    89#include "../modules/modules.h"
  • issm/trunk/src/c/solvers/solver_stokescoupling_nonlinear.cpp

    r9679 r9761  
    66#include "../objects/objects.h"
    77#include "../EnumDefinitions/EnumDefinitions.h"
     8#include "../io/io.h"
    89#include "../modules/modules.h"
    910#include "../solutions/solutions.h"
  • issm/trunk/src/c/solvers/solver_thermal_nonlinear.cpp

    r9632 r9761  
    55#include "../toolkits/toolkits.h"
    66#include "../objects/objects.h"
     7#include "../io/io.h"
    78#include "../EnumDefinitions/EnumDefinitions.h"
    89#include "../modules/modules.h"
Note: See TracChangeset for help on using the changeset viewer.