Changeset 9761
- Timestamp:
- 09/11/11 00:00:59 (14 years ago)
- Location:
- issm/trunk/src
- Files:
-
- 2 added
- 107 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk/src/ad/Makefile.am
r9760 r9761 102 102 ./objects/Inputs/DoubleInput.h\ 103 103 ./objects/Inputs/DoubleInput.cpp\ 104 ./objects/Inputs/ControlInput.h\105 ./objects/Inputs/ControlInput.cpp\106 104 ./objects/Inputs/DatasetInput.h\ 107 105 ./objects/Inputs/DatasetInput.cpp\ … … 190 188 ./Container/Vertices.cpp\ 191 189 ./shared/shared.h\ 192 ./shared/Threads/issm_threads.h\193 ./shared/Threads/LaunchThread.cpp\194 ./shared/Threads/PartitionRange.cpp\195 190 ./shared/Alloc/alloc.h\ 196 191 ./shared/Alloc/alloc.cpp\ … … 207 202 ./shared/Numerics/cross.cpp\ 208 203 ./shared/Numerics/norm.cpp\ 209 ./shared/Numerics/BrentSearch.cpp\210 ./shared/Numerics/OptimalSearch.cpp\211 ./shared/Numerics/OptFunc.cpp\212 204 ./shared/Numerics/extrema.cpp\ 213 205 ./shared/Numerics/UnitConversion.cpp\ … … 308 300 ./modules/ModelProcessorx/SurfaceSlope/CreateConstraintsSurfaceSlope.cpp\ 309 301 ./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\320 302 ./modules/ModelProcessorx/Hydrology/UpdateElementsHydrology.cpp\ 321 303 ./modules/ModelProcessorx/Hydrology/CreateNodesHydrology.cpp\ 322 304 ./modules/ModelProcessorx/Hydrology/CreateConstraintsHydrology.cpp\ 323 305 ./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\328 306 ./modules/ModelProcessorx/Prognostic/UpdateElementsPrognostic.cpp\ 329 307 ./modules/ModelProcessorx/Prognostic/CreateNodesPrognostic.cpp\ … … 371 349 ./modules/InputScalex/InputScalex.h\ 372 350 ./modules/InputScalex/InputScalex.cpp\ 373 ./modules/InputControlUpdatex/InputControlUpdatex.h\374 ./modules/InputControlUpdatex/InputControlUpdatex.cpp\375 351 ./modules/SurfaceAreax/SurfaceAreax.h\ 376 352 ./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\391 353 ./modules/CreateNodalConstraintsx/CreateNodalConstraintsx.h\ 392 354 ./modules/CreateNodalConstraintsx/CreateNodalConstraintsx.cpp\ 393 ./modules/Orthx/Orthx.h\394 ./modules/Orthx/Orthx.cpp\395 355 ./modules/UpdateDynamicConstraintsx/UpdateDynamicConstraintsx.h\ 396 356 ./modules/UpdateDynamicConstraintsx/UpdateDynamicConstraintsx.cpp\ 397 ./modules/Gradjx/Gradjx.h\398 ./modules/Gradjx/Gradjx.cpp\399 357 ./modules/IoModelToConstraintsx/IoModelToConstraintsx.h\ 400 358 ./modules/IoModelToConstraintsx/IoModelToConstraintsx.cpp\ … … 439 397 ./modules/MassFluxx/MassFluxx.cpp\ 440 398 ./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\447 399 ./modules/SystemMatricesx/SystemMatricesx.cpp\ 448 400 ./modules/SystemMatricesx/SystemMatricesx.h\ … … 451 403 ./modules/ConstraintsStatex/ConstraintsStateLocal.h\ 452 404 ./modules/ConstraintsStatex/RiftConstraintsState.cpp\ 453 ./modules/ConstraintsStatex/ThermalConstraintsState.cpp\454 ./modules/ConstraintsStatex/ThermalIsPresent.cpp\455 405 ./modules/Responsex/Responsex.h\ 456 406 ./modules/Responsex/Responsex.cpp\ … … 459 409 ./modules/ResetConstraintsx/ResetConstraintsx.h\ 460 410 ./modules/ResetConstraintsx/ResetConstraintsx.cpp\ 461 ./modules/ResetConstraintsx/ThermalConstraintsReset.cpp\462 411 ./modules/Solverx/Solverx.cpp\ 463 412 ./modules/Solverx/Solverx.h\ … … 473 422 ./modules/OutputRiftsx/OutputRiftsx.h\ 474 423 ./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\481 424 ./modules/RheologyBbarx/RheologyBbarx.cpp\ 482 425 ./modules/RheologyBbarx/RheologyBbarx.h\ 483 426 ./solutions/diagnostic_core.cpp\ 484 427 ./solutions/convergence.cpp\ 485 ./solutions/thermal_core.cpp\486 ./solutions/thermal_core_step.cpp\487 ./solutions/enthalpy_core.cpp\488 428 ./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\497 429 ./solutions/prognostic_core.cpp\ 498 430 ./solutions/balancethickness_core.cpp\ … … 508 440 ./solutions/AnalysisConfiguration.cpp\ 509 441 ./solutions/CorePointerFromSolutionEnum.cpp\ 510 ./solutions/AdjointCorePointerFromSolutionEnum.cpp\511 442 ./solvers/solver_linear.cpp\ 512 ./solvers/solver_adjoint_linear.cpp\513 443 ./solvers/solver_nonlinear.cpp\ 514 ./solvers/solver_stokescoupling_nonlinear.cpp\ 515 ./solvers/solver_thermal_nonlinear.cpp 444 ./solvers/solver_stokescoupling_nonlinear.cpp 516 445 517 446 … … 553 482 ./modules/ModelProcessorx/Qmu/CreateParametersQmu.cpp\ 554 483 ./modules/AverageOntoPartitionx/AverageOntoPartitionx.h 555 556 libDAKOTA_a_CXXFLAGS = -fPIC -D_PARALLEL_ -D_C_ $(CXXOPTFLAGS) 557 endif 558 559 #}}} 484 endif 485 486 #}}} 487 #Thermal sources {{{1 488 489 if THERMAL 490 libpISSM_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 511 endif 512 513 #}}} 514 #Control sources {{{1 515 516 if CONTROL 517 libpISSM_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 567 endif 568 569 #}}} 570 560 571 #Executable {{{1 561 572 -
issm/trunk/src/c/Container/DataSet.cpp
r9320 r9761 19 19 #include "../objects/objects.h" 20 20 #include "../shared/shared.h" 21 #include "../io/io.h" 21 22 #include "../include/include.h" 22 23 #include "../EnumDefinitions/EnumDefinitions.h" … … 240 241 dataset->AddObject(transientinput);} 241 242 break; 243 #ifdef _HAVE_CONTROL_ 242 244 case ControlInputEnum:{ 243 245 ControlInput* controlinputinput=NULL; … … 246 248 dataset->AddObject(controlinputinput);} 247 249 break; 250 #endif 248 251 case DatasetInputEnum:{ 249 252 DatasetInput* datasetinputinput=NULL; -
issm/trunk/src/c/Container/Options.cpp
r9320 r9761 16 16 #include "./DataSet.h" 17 17 #include "../shared/shared.h" 18 #include "../io/io.h" 18 19 #include "../include/include.h" 19 20 #include "../shared/shared.h" -
issm/trunk/src/c/Makefile.am
r9571 r9761 307 307 ./shared/Threads/PartitionRange.cpp\ 308 308 ./shared/Matlab/matlabshared.h\ 309 ./shared/Matlab/PrintfFunction.cpp\310 309 ./shared/Matlab/ModuleBoot.cpp\ 311 310 ./shared/Matlab/mxGetAssignedField.cpp\ … … 355 354 ./shared/Elements/GetGlobalDofList.cpp\ 356 355 ./shared/Elements/GetNumberOfDofs.cpp\ 357 ./shared/String/DescriptorIndex.cpp\358 356 ./shared/String/sharedstring.h\ 359 357 ./shared/Bamg/Abs.h \ … … 415 413 ./io/Matlab/FetchMatlabData.cpp\ 416 414 ./io/Matlab/OptionParse.cpp\ 415 ./io/PrintfFunction.cpp\ 417 416 ./EnumDefinitions/EnumDefinitions.h\ 418 417 ./EnumDefinitions/EnumToModelField.cpp\ … … 685 684 ./modules/Dakotax/SpawnCore.cpp\ 686 685 ./modules/Dakotax/SpawnCoreSerial.cpp\ 686 ./modules/Dakotax/DescriptorIndex.cpp\ 687 687 ./modules/InputToResultx/InputToResultx.cpp\ 688 688 ./modules/InputToResultx/InputToResultx.h\ … … 1000 1000 ./shared/Alloc/alloc.cpp\ 1001 1001 ./shared/Matlab/matlabshared.h\ 1002 ./shared/Matlab/PrintfFunction.cpp\1003 1002 ./shared/Matlab/ModuleBoot.cpp\ 1004 1003 ./shared/Matlab/mxGetAssignedField.cpp\ … … 1046 1045 ./shared/Elements/GetGlobalDofList.cpp\ 1047 1046 ./shared/Elements/GetNumberOfDofs.cpp\ 1048 ./shared/String/DescriptorIndex.cpp\1049 1047 ./shared/String/sharedstring.h\ 1050 1048 ./shared/Bamg/Abs.h \ … … 1104 1102 ./io/Matlab/FetchMatlabData.cpp\ 1105 1103 ./io/Matlab/OptionParse.cpp\ 1104 ./io/PrintfFunction.cpp\ 1106 1105 ./EnumDefinitions/EnumDefinitions.h\ 1107 1106 ./EnumDefinitions/EnumToModelField.cpp\ … … 1366 1365 ./modules/Dakotax/SpawnCore.cpp\ 1367 1366 ./modules/Dakotax/SpawnCoreParallel.cpp\ 1367 ./modules/Dakotax/DescriptorIndex.cpp\ 1368 1368 ./modules/InputToResultx/InputToResultx.cpp\ 1369 1369 ./modules/InputToResultx/InputToResultx.h\ -
issm/trunk/src/c/include/globals.h
r1 r9761 6 6 #define GLOBALS_H_ 7 7 8 externint my_rank;9 externint num_procs;8 int my_rank; 9 int num_procs; 10 10 11 11 #endif -
issm/trunk/src/c/include/include.h
r3775 r9761 6 6 #define _INCLUDEGLOBAL_H_ 7 7 8 #include "./globals.h"9 8 #include "./macros.h" 10 9 #include "./typedefs.h" -
issm/trunk/src/c/io/Matlab/OptionParse.cpp
r9336 r9761 9 9 10 10 #include "../../shared/shared.h" 11 #include "../../io/io.h" 11 12 #include "../../include/include.h" 12 13 #include "./matlabio.h" -
issm/trunk/src/c/io/io.h
r8910 r9761 6 6 #define _IO_H_ 7 7 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 8 15 #include "./Disk/diskio.h" 16 17 #ifdef _SERIAL_ 9 18 #include "./Matlab/matlabio.h" 19 #endif 20 21 /*printf: */ 22 int PrintfFunction(char* format,...); 10 23 11 24 #endif /* _IO_H_ */ -
issm/trunk/src/c/issm.h
r9320 r9761 22 22 #include "./modules/modules.h" 23 23 24 24 25 #endif //ifndef _ISSM_H_ -
issm/trunk/src/c/modules/ConfigureObjectsx/ConfigureObjectsx.cpp
r6412 r9761 7 7 #include "../../shared/shared.h" 8 8 #include "../../include/include.h" 9 #include "../../io/io.h" 9 10 #include "../../toolkits/toolkits.h" 10 11 #include "../../EnumDefinitions/EnumDefinitions.h" -
issm/trunk/src/c/modules/ConstraintsStatex/ConstraintsStatex.cpp
r9679 r9761 7 7 #include "../../shared/shared.h" 8 8 #include "../../include/include.h" 9 #include "../../io/io.h" 9 10 #include "../../toolkits/toolkits.h" 10 11 #include "../../EnumDefinitions/EnumDefinitions.h" … … 35 36 RiftConstraintsState(&converged,&num_unstable_constraints,loads,min_mechanical_constraints,analysis_type); 36 37 } 38 #ifdef _HAVE_THERMAL_ 37 39 else if(ThermalIsPresent(loads,analysis_type)){ 38 40 ThermalConstraintsState(loads,&converged,&num_unstable_constraints,analysis_type); 39 41 } 42 #endif 40 43 else{ 41 44 /*Do nothing, no constraints management!:*/ -
issm/trunk/src/c/modules/ConstraintsStatex/RiftConstraintsState.cpp
r8404 r9761 6 6 #include "../../EnumDefinitions/EnumDefinitions.h" 7 7 #include "../../include/include.h" 8 #include "../../io/io.h" 8 9 #include "../../shared/shared.h" 9 10 -
issm/trunk/src/c/modules/Dakotax/DakotaFree.cpp
r9571 r9761 20 20 21 21 int i; 22 extern int my_rank; 22 23 23 24 double* variables=NULL; -
issm/trunk/src/c/modules/Dakotax/DakotaMPI_Bcast.cpp
r9571 r9761 15 15 16 16 int i; 17 extern int my_rank; 17 18 18 19 /*inputs and outputs: */ -
issm/trunk/src/c/modules/Dakotax/Dakotax.h
r9571 r9761 11 11 /* local prototypes: */ 12 12 int SpawnCore(double* responses, int numresponses, double* variables, char** variables_descriptors,int numvariables, void* femmodel,int counter); 13 int DescriptorIndex(char* root, int* pindex,char* descriptor); 13 14 14 15 #ifdef _SERIAL_ -
issm/trunk/src/c/modules/Dakotax/SpawnCoreParallel.cpp
r9681 r9761 29 29 #include "../../io/io.h" 30 30 #include "../../EnumDefinitions/EnumDefinitions.h" 31 #include "../../io/io.h" 31 32 #include "../../shared/shared.h" 32 33 #include "./Dakotax.h" -
issm/trunk/src/c/modules/Exp2Kmlx/Exp2Kmlx.cpp
r8747 r9761 6 6 #include "../../shared/shared.h" 7 7 #include "../../include/include.h" 8 #include "../../io/io.h" 8 9 #include "../../toolkits/toolkits.h" 9 10 #include "../../EnumDefinitions/EnumDefinitions.h" -
issm/trunk/src/c/modules/GroundingLineMigrationx/GroundingLineMigrationx.cpp
r9356 r9761 7 7 8 8 #include "../../shared/shared.h" 9 #include "../../io/io.h" 9 10 #include "../../include/include.h" 11 #include "../../io/io.h" 10 12 #include "../../toolkits/toolkits.h" 11 13 #include "../../EnumDefinitions/EnumDefinitions.h" -
issm/trunk/src/c/modules/GroundingLineMigrationx/GroundingLineMigrationxUtils.cpp
r9211 r9761 6 6 #include "./GroundingLineMigrationxLocal.h" 7 7 #include "../../shared/shared.h" 8 #include "../../io/io.h" 9 #include "../../io/io.h" 8 10 #include "../../include/include.h" 9 11 #include "../../toolkits/toolkits.h" -
issm/trunk/src/c/modules/InputConvergencex/InputConvergencex.cpp
r6412 r9761 5 5 #include "../../shared/shared.h" 6 6 #include "../../include/include.h" 7 #include "../../io/io.h" 7 8 #include "../../toolkits/toolkits.h" 8 9 #include "../../EnumDefinitions/EnumDefinitions.h" -
issm/trunk/src/c/modules/KMLMeshWritex/KMLFileReadx.cpp
r8468 r9761 5 5 #include "../../shared/shared.h" 6 6 #include "../../include/include.h" 7 #include "../../io/io.h" 7 8 #include "../../toolkits/toolkits.h" 8 9 #include "../../EnumDefinitions/EnumDefinitions.h" -
issm/trunk/src/c/modules/KMLMeshWritex/KMLMeshWritex.cpp
r9259 r9761 5 5 #include "../../shared/shared.h" 6 6 #include "../../include/include.h" 7 #include "../../io/io.h" 7 8 #include "../../toolkits/toolkits.h" 8 9 #include "../../EnumDefinitions/EnumDefinitions.h" -
issm/trunk/src/c/modules/KMLOverlayx/KMLOverlayx.cpp
r8605 r9761 5 5 #include "../../shared/shared.h" 6 6 #include "../../include/include.h" 7 #include "../../io/io.h" 7 8 #include "../../toolkits/toolkits.h" 8 9 #include "../../EnumDefinitions/EnumDefinitions.h" -
issm/trunk/src/c/modules/Kml2Expx/Kml2Expx.cpp
r9259 r9761 6 6 #include "../../shared/shared.h" 7 7 #include "../../include/include.h" 8 #include "../../io/io.h" 8 9 #include "../../toolkits/toolkits.h" 9 10 #include "../../EnumDefinitions/EnumDefinitions.h" -
issm/trunk/src/c/modules/Ll2xyx/Ll2xyx.cpp
r8715 r9761 5 5 #include "../../include/include.h" 6 6 #include "../../shared/shared.h" 7 #include "../../io/io.h" 7 8 #include <math.h> 8 9 -
issm/trunk/src/c/modules/Mergesolutionfromftogx/Mergesolutionfromftogx.cpp
r8809 r9761 4 4 5 5 #include "../VecMergex/VecMergex.h" 6 #include "../../io/io.h" 6 7 #include "./Mergesolutionfromftogx.h" 7 8 -
issm/trunk/src/c/modules/ModelProcessorx/CreateDataSets.cpp
r9340 r9761 67 67 break; 68 68 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_ 69 77 case ThermalAnalysisEnum: 70 78 CreateNodesThermal(pnodes, iomodel); … … 73 81 UpdateElementsThermal(elements,iomodel,analysis_counter,analysis_type); 74 82 break; 75 83 76 84 case EnthalpyAnalysisEnum: 77 85 CreateNodesEnthalpy(pnodes, iomodel); … … 81 89 break; 82 90 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 90 91 case MeltingAnalysisEnum: 91 92 CreateNodesMelting(pnodes, iomodel); … … 94 95 UpdateElementsMelting(elements,iomodel,analysis_counter,analysis_type); 95 96 break; 97 #endif 96 98 97 99 case PrognosticAnalysisEnum: … … 114 116 115 117 /*Update Elements and Materials For Control methods*/ 118 #ifdef _HAVE_CONTROL_ 116 119 UpdateElementsAndMaterialsControl(elements,materials,iomodel); 120 #endif 117 121 118 122 /*Generate objects that are not dependent on any analysis_type: */ -
issm/trunk/src/c/modules/ModelProcessorx/CreateParameters.cpp
r9725 r9761 2 2 * \brief general driver for creating parameters dataset 3 3 */ 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 4 11 5 12 #include "../../Container/Container.h" … … 93 100 94 101 /*Before returning, create parameters in case we are running Qmu or control types runs: */ 102 #ifdef _HAVE_CONTROL_ 95 103 CreateParametersControl(¶meters,iomodel,solution_type,analysis_type); 104 #endif 105 106 #ifdef _HAVE_DAKOTA_ 96 107 CreateParametersQmu(¶meters,iomodel,solution_type,analysis_type); 108 #endif 97 109 98 110 /*Go through all parameters, and convert units to SI: */ -
issm/trunk/src/c/modules/ModelProcessorx/ModelProcessorx.cpp
r9719 r9761 11 11 #include "../../objects/objects.h" 12 12 #include "../../shared/shared.h" 13 #include "../../io/io.h" 13 14 #include "../../Container/Container.h" 14 15 #include "../../EnumDefinitions/EnumDefinitions.h" -
issm/trunk/src/c/modules/Reduceloadx/Reduceloadx.cpp
r9320 r9761 10 10 11 11 #include "./Reduceloadx.h" 12 #include "../../io/io.h" 12 13 13 14 void Reduceloadx( Vec pf, Mat Kfs, Vec y_s,bool flag_ys0){ -
issm/trunk/src/c/modules/ResetConstraintsx/ResetConstraintsx.cpp
r9127 r9761 6 6 #include "../modules.h" 7 7 #include "../../shared/shared.h" 8 #include "../../io/io.h" 8 9 #include "../../include/include.h" 9 10 #include "../../toolkits/toolkits.h" -
issm/trunk/src/c/modules/Solverx/Solverx.cpp
r9320 r9761 6 6 #include "../../shared/shared.h" 7 7 #include "../../include/include.h" 8 #include "../../io/io.h" 8 9 9 10 #ifdef HAVE_CONFIG_H -
issm/trunk/src/c/modules/SystemMatricesx/SystemMatricesx.cpp
r9705 r9761 6 6 #include "../../shared/shared.h" 7 7 #include "../../include/include.h" 8 #include "../../io/io.h" 8 9 #include "../../toolkits/toolkits.h" 9 10 #include "../../EnumDefinitions/EnumDefinitions.h" -
issm/trunk/src/c/modules/UpdateConstraintsx/UpdateConstraintsx.cpp
r9285 r9761 8 8 #include "../../include/include.h" 9 9 #include "../../modules/modules.h" 10 #include "../../io/io.h" 10 11 #include "../../toolkits/toolkits.h" 11 12 #include "../../EnumDefinitions/EnumDefinitions.h" -
issm/trunk/src/c/modules/Xy2llx/Xy2llx.cpp
r8715 r9761 5 5 #include "../../include/include.h" 6 6 #include "../../shared/shared.h" 7 #include "../../io/io.h" 7 8 #include <math.h> 8 9 -
issm/trunk/src/c/objects/Bamg/include.h
r5130 r9761 6 6 #define _INCLUDE2_H_ 7 7 8 #include "../../include/macros.h" 8 9 #include "./macros.h" 9 10 #include "./typedefs.h" -
issm/trunk/src/c/objects/Contour.cpp
r9320 r9761 11 11 #include "./objects.h" 12 12 #include "../include/include.h" 13 #include "../ shared/Matlab/matlabshared.h"13 #include "../io/io.h" 14 14 15 15 void ContourEcho(Contour* contour){ -
issm/trunk/src/c/objects/Elements/Element.h
r9206 r9761 40 40 virtual void GetParameterListOnVertices(double* pvalue,int enumtype,double defaultvalue)=0; 41 41 virtual void GetParameterValue(double* pvalue,Node* node,int enumtype)=0; 42 #ifdef _HAVE_CONTROL_ 42 43 virtual void Gradj(Vec gradient,int control_type)=0; 43 44 virtual double ThicknessAbsMisfit(bool process_units ,int weight_index)=0; … … 50 51 virtual double RheologyBbarAbsGradient(bool process_units,int weight_index)=0; 51 52 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 52 58 virtual double SurfaceArea(void)=0; 53 59 virtual void InputDepthAverageAtBase(int enum_type,int average_enum_type,int object_enum)=0; … … 63 69 virtual void InputCreate(double scalar,int name,int code)=0; 64 70 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; 69 72 virtual void RequestedOutput(int output_enum,int step,double time)=0; 70 73 virtual void MinVel(double* pminvel, bool process_units)=0; … … 81 84 virtual void InputScale(int enum_type,double scale_factor)=0; 82 85 virtual void GetVectorFromInputs(Vec vector,int NameEnum)=0; 83 virtual void InputControlUpdate(double scalar,bool save_parameter)=0;84 86 virtual void InputArtificialNoise(int enum_type,double min,double max)=0; 85 87 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 524 524 } 525 525 /*}}}*/ 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 }/*}}}*/585 526 /*FUNCTION Penta::CreateDVectorDiagnosticHoriz {{{1*/ 586 527 ElementVector* Penta::CreateDVectorDiagnosticHoriz(void){ … … 658 599 Ke=CreateKMatrixBalancethickness(); 659 600 break; 601 #ifdef _HAVE_THERMAL_ 660 602 case ThermalAnalysisEnum: 661 603 Ke=CreateKMatrixThermal(); … … 667 609 Ke=CreateKMatrixMelting(); 668 610 break; 611 #endif 669 612 default: 670 613 _error_("analysis %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type)); … … 1817 1760 } 1818 1761 /*}}}*/ 1762 /*FUNCTION Penta::CreateKMatrixPrognostic {{{1*/ 1763 ElementMatrix* 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*/ 1784 ElementMatrix* 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_ 1819 1798 /*FUNCTION Penta::CreateKMatrixEnthalpy {{{1*/ 1820 1799 ElementMatrix* Penta::CreateKMatrixEnthalpy(void){ … … 2060 2039 } 2061 2040 /*}}}*/ 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 /*}}}*/2096 2041 /*FUNCTION Penta::CreateKMatrixThermal {{{1*/ 2097 2042 ElementMatrix* Penta::CreateKMatrixThermal(void){ … … 2317 2262 } 2318 2263 /*}}}*/ 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 penta2476 double dbasis[3][6]; //for the six nodes of the penta2477 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 penta2538 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 penta2621 double dbasis[3][6]; //for the six nodes of the penta2622 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 penta2683 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 it2879 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 surface2885 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 bubble2986 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 bubble2992 double Ke_temp[numdofbubble][3]={0.0}; //for the six nodes and the bubble2993 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 penta3064 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 equilibrium3097 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 /*}}}*/3265 2264 /*FUNCTION Penta::CreatePVectorEnthalpy {{{1*/ 3266 2265 ElementVector* Penta::CreatePVectorEnthalpy(void){ … … 3494 2493 } 3495 2494 /*}}}*/ 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 /*}}}*/3532 2495 /*FUNCTION Penta::CreatePVectorThermal {{{1*/ 3533 2496 ElementVector* Penta::CreatePVectorThermal(void){ … … 3756 2719 } 3757 2720 /*}}}*/ 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 tria3805 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) above3897 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'_eff4014 * = 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 solution4046 }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 elements4083 * (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 /*}}}*/4221 2721 /*FUNCTION Penta::GetSolutionFromInputsThermal{{{1*/ 4222 2722 void Penta::GetSolutionFromInputsThermal(Vec solution){ … … 4281 2781 } 4282 2782 /*}}}*/ 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*/ 2784 void 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*/ 2851 void 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*/ 2929 void Penta::ControlInputGetGradient(Vec gradient,int enum_type){ 4366 2930 4367 2931 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 4373 2944 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*/ 2949 void 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*/ 2965 void 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*/ 2988 ElementVector* 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*/ 3008 ElementVector* 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*/ 3022 ElementVector* 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*/ 3036 ElementVector* 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; 4396 3047 } 4397 3048 /*}}}*/ … … 4714 3365 this->matice->inputs->DeleteInput(MaterialsRheologyBbarEnum); 4715 3366 } /*}}}*/ 3367 /*FUNCTION Penta::InputControlUpdate{{{1*/ 3368 void 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*/ 3401 cleanup_and_return: 3402 xfree((void**)&control_type); 3403 } 3404 /*}}}*/ 3405 /*FUNCTION Penta::InputUpdateFromSolutionAdjointStokes {{{1*/ 3406 void 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*/ 3449 void 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*/ 3484 double 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*/ 3521 double 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*/ 3558 double 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*/ 3595 double 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*/ 3634 double 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*/ 3671 double Penta::ThicknessAbsGradient(bool process_units,int weight_index){ 3672 3673 _error_("Not implemented yet"); 3674 } 3675 /*}}}*/ 3676 /*FUNCTION Penta::ThicknessAbsMisfit {{{1*/ 3677 double 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*/ 3697 double 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*/ 3712 double 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*/ 3732 void 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*/ 3834 void 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*/ 3839 void Penta::InputUpdateFromVectorDakota(bool* vector, int name, int type){ 3840 _error_(" not supported yet!"); 3841 } 3842 /*}}}*/ 3843 #endif 3844 3845 /*FUNCTION Penta::CreatePVector {{{1*/ 3846 void 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*/ 3908 ElementVector* 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*/ 3930 ElementVector* 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*/ 3944 ElementVector* 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*/ 4003 ElementVector* 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*/ 4075 ElementVector* 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*/ 4089 ElementVector* 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*/ 4148 ElementVector* 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*/ 4220 ElementVector* 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*/ 4248 ElementVector* 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*/ 4262 ElementVector* 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*/ 4278 ElementVector* 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*/ 4294 ElementVector* 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*/ 4382 ElementVector* 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*/ 4396 ElementVector* 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*/ 4441 ElementVector* 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*/ 4455 ElementVector* 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*/ 4534 ElementVector* 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*/ 4599 ElementVector* 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*/ 4613 ElementVector* 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*/ 4669 ElementVector* 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*/ 4734 ElementVector* 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*/ 4756 ElementVector* 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*/ 4770 void 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*/ 4798 void 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 4808 void Penta::Echo(void){ 4809 this->DeepEcho(); 4810 } 4811 /*}}}*/ 4812 /*FUNCTION Penta::Enum {{{1*/ 4813 int Penta::Enum(void){ 4814 4815 return PentaEnum; 4816 4817 } 4818 /*}}}*/ 4819 /*FUNCTION Penta::GetBasalElement{{{1*/ 4820 Penta* 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*/ 4841 void 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*/ 4865 void 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*/ 4873 int Penta::GetElementType(){ 4874 4875 /*return PentaRef field*/ 4876 return this->element_type; 4877 } 4878 /*}}}*/ 4879 /*FUNCTION Penta::GetHorizontalNeighboorSids {{{1*/ 4880 int* Penta::GetHorizontalNeighboorSids(){ 4881 4882 /*return PentaRef field*/ 4883 return &this->horizontalneighborsids[0]; 4884 4885 } 4886 /*}}}*/ 4887 /*FUNCTION Penta::GetLowerElement{{{1*/ 4888 Penta* 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*/ 4898 int 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*/ 4910 void 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*/ 4935 void 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*/ 4964 void 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*/ 4977 void 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*/ 5015 void 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*/ 5023 void 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*/ 5064 void 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*/ 5106 void 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*/ 5142 void 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*/ 5175 void 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*/ 5220 double 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*/ 5236 void 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*/ 5265 void 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*/ 5291 Penta* 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*/ 5301 void 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*/ 5320 double 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 /*}}}*/ 4716 5334 /*FUNCTION Penta::Sid {{{1*/ 4717 5335 int Penta::Sid(){ … … 4769 5387 /*Return output*/ 4770 5388 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);4809 5389 } 4810 5390 /*}}}*/ … … 5105 5685 * object out of the input, with the additional step and time information: */ 5106 5686 this->results->AddObject((Object*)input->SpawnResult(step,time)); 5687 #ifdef _HAVE_CONTROL_ 5107 5688 if(input->Enum()==ControlInputEnum) this->results->AddObject((Object*)((ControlInput*)input)->SpawnGradient(step,time)); 5689 #endif 5108 5690 5109 5691 } … … 5169 5751 5170 5752 /*Control Inputs*/ 5753 #ifdef _HAVE_CONTROL_ 5171 5754 if (control_analysis && iomodel->Data(InversionControlParametersEnum)){ 5172 5755 for(i=0;i<num_control_type;i++){ … … 5211 5794 } 5212 5795 } 5796 #endif 5213 5797 5214 5798 //Need to know the type of approximation for this element … … 5276 5860 InputUpdateFromSolutionDiagnosticVert( solution); 5277 5861 } 5862 #ifdef _HAVE_CONTROL_ 5278 5863 else if (analysis_type==AdjointHorizAnalysisEnum){ 5279 5864 int approximation; … … 5286 5871 } 5287 5872 } 5873 #endif 5288 5874 else if (analysis_type==BedSlopeXAnalysisEnum){ 5289 5875 InputUpdateFromSolutionOneDofCollapsed(solution,BedSlopeXEnum); … … 5304 5890 InputUpdateFromSolutionOneDofCollapsed(solution,ThicknessEnum); 5305 5891 } 5892 #ifdef _HAVE_THERMAL_ 5306 5893 else if (analysis_type==ThermalAnalysisEnum){ 5307 5894 InputUpdateFromSolutionThermal( solution); … … 5313 5900 InputUpdateFromSolutionOneDof(solution,BasalforcingsMeltingRateEnum); 5314 5901 } 5902 #endif 5315 5903 else{ 5316 5904 _error_("analysis %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type)); … … 6050 6638 } 6051 6639 /*}}}*/ 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 /*}}}*/6130 6640 /*FUNCTION Penta::InputUpdateFromSolutionPrognostic{{{1*/ 6131 6641 void Penta::InputUpdateFromSolutionPrognostic(double* solution){ … … 6213 6723 } 6214 6724 /*}}}*/ 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 point6250 * 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 point6325 * 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 /*}}}*/6357 6725 /*FUNCTION Penta::InputUpdateFromSolutionOneDof{{{1*/ 6358 6726 void Penta::InputUpdateFromSolutionOneDof(double* solution,int enum_type){ … … 6456 6824 /*FUNCTION Penta::InputUpdateFromVector(bool* vector, int name, int type);{{{1*/ 6457 6825 void 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 else6516 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 else6537 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){6570 6826 _error_(" not supported yet!"); 6571 6827 } … … 7089 7345 } 7090 7346 /*}}}*/ 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 tria7101 J=tria->RheologyBbarAbsGradient(process_units,weight_index);7102 delete tria->matice; delete tria;7103 return J;7104 }7105 /*}}}*/7106 7347 /*FUNCTION Penta::SetClone {{{1*/ 7107 7348 void Penta::SetClone(int* minranks){ … … 7206 7447 } 7207 7448 /*}}}*/ 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 surface7223 * -> 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 surface7260 * -> 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 surface7297 * -> 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 surface7336 * -> 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 /*}}}*/7358 7449 /*FUNCTION Penta::SurfaceNormal {{{1*/ 7359 7450 void Penta::SurfaceNormal(double* surface_normal, double xyz_list[3][3]){ … … 7378 7469 *(surface_normal+1)=normal[1]/normal_norm; 7379 7470 *(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 surface7397 * -> 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");7423 7471 } 7424 7472 /*}}}*/ … … 7467 7515 return dt; 7468 7516 } 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 /*}}}*/7489 7517 /*FUNCTION Penta::Update(int index,IoModel* iomodel,int analysis_counter,int analysis_type) {{{1*/ 7490 7518 void Penta::Update(int index,IoModel* iomodel,int analysis_counter,int analysis_type){ -
issm/trunk/src/c/objects/Elements/Penta.h
r9733 r9761 68 68 void InputUpdateFromVector(double* vector, int name, int type); 69 69 void InputUpdateFromVector(int* vector, int name, int type); 70 #ifdef _HAVE_DAKOTA_ 70 71 void InputUpdateFromVectorDakota(bool* vector, int name, int type); 71 72 void InputUpdateFromVectorDakota(double* vector, int name, int type); 72 73 void InputUpdateFromVectorDakota(int* vector, int name, int type); 74 #endif 73 75 void InputUpdateFromIoModel(int index, IoModel* iomodel); 74 76 /*}}}*/ … … 83 85 void CreatePVector(Vec pf); 84 86 void DeleteResults(void); 85 double DragCoefficientAbsGradient(bool process_units,int weight_index);86 87 int GetNodeIndex(Node* node); 87 88 void GetSolutionFromInputs(Vec solution); 88 89 double GetZcoord(GaussPenta* gauss); 89 90 void GetVectorFromInputs(Vec vector,int NameEnum); 91 #ifdef _HAVE_CONTROL_ 92 double DragCoefficientAbsGradient(bool process_units,int weight_index); 90 93 void Gradj(Vec gradient,int control_type); 91 94 void GradjDragMacAyeal(Vec gradient); … … 95 98 void GradjBbarPattyn(Vec gradient); 96 99 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 97 113 int Sid(); 98 114 void InputArtificialNoise(int enum_type,double min, double max); 99 void InputControlUpdate(double scalar,bool save_parameter);100 115 bool InputConvergence(double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums); 101 116 void InputCreate(double scalar,int name,int code); … … 104 119 void InputDuplicate(int original_enum,int new_enum); 105 120 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 109 122 void InputToResult(int enum_type,int step,double time); 110 123 double MassFlux(double* segment,bool process_units); … … 120 133 void PotentialSheetUngrounding(Vec potential_sheet_ungrounding); 121 134 void ShelfSync(); 122 double RheologyBbarAbsGradient(bool process_units,int weight_index);123 135 void RequestedOutput(int output_enum,int step,double time); 124 double ThicknessAbsGradient(bool process_units,int weight_index);125 136 void MigrateGroundingLine(); 126 137 void MinVel(double* pminvel, bool process_units); … … 128 139 void MinVy(double* pminvy, bool process_units); 129 140 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);136 141 void PatchFill(int* pcount, Patch* patch); 137 142 void PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes); -
issm/trunk/src/c/objects/Elements/Tria.cpp
r9740 r9761 1250 1250 pe=CreatePVectorDiagnosticMacAyeal(); 1251 1251 break; 1252 case AdjointHorizAnalysisEnum:1253 pe=CreatePVectorAdjointHoriz();1254 break;1255 1252 case DiagnosticHutterAnalysisEnum: 1256 1253 pe=CreatePVectorDiagnosticHutter(); … … 1268 1265 pe=CreatePVectorBalancethickness(); 1269 1266 break; 1267 #ifdef _HAVE_CONTROL_ 1270 1268 case AdjointBalancethicknessAnalysisEnum: 1271 1269 pe=CreatePVectorAdjointBalancethickness(); 1272 1270 break; 1271 case AdjointHorizAnalysisEnum: 1272 pe=CreatePVectorAdjointHoriz(); 1273 break; 1274 #endif 1273 1275 default: 1274 1276 _error_("analysis %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type)); … … 1431 1433 delete gauss; 1432 1434 return pe; 1435 } 1436 /*}}}*/ 1437 /*FUNCTION Tria::CreatePVectorDiagnosticHutter{{{1*/ 1438 ElementVector* 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*/ 1488 ElementVector* 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*/ 1501 ElementVector* 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*/ 1547 ElementVector* 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*/ 1595 ElementVector* 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*/ 1640 ElementVector* 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*/ 1693 void Tria::ComputeBasalStress(Vec eps){ 1694 _error_("Not Implemented yet"); 1695 } 1696 /*}}}*/ 1697 /*FUNCTION Tria::ComputeStrainRate {{{1*/ 1698 void Tria::ComputeStrainRate(Vec eps){ 1699 _error_("Not Implemented yet"); 1700 } 1701 /*}}}*/ 1702 /*FUNCTION Tria::Configure {{{1*/ 1703 void 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*/ 1733 void 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*/ 1768 void 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*/ 1777 void 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*/ 1809 int Tria::Enum(void){ 1810 1811 return TriaEnum; 1812 1813 } 1814 /*}}}*/ 1815 /*FUNCTION Tria::GetArea {{{1*/ 1816 double 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*/ 1832 void 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*/ 1855 void 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*/ 1863 int Tria::GetElementType(){ 1864 1865 /*return TriaRef field*/ 1866 return this->element_type; 1867 1868 } 1869 /*}}}*/ 1870 /*FUNCTION Tria::GetHorizontalNeighboorSids {{{1*/ 1871 int* Tria::GetHorizontalNeighboorSids(){ 1872 1873 /*return TriaRef field*/ 1874 return &this->horizontalneighborsids[0]; 1875 1876 } 1877 /*}}}*/ 1878 /*FUNCTION Tria::GetNodeIndex {{{1*/ 1879 int 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*/ 1890 void 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*/ 1915 void 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*/ 1941 void 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*/ 1967 void 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*/ 1980 void 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*/ 1988 void 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*/ 2007 void 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*/ 2046 void 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*/ 2085 void 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*/ 2121 void 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*/ 2143 void 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*/ 2162 int Tria::Id(){ 2163 2164 return id; 2165 2166 } 2167 /*}}}*/ 2168 /*FUNCTION Tria::Sid {{{1*/ 2169 int Tria::Sid(){ 2170 2171 return sid; 2172 2173 } 2174 /*}}}*/ 2175 /*FUNCTION Tria::InputArtificialNoise{{{1*/ 2176 void 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*/ 2191 void 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*/ 2226 void 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*/ 2245 void 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*/ 2261 void 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*/ 2285 void 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*/ 2344 void 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*/ 2384 void 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*/ 2441 void 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*/ 2528 void 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*/ 2572 void 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*/ 2589 void 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*/ 2632 void 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*/ 2674 double 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*/ 2718 double 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*/ 2779 double 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*/ 2844 double 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*/ 2910 double 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*/ 2971 double 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*/ 3035 double 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*/ 3079 double 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; 1433 3121 } 1434 3122 /*}}}*/ … … 1854 3542 } 1855 3543 /*}}}*/ 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 respective2132 * 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 /*}}}*/2254 3544 /*FUNCTION Tria::DragCoefficientAbsGradient{{{1*/ 2255 3545 double Tria::DragCoefficientAbsGradient(bool process_units,int weight_index){ … … 2296 3586 } 2297 3587 /*}}}*/ 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 3134 3590 /*FUNCTION Tria::InputConvergence{{{1*/ 3135 3591 bool Tria::InputConvergence(double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums){ … … 3226 3682 * object out of the input, with the additional step and time information: */ 3227 3683 this->results->AddObject((Object*)input->SpawnResult(step,time)); 3684 #ifdef _HAVE_CONTROL_ 3228 3685 if(input->Enum()==ControlInputEnum) this->results->AddObject((Object*)((ControlInput*)input)->SpawnGradient(step,time)); 3686 #endif 3229 3687 } 3230 3688 /*}}}*/ … … 3282 3740 3283 3741 /*Control Inputs*/ 3742 #ifdef _HAVE_CONTROL_ 3284 3743 if (control_analysis && iomodel->Data(InversionControlParametersEnum)){ 3285 3744 for(i=0;i<num_control_type;i++){ … … 3324 3783 } 3325 3784 } 3785 #endif 3326 3786 3327 3787 /*DatasetInputs*/ … … 3355 3815 InputUpdateFromSolutionDiagnosticHoriz( solution); 3356 3816 break; 3817 #ifdef _HAVE_CONTROL_ 3357 3818 case AdjointHorizAnalysisEnum: 3358 3819 InputUpdateFromSolutionAdjointHoriz( solution); 3359 3820 break; 3821 case AdjointBalancethicknessAnalysisEnum: 3822 InputUpdateFromSolutionAdjointBalancethickness( solution); 3823 break; 3824 #endif 3360 3825 case BedSlopeXAnalysisEnum: 3361 3826 InputUpdateFromSolutionOneDof(solution,BedSlopeXEnum); … … 3379 3844 InputUpdateFromSolutionOneDof(solution,ThicknessEnum); 3380 3845 break; 3381 case AdjointBalancethicknessAnalysisEnum:3382 InputUpdateFromSolutionAdjointBalancethickness( solution);3383 break;3384 3846 default: 3385 3847 _error_("analysis %i (%s) not supported yet",analysis_type,EnumToStringx(analysis_type)); 3386 3848 } 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);3451 3849 } 3452 3850 /*}}}*/ … … 3751 4149 } 3752 4150 /*}}}*/ 4151 4152 4153 #ifdef _HAVE_DAKOTA_ 3753 4154 /*FUNCTION Tria::InputUpdateFromVectorDakota(double* vector, int name, int type);{{{1*/ 3754 4155 void Tria::InputUpdateFromVectorDakota(double* vector, int name, int type){ … … 3863 4264 } 3864 4265 /*}}}*/ 4266 #endif 3865 4267 /*FUNCTION Tria::InputCreate(double scalar,int enum,int code);{{{1*/ 3866 4268 void Tria::InputCreate(double scalar,int name,int code){ … … 4480 4882 } 4481 4883 /*}}}*/ 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 /*}}}*/4526 4884 /*FUNCTION Tria::RequestedOutput{{{1*/ 4527 4885 void Tria::RequestedOutput(int output_enum,int step,double time){ … … 4698 5056 } 4699 5057 /*}}}*/ 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 /*}}}*/4761 5058 /*FUNCTION Tria::SurfaceArea {{{1*/ 4762 5059 double Tria::SurfaceArea(void){ … … 4788 5085 } 4789 5086 /*}}}*/ 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 24835 * J = --- sqrt( (u - u ) + (v - v ) )4836 * S obs obs4837 */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 ] 24897 * J = 4 \bar{v}^2 | log ( ----------- ) |4898 * [ vel + eps ]4899 * obs4900 */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 obs4966 */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 /*}}}*/4982 5087 /*FUNCTION Tria::SurfaceNormal{{{1*/ 4983 5088 void Tria::SurfaceNormal(double* surface_normal, double xyz_list[3][3]){ … … 5002 5107 *(surface_normal+1)=normal[1]/normal_norm; 5003 5108 *(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 obs5055 */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;5157 5109 } 5158 5110 /*}}}*/ -
issm/trunk/src/c/objects/Elements/Tria.h
r9733 r9761 62 62 void InputUpdateFromVector(int* vector, int name, int type); 63 63 void InputUpdateFromVector(bool* vector, int name, int type); 64 #ifdef _HAVE_DAKOTA_ 64 65 void InputUpdateFromVectorDakota(double* vector, int name, int type); 65 66 void InputUpdateFromVectorDakota(int* vector, int name, int type); 66 67 void InputUpdateFromVectorDakota(bool* vector, int name, int type); 68 #endif 67 69 void InputUpdateFromConstant(double constant, int name); 68 70 void InputUpdateFromConstant(int constant, int name); … … 78 80 void CreateKMatrix(Mat Kff, Mat Kfs,Vec df); 79 81 void CreatePVector(Vec pf); 80 double DragCoefficientAbsGradient(bool process_units,int weight_index);81 82 int GetNodeIndex(Node* node); 82 83 int Sid(); … … 88 89 void GetSolutionFromInputs(Vec solution); 89 90 void GetVectorFromInputs(Vec vector,int NameEnum); 91 #ifdef _HAVE_CONTROL_ 92 double DragCoefficientAbsGradient(bool process_units,int weight_index); 90 93 void Gradj(Vec gradient,int control_type); 91 94 void GradjBGradient(Vec gradient,int weight_index); … … 97 100 void GradjVxBalancedthickness(Vec gradient); 98 101 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 99 116 void InputArtificialNoise(int enum_type,double min, double max); 100 void InputControlUpdate(double scalar,bool save_parameter);101 117 bool InputConvergence(double* eps, int* enums,int num_enums,int* criterionenums,double* criterionvalues,int num_criterionenums); 102 118 void InputCreate(double scalar,int name,int code); … … 105 121 void InputDuplicate(int original_enum,int new_enum); 106 122 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); 111 124 void DeleteResults(void); 112 125 void MaterialUpdateFromTemperature(void){_error_("not implemented yet");}; … … 129 142 void MinVz(double* pminvz, bool process_units); 130 143 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);139 144 void PatchFill(int* pcount, Patch* patch); 140 145 void PatchSize(int* pnumrows, int* pnumvertices,int* pnumnodes); -
issm/trunk/src/c/objects/ExternalResults/PetscVecExternalResult.cpp
r9320 r9761 206 206 char *name = NULL; 207 207 double *serialvec = NULL; 208 extern int my_rank; 208 209 209 210 /*serialize: */ -
issm/trunk/src/c/objects/FemModel.cpp
r9320 r9761 13 13 #include "../Container/Container.h" 14 14 #include "../modules/ModelProcessorx/ModelProcessorx.h" 15 #include "../io/io.h" 15 16 #include "./objects.h" 16 17 #include "../include/include.h" … … 27 28 int analysis_type; 28 29 FILE* IOMODEL; 30 extern int my_rank; 29 31 30 32 /*Open input file on cpu 0: */ -
issm/trunk/src/c/objects/IoModel.cpp
r9725 r9761 16 16 17 17 #include "./objects.h" 18 #include "../io/io.h" 18 19 #include "./Container/Parameters.h" 19 20 #include "../shared/shared.h" -
issm/trunk/src/c/objects/KML/KMLFileReadUtils.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_Attribute.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_ColorStyle.cpp
r9320 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_Container.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_Document.cpp
r9320 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_Feature.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_File.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_Folder.cpp
r9320 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_GroundOverlay.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_Icon.cpp
r9320 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_LatLonBox.cpp
r9320 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_LineString.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_LineStyle.cpp
r9320 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_LinearRing.cpp
r9336 r9761 17 17 #include "../../Container/Container.h" 18 18 #include "../../include/include.h" 19 #include "../../io/io.h" 19 20 #include "../../modules/Ll2xyx/Ll2xyx.h" 20 21 /*}}}*/ -
issm/trunk/src/c/objects/KML/KML_MultiGeometry.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_Object.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_Overlay.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_Placemark.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_PolyStyle.cpp
r9320 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_Polygon.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/KML/KML_Style.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/Materials/Matice.cpp
r9733 r9761 686 686 687 687 /*Control Inputs*/ 688 #ifdef _HAVE_CONTROL_ 688 689 if (control_analysis && iomodel->Data(InversionControlParametersEnum)){ 689 690 for(i=0;i<num_control_type;i++){ … … 701 702 } 702 703 } 704 #endif 703 705 } 704 706 … … 725 727 726 728 /*Control Inputs*/ 729 #ifdef _HAVE_CONTROL_ 727 730 if (control_analysis && iomodel->Data(InversionControlParametersEnum)){ 728 731 for(i=0;i<num_control_type;i++){ … … 740 743 } 741 744 } 745 #endif 742 746 } 743 747 else{ -
issm/trunk/src/c/objects/Options/Option.cpp
r9320 r9761 16 16 #include "../../shared/shared.h" 17 17 #include "../../Container/Container.h" 18 #include "../../io/io.h" 18 19 #include "../../include/include.h" 19 20 /*}}}*/ -
issm/trunk/src/c/objects/Options/OptionCell.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/Options/OptionChar.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/Options/OptionDouble.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/Options/OptionLogical.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/Options/OptionStruct.cpp
r9336 r9761 15 15 #include "../objects.h" 16 16 #include "../../shared/shared.h" 17 #include "../../io/io.h" 17 18 #include "../../Container/Container.h" 18 19 #include "../../include/include.h" -
issm/trunk/src/c/objects/Update.h
r6216 r9761 17 17 virtual void InputUpdateFromVector(double* vector, int name, int type)=0; 18 18 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_ 20 21 virtual void InputUpdateFromVectorDakota(double* vector, int name, int type)=0; 21 22 virtual void InputUpdateFromVectorDakota(int* vector, int name, int type)=0; 22 23 virtual void InputUpdateFromVectorDakota(bool* vector, int name, int type)=0; 24 #endif 23 25 virtual void InputUpdateFromConstant(double constant, int name)=0; 24 26 virtual void InputUpdateFromConstant(int constant, int name)=0; -
issm/trunk/src/c/shared/Exceptions/Exceptions.cpp
r9388 r9761 8 8 #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!" 9 9 #endif 10 10 11 #include "../shared.h" 11 12 #include "../../include/include.h" -
issm/trunk/src/c/shared/Matlab/matlabshared.h
r8 r9761 8 8 #include "../../objects/objects.h" 9 9 10 /*printf: */11 int PrintfFunction(char* format,...);12 int ModuleBoot(void);13 10 14 11 #ifdef _SERIAL_ 15 12 #include "mex.h" 13 int ModuleBoot(void); 16 14 mxArray* mxGetAssignedField(const mxArray* pmxa_array,int number, char* field); 17 15 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 14 14 #include <float.h> /* DBL_EPSILON */ 15 15 #include "../../include/include.h" 16 #include "../../io/io.h" 16 17 /*}}}*/ 17 18 -
issm/trunk/src/c/shared/Numerics/BrentSearch.cpp
r9563 r9761 12 12 #include "../../objects/objects.h" 13 13 #include "../../include/include.h" 14 #include "../../io/io.h" 14 15 #include "../../shared/shared.h" 15 16 #include <float.h> -
issm/trunk/src/c/shared/Numerics/GaussPoints.cpp
r6412 r9761 5 5 #include "../Alloc/alloc.h" 6 6 #include "../../include/include.h" 7 #include "../../io/io.h" 7 8 #include "../Exceptions/exceptions.h" 8 9 #include <math.h> -
issm/trunk/src/c/shared/Numerics/OptimalSearch.cpp
r9563 r9761 11 11 #include "./numerics.h" 12 12 #include "../../objects/objects.h" 13 #include "../../io/io.h" 13 14 #include "../../include/include.h" 14 15 #include "../../shared/shared.h" -
issm/trunk/src/c/shared/shared.h
r6273 r9761 6 6 #define _SHARED_H_ 7 7 8 8 9 #include "Alloc/alloc.h" 9 #include "Matlab/matlabshared.h"10 10 #include "Exceptions/exceptions.h" 11 11 #include "Exp/exp.h" … … 16 16 #include "Numerics/numerics.h" 17 17 #include "Dofs/dofs.h" 18 #include "String/sharedstring.h" //to avoid confusion with <string.h> standard header file19 18 #include "Threads/issm_threads.h" 20 19 #include "Bamg/shared.h" 20 #include "Matlab/matlabshared.h" 21 21 22 22 #endif -
issm/trunk/src/c/solutions/CorePointerFromSolutionEnum.cpp
r9725 r9761 20 20 void CorePointerFromSolutionEnum(void (**psolutioncore)(FemModel*),Parameters* parameters,int solutiontype){ 21 21 22 /*intermediary: */23 bool control_analysis=false;24 bool dakota_analysis=false;25 26 22 /*output: */ 27 23 void (*solutioncore)(FemModel*)=NULL; 28 29 /*retrieve some parameters: */30 parameters->FindParam(&control_analysis,InversionIscontrolEnum);31 parameters->FindParam(&dakota_analysis,QmuIsdakotaEnum);32 24 33 25 switch(solutiontype){ … … 40 32 break; 41 33 case ThermalSolutionEnum: 34 #ifdef _HAVE_THERMAL_ 42 35 solutioncore=&thermal_core; 36 #else 37 _error_("ISSM was not compiled with thermal capabilities. Exiting"); 38 #endif 43 39 break; 44 40 case EnthalpySolutionEnum: 41 #ifdef _HAVE_THERMAL_ 45 42 solutioncore=&enthalpy_core; 43 #else 44 _error_("ISSM was not compiled with thermal capabilities. Exiting"); 45 #endif 46 46 break; 47 47 case PrognosticSolutionEnum: -
issm/trunk/src/c/solutions/ResetBoundaryConditions.cpp
r9298 r9761 5 5 #include "../objects/objects.h" 6 6 #include "../modules/modules.h" 7 #include "../io/io.h" 7 8 #include "../EnumDefinitions/EnumDefinitions.h" 8 9 -
issm/trunk/src/c/solutions/adjointbalancethickness_core.cpp
r9681 r9761 6 6 #include "../objects/objects.h" 7 7 #include "../shared/shared.h" 8 #include "../io/io.h" 8 9 #include "../EnumDefinitions/EnumDefinitions.h" 9 10 #include "./solutions.h" -
issm/trunk/src/c/solutions/adjointdiagnostic_core.cpp
r9681 r9761 6 6 #include "../objects/objects.h" 7 7 #include "../shared/shared.h" 8 #include "../io/io.h" 8 9 #include "../EnumDefinitions/EnumDefinitions.h" 9 10 #include "./solutions.h" -
issm/trunk/src/c/solutions/balancethickness_core.cpp
r9719 r9761 6 6 #include "../objects/objects.h" 7 7 #include "../shared/shared.h" 8 #include "../io/io.h" 8 9 #include "../include/include.h" 9 10 #include "../EnumDefinitions/EnumDefinitions.h" -
issm/trunk/src/c/solutions/bedslope_core.cpp
r9719 r9761 6 6 #include "../toolkits/toolkits.h" 7 7 #include "../objects/objects.h" 8 #include "../io/io.h" 8 9 #include "../EnumDefinitions/EnumDefinitions.h" 9 10 #include "../modules/modules.h" -
issm/trunk/src/c/solutions/control_core.cpp
r9719 r9761 6 6 #include "../objects/objects.h" 7 7 #include "../shared/shared.h" 8 #include "../io/io.h" 8 9 #include "../EnumDefinitions/EnumDefinitions.h" 9 10 #include "./solutions.h" -
issm/trunk/src/c/solutions/controlconvergence.cpp
r9320 r9761 10 10 #include "../objects/objects.h" 11 11 #include "../shared/shared.h" 12 #include "../io/io.h" 12 13 #include "../Container/Container.h" 13 14 #include "../EnumDefinitions/EnumDefinitions.h" -
issm/trunk/src/c/solutions/controltao_core.cpp
r9681 r9761 2 2 * \brief: core of the control solution 3 3 */ 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 5 14 6 15 #ifdef _HAVE_TAO_ -
issm/trunk/src/c/solutions/convergence.cpp
r9679 r9761 5 5 #include "../objects/objects.h" 6 6 #include "../modules/modules.h" 7 #include "../io/io.h" 7 8 #include "../EnumDefinitions/EnumDefinitions.h" 8 9 -
issm/trunk/src/c/solutions/diagnostic_core.cpp
r9719 r9761 6 6 #include "../objects/objects.h" 7 7 #include "../shared/shared.h" 8 #include "../io/io.h" 8 9 #include "../EnumDefinitions/EnumDefinitions.h" 9 10 #include "./solutions.h" -
issm/trunk/src/c/solutions/enthalpy_core.cpp
r9681 r9761 10 10 #include "../modules/modules.h" 11 11 #include "../include/include.h" 12 #include "../io/io.h" 12 13 #include "../solvers/solvers.h" 13 14 -
issm/trunk/src/c/solutions/gradient_core.cpp
r9681 r9761 6 6 #include "../objects/objects.h" 7 7 #include "../shared/shared.h" 8 #include "../io/io.h" 8 9 #include "../EnumDefinitions/EnumDefinitions.h" 9 10 #include "./solutions.h" -
issm/trunk/src/c/solutions/groundinglinemigration2d_core.cpp
r9725 r9761 6 6 #include "../objects/objects.h" 7 7 #include "../shared/shared.h" 8 #include "../io/io.h" 8 9 #include "../EnumDefinitions/EnumDefinitions.h" 9 10 #include "./solutions.h" -
issm/trunk/src/c/solutions/hydrology_core.cpp
r9681 r9761 6 6 #include "../objects/objects.h" 7 7 #include "../shared/shared.h" 8 #include "../io/io.h" 8 9 #include "../EnumDefinitions/EnumDefinitions.h" 9 10 #include "./solutions.h" -
issm/trunk/src/c/solutions/hydrology_core_step.cpp
r9291 r9761 6 6 #include "../objects/objects.h" 7 7 #include "../shared/shared.h" 8 #include "../io/io.h" 8 9 #include "../EnumDefinitions/EnumDefinitions.h" 9 10 #include "./solutions.h" -
issm/trunk/src/c/solutions/issm.cpp
r9702 r9761 3 3 */ 4 4 5 #include "./issm.h" 5 #include "../issm.h" 6 #include "../include/globals.h" 6 7 7 8 int main(int argc,char **argv){ … … 97 98 MPI_Barrier(MPI_COMM_WORLD); start_core=MPI_Wtime( ); 98 99 if(dakota_analysis){ 100 #ifdef _HAVE_DAKOTA_ 99 101 Dakotax(femmodel); 102 #else 103 _error_("ISSM was not compiled with dakota support, cannot carry out dakota analysis!"); 104 #endif 100 105 } 101 106 else if(control_analysis){ 107 #ifdef _HAVE_CONTROL_ 102 108 #ifdef _HAVE_TAO_ 103 //controltao_core(femmodel); 104 control_core(femmodel); 109 controltao_core(femmodel); 105 110 #else 106 111 control_core(femmodel); 112 #endif 113 #else 114 _error_("ISSM was not compiled with control support, cannot carry out dakota analysis!"); 107 115 #endif 108 116 } -
issm/trunk/src/c/solutions/prognostic_core.cpp
r9681 r9761 6 6 #include "../objects/objects.h" 7 7 #include "../shared/shared.h" 8 #include "../io/io.h" 8 9 #include "../EnumDefinitions/EnumDefinitions.h" 9 10 #include "./solutions.h" -
issm/trunk/src/c/solutions/steadystate_core.cpp
r9719 r9761 3 3 */ 4 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 5 11 #include "../toolkits/toolkits.h" 6 12 #include "../objects/objects.h" 7 13 #include "../shared/shared.h" 14 #include "../io/io.h" 8 15 #include "../EnumDefinitions/EnumDefinitions.h" 9 16 #include "./solutions.h" … … 39 46 40 47 _printf_(VerboseSolution(),"%s%i\n"," computing temperature and velocity for step: ",step); 48 #ifdef _HAVE_THERMAL_ 41 49 thermal_core(femmodel); 50 #else 51 _error_("ISSM was not compiled with thermal capabilities. Exiting"); 52 #endif 42 53 43 54 _printf_(VerboseSolution(),"%s\n"," computing new velocity"); -
issm/trunk/src/c/solutions/surfaceslope_core.cpp
r9719 r9761 6 6 #include "../toolkits/toolkits.h" 7 7 #include "../objects/objects.h" 8 #include "../io/io.h" 8 9 #include "../EnumDefinitions/EnumDefinitions.h" 9 10 #include "../solvers/solvers.h" -
issm/trunk/src/c/solutions/thermal_core.cpp
r9681 r9761 6 6 #include "../objects/objects.h" 7 7 #include "../shared/shared.h" 8 #include "../io/io.h" 8 9 #include "../EnumDefinitions/EnumDefinitions.h" 9 10 #include "./solutions.h" -
issm/trunk/src/c/solutions/thermal_core_step.cpp
r6412 r9761 6 6 #include "../objects/objects.h" 7 7 #include "../shared/shared.h" 8 #include "../io/io.h" 8 9 #include "../EnumDefinitions/EnumDefinitions.h" 9 10 #include "./solutions.h" -
issm/trunk/src/c/solutions/transient_core.cpp
r9719 r9761 3 3 */ 4 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 5 11 #include "../toolkits/toolkits.h" 6 12 #include "../objects/objects.h" 7 13 #include "../shared/shared.h" 14 #include "../io/io.h" 8 15 #include "../EnumDefinitions/EnumDefinitions.h" 9 16 #include "./solutions.h" … … 65 72 if(isthermal && dim==3){ 66 73 _printf_(VerboseSolution()," computing temperatures:\n"); 74 #ifdef _HAVE_THERMAL_ 67 75 thermal_core_step(femmodel,step,time); 76 #else 77 _error_("ISSM was not compiled with thermal capabilities. Exiting"); 78 #endif 68 79 } 69 80 -
issm/trunk/src/c/solvers/solver_nonlinear.cpp
r9679 r9761 5 5 #include "../toolkits/toolkits.h" 6 6 #include "../objects/objects.h" 7 #include "../io/io.h" 7 8 #include "../EnumDefinitions/EnumDefinitions.h" 8 9 #include "../modules/modules.h" -
issm/trunk/src/c/solvers/solver_stokescoupling_nonlinear.cpp
r9679 r9761 6 6 #include "../objects/objects.h" 7 7 #include "../EnumDefinitions/EnumDefinitions.h" 8 #include "../io/io.h" 8 9 #include "../modules/modules.h" 9 10 #include "../solutions/solutions.h" -
issm/trunk/src/c/solvers/solver_thermal_nonlinear.cpp
r9632 r9761 5 5 #include "../toolkits/toolkits.h" 6 6 #include "../objects/objects.h" 7 #include "../io/io.h" 7 8 #include "../EnumDefinitions/EnumDefinitions.h" 8 9 #include "../modules/modules.h"
Note:
See TracChangeset
for help on using the changeset viewer.