[cig-commits] commit: Rename .c -> .cxx and make configure automatically use c++
Mercurial
hg at geodynamics.org
Thu May 12 11:21:48 PDT 2011
changeset: 784:46408d74ad35
tag: tip
user: Walter Landry <wlandry at caltech.edu>
date: Thu May 12 11:19:05 2011 -0700
files: Apps/EnergySolver/tests/AdvDiffSteadyState1D/AdvDiffSteadyState1D.c Apps/EnergySolver/tests/AdvDiffSteadyState1D/AdvDiffSteadyState1D.cxx Apps/EnergySolver/tests/CosineHillRotate/CosineHillRotate.c Apps/EnergySolver/tests/CosineHillRotate/CosineHillRotate.cxx Apps/EnergySolver/tests/HomogeneousEssentialBCs/HomogeneousEssentialBCs.c Apps/EnergySolver/tests/HomogeneousEssentialBCs/HomogeneousEssentialBCs.cxx Apps/EnergySolver/tests/HomogeneousNaturalBCs/HomogeneousNaturalBCs.c Apps/EnergySolver/tests/HomogeneousNaturalBCs/HomogeneousNaturalBCs.cxx Apps/StokesMomentumUzawa/tests/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.c Apps/StokesMomentumUzawa/tests/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.cxx Apps/StokesMomentumUzawa/tests/LidDrivenStokesAnalytic/LidDrivenStokesAnalytic.c Apps/StokesMomentumUzawa/tests/LidDrivenStokesAnalytic/LidDrivenStokesAnalytic.cxx Apps/StokesMomentumUzawa/tests/LinearVelocityAnalytic/LinearVelocityAnalytic.c Apps/StokesMomentumUzawa/tests/LinearVelocityAnalytic/LinearVelocityAnalytic.cxx Apps/StokesMomentumUzawa/tests/SimpleShearAnalytic/SimpleShearAnalytic.c Apps/StokesMomentumUzawa/tests/SimpleShearAnalytic/SimpleShearAnalytic.cxx Apps/TempDiffusion/tests/LinearTemperatureField/LinearTemperatureField.c Apps/TempDiffusion/tests/LinearTemperatureField/LinearTemperatureField.cxx Apps/ThermalConvection/tests/ColumnViscosityAnalytic/ColumnViscosityAnalytic.c Apps/ThermalConvection/tests/ColumnViscosityAnalytic/ColumnViscosityAnalytic.cxx Assembly/src/DivergenceMatrixTerm.c Assembly/src/DivergenceMatrixTerm.cxx Assembly/src/Finalise.c Assembly/src/Finalise.cxx Assembly/src/GradientStiffnessMatrixTerm.c Assembly/src/GradientStiffnessMatrixTerm.cxx Assembly/src/Init.c Assembly/src/Init.cxx Assembly/src/IsoviscousStressTensorTerm.c Assembly/src/IsoviscousStressTensorTerm.cxx Assembly/src/LaplacianStiffnessMatrixTerm.c Assembly/src/LaplacianStiffnessMatrixTerm.cxx Assembly/src/MassMatrixTerm.c Assembly/src/MassMatrixTerm.cxx Assembly/src/PressureGradForceTerm.c Assembly/src/PressureGradForceTerm.cxx Assembly/src/PressureGradMatrixTerm.c Assembly/src/PressureGradMatrixTerm.cxx Assembly/src/ThermalBuoyancyForceTerm.c Assembly/src/ThermalBuoyancyForceTerm.cxx Assembly/tests/IsoviscousStiffnessSuite.c Assembly/tests/IsoviscousStiffnessSuite.cxx Discretisation/src/AnalyticSolution.c Discretisation/src/AnalyticSolution.cxx Discretisation/src/BilinearElementType.c Discretisation/src/BilinearElementType.cxx Discretisation/src/BilinearInnerElType.c Discretisation/src/BilinearInnerElType.cxx Discretisation/src/Biquadratic.c Discretisation/src/Biquadratic.cxx Discretisation/src/C0Generator.c Discretisation/src/C0Generator.cxx Discretisation/src/C2Generator.c Discretisation/src/C2Generator.cxx Discretisation/src/ConstantElementType.c Discretisation/src/ConstantElementType.cxx Discretisation/src/Element.c Discretisation/src/Element.cxx Discretisation/src/ElementType.c Discretisation/src/ElementType.cxx Discretisation/src/ElementType_Register.c Discretisation/src/ElementType_Register.cxx Discretisation/src/FeEquationNumber.c Discretisation/src/FeEquationNumber.cxx Discretisation/src/FeMesh.c Discretisation/src/FeMesh.cxx Discretisation/src/FeMesh_Algorithms.c Discretisation/src/FeMesh_Algorithms.cxx Discretisation/src/FeMesh_ElementType.c Discretisation/src/FeMesh_ElementType.cxx Discretisation/src/FeSwarmVariable.c Discretisation/src/FeSwarmVariable.cxx Discretisation/src/FeVariable.c Discretisation/src/FeVariable.cxx Discretisation/src/FieldTest.c Discretisation/src/FieldTest.cxx Discretisation/src/Finalise.c Discretisation/src/Finalise.cxx Discretisation/src/FunctionSuite.c Discretisation/src/FunctionSuite.cxx Discretisation/src/Init.c Discretisation/src/Init.cxx Discretisation/src/Inner2DGenerator.c Discretisation/src/Inner2DGenerator.cxx Discretisation/src/LinearTriangleElementType.c Discretisation/src/LinearTriangleElementType.cxx Discretisation/src/LinkedDofInfo.c Discretisation/src/LinkedDofInfo.cxx Discretisation/src/OperatorFeVariable.c Discretisation/src/OperatorFeVariable.cxx Discretisation/src/P1.c Discretisation/src/P1.cxx Discretisation/src/RegularBilinear.c Discretisation/src/RegularBilinear.cxx Discretisation/src/RegularTrilinear.c Discretisation/src/RegularTrilinear.cxx Discretisation/src/ShapeFeVariable.c Discretisation/src/ShapeFeVariable.cxx Discretisation/src/TrilinearElementType.c Discretisation/src/TrilinearElementType.cxx Discretisation/src/TrilinearInnerElType.c Discretisation/src/TrilinearInnerElType.cxx Discretisation/src/Triquadratic.c Discretisation/src/Triquadratic.cxx Discretisation/tests/C2GeneratorSuite.c Discretisation/tests/C2GeneratorSuite.cxx Discretisation/tests/ElementTypeRegisterSuite.c Discretisation/tests/ElementTypeRegisterSuite.cxx Discretisation/tests/ElementTypeSuite.c Discretisation/tests/ElementTypeSuite.cxx Discretisation/tests/FeEquationNumberSuite.c Discretisation/tests/FeEquationNumberSuite.cxx Discretisation/tests/FeVariableSuite.c Discretisation/tests/FeVariableSuite.cxx Discretisation/tests/TrilinearElementTypeSuite.c Discretisation/tests/TrilinearElementTypeSuite.cxx SConscript SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.c SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.cxx SLE/ProvidedSystems/AdvectionDiffusion/src/Finalise.c SLE/ProvidedSystems/AdvectionDiffusion/src/Finalise.cxx SLE/ProvidedSystems/AdvectionDiffusion/src/Init.c SLE/ProvidedSystems/AdvectionDiffusion/src/Init.cxx SLE/ProvidedSystems/AdvectionDiffusion/src/LumpedMassMatrixForceTerm.c SLE/ProvidedSystems/AdvectionDiffusion/src/LumpedMassMatrixForceTerm.cxx SLE/ProvidedSystems/AdvectionDiffusion/src/MassMatrix_Assembly.c SLE/ProvidedSystems/AdvectionDiffusion/src/MassMatrix_Assembly.cxx SLE/ProvidedSystems/AdvectionDiffusion/src/Multicorrector.c SLE/ProvidedSystems/AdvectionDiffusion/src/Multicorrector.cxx SLE/ProvidedSystems/AdvectionDiffusion/src/Residual.c SLE/ProvidedSystems/AdvectionDiffusion/src/Residual.cxx SLE/ProvidedSystems/AdvectionDiffusion/src/Timestep.c SLE/ProvidedSystems/AdvectionDiffusion/src/Timestep.cxx SLE/ProvidedSystems/AdvectionDiffusion/src/UpwindParameter.c SLE/ProvidedSystems/AdvectionDiffusion/src/UpwindParameter.cxx SLE/ProvidedSystems/AdvectionDiffusion/tests/LumpedMassMatrixSuite.c SLE/ProvidedSystems/AdvectionDiffusion/tests/LumpedMassMatrixSuite.cxx SLE/ProvidedSystems/AdvectionDiffusion/tests/UpwindXiSuite.c SLE/ProvidedSystems/AdvectionDiffusion/tests/UpwindXiSuite.cxx SLE/ProvidedSystems/AdvectionDiffusion/tests/oldTesting/testLumpedMassMatrix.c SLE/ProvidedSystems/AdvectionDiffusion/tests/oldTesting/testLumpedMassMatrix.cxx SLE/ProvidedSystems/AdvectionDiffusion/tests/oldTesting/testUpwindXi.c SLE/ProvidedSystems/AdvectionDiffusion/tests/oldTesting/testUpwindXi.cxx SLE/ProvidedSystems/Energy/src/Energy_SLE.c SLE/ProvidedSystems/Energy/src/Energy_SLE.cxx SLE/ProvidedSystems/Energy/src/Energy_SLE_Solver.c SLE/ProvidedSystems/Energy/src/Energy_SLE_Solver.cxx SLE/ProvidedSystems/Energy/src/Finalise.c SLE/ProvidedSystems/Energy/src/Finalise.cxx SLE/ProvidedSystems/Energy/src/Init.c SLE/ProvidedSystems/Energy/src/Init.cxx SLE/ProvidedSystems/StokesFlow/src/Finalise.c SLE/ProvidedSystems/StokesFlow/src/Finalise.cxx SLE/ProvidedSystems/StokesFlow/src/Init.c SLE/ProvidedSystems/StokesFlow/src/Init.cxx SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE.c SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE.cxx SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_PenaltySolver.c SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_PenaltySolver.cxx SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_UzawaSolver.c SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_UzawaSolver.cxx SLE/ProvidedSystems/StokesFlow/src/UpdateDt.c SLE/ProvidedSystems/StokesFlow/src/UpdateDt.cxx SLE/ProvidedSystems/StokesFlow/src/UzawaPreconditionerTerm.c SLE/ProvidedSystems/StokesFlow/src/UzawaPreconditionerTerm.cxx SLE/ProvidedSystems/src/Finalise.c SLE/ProvidedSystems/src/Finalise.cxx SLE/ProvidedSystems/src/Init.c SLE/ProvidedSystems/src/Init.cxx SLE/SystemSetup/src/Assembler.c SLE/SystemSetup/src/Assembler.cxx SLE/SystemSetup/src/EntryPoint.c SLE/SystemSetup/src/EntryPoint.cxx SLE/SystemSetup/src/Finalise.c SLE/SystemSetup/src/Finalise.cxx SLE/SystemSetup/src/FiniteElementContext.c SLE/SystemSetup/src/FiniteElementContext.cxx SLE/SystemSetup/src/ForceTerm.c SLE/SystemSetup/src/ForceTerm.cxx SLE/SystemSetup/src/ForceVector.c SLE/SystemSetup/src/ForceVector.cxx SLE/SystemSetup/src/Init.c SLE/SystemSetup/src/Init.cxx SLE/SystemSetup/src/MGOpGenerator.c SLE/SystemSetup/src/MGOpGenerator.cxx SLE/SystemSetup/src/MultigridSolver.c SLE/SystemSetup/src/MultigridSolver.cxx SLE/SystemSetup/src/PETScMGSolver.c SLE/SystemSetup/src/PETScMGSolver.cxx SLE/SystemSetup/src/SLE_Solver.c SLE/SystemSetup/src/SLE_Solver.cxx SLE/SystemSetup/src/SROpGenerator.c SLE/SystemSetup/src/SROpGenerator.cxx SLE/SystemSetup/src/SolutionVector.c SLE/SystemSetup/src/SolutionVector.cxx SLE/SystemSetup/src/StiffnessMatrix.c SLE/SystemSetup/src/StiffnessMatrix.cxx SLE/SystemSetup/src/StiffnessMatrixTerm.c SLE/SystemSetup/src/StiffnessMatrixTerm.cxx SLE/SystemSetup/src/SystemLinearEquations.c SLE/SystemSetup/src/SystemLinearEquations.cxx SLE/SystemSetup/tests/ContextSuite.c SLE/SystemSetup/tests/ContextSuite.cxx SLE/SystemSetup/tests/SolutionVectorSuite.c SLE/SystemSetup/tests/SolutionVectorSuite.cxx SLE/SystemSetup/tests/StiffnessMatrixSuite.c SLE/SystemSetup/tests/StiffnessMatrixSuite.cxx SLE/src/Finalise.c SLE/src/Finalise.cxx SLE/src/Init.c SLE/src/Init.cxx SysTest/AnalyticPlugins/AdvDiffSteadyState1D/AdvDiffSteadyState1D.c SysTest/AnalyticPlugins/AdvDiffSteadyState1D/AdvDiffSteadyState1D.cxx SysTest/AnalyticPlugins/CosineHillRotate/CosineHillRotate.c SysTest/AnalyticPlugins/CosineHillRotate/CosineHillRotate.cxx SysTest/AnalyticPlugins/HomogeneousNaturalBCs/HomogeneousNaturalBCs.c SysTest/AnalyticPlugins/HomogeneousNaturalBCs/HomogeneousNaturalBCs.cxx SysTest/AnalyticPlugins/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.c SysTest/AnalyticPlugins/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.cxx SysTest/AnalyticPlugins/LinearTemperatureField/LinearTemperatureField.c SysTest/AnalyticPlugins/LinearTemperatureField/LinearTemperatureField.cxx SysTest/AnalyticPlugins/LinearVelocityAnalytic/LinearVelocityAnalytic.c SysTest/AnalyticPlugins/LinearVelocityAnalytic/LinearVelocityAnalytic.cxx libStgFEM/Toolbox/Toolbox.c libStgFEM/Toolbox/Toolbox.cxx libStgFEM/src/Finalise.c libStgFEM/src/Finalise.cxx libStgFEM/src/Init.c libStgFEM/src/Init.cxx libStgFEM/tests/LibStgFEMSuite.c libStgFEM/tests/LibStgFEMSuite.cxx libStgFEM/tests/testLibStgFEM.c libStgFEM/tests/testLibStgFEM.cxx plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.c plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.cxx plugins/FeVariableImportExporters/FeVariable_ImportExport_ABAQUS/FeVariable_ImportExport_ABAQUS.c plugins/FeVariableImportExporters/FeVariable_ImportExport_ABAQUS/FeVariable_ImportExport_ABAQUS.cxx plugins/FeVariableImportExporters/FeVariable_ImportExport_SpecRidge2D/FeVariable_ImportExport_SpecRidge2D.c plugins/FeVariableImportExporters/FeVariable_ImportExport_SpecRidge2D/FeVariable_ImportExport_SpecRidge2D.cxx plugins/FileAnalyticSolution/FileAnalyticSolution.c plugins/FileAnalyticSolution/FileAnalyticSolution.cxx plugins/Multigrid/Multigrid.c plugins/Multigrid/Multigrid.cxx plugins/Output/CPUTime/CPUTime.c plugins/Output/CPUTime/CPUTime.cxx plugins/Output/CPUTimeAndNumberOfIterationsForInnerAndOuterSolve/CPUTimeAndNumberOfIterationsForInnerAndOuterSolve.c plugins/Output/CPUTimeAndNumberOfIterationsForInnerAndOuterSolve/CPUTimeAndNumberOfIterationsForInnerAndOuterSolve.cxx plugins/Output/FeVariableList/FeVariableList.c plugins/Output/FeVariableList/FeVariableList.cxx plugins/Output/FrequentOutput/FrequentOutput.c plugins/Output/FrequentOutput/FrequentOutput.cxx plugins/Output/PeakMemory/PeakMemory.c plugins/Output/PeakMemory/PeakMemory.cxx plugins/Output/PrintFeVariableDiscreteValues/Plugin.c plugins/Output/PrintFeVariableDiscreteValues/Plugin.cxx plugins/Output/PrintFeVariableDiscreteValues_2dBox/Plugin.c plugins/Output/PrintFeVariableDiscreteValues_2dBox/Plugin.cxx plugins/Output/SwarmVariableList/SwarmVariableList.c plugins/Output/SwarmVariableList/SwarmVariableList.cxx plugins/StandardConditionFunctions/StandardConditionFunctions.c plugins/StandardConditionFunctions/StandardConditionFunctions.cxx
description:
Rename .c -> .cxx and make configure automatically use c++
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/EnergySolver/tests/AdvDiffSteadyState1D/AdvDiffSteadyState1D.c
--- a/Apps/EnergySolver/tests/AdvDiffSteadyState1D/AdvDiffSteadyState1D.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: AdvDiffSteadyState1D.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-/* This analytic solutions is just the advection of a diffusing temperature for one time step.
- * The advection is in the direction of one of the i,j,k axis
- * */
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-#include <string.h>
-
-const Type AdvDiffSteadyState1D_Type = "AdvDiffSteadyState1D";
-
-typedef struct {
- __AnalyticSolution
- AdvDiffResidualForceTerm* residual;
- /* Velocity in this analyticSolution is constant */
- double velocity;
- Axis velocityDirection;
- double A;
- double B;
- double c;
- FeVariable* temperatureField;
-} AdvDiffSteadyState1D;
-
-void AdvDiffSteadyState1D_TemperatureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* temperature ) {
- AdvDiffSteadyState1D* self = (AdvDiffSteadyState1D*)analyticSolution;
- double exponent;
- double kappa = self->residual->defaultDiffusivity;
-
- exponent = self->velocity / kappa * ( coord[ self->velocityDirection ] - self->c );
- *temperature = self->A * exp( exponent ) + self->B;
-}
-
-void AdvDiffSteadyState1D_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* temperature ){
- DomainContext* context = (DomainContext*)_context;
- AdvDiffSteadyState1D* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)AdvDiffSteadyState1D_Type, AdvDiffSteadyState1D, True, 0 /* dummy */ );
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* coord;
-
- feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- AdvDiffSteadyState1D_TemperatureFunction( self, NULL, coord, temperature );
-}
-
-
-void _AdvDiffSteadyState1D_Build( void* analyticSolution, void* data ) {
- AdvDiffSteadyState1D* self = (AdvDiffSteadyState1D*)analyticSolution;
- FeVariable* velocityField = Stg_CheckType( self->residual->velocityField, FeVariable );
- CompositeVC* velocityICs = Stg_CheckType( velocityField->ics, CompositeVC );
- Stream* errorStream = Journal_MyStream( Error_Type, self );
- AllNodesVC* allNodesVC;
- AllNodesVC_Entry* vcEntry;
-
- _AnalyticSolution_Build( self, data );
-
- /* Get AllNodes Variable Condition */
- Stg_Component_Build( velocityICs, data, False );
- Journal_Firewall( velocityICs->itemCount == 1, errorStream,
- "Velocity Field needs to have one and only one Boundary Condition.\n"
- "Currently it has %d types of VariableConditions.\n", velocityICs->itemCount );
- allNodesVC = Stg_CheckType( velocityICs->itemTbl[ 0 ], AllNodesVC );
-
- /* Get Variable Condition entry */
- Journal_Firewall( allNodesVC->_entryCount == 1, errorStream,
- "Velocity Field has more than one Boundary Condition.\n"
- "Currently it has %d VariableCondition entries.\n", allNodesVC->_entryCount );
- vcEntry = &allNodesVC->_entryTbl[0];
-
- /* Get Velocity Direction from Variable Condition */
- if ( strcmp( vcEntry->varName, "vx" ) == 0 ) {
- self->velocityDirection = I_AXIS;
- }
- else if ( strcmp( vcEntry->varName, "vy" ) == 0 ) {
- self->velocityDirection = J_AXIS;
- }
- else if ( strcmp( vcEntry->varName, "vz" ) == 0 ) {
- self->velocityDirection = K_AXIS;
- }
- else {
- Journal_Firewall( False, errorStream, "Cannot recognise Boundary Condition: %s.\n", vcEntry->varName );
- }
-}
-
-void _AdvDiffSteadyState1D_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- AdvDiffSteadyState1D* self = (AdvDiffSteadyState1D*)analyticSolution;
- AbstractContext* context;
- ConditionFunction* condFunc;
-
- _AnalyticSolution_AssignFromXML( self, cf, data );
-
- self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"TemperatureField", FeVariable, True, data );
- AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, self->temperatureField, AdvDiffSteadyState1D_TemperatureFunction );
-
- self->residual = Stg_ComponentFactory_ConstructByName( cf, (Name)"defaultResidualForceTerm", AdvDiffResidualForceTerm, True, data );
-
- self->velocity = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"velocity", 1.0 );
- self->A = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"A", 1.0 );
- self->B = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"B", 0.0 );
- self->c = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"c", 0.0 );
-
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
- condFunc = ConditionFunction_New( AdvDiffSteadyState1D_TemperatureBC, (Name)"AnalyticSolutionFunction" );
- ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
-
-}
-
-void* _AdvDiffSteadyState1D_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(AdvDiffSteadyState1D);
- Type type = AdvDiffSteadyState1D_Type;
- Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
- Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
- Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _AdvDiffSteadyState1D_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _AdvDiffSteadyState1D_AssignFromXML;
- Stg_Component_BuildFunction* _build = _AdvDiffSteadyState1D_Build;
- Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
- Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_AdvDiffSteadyState1D_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, AdvDiffSteadyState1D_Type, (Name)"0", _AdvDiffSteadyState1D_DefaultNew );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/EnergySolver/tests/AdvDiffSteadyState1D/AdvDiffSteadyState1D.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Apps/EnergySolver/tests/AdvDiffSteadyState1D/AdvDiffSteadyState1D.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,177 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: AdvDiffSteadyState1D.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+/* This analytic solutions is just the advection of a diffusing temperature for one time step.
+ * The advection is in the direction of one of the i,j,k axis
+ * */
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+#include <string.h>
+
+const Type AdvDiffSteadyState1D_Type = "AdvDiffSteadyState1D";
+
+typedef struct {
+ __AnalyticSolution
+ AdvDiffResidualForceTerm* residual;
+ /* Velocity in this analyticSolution is constant */
+ double velocity;
+ Axis velocityDirection;
+ double A;
+ double B;
+ double c;
+ FeVariable* temperatureField;
+} AdvDiffSteadyState1D;
+
+void AdvDiffSteadyState1D_TemperatureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* temperature ) {
+ AdvDiffSteadyState1D* self = (AdvDiffSteadyState1D*)analyticSolution;
+ double exponent;
+ double kappa = self->residual->defaultDiffusivity;
+
+ exponent = self->velocity / kappa * ( coord[ self->velocityDirection ] - self->c );
+ *temperature = self->A * exp( exponent ) + self->B;
+}
+
+void AdvDiffSteadyState1D_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* temperature ){
+ DomainContext* context = (DomainContext*)_context;
+ AdvDiffSteadyState1D* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)AdvDiffSteadyState1D_Type, AdvDiffSteadyState1D, True, 0 /* dummy */ );
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* coord;
+
+ feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ AdvDiffSteadyState1D_TemperatureFunction( self, NULL, coord, temperature );
+}
+
+
+void _AdvDiffSteadyState1D_Build( void* analyticSolution, void* data ) {
+ AdvDiffSteadyState1D* self = (AdvDiffSteadyState1D*)analyticSolution;
+ FeVariable* velocityField = Stg_CheckType( self->residual->velocityField, FeVariable );
+ CompositeVC* velocityICs = Stg_CheckType( velocityField->ics, CompositeVC );
+ Stream* errorStream = Journal_MyStream( Error_Type, self );
+ AllNodesVC* allNodesVC;
+ AllNodesVC_Entry* vcEntry;
+
+ _AnalyticSolution_Build( self, data );
+
+ /* Get AllNodes Variable Condition */
+ Stg_Component_Build( velocityICs, data, False );
+ Journal_Firewall( velocityICs->itemCount == 1, errorStream,
+ "Velocity Field needs to have one and only one Boundary Condition.\n"
+ "Currently it has %d types of VariableConditions.\n", velocityICs->itemCount );
+ allNodesVC = Stg_CheckType( velocityICs->itemTbl[ 0 ], AllNodesVC );
+
+ /* Get Variable Condition entry */
+ Journal_Firewall( allNodesVC->_entryCount == 1, errorStream,
+ "Velocity Field has more than one Boundary Condition.\n"
+ "Currently it has %d VariableCondition entries.\n", allNodesVC->_entryCount );
+ vcEntry = &allNodesVC->_entryTbl[0];
+
+ /* Get Velocity Direction from Variable Condition */
+ if ( strcmp( vcEntry->varName, "vx" ) == 0 ) {
+ self->velocityDirection = I_AXIS;
+ }
+ else if ( strcmp( vcEntry->varName, "vy" ) == 0 ) {
+ self->velocityDirection = J_AXIS;
+ }
+ else if ( strcmp( vcEntry->varName, "vz" ) == 0 ) {
+ self->velocityDirection = K_AXIS;
+ }
+ else {
+ Journal_Firewall( False, errorStream, "Cannot recognise Boundary Condition: %s.\n", vcEntry->varName );
+ }
+}
+
+void _AdvDiffSteadyState1D_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ AdvDiffSteadyState1D* self = (AdvDiffSteadyState1D*)analyticSolution;
+ AbstractContext* context;
+ ConditionFunction* condFunc;
+
+ _AnalyticSolution_AssignFromXML( self, cf, data );
+
+ self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"TemperatureField", FeVariable, True, data );
+ AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, self->temperatureField, AdvDiffSteadyState1D_TemperatureFunction );
+
+ self->residual = Stg_ComponentFactory_ConstructByName( cf, (Name)"defaultResidualForceTerm", AdvDiffResidualForceTerm, True, data );
+
+ self->velocity = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"velocity", 1.0 );
+ self->A = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"A", 1.0 );
+ self->B = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"B", 0.0 );
+ self->c = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"c", 0.0 );
+
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+ condFunc = ConditionFunction_New( AdvDiffSteadyState1D_TemperatureBC, (Name)"AnalyticSolutionFunction" );
+ ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
+
+}
+
+void* _AdvDiffSteadyState1D_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(AdvDiffSteadyState1D);
+ Type type = AdvDiffSteadyState1D_Type;
+ Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
+ Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
+ Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _AdvDiffSteadyState1D_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _AdvDiffSteadyState1D_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _AdvDiffSteadyState1D_Build;
+ Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
+ Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_AdvDiffSteadyState1D_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, AdvDiffSteadyState1D_Type, (Name)"0", _AdvDiffSteadyState1D_DefaultNew );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/EnergySolver/tests/CosineHillRotate/CosineHillRotate.c
--- a/Apps/EnergySolver/tests/CosineHillRotate/CosineHillRotate.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: CosineHillRotate.c 968 2007-10-23 07:53:39Z JulianGiordani $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-const Type CosineHillRotate_Type = "CosineHillRotate";
-
-typedef struct {
- __AnalyticSolution
- FeVariable* temperatureField;
- double hillHeight;
- double hillDiameter;
- Coord rotationCentre;
-} CosineHillRotate;
-
-void CosineHillRotate_TemperatureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* temperature ) {
- CosineHillRotate *self = (CosineHillRotate*)analyticSolution;
- double distanceFromCentre = StGermain_DistanceBetweenPoints( self->rotationCentre, coord, 2 );
-
- if (distanceFromCentre < self->hillDiameter )
- *temperature = self->hillHeight * (0.5 + 0.5 * cos( 2.0 * M_PI/self->hillDiameter * distanceFromCentre + M_PI ) );
- else
- *temperature = 0.0;
-}
-
-void CosineHillRotate_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- CosineHillRotate* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)CosineHillRotate_Type, CosineHillRotate, True, 0 );
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
-
- feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- CosineHillRotate_TemperatureFunction( self, feVariable, coord, result );
-}
-
-void _CosineHillRotate_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- CosineHillRotate* self = (CosineHillRotate*)analyticSolution;
- AbstractContext* context;
- ConditionFunction* condFunc;
-
- _AnalyticSolution_AssignFromXML( self, cf, data );
-
- self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"TemperatureField", FeVariable, True, data );
- AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, self->temperatureField, CosineHillRotate_TemperatureFunction );
-
- /* Read values from dictionary */
- self->hillHeight = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"CosineHillHeight" , 1.0 );
- self->hillDiameter = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"CosineHillDiameter", 1.0 );
- self->rotationCentre[ I_AXIS ] = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SolidBodyRotationCentreX" , 0.0 );
- self->rotationCentre[ J_AXIS ] = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SolidBodyRotationCentreY" , 0.0 );
- self->rotationCentre[ K_AXIS ] = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SolidBodyRotationCentreZ" , 0.0 );
-
- /* Create Condition Functions */
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
- condFunc = ConditionFunction_New( CosineHillRotate_TemperatureBC, (Name)"Temperature_CosineHill" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-}
-
-void _CosineHillRotate_Build( void* analyticSolution, void* data ) {
- CosineHillRotate* self = (CosineHillRotate*)analyticSolution;
-
- _AnalyticSolution_Build( self, data );
-}
-
-void* _CosineHillRotate_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(CosineHillRotate);
- Type type = CosineHillRotate_Type;
- Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
- Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
- Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _CosineHillRotate_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _CosineHillRotate_AssignFromXML;
- Stg_Component_BuildFunction* _build = _CosineHillRotate_Build;
- Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
- Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_CosineHillRotate_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, CosineHillRotate_Type, (Name)"0", _CosineHillRotate_DefaultNew );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/EnergySolver/tests/CosineHillRotate/CosineHillRotate.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Apps/EnergySolver/tests/CosineHillRotate/CosineHillRotate.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,137 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: CosineHillRotate.c 968 2007-10-23 07:53:39Z JulianGiordani $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+const Type CosineHillRotate_Type = "CosineHillRotate";
+
+typedef struct {
+ __AnalyticSolution
+ FeVariable* temperatureField;
+ double hillHeight;
+ double hillDiameter;
+ Coord rotationCentre;
+} CosineHillRotate;
+
+void CosineHillRotate_TemperatureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* temperature ) {
+ CosineHillRotate *self = (CosineHillRotate*)analyticSolution;
+ double distanceFromCentre = StGermain_DistanceBetweenPoints( self->rotationCentre, coord, 2 );
+
+ if (distanceFromCentre < self->hillDiameter )
+ *temperature = self->hillHeight * (0.5 + 0.5 * cos( 2.0 * M_PI/self->hillDiameter * distanceFromCentre + M_PI ) );
+ else
+ *temperature = 0.0;
+}
+
+void CosineHillRotate_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ CosineHillRotate* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)CosineHillRotate_Type, CosineHillRotate, True, 0 );
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+
+ feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ CosineHillRotate_TemperatureFunction( self, feVariable, coord, result );
+}
+
+void _CosineHillRotate_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ CosineHillRotate* self = (CosineHillRotate*)analyticSolution;
+ AbstractContext* context;
+ ConditionFunction* condFunc;
+
+ _AnalyticSolution_AssignFromXML( self, cf, data );
+
+ self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"TemperatureField", FeVariable, True, data );
+ AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, self->temperatureField, CosineHillRotate_TemperatureFunction );
+
+ /* Read values from dictionary */
+ self->hillHeight = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"CosineHillHeight" , 1.0 );
+ self->hillDiameter = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"CosineHillDiameter", 1.0 );
+ self->rotationCentre[ I_AXIS ] = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SolidBodyRotationCentreX" , 0.0 );
+ self->rotationCentre[ J_AXIS ] = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SolidBodyRotationCentreY" , 0.0 );
+ self->rotationCentre[ K_AXIS ] = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SolidBodyRotationCentreZ" , 0.0 );
+
+ /* Create Condition Functions */
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+ condFunc = ConditionFunction_New( CosineHillRotate_TemperatureBC, (Name)"Temperature_CosineHill" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+}
+
+void _CosineHillRotate_Build( void* analyticSolution, void* data ) {
+ CosineHillRotate* self = (CosineHillRotate*)analyticSolution;
+
+ _AnalyticSolution_Build( self, data );
+}
+
+void* _CosineHillRotate_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(CosineHillRotate);
+ Type type = CosineHillRotate_Type;
+ Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
+ Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
+ Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _CosineHillRotate_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _CosineHillRotate_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _CosineHillRotate_Build;
+ Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
+ Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_CosineHillRotate_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, CosineHillRotate_Type, (Name)"0", _CosineHillRotate_DefaultNew );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/EnergySolver/tests/HomogeneousEssentialBCs/HomogeneousEssentialBCs.c
--- a/Apps/EnergySolver/tests/HomogeneousEssentialBCs/HomogeneousEssentialBCs.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: HomogeneousEssentialBCs.c 968 2007-10-23 07:53:39Z JulianGiordani $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-const Type HomogeneousEssentialBCs_Type = "HomogeneousEssentialBCs";
-
-typedef struct {
- __AnalyticSolution
- double angle;
- FeVariable* temperatureField;
-} HomogeneousEssentialBCs;
-
-
-void HomogeneousEssentialBCs_Velocity_SkewToMesh( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- HomogeneousEssentialBCs* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)HomogeneousEssentialBCs_Type, HomogeneousEssentialBCs, True, 0 );
- double* result = (double*) _result;
-
- result[ I_AXIS ] = cos( self->angle );
- result[ J_AXIS ] = sin( self->angle );
-}
-
-
-void HomogeneousEssentialBCs_TemperatureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* temperature ) {
- HomogeneousEssentialBCs *self = (HomogeneousEssentialBCs*)analyticSolution;
-
- if ( coord[ J_AXIS ] < tan( self->angle ) * coord[ I_AXIS ] + 0.25 )
- *temperature = 1.0;
- else
- *temperature = 0.0;
-
- /* Perform Essential Boundary Conditions */
- if ( (coord[ I_AXIS ] > 0.99 && coord[ J_AXIS ] > 0.01) || coord[ J_AXIS ] > 0.99 ) {
- *temperature = 0.0;
- }
-}
-
-void HomogeneousEssentialBCs_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- HomogeneousEssentialBCs* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)HomogeneousEssentialBCs_Type, HomogeneousEssentialBCs, True, 0 );
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
-
- feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- HomogeneousEssentialBCs_TemperatureFunction( self, feVariable, coord, result );
-}
-
-void _HomogeneousEssentialBCs_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- HomogeneousEssentialBCs* self = (HomogeneousEssentialBCs*)analyticSolution;
- AbstractContext* context;
- ConditionFunction* condFunc;
-
- _AnalyticSolution_AssignFromXML( self, cf, data );
-
- self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"TemperatureField", FeVariable, True, data );
- AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, self->temperatureField, HomogeneousEssentialBCs_TemperatureFunction );
-
- self->angle = StGermain_DegreeToRadian (Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"VelocitySkewAngle", 45.0 ) );
-
- /* Create Condition Functions */
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
- condFunc = ConditionFunction_New( HomogeneousEssentialBCs_Velocity_SkewToMesh, (Name)"Velocity_SkewToMesh" );
- ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
- condFunc = ConditionFunction_New( HomogeneousEssentialBCs_TemperatureBC, (Name)"Temperature_StepFunction" );
- ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
-}
-
-void _HomogeneousEssentialBCs_Build( void* analyticSolution, void* data ) {
- HomogeneousEssentialBCs* self = (HomogeneousEssentialBCs*)analyticSolution;
-
- _AnalyticSolution_Build( self, data );
-}
-
-void* _HomogeneousEssentialBCs_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(HomogeneousEssentialBCs);
- Type type = HomogeneousEssentialBCs_Type;
- Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
- Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
- Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _HomogeneousEssentialBCs_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _HomogeneousEssentialBCs_AssignFromXML;
- Stg_Component_BuildFunction* _build = _HomogeneousEssentialBCs_Build;
- Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
- Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_HomogeneousEssentialBCs_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, HomogeneousEssentialBCs_Type, (Name)"0", _HomogeneousEssentialBCs_DefaultNew );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/EnergySolver/tests/HomogeneousEssentialBCs/HomogeneousEssentialBCs.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Apps/EnergySolver/tests/HomogeneousEssentialBCs/HomogeneousEssentialBCs.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,147 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: HomogeneousEssentialBCs.c 968 2007-10-23 07:53:39Z JulianGiordani $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+const Type HomogeneousEssentialBCs_Type = "HomogeneousEssentialBCs";
+
+typedef struct {
+ __AnalyticSolution
+ double angle;
+ FeVariable* temperatureField;
+} HomogeneousEssentialBCs;
+
+
+void HomogeneousEssentialBCs_Velocity_SkewToMesh( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ HomogeneousEssentialBCs* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)HomogeneousEssentialBCs_Type, HomogeneousEssentialBCs, True, 0 );
+ double* result = (double*) _result;
+
+ result[ I_AXIS ] = cos( self->angle );
+ result[ J_AXIS ] = sin( self->angle );
+}
+
+
+void HomogeneousEssentialBCs_TemperatureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* temperature ) {
+ HomogeneousEssentialBCs *self = (HomogeneousEssentialBCs*)analyticSolution;
+
+ if ( coord[ J_AXIS ] < tan( self->angle ) * coord[ I_AXIS ] + 0.25 )
+ *temperature = 1.0;
+ else
+ *temperature = 0.0;
+
+ /* Perform Essential Boundary Conditions */
+ if ( (coord[ I_AXIS ] > 0.99 && coord[ J_AXIS ] > 0.01) || coord[ J_AXIS ] > 0.99 ) {
+ *temperature = 0.0;
+ }
+}
+
+void HomogeneousEssentialBCs_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ HomogeneousEssentialBCs* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)HomogeneousEssentialBCs_Type, HomogeneousEssentialBCs, True, 0 );
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+
+ feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ HomogeneousEssentialBCs_TemperatureFunction( self, feVariable, coord, result );
+}
+
+void _HomogeneousEssentialBCs_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ HomogeneousEssentialBCs* self = (HomogeneousEssentialBCs*)analyticSolution;
+ AbstractContext* context;
+ ConditionFunction* condFunc;
+
+ _AnalyticSolution_AssignFromXML( self, cf, data );
+
+ self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"TemperatureField", FeVariable, True, data );
+ AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, self->temperatureField, HomogeneousEssentialBCs_TemperatureFunction );
+
+ self->angle = StGermain_DegreeToRadian (Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"VelocitySkewAngle", 45.0 ) );
+
+ /* Create Condition Functions */
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+ condFunc = ConditionFunction_New( HomogeneousEssentialBCs_Velocity_SkewToMesh, (Name)"Velocity_SkewToMesh" );
+ ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New( HomogeneousEssentialBCs_TemperatureBC, (Name)"Temperature_StepFunction" );
+ ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
+}
+
+void _HomogeneousEssentialBCs_Build( void* analyticSolution, void* data ) {
+ HomogeneousEssentialBCs* self = (HomogeneousEssentialBCs*)analyticSolution;
+
+ _AnalyticSolution_Build( self, data );
+}
+
+void* _HomogeneousEssentialBCs_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(HomogeneousEssentialBCs);
+ Type type = HomogeneousEssentialBCs_Type;
+ Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
+ Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
+ Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _HomogeneousEssentialBCs_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _HomogeneousEssentialBCs_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _HomogeneousEssentialBCs_Build;
+ Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
+ Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_HomogeneousEssentialBCs_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, HomogeneousEssentialBCs_Type, (Name)"0", _HomogeneousEssentialBCs_DefaultNew );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/EnergySolver/tests/HomogeneousNaturalBCs/HomogeneousNaturalBCs.c
--- a/Apps/EnergySolver/tests/HomogeneousNaturalBCs/HomogeneousNaturalBCs.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: HomogeneousNaturalBCs.c 967 2007-10-23 05:27:09Z JulianGiordani $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-const Type HomogeneousNaturalBCs_Type = "HomogeneousNaturalBCs";
-
-typedef struct {
- __AnalyticSolution
- double angle;
- FeVariable* temperatureField;
-} HomogeneousNaturalBCs;
-
-
-void HomogeneousNaturalBCs_Velocity_SkewToMesh( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- HomogeneousNaturalBCs* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)HomogeneousNaturalBCs_Type, HomogeneousNaturalBCs, True, 0 );
- double* result = (double*) _result;
-
- result[ I_AXIS ] = cos( self->angle );
- result[ J_AXIS ] = sin( self->angle );
-}
-
-
-void HomogeneousNaturalBCs_TemperatureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* temperature ) {
- HomogeneousNaturalBCs *self = (HomogeneousNaturalBCs*)analyticSolution;
-
- if ( coord[ J_AXIS ] < tan( self->angle ) * coord[ I_AXIS ] + 0.25 )
- *temperature = 1.0;
- else
- *temperature = 0.0;
-}
-
-void HomogeneousNaturalBCs_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- HomogeneousNaturalBCs* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)HomogeneousNaturalBCs_Type, HomogeneousNaturalBCs, True, 0 );
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
-
- feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- HomogeneousNaturalBCs_TemperatureFunction( self, feVariable, coord, result );
-}
-
-void _HomogeneousNaturalBCs_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- HomogeneousNaturalBCs* self = (HomogeneousNaturalBCs*)analyticSolution;
- AbstractContext* context;
- ConditionFunction* condFunc;
-
- _AnalyticSolution_AssignFromXML( self, cf, data );
-
- self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"TemperatureField", FeVariable, True, data );
- AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, self->temperatureField, HomogeneousNaturalBCs_TemperatureFunction );
-
- self->angle = StGermain_DegreeToRadian (Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"VelocitySkewAngle", 45.0 ) );
-
- /* Create Condition Functions */
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
- condFunc = ConditionFunction_New( HomogeneousNaturalBCs_Velocity_SkewToMesh, (Name)"Velocity_SkewToMesh" );
- ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
- condFunc = ConditionFunction_New( HomogeneousNaturalBCs_TemperatureBC, (Name)"Temperature_StepFunction" );
- ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
-}
-
-void _HomogeneousNaturalBCs_Build( void* analyticSolution, void* data ) {
- HomogeneousNaturalBCs* self = (HomogeneousNaturalBCs*)analyticSolution;
-
- _AnalyticSolution_Build( self, data );
-}
-
-void* _HomogeneousNaturalBCs_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(HomogeneousNaturalBCs);
- Type type = HomogeneousNaturalBCs_Type;
- Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
- Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
- Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _HomogeneousNaturalBCs_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _HomogeneousNaturalBCs_AssignFromXML;
- Stg_Component_BuildFunction* _build = _HomogeneousNaturalBCs_Build;
- Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
- Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_HomogeneousNaturalBCs_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, HomogeneousNaturalBCs_Type, (Name)"0", _HomogeneousNaturalBCs_DefaultNew );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/EnergySolver/tests/HomogeneousNaturalBCs/HomogeneousNaturalBCs.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Apps/EnergySolver/tests/HomogeneousNaturalBCs/HomogeneousNaturalBCs.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,142 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: HomogeneousNaturalBCs.c 967 2007-10-23 05:27:09Z JulianGiordani $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+const Type HomogeneousNaturalBCs_Type = "HomogeneousNaturalBCs";
+
+typedef struct {
+ __AnalyticSolution
+ double angle;
+ FeVariable* temperatureField;
+} HomogeneousNaturalBCs;
+
+
+void HomogeneousNaturalBCs_Velocity_SkewToMesh( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ HomogeneousNaturalBCs* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)HomogeneousNaturalBCs_Type, HomogeneousNaturalBCs, True, 0 );
+ double* result = (double*) _result;
+
+ result[ I_AXIS ] = cos( self->angle );
+ result[ J_AXIS ] = sin( self->angle );
+}
+
+
+void HomogeneousNaturalBCs_TemperatureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* temperature ) {
+ HomogeneousNaturalBCs *self = (HomogeneousNaturalBCs*)analyticSolution;
+
+ if ( coord[ J_AXIS ] < tan( self->angle ) * coord[ I_AXIS ] + 0.25 )
+ *temperature = 1.0;
+ else
+ *temperature = 0.0;
+}
+
+void HomogeneousNaturalBCs_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ HomogeneousNaturalBCs* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)HomogeneousNaturalBCs_Type, HomogeneousNaturalBCs, True, 0 );
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+
+ feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ HomogeneousNaturalBCs_TemperatureFunction( self, feVariable, coord, result );
+}
+
+void _HomogeneousNaturalBCs_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ HomogeneousNaturalBCs* self = (HomogeneousNaturalBCs*)analyticSolution;
+ AbstractContext* context;
+ ConditionFunction* condFunc;
+
+ _AnalyticSolution_AssignFromXML( self, cf, data );
+
+ self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"TemperatureField", FeVariable, True, data );
+ AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, self->temperatureField, HomogeneousNaturalBCs_TemperatureFunction );
+
+ self->angle = StGermain_DegreeToRadian (Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"VelocitySkewAngle", 45.0 ) );
+
+ /* Create Condition Functions */
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+ condFunc = ConditionFunction_New( HomogeneousNaturalBCs_Velocity_SkewToMesh, (Name)"Velocity_SkewToMesh" );
+ ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New( HomogeneousNaturalBCs_TemperatureBC, (Name)"Temperature_StepFunction" );
+ ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
+}
+
+void _HomogeneousNaturalBCs_Build( void* analyticSolution, void* data ) {
+ HomogeneousNaturalBCs* self = (HomogeneousNaturalBCs*)analyticSolution;
+
+ _AnalyticSolution_Build( self, data );
+}
+
+void* _HomogeneousNaturalBCs_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(HomogeneousNaturalBCs);
+ Type type = HomogeneousNaturalBCs_Type;
+ Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
+ Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
+ Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _HomogeneousNaturalBCs_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _HomogeneousNaturalBCs_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _HomogeneousNaturalBCs_Build;
+ Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
+ Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_HomogeneousNaturalBCs_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, HomogeneousNaturalBCs_Type, (Name)"0", _HomogeneousNaturalBCs_DefaultNew );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/StokesMomentumUzawa/tests/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.c
--- a/Apps/StokesMomentumUzawa/tests/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: LidDrivenIsoviscousAnalytic.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-/* This is taken from Mirko Velic's Analytic Stokes Flow solution */
-
-const Type LidDrivenIsoviscousAnalytic_Type = "LidDrivenIsoviscousAnalytic";
-
-typedef struct {
- __FieldTest
- unsigned int wavenumber;
- double A, B, C, D;
-} LidDrivenIsoviscousAnalytic;
-
-
-void LidDrivenIsoviscousAnalytic_CalculateConstants( LidDrivenIsoviscousAnalytic *self ) {
- double E;
- double e_nPI;
- double e_2nPI;
- double e_4nPI;
- double n;
-
- n = (double) self->wavenumber;
-
- e_nPI = exp( n * M_PI );
- e_2nPI = e_nPI * e_nPI;
- e_4nPI = e_2nPI * e_2nPI;
-
- E = (4.0 * n * n * M_PI * M_PI + 2.0 ) * e_2nPI - e_4nPI - 1.0;
-
- self->A = ( e_2nPI - 1.0 )* e_nPI / E;
- self->B = - self->A;
-
- self->C = ( 2.0 * n * M_PI - e_2nPI + 1.0 ) * e_nPI / E;
- self->D = - ( 2.0 * n * M_PI * e_2nPI - e_2nPI + 1.0 ) * e_nPI / E;
-}
-
-void LidDrivenIsoviscousAnalytic_VelocityFunction( void* codelet, double* coord, double* velocity ) {
- LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)codelet;
- double x,y;
- double n;
- double A, B, C, D;
-
- /* Get local copy of constants */
- n = (double) self->wavenumber;
- A = self->A;
- B = self->B;
- C = self->C;
- D = self->D;
-
- /* get copy of coords */
- x = coord[I_AXIS];
- y = coord[J_AXIS];
-
- velocity[ I_AXIS ] = sin( n * M_PI * x ) *
- ( ( A * n * M_PI + C + C * n * M_PI * y) *exp( n * M_PI * y )
- - ( B * n * M_PI - D + D * n * M_PI * y ) * exp( - n * M_PI * y ) );
- velocity[ J_AXIS ] = - n * M_PI * cos( n * M_PI * x ) *
- ( ( A + C * y ) * exp( n * M_PI * y )
- + ( B + D * y ) * exp( - n * M_PI * y ) );
-}
-
-void LidDrivenIsoviscousAnalytic_PressureFunction( void* codelet, double* coord, double* pressure ) {
- LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)codelet;
- double x,y;
- double n;
- double A, B, C, D;
-
- /* Get local copy of constants */
- n = (double) self->wavenumber;
- A = self->A;
- B = self->B;
- C = self->C;
- D = self->D;
-
- /* get copy of coords */
- x = coord[I_AXIS];
- y = coord[J_AXIS];
-
- *pressure = - 2.0 * n * M_PI * cos( n * M_PI * x ) * ( C * exp( n * M_PI * y ) + D * exp( - n * M_PI * y ) );
-}
-
-void _LidDrivenIsoviscousAnalytic_AssignFromXML( void* codelet, Stg_ComponentFactory* cf, void* data ) {
- LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)codelet;
-
- _FieldTest_AssignFromXML( self, cf, data );
-
- /* Set constants */
- self->wavenumber = Stg_ComponentFactory_GetRootDictUnsignedInt( cf, (Dictionary_Entry_Key)"sinusoidalLidWavenumber", 1 );
- LidDrivenIsoviscousAnalytic_CalculateConstants( self );
-}
-
-void _LidDrivenIsoviscousAnalytic_Build( void* codelet, void* data ) {
- LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)codelet;
-
- _FieldTest_Build( self, data );
-
- /* here we assign the memory and the func ptr for analytic sols */
- self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 2 );
- self->_analyticSolutionList[0] = LidDrivenIsoviscousAnalytic_VelocityFunction;
- self->_analyticSolutionList[1] = LidDrivenIsoviscousAnalytic_PressureFunction;
-}
-
-void _LidDrivenIsoviscousAnalytic_Initialise( void* codelet, void* data ) {
- _FieldTest_Initialise( codelet, data );
-}
-
-void* _LidDrivenIsoviscousAnalytic_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(LidDrivenIsoviscousAnalytic);
- Type type = LidDrivenIsoviscousAnalytic_Type;
- Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
- Stg_Class_PrintFunction* _print = _FieldTest_Print;
- Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LidDrivenIsoviscousAnalytic_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _LidDrivenIsoviscousAnalytic_AssignFromXML;
- Stg_Component_BuildFunction* _build = _LidDrivenIsoviscousAnalytic_Build;
- Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
- Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_LidDrivenIsoviscousAnalytic_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, LidDrivenIsoviscousAnalytic_Type, (Name)"0", _LidDrivenIsoviscousAnalytic_DefaultNew );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/StokesMomentumUzawa/tests/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Apps/StokesMomentumUzawa/tests/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,175 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: LidDrivenIsoviscousAnalytic.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+/* This is taken from Mirko Velic's Analytic Stokes Flow solution */
+
+const Type LidDrivenIsoviscousAnalytic_Type = "LidDrivenIsoviscousAnalytic";
+
+typedef struct {
+ __FieldTest
+ unsigned int wavenumber;
+ double A, B, C, D;
+} LidDrivenIsoviscousAnalytic;
+
+
+void LidDrivenIsoviscousAnalytic_CalculateConstants( LidDrivenIsoviscousAnalytic *self ) {
+ double E;
+ double e_nPI;
+ double e_2nPI;
+ double e_4nPI;
+ double n;
+
+ n = (double) self->wavenumber;
+
+ e_nPI = exp( n * M_PI );
+ e_2nPI = e_nPI * e_nPI;
+ e_4nPI = e_2nPI * e_2nPI;
+
+ E = (4.0 * n * n * M_PI * M_PI + 2.0 ) * e_2nPI - e_4nPI - 1.0;
+
+ self->A = ( e_2nPI - 1.0 )* e_nPI / E;
+ self->B = - self->A;
+
+ self->C = ( 2.0 * n * M_PI - e_2nPI + 1.0 ) * e_nPI / E;
+ self->D = - ( 2.0 * n * M_PI * e_2nPI - e_2nPI + 1.0 ) * e_nPI / E;
+}
+
+void LidDrivenIsoviscousAnalytic_VelocityFunction( void* codelet, double* coord, double* velocity ) {
+ LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)codelet;
+ double x,y;
+ double n;
+ double A, B, C, D;
+
+ /* Get local copy of constants */
+ n = (double) self->wavenumber;
+ A = self->A;
+ B = self->B;
+ C = self->C;
+ D = self->D;
+
+ /* get copy of coords */
+ x = coord[I_AXIS];
+ y = coord[J_AXIS];
+
+ velocity[ I_AXIS ] = sin( n * M_PI * x ) *
+ ( ( A * n * M_PI + C + C * n * M_PI * y) *exp( n * M_PI * y )
+ - ( B * n * M_PI - D + D * n * M_PI * y ) * exp( - n * M_PI * y ) );
+ velocity[ J_AXIS ] = - n * M_PI * cos( n * M_PI * x ) *
+ ( ( A + C * y ) * exp( n * M_PI * y )
+ + ( B + D * y ) * exp( - n * M_PI * y ) );
+}
+
+void LidDrivenIsoviscousAnalytic_PressureFunction( void* codelet, double* coord, double* pressure ) {
+ LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)codelet;
+ double x,y;
+ double n;
+ double A, B, C, D;
+
+ /* Get local copy of constants */
+ n = (double) self->wavenumber;
+ A = self->A;
+ B = self->B;
+ C = self->C;
+ D = self->D;
+
+ /* get copy of coords */
+ x = coord[I_AXIS];
+ y = coord[J_AXIS];
+
+ *pressure = - 2.0 * n * M_PI * cos( n * M_PI * x ) * ( C * exp( n * M_PI * y ) + D * exp( - n * M_PI * y ) );
+}
+
+void _LidDrivenIsoviscousAnalytic_AssignFromXML( void* codelet, Stg_ComponentFactory* cf, void* data ) {
+ LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)codelet;
+
+ _FieldTest_AssignFromXML( self, cf, data );
+
+ /* Set constants */
+ self->wavenumber = Stg_ComponentFactory_GetRootDictUnsignedInt( cf, (Dictionary_Entry_Key)"sinusoidalLidWavenumber", 1 );
+ LidDrivenIsoviscousAnalytic_CalculateConstants( self );
+}
+
+void _LidDrivenIsoviscousAnalytic_Build( void* codelet, void* data ) {
+ LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)codelet;
+
+ _FieldTest_Build( self, data );
+
+ /* here we assign the memory and the func ptr for analytic sols */
+ self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 2 );
+ self->_analyticSolutionList[0] = LidDrivenIsoviscousAnalytic_VelocityFunction;
+ self->_analyticSolutionList[1] = LidDrivenIsoviscousAnalytic_PressureFunction;
+}
+
+void _LidDrivenIsoviscousAnalytic_Initialise( void* codelet, void* data ) {
+ _FieldTest_Initialise( codelet, data );
+}
+
+void* _LidDrivenIsoviscousAnalytic_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(LidDrivenIsoviscousAnalytic);
+ Type type = LidDrivenIsoviscousAnalytic_Type;
+ Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
+ Stg_Class_PrintFunction* _print = _FieldTest_Print;
+ Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LidDrivenIsoviscousAnalytic_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _LidDrivenIsoviscousAnalytic_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _LidDrivenIsoviscousAnalytic_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_LidDrivenIsoviscousAnalytic_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, LidDrivenIsoviscousAnalytic_Type, (Name)"0", _LidDrivenIsoviscousAnalytic_DefaultNew );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/StokesMomentumUzawa/tests/LidDrivenStokesAnalytic/LidDrivenStokesAnalytic.c
--- a/Apps/StokesMomentumUzawa/tests/LidDrivenStokesAnalytic/LidDrivenStokesAnalytic.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: LidDrivenStokesAnalytic.c 922 2007-07-25 03:01:19Z DavidLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-#include <assert.h>
-#include <math.h>
-
-const Type StgFEM_LidDrivenStokesAnalytic_Type = "StgFEM_LidDrivenStokesAnalytic";
-
-typedef struct {
- __FieldTest;
- unsigned int n;
- double A, B, C, D;
-} StgFEM_LidDrivenStokesAnalytic;
-
-void StgFEM_LidDrivenStokesAnalytic_CalculateConstants( FieldTest *fieldTest ) {
- StgFEM_LidDrivenStokesAnalytic* self = (StgFEM_LidDrivenStokesAnalytic*)fieldTest;
- double E;
- double e_nPI;
- double e_2nPI;
- double e_4nPI;
- double n;
-
- n = (double)self->n;
-
- e_nPI = exp( n * M_PI );
- e_2nPI = e_nPI * e_nPI;
- e_4nPI = e_2nPI * e_2nPI;
-
- E = (4.0 * n * n * M_PI * M_PI + 2.0 ) * e_2nPI - e_4nPI - 1.0;
-
- self->A = ( e_2nPI - 1.0 )* e_nPI / E;
- self->B = self->A;
-
- self->C = ( 2.0 * n * M_PI - e_2nPI + 1.0 ) * e_nPI / E;
- self->D = - ( 2.0 * n * M_PI * e_2nPI - e_2nPI + 1.0 ) * e_nPI / E;
-}
-
-void StgFEM_LidDrivenStokesAnalytic_VelocityFunction( void* data, double* coord, double* velocity ) {
- StgFEM_LidDrivenStokesAnalytic* self = (StgFEM_LidDrivenStokesAnalytic*)data;
- double x,y;
- double n;
- double A, B, C, D;
-
- n = (double)self->n;
- A = self->A;
- B = self->B;
- C = self->C;
- D = self->D;
-
- /* get copy of coords */
- x = coord[I_AXIS];
- y = coord[J_AXIS];
-
- velocity[ I_AXIS ] = sin( n * M_PI * x ) *
- ( ( A * n * M_PI + C + C * n * M_PI * y) *exp( n * M_PI * y )
- - ( B * n * M_PI - D + D * n * M_PI * y ) * exp( - n * M_PI * y ) );
- velocity[ J_AXIS ] = - n * M_PI * cos( n * M_PI * x ) *
- ( ( A + C * y ) * exp( n * M_PI * y )
- + ( B + D * y ) * exp( - n * M_PI * y ) );
-}
-
-
-void StgFEM_LidDrivenStokesAnalytic_PressureFunction( void* data, double* coord, double* pressure ) {
- StgFEM_LidDrivenStokesAnalytic* self = (StgFEM_LidDrivenStokesAnalytic*)data;
- double x,y;
- double n;
- double A, B, C, D;
-
- n = (double)self->n;
- A = self->A;
- B = self->B;
- C = self->C;
- D = self->D;
-
- /* get copy of coords */
- x = coord[I_AXIS];
- y = coord[J_AXIS];
-
- *pressure = - 2.0 * n * M_PI * cos( n * M_PI * x ) * ( C * exp( n * M_PI * y ) + D * exp( - n * M_PI * y ) );
-}
-
-void _StgFEM_LidDrivenStokesAnalytic_AssignFromXML( void* codelet, Stg_ComponentFactory* cf, void* data ) {
- StgFEM_LidDrivenStokesAnalytic *self = (StgFEM_LidDrivenStokesAnalytic*)codelet;
-
- unsigned int* waveSpeed;
-
- _FieldTest_AssignFromXML( self, cf, data );
-
- /* Set constants */
- *waveSpeed = Stg_ComponentFactory_GetRootDictUnsignedInt( cf, (Dictionary_Entry_Key)"sinusoidalLidWavenumber", 1 );
- self->n = *waveSpeed;
-
- StgFEM_LidDrivenStokesAnalytic_CalculateConstants( (FieldTest*)self );
-}
-
-void _StgFEM_LidDrivenStokesAnalytic_Build( void* codelet, void* data ) {
- StgFEM_LidDrivenStokesAnalytic *self = (StgFEM_LidDrivenStokesAnalytic*)codelet;
-
- _FieldTest_Build( self, data );
-
- /* set the analytic solution functions for the feVariables - must be in the same order as the XML */
- FieldTest_AddAnalyticSolutionFuncToListAtIndex( self, 0, StgFEM_LidDrivenStokesAnalytic_VelocityFunction, 0 );
- FieldTest_AddAnalyticSolutionFuncToListAtIndex( self, 1, StgFEM_LidDrivenStokesAnalytic_PressureFunction, 1 );
-}
-
-void _StgFEM_LidDrivenStokesAnalytic_Initialise( void* codelet, void* data ) {
- _FieldTest_Initialise( codelet, data );
-}
-
-
-void* _StgFEM_LidDrivenStokesAnalytic_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(StgFEM_LidDrivenStokesAnalytic);
- Type type = StgFEM_LidDrivenStokesAnalytic_Type;
- Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
- Stg_Class_PrintFunction* _print = _FieldTest_Print;
- Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_LidDrivenStokesAnalytic_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _StgFEM_LidDrivenStokesAnalytic_AssignFromXML;
- Stg_Component_BuildFunction* _build = _StgFEM_LidDrivenStokesAnalytic_Build;
- Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
- Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
-}
-
-Index StgFEM_LidDrivenStokesAnalytic_Register( PluginsManager* pluginsManager ) {
- Journal_DPrintf( StgFEM_Debug, "In: %s( void* )\n", __func__ );
-
- return PluginsManager_Submit( pluginsManager, StgFEM_LidDrivenStokesAnalytic_Type, (Name)"0", _StgFEM_LidDrivenStokesAnalytic_DefaultNew );
-}
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/StokesMomentumUzawa/tests/LidDrivenStokesAnalytic/LidDrivenStokesAnalytic.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Apps/StokesMomentumUzawa/tests/LidDrivenStokesAnalytic/LidDrivenStokesAnalytic.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,182 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: LidDrivenStokesAnalytic.c 922 2007-07-25 03:01:19Z DavidLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+#include <assert.h>
+#include <math.h>
+
+const Type StgFEM_LidDrivenStokesAnalytic_Type = "StgFEM_LidDrivenStokesAnalytic";
+
+typedef struct {
+ __FieldTest;
+ unsigned int n;
+ double A, B, C, D;
+} StgFEM_LidDrivenStokesAnalytic;
+
+void StgFEM_LidDrivenStokesAnalytic_CalculateConstants( FieldTest *fieldTest ) {
+ StgFEM_LidDrivenStokesAnalytic* self = (StgFEM_LidDrivenStokesAnalytic*)fieldTest;
+ double E;
+ double e_nPI;
+ double e_2nPI;
+ double e_4nPI;
+ double n;
+
+ n = (double)self->n;
+
+ e_nPI = exp( n * M_PI );
+ e_2nPI = e_nPI * e_nPI;
+ e_4nPI = e_2nPI * e_2nPI;
+
+ E = (4.0 * n * n * M_PI * M_PI + 2.0 ) * e_2nPI - e_4nPI - 1.0;
+
+ self->A = ( e_2nPI - 1.0 )* e_nPI / E;
+ self->B = self->A;
+
+ self->C = ( 2.0 * n * M_PI - e_2nPI + 1.0 ) * e_nPI / E;
+ self->D = - ( 2.0 * n * M_PI * e_2nPI - e_2nPI + 1.0 ) * e_nPI / E;
+}
+
+void StgFEM_LidDrivenStokesAnalytic_VelocityFunction( void* data, double* coord, double* velocity ) {
+ StgFEM_LidDrivenStokesAnalytic* self = (StgFEM_LidDrivenStokesAnalytic*)data;
+ double x,y;
+ double n;
+ double A, B, C, D;
+
+ n = (double)self->n;
+ A = self->A;
+ B = self->B;
+ C = self->C;
+ D = self->D;
+
+ /* get copy of coords */
+ x = coord[I_AXIS];
+ y = coord[J_AXIS];
+
+ velocity[ I_AXIS ] = sin( n * M_PI * x ) *
+ ( ( A * n * M_PI + C + C * n * M_PI * y) *exp( n * M_PI * y )
+ - ( B * n * M_PI - D + D * n * M_PI * y ) * exp( - n * M_PI * y ) );
+ velocity[ J_AXIS ] = - n * M_PI * cos( n * M_PI * x ) *
+ ( ( A + C * y ) * exp( n * M_PI * y )
+ + ( B + D * y ) * exp( - n * M_PI * y ) );
+}
+
+
+void StgFEM_LidDrivenStokesAnalytic_PressureFunction( void* data, double* coord, double* pressure ) {
+ StgFEM_LidDrivenStokesAnalytic* self = (StgFEM_LidDrivenStokesAnalytic*)data;
+ double x,y;
+ double n;
+ double A, B, C, D;
+
+ n = (double)self->n;
+ A = self->A;
+ B = self->B;
+ C = self->C;
+ D = self->D;
+
+ /* get copy of coords */
+ x = coord[I_AXIS];
+ y = coord[J_AXIS];
+
+ *pressure = - 2.0 * n * M_PI * cos( n * M_PI * x ) * ( C * exp( n * M_PI * y ) + D * exp( - n * M_PI * y ) );
+}
+
+void _StgFEM_LidDrivenStokesAnalytic_AssignFromXML( void* codelet, Stg_ComponentFactory* cf, void* data ) {
+ StgFEM_LidDrivenStokesAnalytic *self = (StgFEM_LidDrivenStokesAnalytic*)codelet;
+
+ unsigned int* waveSpeed;
+
+ _FieldTest_AssignFromXML( self, cf, data );
+
+ /* Set constants */
+ *waveSpeed = Stg_ComponentFactory_GetRootDictUnsignedInt( cf, (Dictionary_Entry_Key)"sinusoidalLidWavenumber", 1 );
+ self->n = *waveSpeed;
+
+ StgFEM_LidDrivenStokesAnalytic_CalculateConstants( (FieldTest*)self );
+}
+
+void _StgFEM_LidDrivenStokesAnalytic_Build( void* codelet, void* data ) {
+ StgFEM_LidDrivenStokesAnalytic *self = (StgFEM_LidDrivenStokesAnalytic*)codelet;
+
+ _FieldTest_Build( self, data );
+
+ /* set the analytic solution functions for the feVariables - must be in the same order as the XML */
+ FieldTest_AddAnalyticSolutionFuncToListAtIndex( self, 0, StgFEM_LidDrivenStokesAnalytic_VelocityFunction, 0 );
+ FieldTest_AddAnalyticSolutionFuncToListAtIndex( self, 1, StgFEM_LidDrivenStokesAnalytic_PressureFunction, 1 );
+}
+
+void _StgFEM_LidDrivenStokesAnalytic_Initialise( void* codelet, void* data ) {
+ _FieldTest_Initialise( codelet, data );
+}
+
+
+void* _StgFEM_LidDrivenStokesAnalytic_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(StgFEM_LidDrivenStokesAnalytic);
+ Type type = StgFEM_LidDrivenStokesAnalytic_Type;
+ Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
+ Stg_Class_PrintFunction* _print = _FieldTest_Print;
+ Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_LidDrivenStokesAnalytic_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _StgFEM_LidDrivenStokesAnalytic_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _StgFEM_LidDrivenStokesAnalytic_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
+}
+
+Index StgFEM_LidDrivenStokesAnalytic_Register( PluginsManager* pluginsManager ) {
+ Journal_DPrintf( StgFEM_Debug, "In: %s( void* )\n", __func__ );
+
+ return PluginsManager_Submit( pluginsManager, StgFEM_LidDrivenStokesAnalytic_Type, (Name)"0", _StgFEM_LidDrivenStokesAnalytic_DefaultNew );
+}
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/StokesMomentumUzawa/tests/LinearVelocityAnalytic/LinearVelocityAnalytic.c
--- a/Apps/StokesMomentumUzawa/tests/LinearVelocityAnalytic/LinearVelocityAnalytic.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,380 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: LinearVelocityAnalytic.c 1111 2008-04-23 04:12:36Z RobertTurnbull $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-#include <string.h>
-
-const Type LinearVelocityAnalytic_Type = "LinearVelocityAnalytic";
-
-typedef struct {
- __AnalyticSolution
- FeVariable* velocityField;
- double nodeVelocity[8][3];
- double nodeCoords[8][3];
- int cornerNodeCount;
-} LinearVelocityAnalytic;
-
-Index Grid_ProjectIJK( Grid* grid, Index i, Index j, Index k ) {
- IJK ijk = {0,0,0};
-
- ijk[0] = i;
- ijk[1] = j;
- ijk[2] = k;
-
- return Grid_Project( grid, ijk );
-}
-Index Grid_ProjectIJK_MinMax( Grid* grid, Bool iIsMax, Bool jIsMax, Bool kIsMax ) {
- IJK ijk = {0,0,0};
-
- if ( iIsMax )
- ijk[0] = grid->sizes[0] - 1;
- if ( jIsMax )
- ijk[1] = grid->sizes[1] - 1;
- if ( kIsMax )
- ijk[2] = grid->sizes[2] - 1;
-
- return Grid_Project( grid, ijk );
-}
-
-void LinearVelocityAnalytic_GetCornerNodeVelocities(void* analyticSolution) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
- Grid* vertGrid;
- Node_GlobalIndex nodeMapper[8];
- FeVariable* velocityField = self->velocityField;
- FeMesh* mesh = velocityField->feMesh;
- Dimension_Index dim = velocityField->dim;
- Node_Index globalNode_I;
- Node_Index ii;
-
- vertGrid = *(Grid**)ExtensionManager_Get( mesh->info, mesh, ExtensionManager_GetHandle( mesh->info, (Name)"vertexGrid" ) );
-
- /* Find global indicies of nodes */
- self->cornerNodeCount = 4;
- nodeMapper[0] = Grid_ProjectIJK_MinMax( vertGrid, 0, 0, 0 );
- nodeMapper[1] = Grid_ProjectIJK_MinMax( vertGrid, 1, 0, 0 );
- nodeMapper[2] = Grid_ProjectIJK_MinMax( vertGrid, 0, 1, 0 );
- nodeMapper[3] = Grid_ProjectIJK_MinMax( vertGrid, 1, 1, 0 );
- if ( dim == 3 ) {
- self->cornerNodeCount = 8;
- nodeMapper[4] = Grid_ProjectIJK_MinMax( vertGrid, 0, 0, 1 );
- nodeMapper[5] = Grid_ProjectIJK_MinMax( vertGrid, 1, 0, 1 );
- nodeMapper[6] = Grid_ProjectIJK_MinMax( vertGrid, 0, 1, 1 );
- nodeMapper[7] = Grid_ProjectIJK_MinMax( vertGrid, 1, 1, 1 );
- }
-
- /* Loop over corner nodes */
- for ( ii = 0 ; ii < self->cornerNodeCount ; ii++ ) {
- globalNode_I = nodeMapper[ ii ];
- FeVariable_GetValueAtNodeGlobal( velocityField, globalNode_I, self->nodeVelocity[ii] );
- FeVariable_GetCoordAtNodeGlobal( velocityField, globalNode_I, self->nodeCoords[ii] );
- }
-}
-
-void GetLocalCoords( LinearVelocityAnalytic* self, double* coord, double* xi ) {
- FeVariable* velocityField = self->velocityField;
- XYZ min;
- XYZ max;
- Dimension_Index dim = velocityField->dim;
- Dimension_Index dim_I;
-
- _FeVariable_GetMinAndMaxGlobalCoords( velocityField, min, max );
- for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
- xi[ dim_I ] = 2.0 * (coord[ dim_I ] - min[ dim_I ])/(max[dim_I] - min[dim_I]) - 1;
- }
-}
-
-/* Do a normal linear interpolation as if the box were a FEM element */
-void LinearVelocityAnalytic_VelocityFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* velocity ) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
- FeVariable* velocityField = self->velocityField;
- FeMesh* mesh = velocityField->feMesh;
- Dimension_Index dim = velocityField->dim;
- Dimension_Index dim_I;
- XYZ xi;
- double Ni[8];
- Node_Index ii;
- ElementType* elementType;
-
- /* Transform the coordinate into a master coordinate system */
- GetLocalCoords( self, coord, xi );
-
- /* Get Shape Functions */
- elementType = FeMesh_GetElementType( mesh, 0 );
- ElementType_EvaluateShapeFunctionsAt( elementType, xi, Ni );
-
- /* Do interpolation */
- /* Loop over corner nodes */
- memset( velocity, 0, dim*sizeof(double) );
- for ( ii = 0 ; ii < self->cornerNodeCount ; ii++ ) {
- for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
- velocity[ dim_I ] += Ni[ ii ] * self->nodeVelocity[ii][ dim_I ];
- }
- }
-}
-void LinearVelocityAnalytic_PressureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* pressure ) {
- *pressure = 0.0;
-}
-
-void LinearVelocityAnalytic_VelocityGradientsFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* velocityGradients ) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
- FeVariable* velocityField = self->velocityField;
- FeMesh* mesh = velocityField->feMesh;
- ElementType* elementType;
- XYZ xi;
- double jac[3][3];
- double cof[3][3]; /* cofactors */
- double detJac;
- Node_Index node_I;
- double** GNi;
- double** GNx;
- double* nodeCoord;
- double nodeValue;
- Dimension_Index dim = velocityField->dim;
- Dimension_Index i, j, dx, dxi;
- Dimension_Index dim_I;
-
- /* Transform the coordinate into a master coordinate system */
- GetLocalCoords( self, coord, xi );
-
- GNi = Memory_Alloc_2DArray( double, dim, self->cornerNodeCount, (Name)"GNi" );
- GNx = Memory_Alloc_2DArray( double, dim, self->cornerNodeCount, (Name)"GNx" );
-
- /* Get Shape Functions */
- elementType = FeMesh_GetElementType( mesh, 0 );
- elementType->_evaluateShapeFunctionLocalDerivsAt( elementType, xi, GNi );
-
- /* build the jacobian matrix */
- /*
- jac = \sum_i d/d\xi( N_i ) x_i \sum_i d/d\xi( N_i ) y_i
- \sum_i d/d\eta( N_i ) x_i \sum_i d/d\eta( N_i ) y_i
- */
- if( dim == 2 ) {
- jac[0][0] = jac[0][1] = jac[1][0] = jac[1][1] = 0.0;
- for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
- nodeCoord = self->nodeCoords[ node_I ];
- jac[0][0] = jac[0][0] + GNi[0][node_I] * nodeCoord[0];
- jac[0][1] = jac[0][1] + GNi[0][node_I] * nodeCoord[1];
-
- jac[1][0] = jac[1][0] + GNi[1][node_I] * nodeCoord[0];
- jac[1][1] = jac[1][1] + GNi[1][node_I] * nodeCoord[1];
- }
- }
-
- if( dim == 3 ) {
- jac[0][0] = jac[0][1] = jac[0][2] = 0.0;
- jac[1][0] = jac[1][1] = jac[1][2] = 0.0;
- jac[2][0] = jac[2][1] = jac[2][2] = 0.0;
- for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
- nodeCoord = self->nodeCoords[ node_I ];
- jac[0][0] = jac[0][0] + GNi[0][node_I] * nodeCoord[0];
- jac[0][1] = jac[0][1] + GNi[0][node_I] * nodeCoord[1];
- jac[0][2] = jac[0][2] + GNi[0][node_I] * nodeCoord[2];
-
- jac[1][0] = jac[1][0] + GNi[1][node_I] * nodeCoord[0];
- jac[1][1] = jac[1][1] + GNi[1][node_I] * nodeCoord[1];
- jac[1][2] = jac[1][2] + GNi[1][node_I] * nodeCoord[2];
-
- jac[2][0] = jac[2][0] + GNi[2][node_I] * nodeCoord[0];
- jac[2][1] = jac[2][1] + GNi[2][node_I] * nodeCoord[1];
- jac[2][2] = jac[2][2] + GNi[2][node_I] * nodeCoord[2];
- }
- }
-
- /* get determinant of the jacobian matrix */
- if( dim == 2 ) {
- detJac = jac[0][0]*jac[1][1] - jac[0][1]*jac[1][0];
- }
- if( dim == 3 ) {
- detJac = jac[0][0]*( jac[1][1]*jac[2][2] - jac[1][2]*jac[2][1] )
- - jac[0][1]*( jac[1][0]*jac[2][2] - jac[1][2]*jac[2][0] )
- + jac[0][2]*( jac[1][0]*jac[2][1] - jac[1][1]*jac[2][0] );
- }
-
- /* invert the jacobian matrix A^-1 = adj(A)/det(A) */
- if( dim == 2 ) {
- double tmp = jac[0][0];
- jac[0][0] = jac[1][1]/detJac;
- jac[1][1] = tmp/detJac;
- jac[0][1] = -jac[0][1]/detJac;
- jac[1][0] = -jac[1][0]/detJac;
- }
- if( dim == 3 ) {
- /*
- 00 01 02
- 10 11 12
- 20 21 22
- */
- cof[0][0] = jac[1][1]*jac[2][2] - jac[1][2]*jac[2][1];
- cof[1][0] = -(jac[1][0]*jac[2][2] - jac[1][2]*jac[2][0]);
- cof[2][0] = jac[1][0]*jac[2][1] - jac[1][1]*jac[2][0];
-
- cof[0][1] = -(jac[0][1]*jac[2][2] - jac[0][2]*jac[2][1]);
- cof[1][1] = jac[0][0]*jac[2][2] - jac[0][2]*jac[2][0];
- cof[2][1] = -(jac[0][0]*jac[2][1] - jac[0][1]*jac[2][0]);
-
- cof[0][2] = jac[0][1]*jac[1][2] - jac[0][2]*jac[1][1];
- cof[1][2] = -(jac[0][0]*jac[1][2] - jac[0][2]*jac[1][0]);
- cof[2][2] = jac[0][0]*jac[1][1] - jac[0][1]*jac[1][0];
-
- for( i=0; i<dim; i++ ) {
- for( j=0; j<dim; j++ ) {
- jac[i][j] = cof[i][j]/detJac;
- }
- }
-
-
- }
-
- /* get global derivs Ni_x, Ni_y and Ni_z if dim == 3 */
- for( dx=0; dx<dim; dx++ ) {
- for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
- double globalSF_DerivVal = 0.0;
- for(dxi=0; dxi<dim; dxi++) {
- globalSF_DerivVal = globalSF_DerivVal + GNi[dxi][node_I] * jac[dx][dxi];
- }
-
- GNx[dx][node_I] = globalSF_DerivVal;
- }
- }
-
- /* Initialise velocity gradients */
- memset( velocityGradients, 0, sizeof( double ) * dim * dim );
-
- for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
- /* Interpolate derivative from nodes */
- for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
- nodeValue = self->nodeVelocity[ node_I ][ dim_I ];
-
- velocityGradients[dim_I*dim + 0] += GNx[0][node_I] * nodeValue;
- velocityGradients[dim_I*dim + 1] += GNx[1][node_I] * nodeValue;
- if( dim == 3 )
- velocityGradients[dim_I*dim + 2] += GNx[2][node_I] * nodeValue;
- }
- }
- Memory_Free( GNi );
- Memory_Free( GNx );
-}
-
-void LinearVelocityAnalytic_StrainRateFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* strainRate ) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
- Dimension_Index dim = self->velocityField->dim;
- TensorArray velocityGradients;
-
- /* Get Velocity Gradients */
- LinearVelocityAnalytic_VelocityGradientsFunction( self, analyticFeVariable, coord, velocityGradients );
-
- /* Get Strain Rate */
- TensorArray_GetSymmetricPart( velocityGradients, dim, strainRate );
-}
-
-void LinearVelocityAnalytic_StrainRateInvFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* strainRateInv ) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
- Dimension_Index dim = self->velocityField->dim;
- SymmetricTensor strainRate;
-
- /* Get Strain Rate */
- LinearVelocityAnalytic_StrainRateFunction( self, analyticFeVariable, coord, strainRate );
-
- /* Get Invariant */
- *strainRateInv = SymmetricTensor_2ndInvariant( strainRate, dim );
-}
-
-void _LinearVelocityAnalytic_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
- FeVariable* pressureField;
- FeVariable* strainRateField;
- FeVariable* strainRateInvField;
-
- _AnalyticSolution_AssignFromXML( self, cf, data );
-
- self->velocityField = Stg_ComponentFactory_ConstructByName( cf, (Name)"VelocityField", FeVariable, True, data );
- AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, self->velocityField, LinearVelocityAnalytic_VelocityFunction );
-
- pressureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"PressureField", FeVariable, True, data );
- AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, pressureField, LinearVelocityAnalytic_PressureFunction );
-
- strainRateField = Stg_ComponentFactory_ConstructByName( cf, (Name)"StrainRateField", FeVariable, False, data );
- if ( strainRateField )
- AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, strainRateField, LinearVelocityAnalytic_StrainRateFunction );
-
- strainRateInvField = Stg_ComponentFactory_ConstructByName( cf, (Name)"StrainRateInvariantField", FeVariable, False, data );
- if ( strainRateInvField )
- AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, strainRateInvField, LinearVelocityAnalytic_StrainRateInvFunction );
-}
-
-void _LinearVelocityAnalytic_Initialise( void* analyticSolution, void* data ) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
-
- Stg_Component_Initialise( self->velocityField, data, False );
- LinearVelocityAnalytic_GetCornerNodeVelocities( self );
-
- _AnalyticSolution_Initialise( self, data );
-}
-
-void* _LinearVelocityAnalytic_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(LinearVelocityAnalytic);
- Type type = LinearVelocityAnalytic_Type;
- Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
- Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
- Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LinearVelocityAnalytic_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _LinearVelocityAnalytic_AssignFromXML;
- Stg_Component_BuildFunction* _build = _AnalyticSolution_Build;
- Stg_Component_InitialiseFunction* _initialise = _LinearVelocityAnalytic_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
- Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_LinearVelocityAnalytic_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, LinearVelocityAnalytic_Type, (Name)"0", _LinearVelocityAnalytic_DefaultNew );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/StokesMomentumUzawa/tests/LinearVelocityAnalytic/LinearVelocityAnalytic.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Apps/StokesMomentumUzawa/tests/LinearVelocityAnalytic/LinearVelocityAnalytic.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,380 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: LinearVelocityAnalytic.c 1111 2008-04-23 04:12:36Z RobertTurnbull $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+#include <string.h>
+
+const Type LinearVelocityAnalytic_Type = "LinearVelocityAnalytic";
+
+typedef struct {
+ __AnalyticSolution
+ FeVariable* velocityField;
+ double nodeVelocity[8][3];
+ double nodeCoords[8][3];
+ int cornerNodeCount;
+} LinearVelocityAnalytic;
+
+Index Grid_ProjectIJK( Grid* grid, Index i, Index j, Index k ) {
+ IJK ijk = {0,0,0};
+
+ ijk[0] = i;
+ ijk[1] = j;
+ ijk[2] = k;
+
+ return Grid_Project( grid, ijk );
+}
+Index Grid_ProjectIJK_MinMax( Grid* grid, Bool iIsMax, Bool jIsMax, Bool kIsMax ) {
+ IJK ijk = {0,0,0};
+
+ if ( iIsMax )
+ ijk[0] = grid->sizes[0] - 1;
+ if ( jIsMax )
+ ijk[1] = grid->sizes[1] - 1;
+ if ( kIsMax )
+ ijk[2] = grid->sizes[2] - 1;
+
+ return Grid_Project( grid, ijk );
+}
+
+void LinearVelocityAnalytic_GetCornerNodeVelocities(void* analyticSolution) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+ Grid* vertGrid;
+ Node_GlobalIndex nodeMapper[8];
+ FeVariable* velocityField = self->velocityField;
+ FeMesh* mesh = velocityField->feMesh;
+ Dimension_Index dim = velocityField->dim;
+ Node_Index globalNode_I;
+ Node_Index ii;
+
+ vertGrid = *(Grid**)ExtensionManager_Get( mesh->info, mesh, ExtensionManager_GetHandle( mesh->info, (Name)"vertexGrid" ) );
+
+ /* Find global indicies of nodes */
+ self->cornerNodeCount = 4;
+ nodeMapper[0] = Grid_ProjectIJK_MinMax( vertGrid, 0, 0, 0 );
+ nodeMapper[1] = Grid_ProjectIJK_MinMax( vertGrid, 1, 0, 0 );
+ nodeMapper[2] = Grid_ProjectIJK_MinMax( vertGrid, 0, 1, 0 );
+ nodeMapper[3] = Grid_ProjectIJK_MinMax( vertGrid, 1, 1, 0 );
+ if ( dim == 3 ) {
+ self->cornerNodeCount = 8;
+ nodeMapper[4] = Grid_ProjectIJK_MinMax( vertGrid, 0, 0, 1 );
+ nodeMapper[5] = Grid_ProjectIJK_MinMax( vertGrid, 1, 0, 1 );
+ nodeMapper[6] = Grid_ProjectIJK_MinMax( vertGrid, 0, 1, 1 );
+ nodeMapper[7] = Grid_ProjectIJK_MinMax( vertGrid, 1, 1, 1 );
+ }
+
+ /* Loop over corner nodes */
+ for ( ii = 0 ; ii < self->cornerNodeCount ; ii++ ) {
+ globalNode_I = nodeMapper[ ii ];
+ FeVariable_GetValueAtNodeGlobal( velocityField, globalNode_I, self->nodeVelocity[ii] );
+ FeVariable_GetCoordAtNodeGlobal( velocityField, globalNode_I, self->nodeCoords[ii] );
+ }
+}
+
+void GetLocalCoords( LinearVelocityAnalytic* self, double* coord, double* xi ) {
+ FeVariable* velocityField = self->velocityField;
+ XYZ min;
+ XYZ max;
+ Dimension_Index dim = velocityField->dim;
+ Dimension_Index dim_I;
+
+ _FeVariable_GetMinAndMaxGlobalCoords( velocityField, min, max );
+ for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
+ xi[ dim_I ] = 2.0 * (coord[ dim_I ] - min[ dim_I ])/(max[dim_I] - min[dim_I]) - 1;
+ }
+}
+
+/* Do a normal linear interpolation as if the box were a FEM element */
+void LinearVelocityAnalytic_VelocityFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* velocity ) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+ FeVariable* velocityField = self->velocityField;
+ FeMesh* mesh = velocityField->feMesh;
+ Dimension_Index dim = velocityField->dim;
+ Dimension_Index dim_I;
+ XYZ xi;
+ double Ni[8];
+ Node_Index ii;
+ ElementType* elementType;
+
+ /* Transform the coordinate into a master coordinate system */
+ GetLocalCoords( self, coord, xi );
+
+ /* Get Shape Functions */
+ elementType = FeMesh_GetElementType( mesh, 0 );
+ ElementType_EvaluateShapeFunctionsAt( elementType, xi, Ni );
+
+ /* Do interpolation */
+ /* Loop over corner nodes */
+ memset( velocity, 0, dim*sizeof(double) );
+ for ( ii = 0 ; ii < self->cornerNodeCount ; ii++ ) {
+ for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
+ velocity[ dim_I ] += Ni[ ii ] * self->nodeVelocity[ii][ dim_I ];
+ }
+ }
+}
+void LinearVelocityAnalytic_PressureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* pressure ) {
+ *pressure = 0.0;
+}
+
+void LinearVelocityAnalytic_VelocityGradientsFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* velocityGradients ) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+ FeVariable* velocityField = self->velocityField;
+ FeMesh* mesh = velocityField->feMesh;
+ ElementType* elementType;
+ XYZ xi;
+ double jac[3][3];
+ double cof[3][3]; /* cofactors */
+ double detJac;
+ Node_Index node_I;
+ double** GNi;
+ double** GNx;
+ double* nodeCoord;
+ double nodeValue;
+ Dimension_Index dim = velocityField->dim;
+ Dimension_Index i, j, dx, dxi;
+ Dimension_Index dim_I;
+
+ /* Transform the coordinate into a master coordinate system */
+ GetLocalCoords( self, coord, xi );
+
+ GNi = Memory_Alloc_2DArray( double, dim, self->cornerNodeCount, (Name)"GNi" );
+ GNx = Memory_Alloc_2DArray( double, dim, self->cornerNodeCount, (Name)"GNx" );
+
+ /* Get Shape Functions */
+ elementType = FeMesh_GetElementType( mesh, 0 );
+ elementType->_evaluateShapeFunctionLocalDerivsAt( elementType, xi, GNi );
+
+ /* build the jacobian matrix */
+ /*
+ jac = \sum_i d/d\xi( N_i ) x_i \sum_i d/d\xi( N_i ) y_i
+ \sum_i d/d\eta( N_i ) x_i \sum_i d/d\eta( N_i ) y_i
+ */
+ if( dim == 2 ) {
+ jac[0][0] = jac[0][1] = jac[1][0] = jac[1][1] = 0.0;
+ for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
+ nodeCoord = self->nodeCoords[ node_I ];
+ jac[0][0] = jac[0][0] + GNi[0][node_I] * nodeCoord[0];
+ jac[0][1] = jac[0][1] + GNi[0][node_I] * nodeCoord[1];
+
+ jac[1][0] = jac[1][0] + GNi[1][node_I] * nodeCoord[0];
+ jac[1][1] = jac[1][1] + GNi[1][node_I] * nodeCoord[1];
+ }
+ }
+
+ if( dim == 3 ) {
+ jac[0][0] = jac[0][1] = jac[0][2] = 0.0;
+ jac[1][0] = jac[1][1] = jac[1][2] = 0.0;
+ jac[2][0] = jac[2][1] = jac[2][2] = 0.0;
+ for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
+ nodeCoord = self->nodeCoords[ node_I ];
+ jac[0][0] = jac[0][0] + GNi[0][node_I] * nodeCoord[0];
+ jac[0][1] = jac[0][1] + GNi[0][node_I] * nodeCoord[1];
+ jac[0][2] = jac[0][2] + GNi[0][node_I] * nodeCoord[2];
+
+ jac[1][0] = jac[1][0] + GNi[1][node_I] * nodeCoord[0];
+ jac[1][1] = jac[1][1] + GNi[1][node_I] * nodeCoord[1];
+ jac[1][2] = jac[1][2] + GNi[1][node_I] * nodeCoord[2];
+
+ jac[2][0] = jac[2][0] + GNi[2][node_I] * nodeCoord[0];
+ jac[2][1] = jac[2][1] + GNi[2][node_I] * nodeCoord[1];
+ jac[2][2] = jac[2][2] + GNi[2][node_I] * nodeCoord[2];
+ }
+ }
+
+ /* get determinant of the jacobian matrix */
+ if( dim == 2 ) {
+ detJac = jac[0][0]*jac[1][1] - jac[0][1]*jac[1][0];
+ }
+ if( dim == 3 ) {
+ detJac = jac[0][0]*( jac[1][1]*jac[2][2] - jac[1][2]*jac[2][1] )
+ - jac[0][1]*( jac[1][0]*jac[2][2] - jac[1][2]*jac[2][0] )
+ + jac[0][2]*( jac[1][0]*jac[2][1] - jac[1][1]*jac[2][0] );
+ }
+
+ /* invert the jacobian matrix A^-1 = adj(A)/det(A) */
+ if( dim == 2 ) {
+ double tmp = jac[0][0];
+ jac[0][0] = jac[1][1]/detJac;
+ jac[1][1] = tmp/detJac;
+ jac[0][1] = -jac[0][1]/detJac;
+ jac[1][0] = -jac[1][0]/detJac;
+ }
+ if( dim == 3 ) {
+ /*
+ 00 01 02
+ 10 11 12
+ 20 21 22
+ */
+ cof[0][0] = jac[1][1]*jac[2][2] - jac[1][2]*jac[2][1];
+ cof[1][0] = -(jac[1][0]*jac[2][2] - jac[1][2]*jac[2][0]);
+ cof[2][0] = jac[1][0]*jac[2][1] - jac[1][1]*jac[2][0];
+
+ cof[0][1] = -(jac[0][1]*jac[2][2] - jac[0][2]*jac[2][1]);
+ cof[1][1] = jac[0][0]*jac[2][2] - jac[0][2]*jac[2][0];
+ cof[2][1] = -(jac[0][0]*jac[2][1] - jac[0][1]*jac[2][0]);
+
+ cof[0][2] = jac[0][1]*jac[1][2] - jac[0][2]*jac[1][1];
+ cof[1][2] = -(jac[0][0]*jac[1][2] - jac[0][2]*jac[1][0]);
+ cof[2][2] = jac[0][0]*jac[1][1] - jac[0][1]*jac[1][0];
+
+ for( i=0; i<dim; i++ ) {
+ for( j=0; j<dim; j++ ) {
+ jac[i][j] = cof[i][j]/detJac;
+ }
+ }
+
+
+ }
+
+ /* get global derivs Ni_x, Ni_y and Ni_z if dim == 3 */
+ for( dx=0; dx<dim; dx++ ) {
+ for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
+ double globalSF_DerivVal = 0.0;
+ for(dxi=0; dxi<dim; dxi++) {
+ globalSF_DerivVal = globalSF_DerivVal + GNi[dxi][node_I] * jac[dx][dxi];
+ }
+
+ GNx[dx][node_I] = globalSF_DerivVal;
+ }
+ }
+
+ /* Initialise velocity gradients */
+ memset( velocityGradients, 0, sizeof( double ) * dim * dim );
+
+ for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
+ /* Interpolate derivative from nodes */
+ for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
+ nodeValue = self->nodeVelocity[ node_I ][ dim_I ];
+
+ velocityGradients[dim_I*dim + 0] += GNx[0][node_I] * nodeValue;
+ velocityGradients[dim_I*dim + 1] += GNx[1][node_I] * nodeValue;
+ if( dim == 3 )
+ velocityGradients[dim_I*dim + 2] += GNx[2][node_I] * nodeValue;
+ }
+ }
+ Memory_Free( GNi );
+ Memory_Free( GNx );
+}
+
+void LinearVelocityAnalytic_StrainRateFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* strainRate ) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+ Dimension_Index dim = self->velocityField->dim;
+ TensorArray velocityGradients;
+
+ /* Get Velocity Gradients */
+ LinearVelocityAnalytic_VelocityGradientsFunction( self, analyticFeVariable, coord, velocityGradients );
+
+ /* Get Strain Rate */
+ TensorArray_GetSymmetricPart( velocityGradients, dim, strainRate );
+}
+
+void LinearVelocityAnalytic_StrainRateInvFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* strainRateInv ) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+ Dimension_Index dim = self->velocityField->dim;
+ SymmetricTensor strainRate;
+
+ /* Get Strain Rate */
+ LinearVelocityAnalytic_StrainRateFunction( self, analyticFeVariable, coord, strainRate );
+
+ /* Get Invariant */
+ *strainRateInv = SymmetricTensor_2ndInvariant( strainRate, dim );
+}
+
+void _LinearVelocityAnalytic_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+ FeVariable* pressureField;
+ FeVariable* strainRateField;
+ FeVariable* strainRateInvField;
+
+ _AnalyticSolution_AssignFromXML( self, cf, data );
+
+ self->velocityField = Stg_ComponentFactory_ConstructByName( cf, (Name)"VelocityField", FeVariable, True, data );
+ AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, self->velocityField, LinearVelocityAnalytic_VelocityFunction );
+
+ pressureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"PressureField", FeVariable, True, data );
+ AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, pressureField, LinearVelocityAnalytic_PressureFunction );
+
+ strainRateField = Stg_ComponentFactory_ConstructByName( cf, (Name)"StrainRateField", FeVariable, False, data );
+ if ( strainRateField )
+ AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, strainRateField, LinearVelocityAnalytic_StrainRateFunction );
+
+ strainRateInvField = Stg_ComponentFactory_ConstructByName( cf, (Name)"StrainRateInvariantField", FeVariable, False, data );
+ if ( strainRateInvField )
+ AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, strainRateInvField, LinearVelocityAnalytic_StrainRateInvFunction );
+}
+
+void _LinearVelocityAnalytic_Initialise( void* analyticSolution, void* data ) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+
+ Stg_Component_Initialise( self->velocityField, data, False );
+ LinearVelocityAnalytic_GetCornerNodeVelocities( self );
+
+ _AnalyticSolution_Initialise( self, data );
+}
+
+void* _LinearVelocityAnalytic_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(LinearVelocityAnalytic);
+ Type type = LinearVelocityAnalytic_Type;
+ Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
+ Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
+ Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LinearVelocityAnalytic_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _LinearVelocityAnalytic_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _AnalyticSolution_Build;
+ Stg_Component_InitialiseFunction* _initialise = _LinearVelocityAnalytic_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
+ Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_LinearVelocityAnalytic_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, LinearVelocityAnalytic_Type, (Name)"0", _LinearVelocityAnalytic_DefaultNew );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/StokesMomentumUzawa/tests/SimpleShearAnalytic/SimpleShearAnalytic.c
--- a/Apps/StokesMomentumUzawa/tests/SimpleShearAnalytic/SimpleShearAnalytic.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: SimpleShearAnalytic.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-const Type SimpleShearAnalytic_Type = "SimpleShearAnalytic";
-
-typedef struct {
- __AnalyticSolution
- double centreY;
- double factor;
-} SimpleShearAnalytic;
-
-
-void SimpleShearAnalytic_VelocityFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* velocity ) {
- SimpleShearAnalytic *self = (SimpleShearAnalytic*)analyticSolution;
-
- velocity[ I_AXIS ] = self->factor * (coord[ J_AXIS ] - self->centreY);
- velocity[ J_AXIS ] = 0.0;
-}
-
-
-void SimpleShearAnalytic_PressureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* pressure ) {
- *pressure = 0.0;
-}
-
-void _SimpleShearAnalytic_Build( void* analyticSolution, void* data ) {
- SimpleShearAnalytic *self = (SimpleShearAnalytic*)analyticSolution;
-
- _AnalyticSolution_Build( self, data );
-}
-
-void _SimpleShearAnalytic_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- SimpleShearAnalytic *self = (SimpleShearAnalytic*)analyticSolution;
- FeVariable* velocityField;
- FeVariable* pressureField;
-
- _AnalyticSolution_AssignFromXML( self, cf, data );
-
- velocityField = Stg_ComponentFactory_ConstructByName( cf, (Name)"VelocityField", FeVariable, True, data );
- AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, velocityField, SimpleShearAnalytic_VelocityFunction );
-
- pressureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"PressureField", FeVariable, True, data );
- AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, pressureField, SimpleShearAnalytic_PressureFunction );
-
- /* Set constants */
- self->centreY = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"simpleShearCentreY", 0.0 );
- self->factor = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SimpleShearFactor", 1.0 );
-}
-
-void* _SimpleShearAnalytic_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(SimpleShearAnalytic);
- Type type = SimpleShearAnalytic_Type;
- Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
- Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
- Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _SimpleShearAnalytic_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _SimpleShearAnalytic_AssignFromXML;
- Stg_Component_BuildFunction* _build = _SimpleShearAnalytic_Build;
- Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
- Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_SimpleShearAnalytic_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, SimpleShearAnalytic_Type, (Name)"0", _SimpleShearAnalytic_DefaultNew );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/StokesMomentumUzawa/tests/SimpleShearAnalytic/SimpleShearAnalytic.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Apps/StokesMomentumUzawa/tests/SimpleShearAnalytic/SimpleShearAnalytic.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,117 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: SimpleShearAnalytic.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+const Type SimpleShearAnalytic_Type = "SimpleShearAnalytic";
+
+typedef struct {
+ __AnalyticSolution
+ double centreY;
+ double factor;
+} SimpleShearAnalytic;
+
+
+void SimpleShearAnalytic_VelocityFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* velocity ) {
+ SimpleShearAnalytic *self = (SimpleShearAnalytic*)analyticSolution;
+
+ velocity[ I_AXIS ] = self->factor * (coord[ J_AXIS ] - self->centreY);
+ velocity[ J_AXIS ] = 0.0;
+}
+
+
+void SimpleShearAnalytic_PressureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* pressure ) {
+ *pressure = 0.0;
+}
+
+void _SimpleShearAnalytic_Build( void* analyticSolution, void* data ) {
+ SimpleShearAnalytic *self = (SimpleShearAnalytic*)analyticSolution;
+
+ _AnalyticSolution_Build( self, data );
+}
+
+void _SimpleShearAnalytic_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ SimpleShearAnalytic *self = (SimpleShearAnalytic*)analyticSolution;
+ FeVariable* velocityField;
+ FeVariable* pressureField;
+
+ _AnalyticSolution_AssignFromXML( self, cf, data );
+
+ velocityField = Stg_ComponentFactory_ConstructByName( cf, (Name)"VelocityField", FeVariable, True, data );
+ AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, velocityField, SimpleShearAnalytic_VelocityFunction );
+
+ pressureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"PressureField", FeVariable, True, data );
+ AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, pressureField, SimpleShearAnalytic_PressureFunction );
+
+ /* Set constants */
+ self->centreY = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"simpleShearCentreY", 0.0 );
+ self->factor = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SimpleShearFactor", 1.0 );
+}
+
+void* _SimpleShearAnalytic_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(SimpleShearAnalytic);
+ Type type = SimpleShearAnalytic_Type;
+ Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
+ Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
+ Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _SimpleShearAnalytic_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _SimpleShearAnalytic_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _SimpleShearAnalytic_Build;
+ Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
+ Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_SimpleShearAnalytic_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, SimpleShearAnalytic_Type, (Name)"0", _SimpleShearAnalytic_DefaultNew );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/TempDiffusion/tests/LinearTemperatureField/LinearTemperatureField.c
--- a/Apps/TempDiffusion/tests/LinearTemperatureField/LinearTemperatureField.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: LinearTemperatureField.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-/** Pretty simple.
- * One time step with the diffusion coefficiants K = 1
- * TempBCs Bottom BC = 1, top BC = 0, sides = 0
- */
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-const Type LinearTemperatureField_Type = "LinearTemperatureField";
-
-typedef struct { __AnalyticSolution FeVariable* temperatureField; } LinearTemperatureField;
-
-void LinearTemperatureField_TemperatureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* value ) {
- *value = 1.0 - coord[ J_AXIS ];
-}
-
-
-void _LinearTemperatureField_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- LinearTemperatureField *self = (LinearTemperatureField*)analyticSolution;
-
- _AnalyticSolution_AssignFromXML( self, cf, data );
-
- self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"TemperatureField", FeVariable, True, data );
-
- AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, self->temperatureField, LinearTemperatureField_TemperatureFunction );
-}
-
-void _LinearTemperatureField_Build( void* analyticSolution, void* data ) {
- LinearTemperatureField *self = (LinearTemperatureField*)analyticSolution;
-
- _AnalyticSolution_Build( self, data );
-}
-
-void* _LinearTemperatureField_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(LinearTemperatureField);
- Type type = LinearTemperatureField_Type;
- Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
- Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
- Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LinearTemperatureField_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _LinearTemperatureField_AssignFromXML;
- Stg_Component_BuildFunction* _build = _LinearTemperatureField_Build;
- Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
- Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_LinearTemperatureField_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, LinearTemperatureField_Type, (Name)"0", _LinearTemperatureField_DefaultNew );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/TempDiffusion/tests/LinearTemperatureField/LinearTemperatureField.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Apps/TempDiffusion/tests/LinearTemperatureField/LinearTemperatureField.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,101 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: LinearTemperatureField.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+/** Pretty simple.
+ * One time step with the diffusion coefficiants K = 1
+ * TempBCs Bottom BC = 1, top BC = 0, sides = 0
+ */
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+const Type LinearTemperatureField_Type = "LinearTemperatureField";
+
+typedef struct { __AnalyticSolution FeVariable* temperatureField; } LinearTemperatureField;
+
+void LinearTemperatureField_TemperatureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* value ) {
+ *value = 1.0 - coord[ J_AXIS ];
+}
+
+
+void _LinearTemperatureField_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ LinearTemperatureField *self = (LinearTemperatureField*)analyticSolution;
+
+ _AnalyticSolution_AssignFromXML( self, cf, data );
+
+ self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"TemperatureField", FeVariable, True, data );
+
+ AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, self->temperatureField, LinearTemperatureField_TemperatureFunction );
+}
+
+void _LinearTemperatureField_Build( void* analyticSolution, void* data ) {
+ LinearTemperatureField *self = (LinearTemperatureField*)analyticSolution;
+
+ _AnalyticSolution_Build( self, data );
+}
+
+void* _LinearTemperatureField_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(LinearTemperatureField);
+ Type type = LinearTemperatureField_Type;
+ Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
+ Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
+ Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LinearTemperatureField_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _LinearTemperatureField_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _LinearTemperatureField_Build;
+ Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
+ Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_LinearTemperatureField_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, LinearTemperatureField_Type, (Name)"0", _LinearTemperatureField_DefaultNew );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/ThermalConvection/tests/ColumnViscosityAnalytic/ColumnViscosityAnalytic.c
--- a/Apps/ThermalConvection/tests/ColumnViscosityAnalytic/ColumnViscosityAnalytic.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2637 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: ColumnViscosityAnalytic.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-#include <assert.h>
-
-const Type ColumnViscosityAnalytic_Type = "ColumnViscosityAnalytic";
-
-typedef struct {
- __AnalyticSolution
- double ZA;
- double ZB;
- double xc;
- double C1A,C2A,C3A,C4A,C1B,C2B,C3B,C4B;
- FeVariable* velocityField;
- FeVariable* pressureField;
- FeVariable* stressField;
-} ColumnViscosityAnalytic;
-
-#define SMALL 1.0e-5
-#define IS_ODD(A) ( (A) % 2 == 1 )
-
-
-/** Analytic Solution taken from
- * Shijie Zhong. Analytic solutions for Stokes' flow with lateral variations in viscosity. Geophys. J. Int., 124:18-28, 1996.
- * All equations refer to this paper */
-
-void ColumnViscosityAnalytic_TemperatureIC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- FeVariable* temperatureField = (FeVariable*) FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- FeMesh* mesh = temperatureField->feMesh;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double x;
- double y;
- double kx;
- double ky;
- int wavenumberX;
- int wavenumberY;
- double L;
- double min[3], max[3];
-
- /* Find coordinate of node */
- coord = Mesh_GetVertex( mesh, node_lI );
-
- /* Make sure that the box has right dimensions */
- Mesh_GetGlobalCoordRange( mesh, min, max );
- assert( ( max[ J_AXIS ] - min[ J_AXIS ] - 1.0 ) < SMALL );
- L = max[ I_AXIS ] - min[ I_AXIS ];
-
- x = coord[ I_AXIS ] - min[ I_AXIS ];
- y = coord[ J_AXIS ] - min[ J_AXIS ];
-
- wavenumberX = Dictionary_GetInt_WithDefault( dictionary, (Dictionary_Entry_Key)"wavenumberX", 1 );
- wavenumberY = Dictionary_GetInt_WithDefault( dictionary, (Dictionary_Entry_Key)"wavenumberY", 1 );
-
- kx = wavenumberX * M_PI/ L;
- ky = wavenumberY * M_PI;
-
- *result = sin( ky * y ) * cos( kx * x );
-}
-
-void ColumnViscosityAnalytic_Constants( void* analyticSolution ) {
- ColumnViscosityAnalytic* self = (ColumnViscosityAnalytic* ) analyticSolution;
- double n, nx;
- double t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40;
- double t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80;
- double t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t115,t116,t117,t118,t119,t120;
- double t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160;
- double t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199;
- double t201,t202,t203,t204,t206,t207,t208,t209,t210,t211,t212,t213,t215,t216,t217,t218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240;
- double t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256,t257,t258,t259,t260,t261,t262,t263,t264,t265,t267,t268,t269,t270,t272,t273,t274,t275,t276,t277,t278,t279,t280;
- double t281,t282,t283,t284,t285,t286,t288,t289,t290,t291,t292,t295,t296,t297,t298,t299,t300,t301,t303,t304,t305,t307,t308,t310,t311,t312,t313,t314,t315,t316,t317,t318,t319,t320;
- double t321,t322,t323,t324,t325,t326,t327,t328,t329,t330,t331,t332,t334,t335,t336,t337,t338,t339,t340,t341,t342,t344,t345,t346,t347,t348,t349,t350,t351,t352,t353,t354,t355,t356,t358,t359,t360;
- double t361,t362,t363,t364,t365,t366,t367,t368,t369,t370,t371,t372,t373,t374,t375,t376,t377,t378,t379,t380,t381,t382,t383,t384,t385,t386,t387,t389,t390,t391,t393,t394,t395,t396,t397,t398;
- double t401,t402,t403,t404,t405,t406,t407,t408,t409,t410,t411,t412,t413,t414,t415,t416,t417,t418,t419,t421,t422,t423,t424,t425,t426,t427,t428,t429,t430,t431,t432,t433,t434,t436,t437,t438,t439,t440;
- double t441,t442,t443,t444,t445,t446,t447,t448,t450,t451,t453,t454,t455,t456,t457,t458,t459,t461,t462,t463,t464,t465,t466,t468,t469,t470,t471,t474,t475,t478,t480;
- double t482,t483,t484,t485,t488,t489,t490,t492,t493,t495,t497,t498,t499,t501,t502,t503,t504,t505,t507,t508,t509,t510,t511,t512,t513,t515,t518,t520;
- double t522,t525,t527,t528,t529,t530,t532,t533,t534,t535,t536,t538,t539,t541,t542,t544,t545,t546,t547,t548,t549,t550,t551,t552,t553,t554,t555,t556,t557,t560;
- double t561,t562,t563,t564,t567,t568,t571,t573,t575,t576,t578,t579,t583,t590,t591,t594,t595,t596,t597,t598,t600;
- double t601,t602,t604,t606,t607,t608,t611,t613,t615,t616,t617,t619,t621,t623,t624,t625,t626,t627,t629,t630,t632,t633,t634,t638,t639,t640;
- double t641,t642,t643,t644,t645,t647,t648,t649,t650,t651,t652,t653,t654,t655,t656,t657,t658,t659,t660,t662,t663,t665,t666,t667,t668,t670,t671,t672,t673,t674,t675,t676,t679,t680;
- double t682,t683,t684,t685,t686,t688,t689,t690,t691,t693,t694,t695,t696,t697,t698,t699,t700,t701,t702,t704,t705,t708,t709,t711,t712,t713,t714,t717,t718,t719;
- double t721,t722,t723,t726,t727,t728,t730,t733,t734,t735,t736,t737,t738,t739,t740,t741,t744,t745,t746,t749,t750,t752,t753,t754,t755,t757,t758,t759,t760;
- double t761,t762,t763,t764,t766,t767,t768,t770,t771,t772,t773,t774,t775,t776,t777,t778,t780,t781,t782,t785,t786,t789,t790,t791,t792,t793,t794,t795,t796,t797,t798,t800;
- double t801,t806,t807,t808,t809,t811,t812,t817,t818,t819,t821,t822,t824,t827,t828,t830,t834,t835,t837,t840;
- double t842,t843,t844,t845,t846,t849,t850,t853,t854,t855,t857,t858,t859,t860,t863,t864,t867,t868,t869,t873,t874,t877,t878,t879,t880;
- double t884,t888,t891,t894,t900,t901,t903,t904,t907,t908,t909,t911,t914,t915,t916,t919,t920;
- double t923,t924,t925,t926,t927,t929,t932,t935,t937,t939,t942,t943,t944,t945,t947,t948,t949,t950,t952,t953,t954,t955,t956,t957;
- double t961,t964,t965,t966,t967,t968,t969,t971,t972,t974,t977,t978,t981,t983,t987,t988,t992,t993,t994,t997,t998;
- double t1001,t1003,t1005,t1006,t1009,t1010,t1012,t1013,t1015,t1016,t1017,t1018,t1020,t1021,t1029,t1031,t1032,t1033,t1040;
- double t1041,t1042,t1044,t1047,t1050,t1054,t1055,t1057,t1058,t1063,t1068,t1069,t1070,t1079,t1080;
- double t1088,t1089,t1091,t1092,t1094,t1096,t1101,t1102,t1103,t1104,t1105,t1108,t1112,t1113,t1118,t1119,t1120;
- double t1121,t1122,t1123,t1124,t1125,t1126,t1127,t1128,t1129,t1130,t1132,t1133,t1134,t1135,t1138,t1139,t1140,t1141,t1142,t1145,t1146,t1148,t1149,t1150,t1153,t1154,t1156,t1157,t1158,t1159;
- double t1161,t1162,t1165,t1166,t1170,t1171,t1172,t1173,t1175,t1176,t1178,t1180,t1181,t1182,t1185,t1189,t1192,t1193,t1195,t1196,t1199;
- double t1201,t1203,t1209,t1210,t1211,t1213,t1214,t1218,t1221,t1224,t1225,t1226,t1228,t1233,t1234,t1235,t1236,t1237,t1240;
- double t1241,t1242,t1243,t1244,t1245,t1248,t1251,t1252,t1257,t1258,t1259,t1260,t1263,t1268,t1269,t1272,t1280;
- double t1282,t1283,t1284,t1285,t1287,t1288,t1289,t1292,t1293,t1296,t1297,t1300,t1304,t1307,t1310,t1311,t1312,t1316,t1317,t1320;
- double t1321,t1323,t1328,t1330,t1331,t1332,t1333,t1336,t1338,t1343,t1344,t1346,t1349,t1350,t1354;
- double t1366,t1369,t1370,t1371,t1376,t1378,t1380,t1383,t1386,t1387,t1388,t1391,t1393,t1399;
- double t1411,t1412,t1420,t1427;
- double t1450,t1456,t1468,t1472,t1474,t1478;
- double t1504,t1511;
- double t1545;
- double t1564,t1583;
-
-
- /* del_rho = sin(ny*Pi*y)*cos(nx*Pi*x) n=nx gives only non-zero terms*/
- n = 1;
- /* only one n in Fourier series because del_rho has cos term */
- nx = n;
-
- self->C1A = 0;
- /****************************************************************************************/
- t1 = nx * 0.3141592654e1;
- t2 = sin(t1);
- t3 = nx * t2;
- t4 = n * n;
- t5 = t4 * t4;
- t6 = 0.3141592654e1 * 0.3141592654e1;
- t8 = t3 * t5 * t6;
- t9 = self->ZA * self->xc;
- t12 = exp( self->xc * n * 0.3141592654e1);
- t13 = t12 * t12;
- t15 = n * 0.3141592654e1;
- t16 = exp(t15);
- t17 = t16 * t16;
- t18 = t17 * t16;
- t19 = self->ZB * t13 * t18;
- t20 = t9 * t19;
- t23 = self->ZA * self->ZA;
- t24 = nx * nx;
- t25 = t24 * nx;
- t26 = t23 * t25;
- t28 = t13 * t13;
- t29 = t28 * t13;
- t33 = nx * self->ZB;
- t34 = t1 * self->xc;
- t35 = sin(t34);
- t36 = t4 * n;
- t37 = t35 * t36;
- t38 = t33 * t37;
- t39 = 0.3141592654e1 * self->ZA;
- t40 = t13 * t12;
- t41 = t17 * t40;
- t45 = self->ZB * self->ZB;
- t46 = t45 * t24;
- t47 = t46 * t4;
- t48 = 0.3141592654e1 * self->xc;
- t49 = t13 * t17;
- t53 = self->xc * self->xc;
- t54 = t36 * t53;
- t56 = t54 * t6 * t45;
- t57 = cos(t34);
- t58 = t57 * t24;
- t59 = t28 * t12;
- t60 = t17 * t59;
- t61 = t58 * t60;
- t64 = t25 * t2;
- t65 = t64 * t15;
- t72 = nx * t23;
- t74 = t72 * t2 * t5;
- t75 = t6 * t53;
- t76 = t16 * t29;
- t80 = t23 * n;
- t81 = t80 * 0.3141592654e1;
- t82 = t18 * t28;
- t86 = nx * t5;
- t87 = t23 * t6;
- t89 = self->xc * t2;
- t90 = t13 * t18;
- t91 = t89 * t90;
- t94 = t28 * t28;
- t96 = t24 * n;
- t98 = t4 * t45;
- t99 = t98 * 0.3141592654e1;
- t100 = t58 * t41;
- t104 = 0.3141592654e1 * t25;
- t105 = self->ZA * n * t104;
- t106 = t2 * self->ZB;
- t110 = t17 * t17;
- t111 = self->ZA * t110;
- t116 = n * t28;
- t122 = t64 * t4 * t6;
- t126 = t23 * t29 * t4;
- t128 = t24 * self->xc;
- t132 = t36 * t23;
- t133 = t6 * t57;
- t135 = t128 * t41;
- t138 = t6 * self->xc;
- t142 = t72 * t2;
- t147 = 0.4e1 * t8 * t20 - 0.2e1 * t26 * t2 * t16 * t29 - 0.8e1 * t38 * t39 * t41 + 0.4e1 * t47 * t48 * t49 - 0.8e1 * t56 * t61 - 0.4e1 * t65 * t20 + 0.2e1 * t26 * t2 * t18 * t28 - 0.4e1 * t74 * t75 * t76 - 0.2e1 * t81 * t64 * t82 - 0.4e1 * t86 * t87 * t91 - t23 * t94 * t96 + 0.8e1 * t99 * t100 - 0.2e1 * t105 * t106 * t82 - 0.4e1 * t38 * t48 * t111 * t12 + 0.2e1 * t116 * self->ZB * t111 * t24 + 0.4e1 * t122 * t20 + 0.4e1 * t126 * 0.3141592654e1 * t17 * t128 + 0.8e1 * t132 * t133 * t135 + 0.4e1 * t74 * t138 * t76 - 0.2e1 * t142 * t4 * t18 * t28;
- t149 = self->ZA * t25 * t2;
- t150 = self->ZB * t28;
- t154 = t35 * t5;
- t155 = t72 * t154;
- t156 = t75 * t41;
- t159 = nx * self->ZA;
- t160 = t2 * t36;
- t161 = t159 * t160;
- t162 = 0.3141592654e1 * self->ZB;
- t163 = t28 * t16;
- t167 = t23 * t57;
- t168 = t167 * t24;
- t169 = n * t110;
- t170 = t169 * t40;
- t173 = self->ZA * self->ZB;
- t174 = t173 * t90;
- t177 = t36 * 0.3141592654e1;
- t181 = t80 * t104;
- t184 = n * t17;
- t188 = t17 * t29;
- t190 = t4 * 0.3141592654e1;
- t191 = t190 * t24;
- t206 = t138 * t60;
- t209 = t23 * t4;
- t211 = t209 * t6 * t25;
- t212 = t89 * t76;
- t216 = self->ZB * t16 * t29;
- t217 = t9 * t216;
- t220 = self->ZB * t110;
- t221 = self->ZA * t24;
- t222 = t221 * n;
- t225 = t132 * t75;
- t232 = t45 * t28;
- t233 = t110 * t24;
- t234 = t233 * n;
- t236 = t209 * 0.3141592654e1;
- t237 = t17 * self->xc;
- t239 = t237 * t13 * t24;
- t242 = -0.2e1 * t149 * t150 * t16 - 0.8e1 * t155 * t156 - 0.2e1 * t161 * t162 * t163 + 0.2e1 * t168 * t170 + 0.2e1 * t65 * t174 - 0.2e1 * t142 * t177 * t76 + 0.4e1 * t181 * t91 - 0.4e1 * t168 * t184 * t59 - 0.4e1 * t188 * t23 * t191 + 0.4e1 * t38 * t48 * self->ZA * t17 * t40 + 0.4e1 * t49 * t23 * t191 + 0.2e1 * t26 * t2 * t13 * t18 - 0.8e1 * t155 * t206 + 0.4e1 * t211 * t212 - 0.4e1 * t8 * t217 + 0.2e1 * t220 * t222 - 0.8e1 * t225 * t100 + 0.2e1 * t142 * t4 * t16 * t29 + t232 * t234 - 0.4e1 * t236 * t239;
- t244 = nx * t45;
- t245 = t244 * t37;
- t246 = t110 * t40;
- t251 = t237 * t59;
- t256 = t64 * t90;
- t260 = t36 * t45 * t133;
- t263 = t45 * t57;
- t264 = t263 * t24;
- t265 = t169 * t12;
- t269 = t6 * t36;
- t270 = t17 * t24;
- t274 = t110 * t13;
- t276 = t190 * t128;
- t279 = nx * t36;
- t281 = t28 * t40;
- t282 = t281 * t35;
- t286 = t138 * t41;
- t289 = t75 * t60;
- t296 = t190 * t173;
- t305 = t86 * t45 * t35;
- t312 = t33 * t154;
- t313 = t6 * self->ZA;
- t324 = t232 * t270;
- t327 = -0.2e1 * t245 * t48 * t246 + 0.4e1 * t159 * t37 * t162 * t251 + 0.4e1 * t209 * t75 * t256 + 0.8e1 * t260 * t135 + 0.2e1 * t264 * t265 + 0.32e2 * t9 * t150 * t269 * t270 + 0.4e1 * t274 * t23 * t276 + 0.2e1 * t279 * t45 * t282 * t48 + 0.8e1 * t155 * t286 + 0.8e1 * t155 * t289 - 0.8e1 * t150 * self->ZA * t96 * t17 + 0.8e1 * t296 * t61 - 0.2e1 * t105 * t106 * t163 - 0.2e1 * t81 * t256 - 0.8e1 * t305 * t156 - 0.4e1 * t33 * t282 * t177 * t9 - 0.16e2 * t312 * t313 * t237 * t40 - 0.4e1 * t168 * t184 * t40 + 0.2e1 * t168 * t265 + 0.16e2 * t269 * t53 * t324;
- t328 = t3 * t4;
- t331 = t72 * t37;
- t332 = t48 * t60;
- t335 = n * t94;
- t345 = t72 * t35;
- t349 = t173 * t57;
- t355 = t53 * t17;
- t364 = t54 * t6 * self->ZB;
- t365 = t28 * t17;
- t369 = self->xc * self->ZB;
- t370 = t269 * t369;
- t371 = self->ZA * t57;
- t373 = t371 * t270 * t40;
- t385 = nx * t35;
- t396 = t4 * self->xc;
- t397 = t396 * t162;
- t415 = t37 * t48;
- t418 = -0.32e2 * t364 * t365 * t221 - 0.16e2 * t370 * t373 - 0.4e1 * t331 * t48 * t41 + 0.4e1 * t86 * t23 * t53 * t6 * t2 * t90 + 0.2e1 * t385 * t177 * t23 * self->xc * t246 + 0.16e2 * t132 * t53 * t6 * t28 * t270 - 0.4e1 * t397 * t371 * t233 * t12 - 0.12e2 * t173 * t58 * t190 * t251 + 0.2e1 * t385 * t36 * 0.3141592654e1 * t23 * self->xc * t59 - 0.8e1 * t99 * t61 - 0.2e1 * t244 * t59 * t415;
- t427 = t371 * t270 * t59;
- t439 = t209 * t48;
- t440 = t110 * t12;
- t441 = t58 * t440;
- t447 = t36 * self->xc;
- t455 = t48 * t440;
- t471 = self->ZB * t17;
- t492 = 0.12e2 * t397 * t373 - 0.4e1 * t122 * t217 + 0.16e2 * t364 * t427 + 0.16e2 * t312 * t313 * t355 * t40 - 0.8e1 * t279 * t39 * t35 * self->ZB * t60 + 0.2e1 * t439 * t441 - 0.2e1 * t81 * t64 * t163 + 0.8e1 * t447 * t87 * t61 + 0.2e1 * t23 * t59 * t57 * t276 + 0.2e1 * t245 * t455 - 0.4e1 * t349 * t96 * t440 - 0.16e2 * t370 * t427 + 0.4e1 * t181 * t212 - 0.16e2 * t365 * t23 * t269 * t128 + 0.16e2 * t86 * t138 * self->ZA * t35 * t471 * t59 + 0.8e1 * t305 * t289 - 0.4e1 * t439 * t100 + 0.2e1 * self->ZB * t25 * t2 * self->ZA * t18 * t28 + 0.2e1 * t142 * t4 * t28 * t16 - 0.8e1 * t56 * t100;
- t499 = self->ZA * t53 * t19;
- t505 = t396 * 0.3141592654e1;
- t518 = t173 * t53 * t16 * t29;
- t533 = t23 * t28;
- t535 = t188 * t45;
- t538 = t24 * t4;
- t545 = t3 * t177;
- t546 = t173 * t76;
- t555 = t45 * t110;
- t557 = t72 * t160;
- t561 = -0.8e1 * t225 * t61 - 0.2e1 * t161 * t162 * t82 + t533 * t234 + 0.4e1 * t535 * t191 + 0.4e1 * t167 * t538 * t332 + 0.4e1 * t349 * t96 * t60 + 0.2e1 * t545 * t546 - 0.2e1 * t264 * t170 + 0.4e1 * t397 * t281 * self->ZA * t58 - t555 * t96 - 0.4e1 * t557 * t48 * t76;
- t567 = t396 * 0.3141592654e1 * t45;
- t568 = t58 * t246;
- t597 = t58 * n;
- t615 = t13 * t45;
- t616 = t615 * t233;
- t619 = t94 * t45;
- t621 = t45 * t59;
- t625 = 0.2e1 * t149 * t216 + 0.2e1 * t567 * t568 - 0.16e2 * t269 * self->xc * t324 - 0.2e1 * t236 * self->xc * t281 * t58 - 0.2e1 * t142 * t177 * t90 - 0.8e1 * t567 * t100 + 0.2e1 * t65 * t546 - 0.8e1 * t305 * t206 + 0.2e1 * n * t45 * t281 * t57 * t24 - t23 * t110 * t96 - 0.8e1 * t296 * t100 + 0.2e1 * t23 * t281 * t597 + 0.4e1 * t545 * t20 + 0.2e1 * t159 * t2 * t4 * self->ZB * t163 - 0.4e1 * t557 * t48 * t90 + 0.4e1 * t122 * t518 + 0.8e1 * t263 * t538 * t332 - 0.4e1 * t505 * t616 - t619 * t96 - 0.2e1 * t621 * t57 * t276;
- t626 = t49 * t45;
- t660 = t29 * t45;
- t685 = 0.2e1 * t545 * t174 - 0.4e1 * t126 * 0.3141592654e1 * t24 * self->xc - 0.4e1 * t47 * t48 * t188 + 0.4e1 * t505 * t660 * t24 - 0.2e1 * t142 * t177 * t163 - 0.2e1 * t142 * t4 * t13 * t18 + 0.8e1 * t260 * t128 * t60 - 0.2e1 * t328 * t546 - 0.2e1 * t26 * t2 * t28 * t16 + 0.4e1 * t545 * t217 - 0.4e1 * t209 * t138 * t256;
- t690 = t6 * 0.3141592654e1;
- t691 = self->ZA * t690;
- t693 = t24 * t24;
- t694 = t693 * self->xc;
- t695 = t188 * t694;
- t698 = t23 * self->ZA;
- t699 = t698 * t690;
- t700 = t699 * t5;
- t704 = t5 * t4;
- t705 = t691 * t704;
- t709 = t691 * t5;
- t713 = t5 * n;
- t714 = t713 * self->ZB;
- t718 = t698 * t6;
- t719 = t713 * t28;
- t722 = t699 * t704;
- t726 = t713 * t94;
- t733 = t713 * t45;
- t736 = t87 * t36;
- t740 = -0.4e1 * t691 * t98 * t695 + 0.8e1 * t700 * t270 * t13 + 0.4e1 * t705 * t660 * self->xc + 0.8e1 * t709 * t660 * t128 + 0.2e1 * t87 * t714 * t110 + t718 * t719 * t110 - 0.4e1 * t722 * t237 * t13 - t313 * t726 * t45 - 0.4e1 * t699 * t704 * self->xc * t29 + t313 * t733 * t28 + 0.4e1 * t736 * t150 * t233;
- t746 = t313 * t36;
- t752 = t6 * t6;
- t753 = t23 * t752;
- t759 = t698 * t752;
- t760 = t759 * t36;
- t761 = t17 * t693;
- t762 = self->xc * t28;
- t763 = t761 * t762;
- t766 = t87 * t713;
- t773 = t699 * t4;
- t774 = t110 * t693;
- t775 = self->xc * t13;
- t785 = t704 * t17;
- t789 = -0.16e2 * t736 * t150 * t270 + t718 * t116 * t693 - 0.2e1 * t746 * t555 * t24 + 0.4e1 * t705 * t535 + 0.64e2 * t753 * t713 * t17 * t150 * t128 - 0.16e2 * t760 * t763 + 0.2e1 * t766 * t150 * t110 + 0.4e1 * t722 * t274 * self->xc + 0.4e1 * t773 * t774 * t775 - 0.8e1 * t766 * t150 * t17 + 0.8e1 * t700 * t233 * t775 + 0.4e1 * t699 * t785 * t13;
- t791 = t691 * t4;
- t792 = t45 * t693;
- t793 = t49 * t792;
- t796 = t759 * t713;
- t797 = t53 * t28;
- t798 = t270 * t797;
- t801 = t87 * n;
- t818 = t5 * t36;
- t819 = t753 * t818;
- t827 = t753 * t36 * self->ZB;
- t830 = self->xc * t45;
- t834 = -0.4e1 * t791 * t793 + 0.32e2 * t796 * t798 + 0.2e1 * t801 * self->ZB * t693 * t110 + 0.2e1 * t718 * t36 * t28 * t24 - 0.8e1 * t700 * t128 * t29 - 0.8e1 * t700 * t239 - 0.8e1 * t801 * t150 * t761 + 0.32e2 * t819 * t365 * t369 - 0.64e2 * t753 * t714 * t798 + 0.32e2 * t827 * t763 + 0.4e1 * t705 * t830 * t49;
- t842 = self->xc * t29;
- t843 = t270 * t842;
- t849 = t759 * t818;
- t853 = t691 * t396;
- t857 = t691 * t5 * t45;
- t869 = t313 * n;
- t874 = -0.2e1 * t718 * t36 * t94 * t24 - 0.4e1 * t773 * t761 * t29 + 0.8e1 * t700 * t843 + 0.2e1 * t87 * t726 * self->ZB + 0.16e2 * t849 * t797 * t17 + 0.4e1 * t853 * t793 + 0.8e1 * t857 * t239 + 0.2e1 * t801 * t150 * t693 - 0.8e1 * t700 * t270 * t29 - 0.8e1 * t709 * t49 * t46 - t869 * t619 * t693 + t869 * t232 * t693;
- t877 = self->ZA * t752;
- t878 = t877 * t818;
- t911 = 0.16e2 * t878 * t53 * t45 * t365 - 0.4e1 * t699 * t785 * t29 - 0.4e1 * t705 * t188 * t830 + 0.2e1 * t801 * t94 * t693 * self->ZB - 0.8e1 * t857 * t843 - t718 * t726 + 0.4e1 * t773 * t761 * t13 - 0.4e1 * t705 * t775 * t555 + 0.2e1 * t746 * t232 * t233 - 0.16e2 * t878 * t830 * t365 - 0.2e1 * t746 * t619 * t24;
- t916 = t110 * t28;
- t945 = t28 * t693 * t45 * t17;
- t948 = 0.32e2 * t877 * t733 * t798 + 0.2e1 * t718 * t36 * t916 * t24 - 0.4e1 * t705 * t626 + t718 * n * t916 * t693 - t869 * t792 * t110 - 0.4e1 * t773 * t761 * t775 + t718 * t719 + 0.2e1 * t746 * t232 * t24 - 0.16e2 * t849 * t365 * self->xc - t718 * t713 * t110 - 0.4e1 * t773 * t694 * t29 + 0.16e2 * t877 * t54 * t945;
- t974 = t761 * t797;
- t987 = 0.4e1 * t773 * t695 + 0.4e1 * t736 * t150 * t24 + 0.4e1 * t722 * t842 * t17 - 0.16e2 * t877 * t447 * t945 + 0.2e1 * t87 * t714 * t28 + t313 * t713 * t916 * t45 - 0.4e1 * t853 * t615 * t774 - 0.32e2 * t877 * t713 * self->xc * t324 + 0.16e2 * t760 * t974 + 0.4e1 * t736 * t94 * t24 * self->ZB + t869 * t792 * t916 - 0.8e1 * t691 * t5 * self->xc * t616;
- t1021 = -t718 * t169 * t693 - 0.32e2 * t827 * t974 + 0.2e1 * t801 * t150 * t774 + 0.4e1 * t791 * t188 * t792 + 0.4e1 * t736 * t220 * t24 + 0.4e1 * t791 * t842 * t792 + 0.8e1 * t709 * t660 * t270 - t718 * t335 * t693 - 0.2e1 * t718 * t36 * t110 * t24 - 0.32e2 * t819 * t797 * t471 - t313 * t733 * t110 - 0.32e2 * t796 * t270 * t762;
-
- self->C2A = (t147 - 0.4e1 * t65 * t217 + t418 + 0.2e1 * t150 * t222 + t327 - 0.2e1 * t149 * t19 + 0.2e1 * t335 * self->ZB * t24 * self->ZA - 0.16e2 * t312 * t313 * t355 * t59 - 0.4e1 * t281 * self->ZB * self->ZA * t597 - 0.2e1 * t505 * t45 * t281 * t58 - 0.4e1 * t211 * t2 * t53 * t76 + 0.8e1 * t305 * t286 - 0.4e1 * t122 * t499 - 0.4e1 * t331 * t332 + 0.8e1 * t345 * t177 * t60 - 0.2e1 * t142 * t177 * t82 + 0.2e1 * t72 * t281 * t415 + 0.4e1 * t349 * t96 * t41 - 0.2e1 * t81 * t64 * t76 + 0.2e1 * t58 * t80 * t59 + 0.8e1 * t345 * t177 * t41 - 0.4e1 * t8 * t499 + t242 + 0.4e1 * t8 * t518 + t625 + t685 + 0.2e1 * t328 * t174 + 0.2e1 * t331 * t455 - 0.2e1 * t33 * t2 * t4 * self->ZA * t82 - 0.4e1 * t626 * t191 + 0.16e2 * t364 * t373 - 0.2e1 * t621 * t597 - 0.2e1 * t439 * t568 + t492 + t533 * t96 + t232 * t96 + 0.2e1 * t567 * t441 + t561) / (t740 + t789 + t834 + t874 + t911 + t948 + t987 + t1021);
- /****************************************************************************************/
- t1 = n * n;
- t2 = t1 * n;
- t3 = t2 * 0.3141592654e1;
- t4 = t3 * self->xc;
- t5 = self->ZB * self->ZB;
- t7 = exp(n * 0.3141592654e1);
- t8 = t7 * t7;
- t9 = t5 * t8;
- t12 = exp( self->xc * n * 0.3141592654e1);
- t13 = t12 * t12;
- t14 = t13 * t13;
- t15 = t14 * t13;
- t19 = nx * nx;
- t21 = nx * 0.3141592654e1;
- t22 = sin(t21);
- t23 = t19 * nx * t22;
- t24 = t23 * 0.3141592654e1;
- t25 = self->ZA * self->ZB;
- t26 = t7 * t15;
- t27 = t25 * t26;
- t30 = t21 * self->xc;
- t31 = sin(t30);
- t32 = t31 * nx;
- t33 = t32 * n;
- t34 = self->ZA * self->ZA;
- t35 = t8 * t8;
- t36 = t34 * t35;
- t40 = t2 * t34;
- t41 = 0.3141592654e1 * t8;
- t42 = t41 * t15;
- t45 = t1 * t5;
- t46 = t14 * t14;
- t49 = t19 * t5;
- t51 = t19 * t46;
- t53 = t19 * t34;
- t55 = t8 * t7;
- t56 = t13 * t55;
- t57 = t25 * t56;
- t60 = t2 * nx;
- t61 = 0.3141592654e1 * 0.3141592654e1;
- t63 = t60 * t31 * t61;
- t64 = self->xc * self->xc;
- t65 = self->ZA * t64;
- t66 = self->ZB * t8;
- t67 = t14 * t12;
- t68 = t66 * t67;
- t69 = t65 * t68;
- t72 = -0.4e1 * t4 * t9 * t15 + 0.4e1 * t24 * t27 + 0.4e1 * t33 * t36 * t12 - 0.4e1 * t40 * t42 - t45 * t46 + t45 * t14 - t49 * t14 + t51 * t5 - t53 * t14 + 0.4e1 * t24 * t57 + 0.32e2 * t63 * t69;
- t73 = t1 * nx;
- t75 = t73 * t31 * 0.3141592654e1;
- t76 = t8 * t67;
- t77 = t25 * t76;
- t80 = t1 * t1;
- t81 = t80 * t34;
- t83 = t61 * t14;
- t87 = t1 * t19;
- t88 = cos(t30);
- t90 = t87 * t88 * t61;
- t91 = t5 * t64;
- t92 = t13 * t12;
- t93 = t8 * t92;
- t94 = t91 * t93;
- t100 = self->ZB * t64 * self->ZA * t8 * t92;
- t103 = n * t19;
- t105 = t103 * t88 * 0.3141592654e1;
- t106 = self->ZA * self->xc;
- t107 = self->ZB * t35;
- t109 = t106 * t107 * t12;
- t112 = t34 * self->xc;
- t113 = t112 * t93;
- t116 = t35 * t14;
- t118 = t1 * self->ZA;
- t119 = self->ZB * t14;
- t122 = t1 * t46;
- t125 = t19 * self->ZB;
- t126 = t35 * self->ZA;
- t127 = t125 * t126;
- t129 = t1 * self->ZB;
- t132 = -0.16e2 * t75 * t77 + 0.16e2 * t81 * t64 * t83 * t8 + 0.16e2 * t90 * t94 - 0.32e2 * t90 * t100 + 0.8e1 * t105 * t109 - 0.8e1 * t75 * t113 + t45 * t116 + 0.2e1 * t118 * t119 + 0.2e1 * t122 * t25 - 0.2e1 * t127 + 0.2e1 * t129 * t126;
- t134 = t1 * t34;
- t136 = t34 * t64;
- t137 = t136 * t76;
- t141 = t91 * t76;
- t145 = t103 * t34;
- t146 = 0.3141592654e1 * self->xc;
- t147 = t8 * t13;
- t153 = t14 * self->ZA;
- t156 = self->xc * t5;
- t157 = t156 * t93;
- t160 = t103 * t5;
- t162 = t146 * t8 * t15;
- t166 = t34 * t7 * t15;
- t169 = t134 * t116 - 0.16e2 * t63 * t137 - t49 * t116 - 0.16e2 * t63 * t141 - t53 * t116 + 0.4e1 * t145 * t146 * t147 - 0.2e1 * t51 * t25 - 0.2e1 * t125 * t153 - 0.16e2 * t75 * t157 + 0.4e1 * t160 * t162 - 0.4e1 * t24 * t166;
- t170 = t106 * t68;
- t177 = t35 * t92;
- t178 = t112 * t177;
- t181 = t156 * t76;
- t186 = t35 * t12;
- t187 = t112 * t186;
- t193 = t5 * 0.3141592654e1;
- t206 = t34 * t14;
- t207 = t206 * t7;
- t210 = -0.32e2 * t63 * t170 + 0.32e2 * t90 * t170 + 0.8e1 * t75 * t109 + 0.4e1 * t105 * t178 - 0.16e2 * t75 * t181 - 0.16e2 * t90 * t113 - 0.4e1 * t75 * t187 + 0.16e2 * t90 * t141 - 0.4e1 * t103 * t15 * t193 * self->xc + 0.16e2 * t73 * t22 * t34 * t146 * t26 + 0.4e1 * t32 * n * t34 * t67 + 0.4e1 * t24 * t207;
- t217 = t106 * t66 * t92;
- t226 = t88 * t19 * n;
- t227 = 0.3141592654e1 * t34;
- t229 = t227 * self->xc * t67;
- t232 = t73 * t31;
- t234 = t146 * t5 * t67;
- t238 = t61 * self->ZB;
- t239 = t14 * t8;
- t240 = t238 * t239;
- t243 = t136 * t93;
- t246 = -0.8e1 * t33 * t25 * t186 + 0.32e2 * t90 * t217 - t45 * t35 + t53 * t35 - t134 * t35 - t134 * t46 + t134 * t14 - 0.4e1 * t226 * t229 + 0.4e1 * t232 * t234 + 0.32e2 * t87 * t65 * t240 + 0.16e2 * t63 * t243;
- t247 = t14 * t92;
- t249 = t227 * t247 * self->xc;
- t254 = t73 * t22;
- t259 = t60 * t22 * t61;
- t260 = t112 * t26;
- t264 = t146 * t247 * t5;
- t268 = self->xc * t14;
- t274 = t5 * t14;
- t275 = t274 * t8;
- t280 = n * nx;
- t281 = t280 * t22;
- t282 = t55 * t14;
- t283 = t25 * t282;
- t290 = self->ZA * t247 * self->xc * self->ZB;
- t295 = t22 * nx * t1 * 0.3141592654e1;
- t298 = -0.4e1 * t232 * t249 + 0.8e1 * t105 * t217 - 0.4e1 * t254 * t227 * t26 - 0.8e1 * t259 * t260 - 0.4e1 * t232 * t264 - 0.16e2 * t81 * t61 * t268 * t8 + 0.16e2 * t80 * t64 * t61 * t275 - 0.4e1 * t232 * t229 + 0.8e1 * t281 * t283 - 0.4e1 * t105 * t187 + 0.8e1 * t75 * t290 + 0.4e1 * t295 * t27;
- t301 = t61 * t5;
- t307 = t87 * t34;
- t312 = t61 * self->xc;
- t313 = t312 * t239;
- t317 = t34 * t55 * t14;
- t329 = self->ZB * t13 * t55;
- t330 = t65 * t329;
- t337 = -0.16e2 * t87 * t64 * t301 * t239 - 0.32e2 * t90 * t69 - 0.16e2 * t307 * t64 * t61 * t239 + 0.16e2 * t307 * t313 + 0.4e1 * t24 * t317 + t53 * t46 + t49 * t35 - 0.32e2 * t63 * t100 - 0.4e1 * t280 * t31 * t34 * t247 + 0.8e1 * t259 * t330 - 0.4e1 * t280 * t31 * t247 * t5;
- t340 = t5 * t35;
- t344 = t25 * t93;
- t356 = t41 * t13;
- t360 = t23 * n * t61;
- t363 = t25 * t64 * t7 * t15;
- t366 = t156 * t177;
- t369 = t14 * t7;
- t370 = t25 * t369;
- t373 = t156 * t186;
- t378 = 0.4e1 * t24 * t283 + 0.4e1 * t33 * t340 * t12 - 0.16e2 * t75 * t344 - 0.4e1 * t280 * t31 * t5 * t67 + 0.8e1 * t33 * t25 * t247 + 0.32e2 * t63 * t217 + 0.4e1 * t40 * t356 - 0.8e1 * t360 * t363 + 0.4e1 * t75 * t366 + 0.4e1 * t295 * t370 - 0.4e1 * t75 * t373 - 0.4e1 * t105 * t366;
- t382 = t112 * t76;
- t387 = t80 * t61;
- t391 = t136 * t26;
- t409 = 0.16e2 * t63 * t382 + 0.4e1 * t226 * t234 - 0.16e2 * t387 * self->xc * t275 + 0.8e1 * t259 * t391 - 0.16e2 * t105 * t344 + 0.4e1 * t226 * t264 - 0.8e1 * t105 * t170 + 0.16e2 * t232 * t193 * t76 + 0.8e1 * t360 * t330 - 0.8e1 * t105 * t290 + 0.16e2 * t90 * t243;
- t423 = t153 * t8;
- t426 = t34 * t13;
- t427 = t426 * t55;
- t430 = t34 * t8;
- t437 = t80 * self->ZA;
- t441 = 0.4e1 * t145 * t42 - 0.16e2 * t90 * t157 + 0.24e2 * t75 * t217 + 0.4e1 * t226 * t249 + 0.4e1 * t254 * t227 * t282 + 0.4e1 * t160 * t356 - 0.8e1 * t129 * t423 - 0.8e1 * t281 * t427 - 0.8e1 * t33 * t430 * t67 + 0.8e1 * t33 * t430 * t92 + 0.32e2 * t437 * self->ZB * t313;
- t453 = t106 * self->ZB * t7 * t15;
- t456 = t2 * t5;
- t459 = t112 * t56;
- t462 = t126 * t14;
- t474 = t40 * 0.3141592654e1;
- t475 = self->xc * t8;
- t480 = t146 * t13 * t35;
- t483 = -0.4e1 * t103 * self->xc * t193 * t147 + 0.16e2 * t87 * t61 * t156 * t239 + 0.8e1 * t259 * t453 - 0.4e1 * t456 * t356 + 0.8e1 * t259 * t459 - 0.2e1 * t125 * t462 - 0.8e1 * t281 * t207 + 0.16e2 * t295 * t459 - 0.8e1 * t60 * t22 * self->ZA * t312 * t329 + 0.4e1 * t474 * t475 * t15 + 0.4e1 * t160 * t480;
- t497 = t136 * t56;
- t504 = t9 * t13;
- t509 = t475 * t13;
- t512 = -0.8e1 * t105 * t113 - 0.4e1 * t254 * t227 * t56 + 0.8e1 * t281 * t57 + 0.4e1 * t295 * t283 + 0.2e1 * t129 * t462 + 0.4e1 * t24 * t370 - 0.8e1 * t360 * t497 - 0.4e1 * t24 * t427 - 0.4e1 * t145 * t162 + 0.4e1 * t4 * t504 - 0.8e1 * t281 * t370 - 0.4e1 * t474 * t509;
- t528 = t5 * t13;
- t529 = t528 * t35;
- t532 = t106 * t329;
- t542 = -0.16e2 * t295 * t453 - 0.32e2 * t437 * t64 * t240 + 0.8e1 * t281 * t317 + 0.24e2 * t75 * t170 - 0.4e1 * t75 * t178 + 0.8e1 * t360 * t453 - 0.4e1 * t4 * t529 - 0.16e2 * t295 * t532 - 0.8e1 * t33 * t344 - 0.16e2 * t90 * t181 + 0.4e1 * t33 * t340 * t92;
- t557 = t146 * t15;
- t562 = self->xc * t15;
- t563 = t562 * t5;
- t573 = 0.16e2 * t232 * t193 * t93 - 0.8e1 * t259 * t363 - 0.8e1 * t259 * t497 + 0.8e1 * t33 * t77 + 0.8e1 * t360 * t391 + 0.4e1 * t254 * t227 * t369 + 0.4e1 * t145 * t557 + 0.8e1 * t281 * t166 + 0.4e1 * t3 * t563 + 0.8e1 * t105 * t382 - 0.4e1 * t145 * t480 - 0.4e1 * t33 * t36 * t92;
- t600 = 0.4e1 * t456 * t42 - 0.8e1 * t360 * t260 - 0.4e1 * t40 * t557 - 0.4e1 * t105 * t373 + 0.16e2 * t226 * t227 * t93 - 0.16e2 * t90 * t382 - 0.4e1 * t145 * t356 - 0.16e2 * t63 * t157 - 0.32e2 * t87 * t25 * t313 - 0.16e2 * t226 * t227 * t76 - 0.16e2 * t63 * t113;
- t623 = self->xc * t13;
- t627 = 0.8e1 * t125 * t423 - 0.8e1 * t360 * t532 + 0.16e2 * t90 * t137 - 0.4e1 * t160 * t42 + 0.16e2 * t63 * t94 + 0.16e2 * t63 * t181 - 0.8e1 * t281 * t27 - 0.8e1 * t75 * t382 + 0.8e1 * t360 * t459 + 0.4e1 * t295 * t57 + 0.16e2 * t105 * t77 + 0.4e1 * t474 * t623 * t35;
- t632 = t61 * 0.3141592654e1;
- t633 = t632 * t8;
- t634 = t80 * n;
- t638 = t632 * t634;
- t639 = t638 * self->xc;
- t642 = t61 * t34;
- t643 = t122 * t19;
- t649 = t61 * t61;
- t650 = t649 * t1;
- t652 = t19 * t19;
- t653 = t14 * t652;
- t654 = t653 * t9;
- t657 = t14 * t1;
- t658 = t657 * t19;
- t665 = t632 * t34;
- t666 = t665 * t2;
- t667 = t8 * t19;
- t668 = t667 * t623;
- t674 = t665 * n;
- t675 = t652 * self->xc;
- t682 = 0.8e1 * t633 * t426 * t634 - 0.8e1 * t639 * t529 - 0.4e1 * t642 * t643 + 0.2e1 * t642 * t116 * t80 + 0.32e2 * t650 * t64 * t654 + 0.4e1 * t301 * t658 + 0.4e1 * t387 * t46 * self->ZA * self->ZB - 0.16e2 * t666 * t668 - 0.16e2 * t666 * t667 * t15 - 0.8e1 * t674 * t675 * t15 + 0.4e1 * t238 * t153 * t80;
- t683 = t46 * t652;
- t686 = t633 * t15;
- t691 = t35 * t80;
- t698 = t35 * t652;
- t705 = t14 * t80;
- t708 = t61 * t35;
- t717 = -0.2e1 * t642 * t683 - 0.8e1 * t686 * t5 * t634 * self->xc - 0.2e1 * t301 * t691 + 0.8e1 * t638 * t563 - 0.2e1 * t642 * t691 - 0.2e1 * t642 * t698 - 0.2e1 * t301 * t698 - 0.2e1 * t301 * t683 + 0.2e1 * t642 * t705 + 0.2e1 * t708 * t274 * t80 + 0.2e1 * t301 * t653 - 0.2e1 * t642 * t80 * t46;
- t727 = t61 * t46;
- t737 = t649 * t34;
- t738 = t737 * t1;
- t739 = t8 * t652;
- t740 = t739 * t268;
- t746 = t61 * self->ZA;
- t754 = t632 * n * self->xc;
- t758 = 0.2e1 * t301 * t705 + 0.2e1 * t642 * t653 - 0.8e1 * t665 * self->xc * t634 * t15 - 0.2e1 * t727 * t5 * t80 - 0.32e2 * t650 * self->xc * t654 + 0.2e1 * t301 * t698 * t14 - 0.32e2 * t738 * t740 + 0.8e1 * t674 * t739 * t562 + 0.4e1 * t746 * t119 * t652 + 0.8e1 * t674 * t698 * t623 - 0.8e1 * t754 * t528 * t698;
- t762 = t633 * t13;
- t764 = t5 * n * t652;
- t767 = t80 * t1;
- t768 = t649 * t767;
- t772 = t649 * self->ZA;
- t773 = t772 * t129;
- t777 = t35 * t1 * t19;
- t780 = t632 * t5;
- t781 = t780 * t15;
- t786 = t698 * self->ZA;
- t790 = t64 * t14;
- t800 = t649 * t8;
- t809 = 0.4e1 * t238 * t126 * t80 - 0.8e1 * t762 * t764 - 0.32e2 * t768 * self->xc * t275 + 0.64e2 * t773 * t740 - 0.4e1 * t301 * t777 - 0.8e1 * t781 * n * t8 * t675 + 0.4e1 * t238 * t786 + 0.32e2 * t768 * t34 * t790 * t8 - 0.8e1 * t633 * t528 * t634 + 0.8e1 * t754 * t528 * t739 + 0.128e3 * t800 * t119 * t80 * t19 * t106 + 0.8e1 * t674 * t739 * t13;
- t812 = t649 * t80;
- t817 = t83 * self->ZB;
- t824 = t746 * self->ZB;
- t828 = t800 * t14;
- t855 = -0.64e2 * t812 * self->xc * t274 * t667 + 0.4e1 * t817 * t786 + 0.4e1 * t727 * self->ZA * t652 * self->ZB - 0.32e2 * t824 * t657 * t667 - 0.32e2 * t828 * t34 * t767 * self->xc - 0.8e1 * t633 * t15 * t34 * t634 - 0.8e1 * t674 * t739 * t15 + 0.32e2 * t768 * t64 * t275 + 0.4e1 * t708 * t14 * t307 + 0.2e1 * t708 * t206 * t652 + 0.8e1 * t632 * t35 * t13 * t34 * t634 * self->xc;
- t858 = t35 * t19;
- t873 = t2 * t8;
- t878 = t61 * t1;
- t901 = -0.16e2 * t632 * t2 * self->xc * t528 * t858 + 0.8e1 * t824 * t658 + 0.4e1 * t301 * t14 * t777 - 0.8e1 * t665 * t634 * t509 - 0.8e1 * t674 * t739 * t623 - 0.16e2 * t781 * t873 * t19 * self->xc + 0.8e1 * t878 * t14 * t127 + 0.8e1 * t878 * self->ZA * t51 * self->ZB + 0.8e1 * t686 * t764 + 0.8e1 * t665 * self->xc * t634 * t15 * t8 + 0.8e1 * t633 * t15 * t5 * t634 + 0.4e1 * t387 * t14 * t107 * self->ZA;
- t903 = t739 * t790;
- t923 = t737 * t80;
- t924 = t667 * t790;
- t927 = t780 * t2;
- t937 = t15 * t19 * self->xc;
- t943 = 0.32e2 * t738 * t903 + 0.16e2 * t781 * t873 * t19 + 0.8e1 * t754 * t15 * t652 * t5 + 0.16e2 * t666 * t858 * t623 + 0.64e2 * t828 * t25 * t767 * self->xc - 0.16e2 * t762 * t456 * t19 + 0.64e2 * t923 * t924 + 0.16e2 * t927 * t668 - 0.64e2 * t768 * self->ZA * t790 * t66 - 0.64e2 * t773 * t903 + 0.16e2 * t927 * t937 + 0.16e2 * t666 * t667 * t562;
- t977 = 0.64e2 * t812 * t5 * t924 + 0.8e1 * t639 * t504 + 0.8e1 * t238 * t35 * t118 * t19 + 0.4e1 * t642 * t658 - 0.16e2 * t817 * t437 * t8 - 0.128e3 * t772 * self->ZB * t80 * t924 + 0.16e2 * t666 * t667 * t13 - 0.4e1 * t301 * t643 - 0.16e2 * t824 * t653 * t8 - 0.4e1 * t642 * t777 - 0.64e2 * t923 * t667 * t268 - 0.16e2 * t666 * t937;
-
- self->C3A = (t72 + t132 + t169 + t210 + t246 + t298 + t337 + t378 + t409 + t441 + t483 + t512 + t542 + t573 + t600 + t627) / (t682 + t717 + t758 + t809 + t855 + t901 + t943 + t977);
- /****************************************************************************************/
- self->C4A = 0;
- /****************************************************************************************/
- t1 = nx * 0.3141592654e1;
- t2 = t1 * self->xc;
- t3 = cos(t2);
- t4 = nx * nx;
- t6 = n * 0.3141592654e1;
- t7 = t3 * t4 * t6;
- t8 = self->ZA * self->ZB;
- t9 = exp(t6);
- t10 = t9 * t9;
- t11 = self->xc * n;
- t13 = exp(t11 * 0.3141592654e1);
- t14 = t13 * t13;
- t15 = t14 * t13;
- t16 = t14 * t14;
- t17 = t16 * t15;
- t18 = t10 * t17;
- t19 = t8 * t18;
- t22 = sin(t2);
- t23 = nx * t22;
- t24 = t23 * n;
- t25 = self->ZB * self->ZB;
- t30 = n * n;
- t31 = t30 * n;
- t32 = t31 * nx;
- t33 = 0.3141592654e1 * 0.3141592654e1;
- t35 = t32 * t22 * t33;
- t36 = self->ZA * self->ZA;
- t37 = t36 * self->xc;
- t38 = t16 * t13;
- t39 = t10 * t38;
- t40 = t37 * t39;
- t43 = sin(t1);
- t44 = nx * t43;
- t45 = t30 * 0.3141592654e1;
- t46 = t44 * t45;
- t47 = self->ZA * self->xc;
- t49 = self->ZB * t16 * t9;
- t54 = t4 * nx * t43;
- t55 = self->xc * self->xc;
- t57 = t54 * t30 * t55;
- t58 = t33 * 0.3141592654e1;
- t59 = t58 * t25;
- t60 = t16 * t9;
- t61 = t59 * t60;
- t64 = self->xc * t25;
- t65 = t14 * t9;
- t66 = t64 * t65;
- t70 = t44 * t31 * t33;
- t71 = t37 * t65;
- t74 = t10 * t15;
- t75 = t64 * t74;
- t78 = t25 * t10;
- t83 = t54 * n * t33;
- t84 = t55 * t25;
- t85 = t10 * t9;
- t86 = t14 * t85;
- t87 = t84 * t86;
- t90 = t30 * t30;
- t92 = t44 * t90 * t58;
- t93 = t55 * self->xc;
- t94 = t93 * t25;
- t95 = t85 * t16;
- t96 = t94 * t95;
- t102 = t23 * t45;
- t103 = t10 * t10;
- t104 = self->ZB * t103;
- t106 = t47 * t104 * t15;
- t111 = t54 * 0.3141592654e1;
- t112 = t25 * t85;
- t113 = t112 * t16;
- t115 = t8 * t39;
- t118 = t16 * t14;
- t119 = t85 * t118;
- t120 = t37 * t119;
- t123 = t16 * t16;
- t124 = t36 * t123;
- t125 = t124 * t9;
- t127 = -0.8e1 * t7 * t19 + 0.2e1 * t24 * t25 * t13 * t10 - 0.16e2 * t35 * t40 - 0.16e2 * t46 * t47 * t49 - 0.8e1 * t57 * t61 + 0.4e1 * t46 * t66 + 0.2e1 * t70 * t71 - 0.16e2 * t35 * t75 + 0.6e1 * t24 * t78 * t38 - 0.2e1 * t83 * t87 - 0.8e1 * t92 * t96 - 0.8e1 * t46 * t37 * t95 - 0.12e2 * t102 * t106 + 0.2e1 * t83 * t71 + t111 * t113 + 0.8e1 * t7 * t115 + 0.2e1 * t83 * t120 + t111 * t125;
- t128 = t37 * t74;
- t131 = t44 * n;
- t133 = t25 * t9 * t118;
- t136 = t36 * t14;
- t137 = t136 * t9;
- t140 = t30 * t4;
- t142 = t140 * t3 * t33;
- t143 = t64 * t39;
- t147 = t30 * nx * t43;
- t148 = 0.3141592654e1 * t36;
- t149 = t9 * t118;
- t153 = t44 * t31 * self->ZA;
- t154 = t33 * self->xc;
- t155 = t154 * t49;
- t160 = self->ZA * t17 * self->xc * self->ZB;
- t163 = t103 * t13;
- t164 = t64 * t163;
- t170 = t44 * t90 * t55;
- t171 = t58 * self->ZB;
- t172 = self->ZA * t16;
- t174 = t171 * t172 * t9;
- t177 = t36 * t55;
- t178 = t177 * t149;
- t181 = t54 * t11;
- t182 = t33 * t25;
- t186 = t25 * t14;
- t187 = t186 * t9;
- t193 = t186 * t85;
- t198 = self->ZB * t55;
- t199 = self->ZA * t103;
- t201 = t198 * t199 * t15;
- t204 = 0.2e1 * t7 * t128 - 0.2e1 * t131 * t133 - 0.2e1 * t131 * t137 + 0.16e2 * t142 * t143 - t147 * t148 * t149 + 0.8e1 * t153 * t155 - 0.4e1 * t7 * t160 + 0.2e1 * t7 * t164 + 0.10e2 * t102 * t40 + 0.16e2 * t170 * t174 + 0.2e1 * t83 * t178 - 0.2e1 * t181 * t182 * t65 - t111 * t187 - 0.2e1 * t70 * t87 + 0.4e1 * t102 * t160 - 0.2e1 * t131 * t193 - 0.16e2 * t142 * t75 + 0.16e2 * t35 * t201;
- t210 = t32 * t22;
- t211 = t33 * t55;
- t212 = t25 * t38;
- t213 = t211 * t212;
- t216 = n * nx;
- t217 = t22 * t25;
- t222 = self->ZB * t85 * t16;
- t226 = t23 * t30;
- t227 = t13 * t10;
- t228 = t148 * t227;
- t233 = t37 * t163;
- t237 = n * t4 * t3;
- t238 = t148 * t74;
- t241 = t64 * t86;
- t245 = t148 * self->xc * t15;
- t248 = t112 * t118;
- t250 = t22 * t36;
- t256 = 0.3141592654e1 * t25;
- t257 = t256 * t39;
- t262 = t38 * t103;
- t263 = t37 * t262;
- t267 = t148 * t17 * self->xc;
- t270 = -0.6e1 * t7 * t143 - 0.4e1 * t24 * t19 - 0.8e1 * t210 * t213 - 0.2e1 * t216 * t217 * t15 - 0.32e2 * t153 * t211 * t222 + 0.4e1 * t226 * t228 + 0.16e2 * t142 * t201 + 0.2e1 * t7 * t233 - 0.4e1 * t237 * t238 - 0.2e1 * t83 * t241 - 0.2e1 * t237 * t245 + t111 * t248 + 0.2e1 * t216 * t250 * t15 - 0.2e1 * t131 * t125 - 0.4e1 * t226 * t257 + t147 * t148 * t95 - 0.2e1 * t102 * t263 + 0.2e1 * t237 * t267;
- t273 = t37 * t149;
- t277 = t47 * t104 * t13;
- t285 = t31 * t36;
- t286 = t44 * t285;
- t291 = t25 * t123 * t9;
- t304 = 0.3141592654e1 * self->xc;
- t305 = t304 * t212;
- t312 = t256 * t18;
- t315 = t8 * t60;
- t319 = t54 * t30 * t58;
- t323 = t90 * t36;
- t324 = t44 * t323;
- t325 = t55 * t58;
- t326 = t325 * t60;
- t329 = 0.2e1 * t102 * t164 + 0.2e1 * t83 * t273 - 0.4e1 * t102 * t277 - 0.2e1 * t7 * t263 + 0.4e1 * t24 * t8 * t17 - 0.4e1 * t286 * t154 * t60 - 0.2e1 * t131 * t291 - t147 * t148 * t119 + 0.2e1 * t24 * t78 * t17 + 0.2e1 * t54 * t85 * 0.3141592654e1 * self->ZA * self->ZB - 0.4e1 * t226 * t305 - 0.2e1 * t70 * t66 + t147 * t256 * t95 + 0.4e1 * t237 * t312 + 0.2e1 * t111 * t315 - 0.8e1 * t319 * t96 - t111 * t193 - 0.8e1 * t324 * t326;
- t332 = t8 * t95;
- t335 = t136 * t85;
- t337 = t256 * t227;
- t340 = t177 * t119;
- t346 = t37 * t86;
- t351 = t103 * t15;
- t352 = t177 * t351;
- t355 = t64 * t119;
- t358 = t8 * t227;
- t361 = t85 * 0.3141592654e1;
- t365 = t84 * t39;
- t372 = self->ZB * t10;
- t373 = t372 * t38;
- t374 = t47 * t373;
- t379 = t177 * t39;
- t384 = -0.2e1 * t46 * t332 + t111 * t335 + 0.4e1 * t237 * t337 - 0.2e1 * t83 * t340 + 0.16e2 * t286 * t211 * t95 + 0.2e1 * t70 * t346 - 0.8e1 * t170 * t61 - 0.8e1 * t142 * t352 - 0.2e1 * t83 * t355 - 0.4e1 * t24 * t358 + 0.2e1 * t147 * t361 * t8 + 0.8e1 * t35 * t365 - 0.2e1 * t226 * t267 + 0.8e1 * t102 * t115 - 0.12e2 * t102 * t374 + 0.16e2 * t142 * t40 - 0.8e1 * t142 * t379 + 0.4e1 * t237 * t228;
- t386 = t54 * t30 * t93;
- t387 = self->ZA * t85;
- t389 = t171 * t387 * t16;
- t394 = t64 * t60;
- t398 = t304 * t25 * t15;
- t401 = t361 * t25;
- t405 = t84 * t65;
- t410 = t148 * t18;
- t414 = t25 * t16 * t9;
- t417 = t84 * t74;
- t422 = t177 * t86;
- t428 = self->ZB * t38;
- t429 = t47 * t428;
- t432 = t148 * t39;
- t439 = 0.16e2 * t386 * t389 - 0.16e2 * t386 * t174 + 0.8e1 * t46 * t394 + 0.2e1 * t237 * t398 - t147 * t401 + 0.4e1 * t7 * t374 + 0.2e1 * t83 * t405 - 0.4e1 * t46 * t241 - 0.4e1 * t226 * t410 + 0.2e1 * t131 * t414 + 0.8e1 * t35 * t417 - 0.8e1 * t142 * t365 + 0.2e1 * t70 * t422 - 0.4e1 * t181 * t182 * t60 + 0.12e2 * t102 * t429 - 0.4e1 * t226 * t432 + 0.32e2 * t35 * t374 - 0.4e1 * t7 * t106;
- t442 = t36 * t9 * t118;
- t444 = t123 * t9;
- t445 = t8 * t444;
- t448 = t361 * t36;
- t451 = t47 * t372 * t17;
- t454 = t94 * t60;
- t457 = t25 * t103;
- t465 = t47 * t372 * t15;
- t468 = t36 * t85;
- t469 = t468 * t16;
- t474 = t43 * t85;
- t478 = t8 * t74;
- t484 = t256 * t74;
- t489 = t198 * self->ZA * t10 * t15;
- t501 = -t111 * t442 + 0.4e1 * t131 * t445 - t147 * t448 + 0.4e1 * t7 * t451 + 0.8e1 * t92 * t454 - 0.2e1 * t24 * t457 * t13 - 0.2e1 * t286 * t211 * t65 + 0.4e1 * t7 * t465 + t111 * t469 - 0.2e1 * t216 * t250 * t17 - 0.2e1 * t216 * t474 * t25 - 0.4e1 * t24 * t478 + 0.4e1 * t24 * t8 * t38 + 0.4e1 * t226 * t484 - 0.16e2 * t142 * t489 - 0.2e1 * t24 * t212 * t103 - 0.2e1 * t216 * t22 * t17 * t25 + 0.2e1 * t70 * t120;
- t504 = t33 * t36 * t55 * t38;
- t507 = t37 * t18;
- t512 = t47 * self->ZB * t13 * t10;
- t518 = t59 * t95;
- t530 = t84 * t351;
- t534 = t37 * t227;
- t549 = -0.8e1 * t210 * t504 + 0.2e1 * t102 * t507 + 0.4e1 * t7 * t512 + t111 * t133 - 0.16e2 * t35 * t489 + 0.8e1 * t170 * t518 + 0.2e1 * t24 * t36 * t13 * t10 + 0.4e1 * t131 * t387 * self->ZB + 0.12e2 * t102 * t465 - 0.8e1 * t142 * t530 + t111 * t291 - 0.2e1 * t102 * t534 - 0.4e1 * t70 * t394 - 0.10e2 * t102 * t128 + 0.4e1 * t237 * t305 + 0.8e1 * t102 * t19 + 0.2e1 * t83 * t346 - 0.16e2 * t35 * t128;
- t557 = t468 * t118;
- t562 = t93 * t58;
- t563 = t562 * t60;
- t567 = t44 * t90 * t93;
- t575 = self->ZA * t55;
- t576 = t575 * t428;
- t583 = t37 * t60;
- t590 = t140 * t3;
- t601 = -0.2e1 * t226 * t398 - 0.2e1 * t70 * t340 - 0.2e1 * t131 * t557 - 0.4e1 * t24 * t115 + 0.8e1 * t324 * t563 + 0.16e2 * t567 * t389 + 0.16e2 * t70 * t84 * t95 + 0.2e1 * t70 * t178 - 0.16e2 * t142 * t576 - 0.4e1 * t237 * t257 - 0.4e1 * t226 * t312 + 0.8e1 * t46 * t583 + 0.2e1 * t24 * t36 * t38 * t103 + 0.8e1 * t590 * t213 + 0.2e1 * t102 * t143 - 0.16e2 * t35 * t143 + 0.2e1 * t131 * t248 + 0.4e1 * t46 * t346;
- t604 = n * t36;
- t606 = t154 * t95;
- t625 = t36 * t103;
- t640 = t30 * t36;
- t641 = t54 * t640;
- t642 = t325 * t95;
- t647 = -0.4e1 * t131 * t315 - 0.4e1 * t54 * t604 * t606 - t147 * t148 * t60 + 0.16e2 * t35 * t576 - 0.8e1 * t102 * t478 + 0.32e2 * t142 * t465 - 0.4e1 * t237 * t484 - 0.2e1 * t70 * t355 + 0.2e1 * t70 * t273 + 0.2e1 * t102 * t233 - 0.2e1 * t24 * t625 * t13 - 0.8e1 * t7 * t358 - 0.2e1 * t111 * t445 - 0.4e1 * t7 * t429 + 0.16e2 * t46 * t47 * t222 + 0.2e1 * t131 * t113 + 0.8e1 * t641 * t642 - 0.2e1 * t7 * t534;
- t652 = t36 * t16;
- t653 = t652 * t9;
- t655 = t64 * t227;
- t658 = t182 * t95;
- t663 = t562 * t95;
- t684 = t64 * t351;
- t689 = t36 * t10;
- t695 = t154 * t222;
- t698 = -0.4e1 * t216 * t217 * t38 - t111 * t653 - 0.2e1 * t7 * t655 - 0.4e1 * t181 * t658 + 0.2e1 * t131 * t469 - 0.8e1 * t641 * t663 - 0.4e1 * t83 * t583 - 0.2e1 * t83 * t177 * t65 - 0.4e1 * t24 * t457 * t15 + 0.16e2 * t70 * t84 * t60 + 0.8e1 * t57 * t518 - 0.32e2 * t142 * t374 + 0.4e1 * t24 * t8 * t351 + 0.4e1 * t102 * t684 - t147 * t256 * t86 - 0.2e1 * t24 * t689 * t15 - 0.2e1 * t70 * t241 + 0.8e1 * t153 * t695;
- t711 = t575 * t373;
- t717 = t304 * t17 * t25;
- t736 = t177 * t74;
- t739 = 0.2e1 * t226 * t245 - 0.8e1 * t102 * t358 - 0.16e2 * t57 * t389 - 0.2e1 * t102 * t655 + 0.8e1 * t590 * t504 - 0.8e1 * t641 * t326 - 0.16e2 * t35 * t711 - t111 * t557 + t111 * t137 - 0.2e1 * t226 * t717 + 0.8e1 * t102 * t37 * t351 + 0.2e1 * t131 * t335 - 0.4e1 * t131 * t332 - 0.2e1 * t216 * t474 * t36 - 0.2e1 * t111 * t332 + 0.16e2 * t142 * t711 - t147 * t256 * t60 + 0.8e1 * t142 * t736;
- t750 = t64 * t262;
- t763 = t44 * t640;
- t770 = t84 * t119;
- t782 = 0.4e1 * t102 * t512 + 0.8e1 * t142 * t417 + 0.8e1 * t641 * t563 - 0.2e1 * t7 * t507 + 0.2e1 * t7 * t750 - 0.8e1 * t35 * t352 + 0.4e1 * t237 * t410 + 0.4e1 * t7 * t684 - 0.2e1 * t46 * t445 + t147 * t148 * t65 + 0.4e1 * t763 * t304 * t119 + 0.16e2 * t70 * t177 * t60 + 0.2e1 * t70 * t770 - t111 * t414 - 0.16e2 * t567 * t174 - 0.4e1 * t46 * t71 - 0.4e1 * t46 * t355 - 0.4e1 * t7 * t277;
- t797 = t64 * t149;
- t821 = -t54 * t448 + 0.2e1 * t131 * t442 + 0.8e1 * t7 * t478 + 0.8e1 * t35 * t379 - 0.2e1 * t181 * t182 * t149 + 0.2e1 * t70 * t405 + 0.2e1 * t83 * t770 - 0.2e1 * t70 * t797 - 0.6e1 * t7 * t75 - 0.4e1 * t286 * t606 - 0.4e1 * t237 * t432 + t147 * t256 * t149 - 0.4e1 * t763 * t304 * t149 - 0.2e1 * t102 * t75 + 0.2e1 * t237 * t717 + 0.8e1 * t324 * t642 - 0.16e2 * t170 * t389 + 0.2e1 * t83 * t422;
- t827 = t84 * t149;
- t846 = t54 * n * self->ZA;
- t854 = t64 * t18;
- t867 = -0.16e2 * t142 * t128 + 0.32e2 * t35 * t465 - 0.2e1 * t83 * t827 + 0.2e1 * t46 * t315 + t147 * t148 * t86 - 0.4e1 * t102 * t451 - 0.8e1 * t226 * t148 * self->xc * t38 - 0.2e1 * t24 * t689 * t38 + 0.2e1 * t131 * t187 + 0.8e1 * t846 * t155 + 0.8e1 * t35 * t736 + 0.2e1 * t24 * t689 * t17 - 0.2e1 * t7 * t854 + t147 * t256 * t119 + 0.2e1 * t102 * t854 - 0.8e1 * t35 * t530 + 0.4e1 * t46 * t797 + 0.2e1 * t102 * t750;
- t909 = -0.8e1 * t324 * t663 + t147 * t256 * t444 - t147 * t256 * t65 + 0.4e1 * t226 * t238 + 0.2e1 * t7 * t40 - t54 * t401 + 0.16e2 * t57 * t174 + 0.4e1 * t226 * t337 + 0.4e1 * t24 * t8 * t163 + 0.8e1 * t846 * t695 + 0.8e1 * t319 * t454 + 0.2e1 * t131 * t653 - 0.8e1 * t46 * t64 * t95 + 0.6e1 * t24 * t78 * t15 - 0.4e1 * t44 * t31 * self->xc * t658 - 0.32e2 * t153 * t211 * t49 - 0.2e1 * t70 * t827 + t147 * t148 * t444;
- t914 = t25 * self->ZB;
- t915 = t33 * t914;
- t919 = t4 * t4;
- t920 = t16 * t919;
- t929 = t123 * t90;
- t932 = t919 * t103;
- t935 = t33 * self->ZB;
- t939 = t652 * t919;
- t942 = t16 * t30;
- t943 = t942 * t4;
- t949 = t103 * t16;
- t950 = t949 * t90;
- t953 = -0.2e1 * t915 * t103 * t90 + 0.2e1 * t915 * t920 - 0.2e1 * t915 * t123 * t919 + 0.2e1 * t915 * t16 * t90 - 0.2e1 * t915 * t929 - 0.2e1 * t915 * t932 - 0.2e1 * t935 * t323 * t123 + 0.2e1 * t935 * t939 + 0.4e1 * t915 * t943 + 0.4e1 * t182 * t172 * t90 + 0.2e1 * t915 * t950;
- t954 = t171 * t36;
- t955 = t90 * n;
- t956 = self->xc * t955;
- t957 = t118 * t10;
- t964 = t33 * t33;
- t965 = t964 * self->ZB;
- t966 = t965 * t640;
- t967 = t10 * t919;
- t968 = t55 * t16;
- t969 = t967 * t968;
- t972 = t935 * t36;
- t974 = t103 * t30 * t4;
- t977 = self->xc * t16;
- t978 = t967 * t977;
- t981 = t90 * t30;
- t983 = t16 * t10;
- t987 = t182 * self->ZA;
- t988 = t4 * t10;
- t992 = t171 * t604;
- t993 = self->xc * t14;
- t994 = t932 * t993;
- t997 = t182 * t30;
- t1005 = t171 * t285;
- t1006 = t988 * t993;
- t1009 = t58 * t914;
- t1010 = t1009 * t31;
- t1013 = 0.8e1 * t954 * t956 * t957 + 0.2e1 * t915 * t932 * t16 + 0.32e2 * t966 * t969 - 0.4e1 * t972 * t974 - 0.32e2 * t966 * t978 + 0.32e2 * t965 * t981 * t177 * t983 - 0.32e2 * t987 * t942 * t988 + 0.8e1 * t992 * t994 + 0.8e1 * t997 * t949 * self->ZA * t4 - 0.2e1 * t935 * t124 * t919 - 0.16e2 * t1005 * t1006 + 0.16e2 * t1010 * t1006;
- t1015 = t964 * t25;
- t1016 = self->ZA * t30;
- t1017 = t1015 * t1016;
- t1020 = t967 * t993;
- t1031 = t1009 * t118;
- t1032 = t31 * t10;
- t1040 = t964 * t914;
- t1041 = t1040 * t90;
- t1044 = t55 * t10 * t4 * t16;
- t1047 = t1040 * t30;
- t1050 = t123 * self->ZA;
- t1054 = t977 * t988;
- t1057 = 0.64e2 * t1017 * t978 - 0.8e1 * t992 * t1020 + 0.2e1 * t972 * t950 + 0.4e1 * t182 * t929 * self->ZA + 0.4e1 * t182 * t199 * t90 - 0.16e2 * t1031 * t1032 * t4 * self->xc + 0.4e1 * t182 * t172 * t919 + 0.64e2 * t1041 * t1044 + 0.32e2 * t1047 * t969 + 0.4e1 * t182 * t1050 * t919 - 0.64e2 * t1041 * t1054;
- t1058 = t1009 * n;
- t1063 = t932 * self->ZA;
- t1069 = t123 * t30 * t4;
- t1080 = t993 * t103 * t4;
- t1088 = t935 * t103;
- t1094 = -0.8e1 * t1058 * t994 - 0.32e2 * t1047 * t978 + 0.4e1 * t182 * t1063 - 0.4e1 * t915 * t974 - 0.4e1 * t915 * t1069 - 0.2e1 * t935 * t625 * t90 - 0.8e1 * t1009 * t10 * t14 * t955 - 0.16e2 * t1010 * t1080 - 0.2e1 * t935 * t625 * t919 - 0.64e2 * t1017 * t969 + 0.2e1 * t1088 * t939 + 0.8e1 * t1009 * t957 * t955;
- t1113 = t955 * t118 * self->xc;
- t1120 = t4 * t118;
- t1125 = t981 * self->xc;
- t1133 = n * t10;
- t1140 = -0.8e1 * t954 * t955 * t10 * t993 + 0.2e1 * t935 * t652 * t90 - 0.64e2 * t1015 * t981 * t575 * t983 + 0.8e1 * t182 * t103 * t1016 * t4 + 0.8e1 * t1009 * t1113 + 0.16e2 * t954 * t1032 * t4 * t14 - 0.16e2 * t954 * t1032 * t1120 + 0.64e2 * t1015 * t10 * t172 * t1125 + 0.8e1 * t171 * t103 * t136 * t956 - 0.8e1 * t1031 * t1133 * t919 * self->xc + 0.8e1 * t1058 * t1020;
- t1153 = self->xc * t118;
- t1165 = t182 * t16;
- t1170 = t171 * t10;
- t1178 = self->ZA * t90;
- t1182 = 0.4e1 * t1088 * t652 * t140 + 0.8e1 * t954 * t1133 * t919 * t14 + 0.4e1 * t972 * t943 - 0.4e1 * t972 * t1069 - 0.16e2 * t954 * t31 * t4 * t1153 - 0.8e1 * t954 * n * t919 * t1153 - 0.8e1 * t954 * t1133 * t919 * t118 + 0.4e1 * t1165 * t1063 + 0.16e2 * t1005 * t1080 - 0.8e1 * t1170 * t118 * t36 * t955 - 0.16e2 * t987 * t920 * t10 - 0.16e2 * t1165 * t1178 * t10;
- t1195 = t1040 * t981;
- t1199 = t1009 * t955;
- t1203 = t1009 * t10;
- t1211 = t965 * t323;
- t1225 = -0.32e2 * t965 * t10 * t652 * t1125 + 0.4e1 * t915 * t16 * t974 + 0.4e1 * t182 * t90 * t949 * self->ZA + 0.32e2 * t1195 * t968 * t10 - 0.8e1 * t1199 * t993 * t103 + 0.8e1 * t1203 * t118 * n * t919 + 0.8e1 * t1170 * t136 * t955 + 0.64e2 * t1211 * t1044 + 0.16e2 * t1031 * t1032 * t4 + 0.8e1 * t987 * t943 + 0.8e1 * t1199 * t993 * t10 + 0.8e1 * t997 * t1050 * t4;
- t1263 = -0.128e3 * t1015 * t1178 * t1044 + 0.16e2 * t1005 * t988 * t1153 + 0.8e1 * t1058 * t1153 * t919 + 0.16e2 * t1010 * t1120 * self->xc - 0.8e1 * t954 * t1113 - 0.8e1 * t1203 * t14 * n * t919 - 0.16e2 * t1203 * t14 * t31 * t4 - 0.8e1 * t1203 * t1113 - 0.32e2 * t1195 * t977 * t10 - 0.64e2 * t1211 * t1054 + 0.8e1 * t992 * t967 * t1153 + 0.128e3 * t1015 * t983 * t90 * t4 * t47;
-
- self->C1B = (t127 + t204 + t270 + t329 + t384 + t439 + t501 + t549 + t601 + t647 + t698 + t739 + t782 + t821 + t867 + t909) / (t953 + t1013 + t1057 + t1094 + t1140 + t1182 + t1225 + t1263);
- /****************************************************************************************/
- t1 = n * n;
- t2 = t1 * n;
- t3 = nx * t2;
- t4 = 0.3141592654e1 * self->ZA;
- t5 = t3 * t4;
- t6 = nx * 0.3141592654e1;
- t7 = t6 * self->xc;
- t8 = sin(t7);
- t9 = t8 * self->ZB;
- t10 = n * 0.3141592654e1;
- t11 = exp(t10);
- t12 = t11 * t11;
- t15 = exp( self->xc * n * 0.3141592654e1);
- t16 = t15 * t15;
- t17 = t16 * t16;
- t18 = t17 * t15;
- t19 = t12 * t18;
- t23 = t1 * t1;
- t24 = nx * t23;
- t25 = self->ZB * self->ZB;
- t27 = t18 * t8;
- t28 = 0.3141592654e1 * 0.3141592654e1;
- t29 = self->xc * self->xc;
- t30 = t28 * t29;
- t34 = t1 * self->xc;
- t35 = 0.3141592654e1 * self->ZB;
- t36 = t34 * t35;
- t37 = cos(t7);
- t38 = self->ZA * t37;
- t39 = nx * nx;
- t40 = t39 * t12;
- t41 = t16 * t15;
- t43 = t38 * t40 * t41;
- t46 = t25 * n;
- t47 = t46 * 0.3141592654e1;
- t48 = t39 * nx;
- t49 = sin(t6);
- t50 = t48 * t49;
- t51 = t12 * t11;
- t52 = t51 * t17;
- t53 = t50 * t52;
- t56 = t34 * 0.3141592654e1 * t25;
- t57 = t37 * t39;
- t58 = t17 * t41;
- t59 = t12 * t58;
- t60 = t57 * t59;
- t63 = t25 * t18;
- t64 = t57 * n;
- t67 = self->ZA * self->ZA;
- t68 = t67 * n;
- t69 = 0.3141592654e1 * t48;
- t70 = t68 * t69;
- t71 = t49 * self->xc;
- t72 = t17 * t16;
- t73 = t11 * t72;
- t74 = t71 * t73;
- t77 = t1 * t67;
- t78 = t77 * 0.3141592654e1;
- t81 = nx * t25;
- t82 = t81 * t49;
- t83 = t17 * t17;
- t85 = t1 * t83 * t11;
- t87 = nx * self->ZB;
- t88 = t8 * t2;
- t89 = t87 * t88;
- t90 = 0.3141592654e1 * self->xc;
- t91 = t12 * t12;
- t92 = self->ZA * t91;
- t97 = self->ZB * self->ZA;
- t98 = t97 * t37;
- t99 = t39 * n;
- t100 = t12 * t41;
- t104 = 0.8e1 * t5 * t9 * t19 + 0.8e1 * t24 * t25 * t27 * t30 + 0.12e2 * t36 * t43 - t47 * t53 - 0.2e1 * t56 * t60 - 0.4e1 * t63 * t64 + 0.6e1 * t70 * t74 + 0.4e1 * t78 * t60 - t82 * t85 + 0.4e1 * t89 * t90 * t92 * t41 + 0.4e1 * t98 * t99 * t100;
- t105 = t67 * t48;
- t106 = t49 * t51;
- t107 = t106 * t72;
- t109 = t1 * 0.3141592654e1;
- t110 = t109 * self->xc;
- t115 = nx * t67;
- t116 = t115 * t49;
- t117 = t1 * t16;
- t118 = t117 * t11;
- t120 = t2 * t25;
- t121 = t28 * 0.3141592654e1;
- t122 = t121 * t29;
- t123 = t120 * t122;
- t129 = t1 * self->ZB;
- t130 = t129 * t4;
- t131 = t57 * t100;
- t134 = t12 * t16;
- t136 = t109 * t39;
- t139 = self->ZB * t18;
- t141 = t39 * t1;
- t142 = t141 * t90;
- t145 = t77 * t90;
- t146 = t91 * t41;
- t147 = t57 * t146;
- t151 = t25 * t39 * t1;
- t152 = t72 * t12;
- t156 = t49 * t2;
- t158 = t83 * t11;
- t162 = -t105 * t107 + 0.8e1 * t110 * t72 * t25 * t39 - t116 * t118 + 0.8e1 * t123 * t53 + 0.8e1 * t5 * t9 * t59 - 0.8e1 * t130 * t131 - 0.8e1 * t134 * t25 * t136 - 0.12e2 * t139 * t38 * t142 - 0.8e1 * t145 * t147 - 0.8e1 * t151 * t90 * t152 - 0.2e1 * t87 * t156 * t4 * t158;
- t164 = t115 * t88;
- t165 = t90 * t19;
- t168 = t25 * t48;
- t169 = t49 * t16;
- t170 = t169 * t11;
- t174 = self->ZA * n * t69;
- t175 = self->ZB * t51;
- t176 = t175 * t17;
- t177 = t71 * t176;
- t180 = t1 * t29;
- t181 = t28 * t25;
- t182 = t180 * t181;
- t183 = t50 * t73;
- t186 = self->ZA * t1;
- t187 = t28 * t48;
- t188 = t186 * t187;
- t189 = self->ZB * t17;
- t190 = t189 * t11;
- t191 = t71 * t190;
- t194 = t50 * t158;
- t196 = t115 * t156;
- t197 = t90 * t73;
- t201 = t49 * t17 * t11;
- t204 = t88 * t90;
- t207 = t68 * 0.3141592654e1;
- t208 = t17 * t11;
- t209 = t50 * t208;
- t211 = -0.2e1 * t164 * t165 - t168 * t170 + t168 * t107 + 0.8e1 * t174 * t177 + 0.2e1 * t182 * t183 + 0.8e1 * t188 * t191 + t47 * t194 - 0.6e1 * t196 * t197 - t168 * t201 - 0.4e1 * t81 * t18 * t204 - t207 * t209;
- t212 = t2 * 0.3141592654e1;
- t213 = t212 * t52;
- t215 = t81 * t8;
- t216 = t212 * t59;
- t219 = t3 * t90;
- t220 = t25 * t8;
- t221 = t18 * t91;
- t225 = t71 * t52;
- t231 = t16 * t51;
- t232 = t50 * t231;
- t237 = self->ZA * t12;
- t243 = t67 * t28;
- t244 = t24 * t243;
- t245 = t71 * t231;
- t249 = -t116 * t213 - 0.4e1 * t215 * t216 + 0.2e1 * t219 * t220 * t221 - 0.4e1 * t70 * t225 + 0.4e1 * t98 * t99 * t146 + t47 * t232 - 0.2e1 * t145 * t57 * t221 + 0.4e1 * t89 * t90 * t237 * t41 - t105 * t201 - 0.6e1 * t244 * t245 + t105 * t170;
- t252 = t25 * t37;
- t253 = t252 * t39;
- t255 = n * t15 * t12;
- t258 = t2 * t29;
- t259 = self->ZB * t28;
- t260 = t258 * t259;
- t263 = t106 * t17;
- t265 = self->xc * t25;
- t269 = t25 * t49;
- t270 = t269 * t52;
- t273 = t1 * t25;
- t274 = t273 * 0.3141592654e1;
- t275 = t57 * t19;
- t278 = t24 * t30;
- t288 = t1 * t11 * t72;
- t290 = t212 * t208;
- t292 = t2 * self->xc;
- t296 = 0.2e1 * t253 * t255 + 0.16e2 * t260 * t43 + t105 * t263 - 0.4e1 * t10 * t265 * t53 + 0.4e1 * t219 * t270 - 0.12e2 * t274 * t275 + 0.8e1 * t278 * t270 - 0.2e1 * self->ZB * n * t69 * t49 * self->ZA * t158 - t82 * t288 - t116 * t290 + 0.16e2 * t292 * t243 * t275;
- t301 = t50 * t176;
- t304 = t51 * t72;
- t305 = t71 * t304;
- t308 = t25 * t41;
- t311 = self->ZA * t48;
- t312 = t311 * t49;
- t317 = t91 * t15;
- t318 = t57 * t317;
- t321 = t81 * t88;
- t322 = t90 * t59;
- t325 = t212 * t231;
- t327 = t15 * t12;
- t328 = t57 * t327;
- t331 = t77 * t187;
- t334 = t2 * self->ZA;
- t335 = t334 * t122;
- t336 = t50 * t190;
- t339 = 0.8e1 * t151 * t90 * t134 + 0.16e2 * t186 * t30 * t301 - 0.2e1 * t70 * t305 + 0.2e1 * t308 * t64 - 0.2e1 * t312 * self->ZB * t83 * t11 + 0.2e1 * t56 * t318 + 0.2e1 * t321 * t322 - t116 * t325 - 0.4e1 * t274 * t328 + 0.2e1 * t331 * t305 - 0.16e2 * t335 * t336;
- t341 = t169 * t51;
- t344 = t49 * t11 * t72;
- t346 = t77 * t30;
- t347 = t50 * t304;
- t350 = t25 * t51;
- t352 = nx * self->ZA;
- t353 = t49 * t23;
- t354 = t352 * t353;
- t355 = t28 * self->xc;
- t362 = t25 * t91;
- t365 = t23 * n;
- t366 = nx * t365;
- t367 = t366 * t122;
- t368 = self->ZB * t49;
- t369 = self->ZA * t51;
- t370 = t369 * t17;
- t371 = t368 * t370;
- t374 = t115 * t353;
- t375 = t355 * t73;
- t381 = t105 * t341 - t105 * t344 - 0.2e1 * t346 * t347 - t350 * t50 - 0.8e1 * t354 * t355 * t176 - 0.4e1 * t98 * t99 * t317 - 0.2e1 * t362 * t99 - 0.16e2 * t367 * t371 + 0.6e1 * t374 * t375 - 0.8e1 * t182 * t53 - t82 * t290;
- t382 = t71 * t208;
- t394 = t2 * t67;
- t395 = t394 * t122;
- t398 = t352 * t156;
- t402 = t17 * t12;
- t403 = t39 * self->ZA;
- t404 = t402 * t403;
- t407 = t269 * t208;
- t411 = t49 * t83 * t11;
- t413 = t46 * t69;
- t419 = -0.4e1 * t331 * t382 + 0.2e1 * t115 * t58 * t204 - 0.2e1 * t145 * t60 + 0.12e2 * t274 * t131 + 0.2e1 * t346 * t232 + 0.8e1 * t395 * t53 - 0.8e1 * t398 * t90 * t176 - 0.64e2 * t260 * t404 + 0.4e1 * t219 * t407 + t168 * t411 - 0.6e1 * t413 * t74 - 0.2e1 * t110 * t308 * t57;
- t424 = t16 * t11;
- t425 = t212 * t424;
- t427 = t258 * t181;
- t430 = t67 * t29;
- t431 = t366 * t430;
- t432 = t121 * t49;
- t433 = t432 * t52;
- t436 = n * t12;
- t437 = t436 * t18;
- t440 = t29 * self->xc;
- t441 = t440 * t121;
- t442 = t394 * t441;
- t445 = t67 * t37;
- t446 = t445 * t39;
- t448 = n * t18 * t91;
- t453 = t352 * t49;
- t458 = t8 * t23;
- t462 = t81 * t458;
- t463 = t30 * t19;
- t466 = -t47 * t209 + t116 * t425 - 0.8e1 * t427 * t275 + 0.8e1 * t431 * t433 - 0.2e1 * t253 * t437 - 0.8e1 * t442 * t53 - 0.2e1 * t446 * t448 + 0.2e1 * t175 * t312 + 0.6e1 * t453 * t129 * t208 + 0.8e1 * t115 * t18 * t458 * t30 + 0.8e1 * t462 * t463;
- t470 = t436 * t58;
- t475 = t2 * t121 * t440 * t25;
- t485 = t212 * t73;
- t488 = t67 * t72 * t1;
- t490 = t39 * self->xc;
- t501 = 0.4e1 * t374 * t355 * t52 + 0.2e1 * t446 * t470 - 0.8e1 * t475 * t53 - 0.2e1 * t446 * t437 - 0.4e1 * t36 * t38 * t39 * t15 * t12 - t116 * t485 + 0.8e1 * t488 * 0.3141592654e1 * t12 * t490 - t207 * t183 - 0.2e1 * t182 * t232 - 0.6e1 * t413 * t245 - 0.4e1 * t413 * t382;
- t503 = t115 * t8;
- t510 = t355 * t19;
- t513 = t432 * t208;
- t525 = t38 * t40 * t18;
- t533 = -0.4e1 * t503 * t216 - 0.4e1 * t89 * t90 * t92 * t15 - 0.16e2 * t462 * t510 + 0.8e1 * t431 * t513 - 0.4e1 * t78 * t131 + t47 * t183 - 0.2e1 * t67 * t83 * t99 + 0.4e1 * t331 * t225 + 0.16e2 * t260 * t525 - 0.4e1 * t89 * t90 * t237 * t58 - t207 * t53;
- t536 = t28 * t37;
- t538 = t490 * t100;
- t541 = t334 * t441;
- t547 = t394 * t30;
- t550 = t212 * t19;
- t553 = t366 * t441;
- t556 = n * t17;
- t571 = -0.8e1 * t427 * t131 + 0.16e2 * t394 * t536 * t538 + 0.16e2 * t541 * t336 + 0.2e1 * t453 * t129 * t158 - 0.8e1 * t547 * t147 + 0.4e1 * t503 * t550 - 0.8e1 * t553 * t270 + 0.4e1 * t556 * self->ZB * t92 * t39 - 0.2e1 * t67 * t91 * t99 - t82 * t425 + 0.4e1 * t78 * t275 + 0.2e1 * t78 * self->xc * t41 * t57;
- t583 = t90 * t317;
- t594 = t212 * t158;
- t596 = t152 * t67;
- t602 = t67 * t17;
- t607 = 0.8e1 * t367 * t407 - 0.4e1 * t98 * t99 * t59 + 0.16e2 * t260 * t18 * self->ZA * t57 + 0.2e1 * t321 * t583 - 0.6e1 * t174 * t368 * t52 - 0.4e1 * t89 * t90 * self->ZA * t15 * t12 + t116 * t594 - 0.8e1 * t596 * t136 - 0.4e1 * t98 * t99 * t327 + 0.2e1 * t602 * t99 + 0.2e1 * t164 * t583;
- t613 = t83 * t25;
- t616 = t81 * t156;
- t627 = t90 * t231;
- t630 = t91 * t16;
- t638 = 0.4e1 * t196 * t90 * t208 - 0.8e1 * t130 * t60 - 0.2e1 * t613 * t99 + 0.6e1 * t616 * t197 - 0.8e1 * t547 * t131 + 0.8e1 * t67 * t18 * t37 * t142 + 0.2e1 * t145 * t328 - 0.6e1 * t196 * t627 + 0.8e1 * t630 * t67 * t142 - 0.8e1 * t547 * t275 + 0.8e1 * t395 * t209;
- t643 = t77 * t355;
- t648 = t115 * t458;
- t651 = t134 * t67;
- t657 = t30 * t304;
- t660 = t30 * t146;
- t665 = t25 * t17;
- t668 = t50 * t424;
- t671 = -0.4e1 * t321 * t90 * t146 - 0.6e1 * t643 * t232 + 0.8e1 * t182 * t209 - 0.16e2 * t648 * t510 + 0.8e1 * t651 * t136 + 0.8e1 * t89 * t4 * t100 - 0.2e1 * t374 * t657 - 0.8e1 * t648 * t660 + 0.8e1 * t130 * t328 + 0.2e1 * t665 * t99 + 0.2e1 * t346 * t668;
- t672 = t90 * t424;
- t676 = t120 * t536;
- t680 = t436 * t41;
- t688 = t366 * t67 * t440;
- t696 = self->xc * t12;
- t697 = t696 * t18;
- t701 = t252 * t141;
- t702 = t90 * t221;
- t705 = 0.2e1 * t196 * t672 - t47 * t347 + 0.16e2 * t676 * t538 - t116 * t85 - 0.2e1 * t253 * t680 + t207 * t194 + 0.4e1 * t98 * t99 * t19 - 0.8e1 * t688 * t433 + 0.16e2 * t541 * t301 - 0.6e1 * t312 * t190 + 0.4e1 * t352 * t88 * t35 * t697 + 0.2e1 * t701 * t702;
- t712 = t24 * t430;
- t713 = t28 * t49;
- t721 = t1 * t17 * t11;
- t726 = self->ZB * self->xc;
- t737 = n * t91;
- t741 = 0.8e1 * t346 * t209 + 0.2e1 * t712 * t713 * t424 + 0.8e1 * t130 * t275 - t47 * t668 + t116 * t721 - 0.8e1 * t688 * t513 + 0.4e1 * t352 * t27 * t212 * t726 + 0.8e1 * t648 * t463 + 0.4e1 * t274 * t60 - 0.4e1 * t374 * t355 * t208 - 0.4e1 * t253 * t737 * t41;
- t745 = t269 * t231;
- t749 = t1 * t28 * t265;
- t757 = t16 * t39;
- t758 = t696 * t757;
- t762 = t69 * t49;
- t772 = t355 * t100;
- t775 = t81 * t353;
- t778 = -0.8e1 * t398 * t90 * t190 - 0.2e1 * t278 * t745 + 0.4e1 * t749 * t53 + 0.32e2 * t394 * t29 * t28 * t17 * t40 - 0.8e1 * t78 * t758 + t350 * n * t762 - 0.6e1 * t87 * t49 * t186 * t52 - 0.8e1 * t553 * t407 - 0.4e1 * t749 * t209 + 0.16e2 * t648 * t772 - 0.6e1 * t775 * t375;
- t790 = t212 * t304;
- t793 = t156 * 0.3141592654e1;
- t795 = t355 * t304;
- t800 = t91 * t39;
- t801 = t800 * n;
- t807 = t2 * t28;
- t808 = t807 * t726;
- t811 = -0.2e1 * t616 * t672 - 0.2e1 * t446 * t680 - 0.2e1 * t78 * self->xc * t58 * t57 + 0.8e1 * t367 * t270 - t82 * t790 + t115 * t51 * t793 - 0.2e1 * t775 * t795 + 0.8e1 * t123 * t209 + 0.2e1 * t665 * t801 - 0.2e1 * t67 * t41 * t64 - 0.32e2 * t808 * t43;
- t812 = t117 * t51;
- t821 = t24 * t355;
- t827 = t90 * t304;
- t840 = t800 * t41;
- t844 = -t116 * t812 - 0.2e1 * t110 * t25 * t58 * t57 - 0.4e1 * t78 * t328 + t82 * t485 - 0.4e1 * t821 * t407 + 0.4e1 * t196 * t90 * t52 + 0.2e1 * t196 * t827 + t82 * t325 + 0.2e1 * t253 * t448 - 0.32e2 * t402 * t67 * t807 * t490 - t207 * t232 + 0.12e2 * t186 * t90 * self->ZB * t37 * t840;
- t849 = t1 * t51;
- t850 = t849 * t17;
- t860 = t269 * t424;
- t863 = t273 * t187;
- t874 = 0.16e2 * t462 * t772 - t116 * t850 + 0.16e2 * t553 * t371 + t116 * t288 - 0.12e2 * t97 * t57 * t109 * t697 + t82 * t594 - 0.2e1 * t278 * t860 - 0.2e1 * t863 * t305 - 0.16e2 * t180 * t259 * t311 * t201 - 0.6e1 * t863 * t74 + 0.8e1 * t174 * t191;
- t879 = self->xc * self->ZA;
- t888 = t67 * t51;
- t901 = self->ZA * t17;
- t903 = t368 * t901 * t11;
- t908 = -0.2e1 * t352 * t51 * t156 * t35 + 0.64e2 * t879 * t189 * t807 * t40 + 0.2e1 * t46 * t58 * t37 * t39 - t888 * t50 + t105 * t411 - 0.16e2 * t335 * t301 + 0.8e1 * t152 * t25 * t136 - 0.8e1 * t278 * t407 + 0.2e1 * t712 * t713 * t231 - 0.16e2 * t367 * t903 + 0.2e1 * t145 * t318;
- t923 = t71 * t424;
- t926 = t87 * t458;
- t927 = t28 * self->ZA;
- t944 = 0.8e1 * t354 * t355 * t190 - 0.8e1 * t110 * t16 * t25 * t800 - 0.2e1 * t374 * t30 * t73 - 0.16e2 * t354 * t30 * t176 - 0.2e1 * t244 * t923 - 0.32e2 * t926 * t927 * t696 * t41 - 0.32e2 * t808 * t525 + 0.6e1 * t749 * t232 - 0.8e1 * t188 * t177 + 0.4e1 * t36 * t58 * self->ZA * t57 + 0.4e1 * t821 * t270;
- t948 = t90 * t327;
- t961 = t30 * t100;
- t964 = t29 * t49;
- t981 = t106 * t1;
- t983 = -0.2e1 * t219 * t220 * t100 + 0.2e1 * t321 * t948 - 0.16e2 * t189 * self->ZA * t99 * t12 - 0.2e1 * t369 * n * t69 * t368 + 0.2e1 * t374 * t795 - 0.8e1 * t462 * t961 - 0.8e1 * t244 * t964 * t208 + 0.2e1 * t413 * t923 + 0.4e1 * t36 * t38 * t40 * t58 - 0.2e1 * t87 * t51 * t49 * t1 * self->ZA + t888 * n * t762 + t115 * t981;
- t1012 = 0.6e1 * t616 * t627 - t82 * t213 + 0.2e1 * t775 * t657 - 0.12e2 * t215 * t550 - 0.6e1 * t145 * t131 + 0.2e1 * t81 * t41 * t204 + 0.6e1 * self->ZB * t48 * t49 * t370 - 0.4e1 * t70 * t382 + 0.2e1 * t446 * t255 + 0.8e1 * t89 * t4 * t327 - 0.4e1 * t56 * t147;
- t1018 = t212 * t100;
- t1029 = t212 * t327;
- t1040 = 0.6e1 * t70 * t245 + 0.2e1 * t56 * t328 + t207 * t668 + 0.4e1 * t503 * t1018 + 0.2e1 * t253 * t470 - 0.6e1 * t398 * t35 * t208 - 0.8e1 * t331 * t964 * t52 - 0.4e1 * t503 * t1029 + 0.6e1 * t821 * t745 + 0.4e1 * t63 * t37 * t142 + 0.16e2 * t260 * t38 * t840;
- t1068 = t207 * t347 - 0.2e1 * t164 * t702 - 0.2e1 * t331 * t964 * t73 + 0.8e1 * t374 * t30 * t52 + 0.16e2 * t278 * t903 + 0.2e1 * t863 * t923 + 0.6e1 * t445 * t141 * t165 - 0.2e1 * t164 * t90 * t100 + 0.6e1 * t331 * t74 - 0.2e1 * t182 * t668 - 0.2e1 * t115 * t41 * t204;
- t1079 = t58 * t8;
- t1091 = t807 * t29;
- t1092 = t665 * t40;
- t1101 = self->ZB * t91;
- t1102 = t403 * n;
- t1105 = -0.4e1 * t58 * self->ZB * self->ZA * t64 - t82 * t850 + 0.2e1 * t821 * t860 + t81 * t51 * t793 + 0.2e1 * t3 * t25 * t1079 * t90 + t82 * t721 - 0.2e1 * t643 * t668 + 0.16e2 * t926 * t927 * t29 * t91 * t41 + 0.32e2 * t1091 * t1092 - 0.2e1 * t219 * t220 * t19 + 0.4e1 * t139 * self->ZA * t64 + 0.4e1 * t1101 * t1102;
- t1108 = t849 * t72;
- t1121 = t737 * t15;
- t1124 = t29 * t12;
- t1133 = t116 * t1108 - 0.8e1 * t475 * t209 - 0.32e2 * t807 * self->xc * t1092 + 0.2e1 * t278 * t269 * t73 + t82 * t812 - 0.6e1 * t56 * t131 + 0.2e1 * t253 * t1121 + 0.16e2 * t926 * t927 * t1124 * t41 + t168 * t263 - 0.2e1 * t616 * t827 + t81 * t981;
- t1134 = t394 * t28;
- t1159 = -0.8e1 * t1134 * t29 * t18 * t57 + t82 * t118 - 0.12e2 * t215 * t1018 + 0.2e1 * t602 * t801 - t168 * t341 + 0.2e1 * t67 * t58 * t64 + t168 * t344 - 0.6e1 * t174 * t368 * t208 + 0.16e2 * t553 * t903 + t116 * t790 - 0.4e1 * t36 * t38 * t800 * t15;
- t1161 = n * t83;
- t1173 = self->ZB * t12;
- t1196 = 0.4e1 * t1161 * self->ZB * t39 * self->ZA - 0.4e1 * t215 * t1029 - 0.8e1 * t488 * 0.3141592654e1 * t39 * self->xc + 0.32e2 * t821 * self->ZA * t8 * t1173 * t18 - 0.8e1 * t427 * t147 + 0.6e1 * t701 * t165 - 0.16e2 * t926 * t927 * t1124 * t18 - 0.8e1 * t1091 * t63 * t57 - 0.8e1 * t442 * t209 - 0.8e1 * t462 * t660 - 0.6e1 * t398 * t35 * t52;
- t1228 = 0.2e1 * t413 * t305 - 0.8e1 * t648 * t961 - 0.16e2 * t87 * t27 * t23 * t28 * self->ZA * t29 + 0.4e1 * t189 * t1102 - 0.4e1 * t87 * t1079 * t212 * t879 + 0.2e1 * t164 * t948 - 0.2e1 * t70 * t923 + 0.2e1 * t164 * t322 + 0.2e1 * t446 * t1121 + 0.2e1 * t863 * t964 * t304 - t82 * t1108 + 0.16e2 * t676 * t490 * t19;
- t1234 = t25 * self->ZB;
- t1235 = t1234 * t28;
- t1236 = t365 * t91;
- t1240 = self->ZB * t121;
- t1241 = t1240 * t77;
- t1242 = t39 * t39;
- t1243 = t12 * t1242;
- t1244 = self->xc * t72;
- t1245 = t1243 * t1244;
- t1248 = t365 * t25;
- t1252 = t243 * n;
- t1257 = t23 * t1;
- t1258 = t1240 * t1257;
- t1259 = t67 * t12;
- t1260 = self->xc * t16;
- t1268 = t1234 * t121;
- t1269 = t1268 * t23;
- t1272 = t1242 * t91;
- t1280 = t67 * self->xc;
- t1284 = t28 * t28;
- t1285 = t67 * t1284;
- t1287 = t1285 * t2 * self->ZB;
- t1288 = t17 * self->xc;
- t1289 = t1243 * t1288;
- t1292 = 0.2e1 * t1235 * t1236 * t17 + 0.8e1 * t1241 * t1245 + 0.4e1 * t927 * t1248 * t91 - 0.2e1 * t1252 * self->ZB * t1242 * t91 - 0.8e1 * t1258 * t1259 * t1260 - 0.4e1 * t1235 * t2 * t83 * t39 + 0.16e2 * t1269 * t758 + 0.2e1 * t1252 * t189 * t1272 - 0.2e1 * t1252 * t83 * t1242 * self->ZB + 0.8e1 * t1258 * t630 * t1280 - 0.32e2 * t1287 * t1289;
- t1293 = t365 * t83;
- t1300 = self->ZA * t1284;
- t1304 = t17 * t1242 * t25 * t12;
- t1307 = t927 * t2;
- t1311 = t23 * t2;
- t1312 = t1300 * t1311;
- t1316 = t1234 * t1284;
- t1317 = t1316 * t1311;
- t1321 = t1240 * t23;
- t1331 = t1240 * t23 * t67;
- t1332 = t40 * t1244;
- t1338 = t1243 * t1260;
- t1344 = -0.2e1 * t1235 * t1293 - 0.16e2 * t181 * t365 * t901 * t12 - 0.64e2 * t1300 * t258 * t1304 + 0.8e1 * t1307 * t613 * t39 + 0.64e2 * t1312 * t265 * t402 - 0.32e2 * t1317 * t1288 * t12 - 0.16e2 * t1321 * t67 * t39 * t1244 + 0.2e1 * t1235 * n * t1272 * t17 + 0.16e2 * t1331 * t1332 + 0.64e2 * t1300 * t292 * t1304 - 0.8e1 * t1241 * t1338 - 0.2e1 * t243 * t1293 * self->ZB;
- t1346 = t1316 * t2;
- t1349 = t927 * n;
- t1350 = t25 * t1242;
- t1354 = t1268 * t1257;
- t1366 = t1268 * t1;
- t1370 = t29 * t17;
- t1371 = t1243 * t1370;
- t1386 = -0.32e2 * t1346 * t1289 + 0.4e1 * t1349 * t1350 * t91 + 0.8e1 * t1354 * t1260 * t12 - 0.16e2 * t181 * n * t901 * t1243 - 0.4e1 * t1235 * t2 * t91 * t39 + 0.8e1 * t1366 * t152 * t1242 + 0.32e2 * t1287 * t1371 + 0.8e1 * t1258 * t1280 * t152 - 0.8e1 * t1354 * t1260 * t91 + 0.128e3 * t1300 * t365 * self->xc * t1092 + 0.8e1 * t1366 * t1338;
- t1387 = t1257 * t12;
- t1391 = t1240 * t1;
- t1399 = t1272 * t1260;
- t1412 = t1285 * t1311;
- t1427 = -0.8e1 * t1268 * t1387 * t16 - 0.8e1 * t1391 * t67 * t1242 * t1244 - 0.4e1 * t1134 * t1101 * t39 + 0.8e1 * t1241 * t1399 - 0.8e1 * t1258 * t596 + 0.4e1 * t927 * t1293 * t25 - 0.16e2 * t1331 * t758 + 0.8e1 * t1307 * t665 * t39 + 0.32e2 * t1412 * t1370 * t1173 + 0.8e1 * t1307 * t665 * t800 + 0.8e1 * t1391 * t1259 * t1242 * t16 - 0.8e1 * t1391 * t1259 * t1242 * t72;
- t1456 = t365 * self->ZB;
- t1468 = 0.4e1 * t927 * t1248 * t17 - 0.2e1 * t1235 * n * t1242 * t91 + 0.8e1 * t1366 * t1244 * t1242 - 0.16e2 * t1269 * t134 * t39 + 0.8e1 * t1268 * t1257 * t72 * self->xc + 0.16e2 * t1321 * t1259 * t757 + 0.32e2 * t1317 * t1370 * t12 + 0.4e1 * t1349 * t613 * t1242 + 0.2e1 * t243 * t1456 * t17 - 0.64e2 * t1285 * t365 * t12 * t189 * t490 - 0.8e1 * t1354 * t152 * self->xc;
- t1472 = t1316 * t365;
- t1474 = t1124 * t39 * t17;
- t1478 = t17 * t91;
- t1504 = t72 * t39;
- t1511 = 0.4e1 * t1134 * t189 * t800 + 0.64e2 * t1472 * t1474 + 0.4e1 * t1235 * t2 * t1478 * t39 + 0.4e1 * t1349 * t665 * t1242 - 0.8e1 * t1258 * t1280 * t72 + 0.2e1 * t1252 * t189 * t1242 + 0.2e1 * t243 * t365 * t189 * t91 + 0.4e1 * t927 * t365 * t1478 * t25 - 0.128e3 * t1300 * t1248 * t1474 - 0.2e1 * t1235 * t1236 + 0.16e2 * t1269 * t1504 * self->xc + 0.2e1 * t1235 * t365 * t17;
- t1545 = -0.2e1 * t1235 * t1161 * t1242 + 0.4e1 * t1349 * t1350 * t1478 - 0.8e1 * t1366 * t1245 + 0.2e1 * t1235 * t556 * t1242 - 0.32e2 * t1412 * t402 * t726 - 0.8e1 * t1366 * t1399 + 0.8e1 * t1258 * t651 - 0.2e1 * t243 * t1456 * t91 + 0.8e1 * t1268 * t1387 * t72 - 0.16e2 * t1269 * t1332 + 0.4e1 * t1134 * t189 * t39 + 0.16e2 * t1269 * t152 * t39;
- t1564 = t1260 * t800;
- t1583 = 0.64e2 * t1285 * t1456 * t1474 - 0.64e2 * t1472 * t1288 * t40 - 0.8e1 * t1366 * t134 * t1242 + 0.8e1 * t1307 * t362 * t39 + 0.4e1 * t1235 * t2 * t17 * t39 + 0.32e2 * t1346 * t1371 - 0.16e2 * t1269 * t1564 - 0.16e2 * t1321 * t1259 * t1504 + 0.16e2 * t1331 * t1564 - 0.64e2 * t1312 * t29 * t25 * t402 - 0.4e1 * t1134 * t83 * t39 * self->ZB - 0.32e2 * t181 * t2 * t404;
-
- self->C2B = (t1133 + t1196 + t1068 + t811 + t466 + t1012 + t381 + t162 + t249 + t533 + t844 + t104 + t1159 + t571 + t211 + t874 + t607 + t339 + t296 + t638 + t908 + t671 + t419 + t983 + t705 + t1105 + t501 + t778 + t1040 + t1228 + t741 + t944) / (t1292 + t1344 + t1386 + t1427 + t1468 + t1511 + t1545 + t1583);
- /****************************************************************************************/
- t1 = n * n;
- t2 = t1 * n;
- t3 = t2 * nx;
- t4 = nx * 0.3141592654e1;
- t5 = t4 * self->xc;
- t6 = sin(t5);
- t7 = 0.3141592654e1 * 0.3141592654e1;
- t9 = t3 * t6 * t7;
- t10 = self->xc * self->xc;
- t11 = self->ZA * self->ZA;
- t12 = t10 * t11;
- t13 = n * 0.3141592654e1;
- t14 = exp(t13);
- t15 = t14 * t14;
- t16 = self->xc * n;
- t18 = exp(t16 * 0.3141592654e1);
- t19 = t18 * t18;
- t20 = t19 * t18;
- t21 = t15 * t20;
- t22 = t12 * t21;
- t25 = nx * t6;
- t26 = t1 * 0.3141592654e1;
- t27 = t25 * t26;
- t28 = self->ZA * self->ZB;
- t29 = t18 * t15;
- t30 = t28 * t29;
- t33 = t25 * n;
- t34 = t11 * t15;
- t35 = t19 * t19;
- t36 = t35 * t18;
- t40 = t25 * t1;
- t41 = 0.3141592654e1 * t11;
- t42 = t15 * t36;
- t43 = t41 * t42;
- t46 = nx * nx;
- t47 = t1 * t46;
- t48 = t47 * t11;
- t49 = t7 * self->xc;
- t50 = t35 * t15;
- t51 = t49 * t50;
- t55 = sin(t4);
- t56 = t46 * nx * t55;
- t58 = t56 * n * t7;
- t59 = self->ZB * self->ZB;
- t60 = t10 * t59;
- t61 = t15 * t14;
- t62 = t19 * t61;
- t63 = t60 * t62;
- t66 = t19 * t14;
- t67 = t60 * t66;
- t70 = t28 * t42;
- t73 = cos(t5);
- t74 = t47 * t73;
- t75 = t7 * t11;
- t77 = t75 * t10 * t36;
- t80 = t73 * t46;
- t81 = t80 * n;
- t82 = 0.3141592654e1 * t59;
- t83 = t82 * t42;
- t87 = self->xc * t11;
- t88 = t87 * t62;
- t91 = n * nx;
- t92 = t55 * t61;
- t96 = nx * t55;
- t98 = t96 * t2 * t7;
- t101 = self->xc * t59;
- t102 = t101 * t62;
- t108 = t1 * t1;
- t109 = t108 * t7;
- t111 = t59 * t35;
- t112 = t111 * t15;
- t115 = t35 * t20;
- t123 = t1 * nx * t55;
- t124 = t61 * t35;
- t127 = t35 * t19;
- t128 = t61 * t127;
- t129 = t60 * t128;
- t132 = t56 * t16;
- t133 = t7 * t59;
- t134 = t133 * t124;
- t137 = 0.6e1 * t58 * t88 - 0.2e1 * t91 * t92 * t11 + 0.2e1 * t98 * t63 - 0.6e1 * t58 * t102 - 0.2e1 * t91 * t92 * t59 - 0.16e2 * t109 * self->xc * t112 - 0.2e1 * t91 * t6 * t115 * t59 + 0.12e2 * t40 * t83 + t123 * t41 * t124 - 0.2e1 * t58 * t129 + 0.4e1 * t132 * t134;
- t139 = t56 * 0.3141592654e1;
- t140 = t111 * t14;
- t144 = t49 * t124;
- t147 = t91 * t55;
- t148 = t61 * self->ZA;
- t154 = self->ZA * t115 * self->xc * self->ZB;
- t157 = t7 * 0.3141592654e1;
- t159 = t96 * t108 * t157;
- t160 = t10 * self->xc;
- t161 = t160 * t59;
- t162 = t35 * t14;
- t163 = t161 * t162;
- t166 = t28 * t162;
- t169 = t80 * t13;
- t170 = t101 * t42;
- t173 = t2 * t11;
- t174 = t96 * t173;
- t175 = t7 * t10;
- t179 = t59 * t15;
- t184 = t15 * t15;
- t193 = t139 * t140 + 0.4e1 * t56 * n * t11 * t144 + 0.4e1 * t147 * t148 * self->ZB + 0.4e1 * t27 * t154 + 0.8e1 * t159 * t163 - 0.12e2 * t147 * t166 + 0.2e1 * t169 * t170 - 0.16e2 * t174 * t175 * t124 + 0.2e1 * t33 * t179 * t20 - 0.2e1 * t33 * t11 * t36 * t184 + 0.2e1 * t56 * t61 * 0.3141592654e1 * self->ZA * self->ZB;
- t194 = t173 * 0.3141592654e1;
- t195 = self->xc * t15;
- t196 = t195 * t19;
- t202 = t15 * t115;
- t203 = t28 * t202;
- t206 = t96 * t26;
- t207 = t14 * t127;
- t208 = t101 * t207;
- t211 = t12 * t128;
- t218 = t11 * t61;
- t219 = t218 * t35;
- t221 = t108 * self->ZA;
- t223 = t7 * self->ZB;
- t224 = t223 * t50;
- t227 = self->ZA * self->xc;
- t228 = self->ZB * t15;
- t229 = t228 * t36;
- t230 = t227 * t229;
- t233 = t87 * t207;
- t236 = t6 * t11;
- t240 = -0.4e1 * t194 * t196 + 0.4e1 * t194 * t195 * t127 + 0.4e1 * t33 * t203 - 0.12e2 * t206 * t208 + 0.2e1 * t58 * t211 - 0.16e2 * t47 * t10 * t133 * t50 + t139 * t219 - 0.32e2 * t221 * t10 * t224 - 0.4e1 * t169 * t230 - 0.6e1 * t98 * t233 + 0.2e1 * t91 * t236 * t20;
- t244 = t227 * t228 * t20;
- t252 = t184 * t18;
- t253 = t101 * t252;
- t256 = t35 * t35;
- t257 = t256 * t14;
- t258 = t28 * t257;
- t261 = t108 * t11;
- t263 = t7 * t35;
- t268 = self->ZB * t61 * t35;
- t273 = t96 * t108 * t160;
- t274 = t157 * self->ZB;
- t276 = t274 * t148 * t35;
- t279 = t101 * t21;
- t282 = 0.3141592654e1 * self->xc;
- t283 = t59 * t36;
- t284 = t282 * t283;
- t289 = 0.4e1 * t169 * t244 - 0.4e1 * t132 * t133 * t162 - 0.2e1 * t147 * t140 - 0.2e1 * t27 * t253 + 0.2e1 * t139 * t258 + 0.16e2 * t261 * t10 * t263 * t15 - 0.16e2 * t206 * t227 * t268 - 0.16e2 * t273 * t276 - 0.6e1 * t27 * t279 - 0.4e1 * t40 * t284 - 0.32e2 * t9 * t230;
- t290 = t1 * t11;
- t291 = t96 * t290;
- t297 = t59 * t61;
- t298 = t297 * t127;
- t300 = self->ZB * t36;
- t301 = t227 * t300;
- t304 = t1 * t59;
- t305 = t184 * t35;
- t310 = t46 * self->ZB;
- t311 = t184 * self->ZA;
- t312 = t310 * t311;
- t314 = t60 * t21;
- t317 = t1 * self->ZA;
- t318 = self->ZB * t35;
- t321 = t1 * t256;
- t324 = t96 * t261;
- t325 = t10 * t157;
- t326 = t325 * t124;
- t329 = -0.4e1 * t291 * t282 * t128 + t123 * t82 * t62 - t139 * t298 + 0.12e2 * t27 * t301 + t304 * t305 - 0.2e1 * t58 * t12 * t66 - 0.2e1 * t312 + 0.8e1 * t9 * t314 + 0.2e1 * t317 * t318 + 0.2e1 * t321 * t28 - 0.8e1 * t324 * t326;
- t331 = t28 * t124;
- t334 = 0.3141592654e1 * t15;
- t335 = t334 * t127;
- t338 = t35 * self->ZA;
- t341 = t46 * t256;
- t344 = t46 * t11;
- t346 = t46 * t59;
- t348 = t297 * t35;
- t351 = self->ZA * t10;
- t352 = t351 * t300;
- t355 = t1 * self->ZB;
- t362 = 0.12e2 * t147 * t331 - 0.4e1 * t173 * t335 - 0.2e1 * t310 * t338 - 0.2e1 * t341 * t28 - t344 * t305 - t346 * t305 + 0.2e1 * t147 * t348 + 0.16e2 * t9 * t352 + 0.2e1 * t355 * t311 + t290 * t305 + 0.2e1 * t33 * t34 * t20;
- t363 = t36 * t184;
- t364 = t87 * t363;
- t368 = t47 * t73 * t7;
- t373 = t160 * t157;
- t374 = t373 * t124;
- t377 = t311 * t35;
- t380 = t12 * t62;
- t386 = self->ZB * t10 * self->ZA * t15 * t20;
- t389 = t87 * t66;
- t393 = t56 * t1 * t10;
- t401 = 0.2e1 * t27 * t364 - 0.16e2 * t368 * t279 - t123 * t41 * t257 + 0.8e1 * t324 * t374 + 0.2e1 * t355 * t377 - 0.2e1 * t98 * t380 - 0.16e2 * t9 * t386 + 0.2e1 * t58 * t389 + 0.16e2 * t393 * t276 + t123 * t82 * t162 - 0.2e1 * t33 * t179 * t36;
- t412 = t11 * t14 * t127;
- t416 = t11 * t19;
- t417 = t416 * t61;
- t421 = t96 * t2 * self->ZA;
- t426 = t56 * n * self->ZA;
- t427 = t318 * t14;
- t428 = t49 * t427;
- t431 = t82 * t29;
- t434 = t87 * t21;
- t442 = 0.2e1 * t33 * t11 * t184 * t18 + 0.4e1 * t81 * t284 - t139 * t412 + 0.2e1 * t147 * t219 - 0.2e1 * t147 * t417 + 0.32e2 * t421 * t175 * t268 + 0.8e1 * t426 * t428 + 0.4e1 * t81 * t431 - 0.2e1 * t169 * t434 - 0.2e1 * t98 * t129 - 0.32e2 * t47 * t28 * t51;
- t443 = t184 * t20;
- t447 = t61 * 0.3141592654e1;
- t448 = t447 * t11;
- t450 = t49 * t268;
- t453 = t60 * t42;
- t456 = t41 * t202;
- t463 = t101 * t443;
- t469 = t41 * self->xc * t20;
- t474 = -0.8e1 * t27 * t87 * t443 - t56 * t448 - 0.8e1 * t426 * t450 + 0.8e1 * t368 * t453 + 0.4e1 * t40 * t456 + 0.4e1 * t40 * t431 - 0.4e1 * t81 * t456 - 0.4e1 * t27 * t463 + 0.6e1 * t139 * t331 + 0.2e1 * t40 * t469 - 0.16e2 * t9 * t434;
- t482 = t108 * t10;
- t492 = n * t46;
- t493 = t492 * t11;
- t495 = t282 * t19 * t184;
- t498 = t56 * t290;
- t499 = t325 * t162;
- t502 = t416 * t14;
- t504 = t60 * t207;
- t507 = -t123 * t82 * t257 - 0.4e1 * t169 * t301 + t123 * t41 * t162 + 0.16e2 * t482 * t7 * t112 - 0.12e2 * t206 * t102 - t123 * t82 * t66 - 0.4e1 * t147 * t258 - 0.4e1 * t493 * t495 - 0.8e1 * t498 * t499 + t139 * t502 - 0.2e1 * t98 * t504;
- t508 = t101 * t162;
- t512 = t41 * t115 * self->xc;
- t515 = t87 * t42;
- t520 = self->ZB * t184;
- t522 = t227 * t520 * t18;
- t525 = t492 * t59;
- t528 = t6 * t59;
- t532 = t520 * t20;
- t533 = t351 * t532;
- t539 = t447 * t59;
- t544 = 0.8e1 * t206 * t508 - 0.2e1 * t40 * t512 - 0.16e2 * t368 * t515 + 0.12e2 * t206 * t88 + 0.4e1 * t27 * t522 + 0.4e1 * t525 * t495 - 0.4e1 * t91 * t528 * t36 - 0.16e2 * t368 * t533 - 0.16e2 * t206 * t227 * t427 - t56 * t539 - 0.2e1 * t132 * t133 * t66;
- t551 = t87 * t162;
- t554 = t351 * t229;
- t560 = t59 * t19;
- t561 = t560 * t14;
- t564 = t101 * t202;
- t567 = t87 * t252;
- t573 = t227 * t228 * t115;
- t578 = 0.4e1 * t33 * t70 + 0.4e1 * t493 * t335 - 0.4e1 * t58 * t551 + 0.16e2 * t9 * t554 - 0.4e1 * t33 * t28 * t252 + 0.2e1 * t147 * t561 + 0.2e1 * t169 * t564 - 0.2e1 * t27 * t567 - 0.8e1 * t324 * t499 - 0.4e1 * t169 * t573 + 0.12e2 * t27 * t244;
- t579 = t82 * t202;
- t591 = t282 * t115 * t59;
- t598 = t101 * t66;
- t606 = -0.4e1 * t81 * t579 - 0.2e1 * t169 * t567 - 0.6e1 * t27 * t170 + 0.8e1 * t169 * t203 + 0.2e1 * t98 * t67 + 0.2e1 * t81 * t591 + 0.32e2 * t368 * t244 - 0.2e1 * t27 * t564 + 0.4e1 * t206 * t598 + 0.16e2 * t9 * t170 + 0.2e1 * t33 * t283 * t184;
- t608 = t373 * t162;
- t611 = t59 * t184;
- t617 = t101 * t29;
- t624 = t227 * self->ZB * t18 * t15;
- t629 = t157 * t59;
- t630 = t629 * t124;
- t633 = t3 * t6;
- t634 = t175 * t283;
- t644 = 0.8e1 * t498 * t608 + 0.2e1 * t33 * t611 * t18 - 0.4e1 * t206 * t389 - 0.2e1 * t27 * t617 - 0.4e1 * t169 * t154 + 0.4e1 * t27 * t624 + 0.12e2 * t27 * t230 - 0.8e1 * t393 * t630 - 0.8e1 * t633 * t634 + 0.16e2 * t47 * t7 * t101 * t50 + 0.2e1 * t123 * t447 * t28;
- t645 = t41 * t29;
- t648 = t2 * 0.3141592654e1;
- t649 = t648 * self->xc;
- t650 = t560 * t184;
- t656 = t56 * t1 * t157;
- t659 = t87 * t128;
- t662 = t96 * t482;
- t663 = t629 * t162;
- t671 = t161 * t124;
- t674 = t218 * t127;
- t679 = 0.4e1 * t81 * t645 - 0.4e1 * t649 * t650 - 0.8e1 * t169 * t70 + 0.8e1 * t656 * t163 - 0.2e1 * t98 * t659 - 0.8e1 * t662 * t663 - 0.32e2 * t421 * t175 * t427 - 0.2e1 * t147 * t502 + 0.8e1 * t656 * t671 + 0.2e1 * t147 * t674 - 0.16e2 * t368 * t386;
- t714 = t334 * t19;
- t719 = t12 * t42;
- t722 = t304 * t35 - t346 * t35 + t341 * t59 - t344 * t35 + t344 * t256 + t346 * t184 - 0.16e2 * t368 * t554 - 0.16e2 * t48 * t175 * t50 + 0.4e1 * t525 * t714 - 0.2e1 * t58 * t659 + 0.8e1 * t368 * t719;
- t730 = self->xc * t19;
- t735 = t59 * t256 * t14;
- t752 = 0.4e1 * t173 * t714 - 0.6e1 * t27 * t515 - 0.16e2 * t9 * t279 + 0.4e1 * t194 * t730 * t184 - t139 * t735 - 0.4e1 * t492 * t127 * t82 * self->xc - 0.4e1 * t98 * t508 - t123 * t41 * t207 - 0.2e1 * t147 * t298 + 0.8e1 * t368 * t314 + 0.6e1 * t132 * t133 * t207;
- t755 = t28 * t21;
- t759 = t274 * t338 * t14;
- t767 = t11 * t35;
- t768 = t767 * t14;
- t778 = t560 * t61;
- t781 = -0.2e1 * t58 * t504 - 0.8e1 * t27 * t755 + 0.16e2 * t662 * t759 + 0.12e2 * t291 * t282 * t207 - 0.6e1 * t27 * t434 + t139 * t768 - 0.8e1 * t498 * t326 + 0.4e1 * t33 * t611 * t20 + 0.2e1 * t81 * t512 - t139 * t561 + 0.2e1 * t147 * t778;
- t786 = t12 * t443;
- t790 = t282 * t59 * t20;
- t796 = t59 * t14 * t127;
- t806 = t41 * t21;
- t811 = -0.8e1 * t393 * t663 + 0.8e1 * t368 * t786 + 0.2e1 * t81 * t790 + 0.4e1 * t169 * t624 + t139 * t796 + 0.2e1 * t206 * t258 - 0.2e1 * t40 * t591 - 0.8e1 * t662 * t630 - 0.4e1 * t33 * t30 - 0.4e1 * t40 * t806 + 0.8e1 * t9 * t786;
- t819 = t282 * t15 * t127;
- t822 = t101 * t363;
- t830 = t11 * t256 * t14;
- t835 = t227 * t532;
- t842 = 0.2e1 * t33 * t11 * t18 * t15 + t123 * t41 * t66 - 0.4e1 * t493 * t819 - 0.2e1 * t27 * t822 - 0.16e2 * t368 * t170 - 0.4e1 * t169 * t463 - t139 * t830 - 0.4e1 * t649 * t179 * t127 + 0.12e2 * t27 * t835 - 0.16e2 * t368 * t434 - 0.2e1 * t40 * t790;
- t845 = t87 * t202;
- t854 = t338 * t15;
- t859 = t12 * t207;
- t868 = t139 * t348 - 0.2e1 * t27 * t845 + 0.8e1 * t169 * t755 - 0.2e1 * t58 * t380 + 0.6e1 * t206 * t331 + 0.8e1 * t310 * t854 - 0.2e1 * t169 * t822 + 0.2e1 * t98 * t859 + 0.8e1 * t159 * t671 + 0.8e1 * t74 * t634 - 0.2e1 * t169 * t253;
- t880 = t60 * t443;
- t891 = t101 * t128;
- t894 = -t123 * t539 - 0.2e1 * t147 * t796 + 0.32e2 * t368 * t230 + t139 * t674 - 0.16e2 * t98 * t60 * t124 + 0.32e2 * t9 * t244 + 0.8e1 * t368 * t880 - 0.8e1 * t40 * t41 * self->xc * t36 - t123 * t82 * t128 - 0.6e1 * t58 * t233 + 0.2e1 * t58 * t891;
- t903 = t179 * t19;
- t920 = t56 * t1 * t160;
- t925 = -0.2e1 * t174 * t175 * t66 - 0.4e1 * t493 * t714 + 0.4e1 * t649 * t903 - 0.4e1 * t81 * t43 + t123 * t82 * t207 + 0.4e1 * t206 * t891 - 0.16e2 * t273 * t759 - 0.8e1 * t27 * t203 + 0.32e2 * t221 * self->ZB * t51 - 0.16e2 * t920 * t759 - 0.8e1 * t9 * t453;
- t932 = t87 * t29;
- t945 = t82 * t21;
- t953 = -0.16e2 * t920 * t276 - 0.8e1 * t169 * t30 - 0.8e1 * t633 * t77 - 0.2e1 * t27 * t932 - 0.4e1 * t174 * t49 * t162 + 0.8e1 * t206 * t87 * t124 - 0.2e1 * t147 * t768 + 0.4e1 * t169 * t522 - 0.12e2 * t81 * t945 + 0.4e1 * t33 * t28 * t115 + 0.4e1 * t525 * t819;
- t971 = t282 * t127;
- t978 = -0.6e1 * t98 * t102 + 0.2e1 * t169 * t515 - 0.2e1 * t310 * t377 + 0.2e1 * t147 * t830 + 0.8e1 * t368 * t22 - 0.2e1 * t169 * t617 + 0.16e2 * t662 * t276 - 0.8e1 * t355 * t854 + 0.4e1 * t493 * t971 - 0.16e2 * t9 * t533 - 0.2e1 * t169 * t279;
- t997 = self->xc * t127;
- t998 = t997 * t59;
- t1003 = 0.4e1 * t40 * t579 + 0.2e1 * t169 * t845 + 0.16e2 * t9 * t515 + 0.8e1 * t206 * t551 + t123 * t41 * t128 + 0.16e2 * t98 * t60 * t162 + 0.2e1 * t169 * t364 - 0.2e1 * t169 * t932 + t139 * t778 + 0.4e1 * t648 * t998 + 0.2e1 * t147 * t412;
- t1006 = t2 * t59;
- t1017 = self->xc * t35;
- t1033 = 0.4e1 * t1006 * t335 + 0.4e1 * t81 * t806 - 0.2e1 * t33 * t34 * t115 + 0.8e1 * t498 * t374 - 0.16e2 * t261 * t7 * t1017 * t15 + 0.8e1 * t206 * t101 * t124 - t123 * t448 + 0.2e1 * t147 * t735 + 0.6e1 * t98 * t208 + 0.6e1 * t98 * t88 - 0.4e1 * t33 * t755;
- t1055 = -0.4e1 * t173 * t971 + 0.2e1 * t98 * t891 + 0.8e1 * t9 * t880 + 0.4e1 * t169 * t835 - t304 * t184 + t344 * t184 - t123 * t41 * t62 - 0.2e1 * t98 * t598 + 0.2e1 * t58 * t859 + 0.32e2 * t47 * t351 * t224 + 0.2e1 * t98 * t389;
- t1070 = t15 * t19;
- t1089 = -0.16e2 * t368 * t352 - 0.8e1 * t9 * t719 + 0.4e1 * t96 * t2 * self->xc * t134 - 0.2e1 * t91 * t236 * t115 + 0.4e1 * t27 * t573 + 0.4e1 * t493 * t282 * t1070 + 0.2e1 * t33 * t59 * t18 * t15 + 0.12e2 * t40 * t945 - 0.4e1 * t492 * self->xc * t82 * t1070 - 0.2e1 * t91 * t528 * t20 + 0.8e1 * t324 * t608;
- t1113 = t123 * t82 * t124 + 0.8e1 * t421 * t428 - t139 * t417 + 0.4e1 * t40 * t645 + 0.16e2 * t393 * t759 - 0.2e1 * t33 * t179 * t115 - 0.4e1 * t525 * t335 + 0.4e1 * t33 * t28 * t36 - 0.4e1 * t1006 * t714 + 0.6e1 * t206 * t166 - 0.8e1 * t421 * t450;
- t1119 = t321 * t46;
- t1122 = t157 * t11;
- t1123 = t1122 * t2;
- t1124 = t184 * t46;
- t1128 = t108 * n;
- t1132 = t7 * t7;
- t1133 = t1132 * t11;
- t1134 = t1133 * t108;
- t1135 = t15 * t46;
- t1139 = t7 * self->ZA;
- t1140 = t1139 * self->ZB;
- t1141 = t1 * t35;
- t1145 = t629 * t2;
- t1146 = t1135 * t730;
- t1149 = t157 * t1128;
- t1150 = t1149 * self->xc;
- t1153 = t46 * self->xc;
- t1154 = t1153 * t127;
- t1158 = t184 * t1 * t46;
- t1161 = t46 * t46;
- t1162 = t35 * t1161;
- t1166 = t7 * t1;
- t1170 = -0.4e1 * t133 * t1119 + 0.16e2 * t1123 * t1124 * t730 - 0.8e1 * t1122 * t1128 * t196 - 0.64e2 * t1134 * t1135 * t1017 - 0.32e2 * t1140 * t1141 * t1135 + 0.16e2 * t1145 * t1146 - 0.8e1 * t1150 * t650 - 0.16e2 * t1123 * t1154 - 0.4e1 * t133 * t1158 - 0.16e2 * t1140 * t1162 * t15 + 0.8e1 * t1166 * t35 * t312;
- t1171 = t1161 * t184;
- t1175 = t1122 * n;
- t1176 = t15 * t1161;
- t1180 = t1132 * self->ZA;
- t1181 = t1180 * t355;
- t1182 = t1176 * t1017;
- t1185 = t1161 * self->xc;
- t1189 = t1133 * t1;
- t1192 = t108 * t1;
- t1193 = t1132 * t1192;
- t1195 = t10 * t35;
- t1199 = t157 * t15;
- t1203 = t1141 * t46;
- t1211 = t184 * t108;
- t1218 = 0.2e1 * t133 * t1171 * t35 + 0.8e1 * t1175 * t1176 * t997 + 0.64e2 * t1181 * t1182 - 0.8e1 * t1175 * t1185 * t127 - 0.32e2 * t1189 * t1182 - 0.64e2 * t1193 * self->ZA * t1195 * t228 + 0.8e1 * t1199 * t416 * t1128 + 0.8e1 * t1140 * t1203 - 0.4e1 * t75 * t1158 - 0.8e1 * t1199 * t560 * t1128 - 0.2e1 * t133 * t1211 - 0.8e1 * t1199 * t127 * t11 * t1128;
- t1221 = t256 * t1161;
- t1224 = t35 * t108;
- t1233 = t7 * t256;
- t1236 = -t75 * t1211 - t75 * t1221 - t133 * t1221 + t75 * t1224 - t75 * t1171 - t133 * t1171 + t133 * t1224 + t75 * t1162 - t75 * t108 * t256 + t133 * t1162 - t1233 * t59 * t108;
- t1240 = t1135 * t1195;
- t1252 = t629 * t127;
- t1263 = t1171 * self->ZA;
- t1280 = -0.128e3 * t1180 * self->ZB * t108 * t1240 + 0.32e2 * t1193 * t10 * t112 + 0.4e1 * t133 * t1203 + 0.4e1 * t109 * t256 * self->ZA * self->ZB - 0.8e1 * t1252 * n * t15 * t1185 + 0.8e1 * t1175 * t1171 * t730 - 0.8e1 * t1175 * t1176 * t127 + 0.4e1 * t223 * t1263 - 0.8e1 * t1175 * t1176 * t730 + 0.8e1 * t1166 * self->ZA * t341 * self->ZB + 0.64e2 * t1134 * t1240 + 0.8e1 * t1122 * self->xc * t1128 * t127 * t15;
- t1283 = t1199 * t19;
- t1287 = t1199 * t127;
- t1289 = t59 * n * t1161;
- t1293 = t157 * n * self->xc;
- t1304 = t1132 * t108;
- t1310 = t263 * self->ZB;
- t1316 = t2 * t15;
- t1323 = -0.16e2 * t1283 * t1006 * t46 + 0.8e1 * t1287 * t1289 + 0.8e1 * t1293 * t127 * t1161 * t59 + 0.16e2 * t1123 * t1135 * t19 + 0.8e1 * t1293 * t560 * t1176 + 0.64e2 * t1304 * t59 * t1240 + 0.4e1 * t75 * t1203 + 0.4e1 * t1310 * t1263 + 0.4e1 * t223 * t338 * t108 - 0.16e2 * t1252 * t1316 * t1153 - 0.16e2 * t1310 * t221 * t15;
- t1330 = t1132 * t15;
- t1336 = t1132 * t1;
- t1338 = t1162 * t179;
- t1370 = 0.8e1 * t1175 * t1176 * t19 + 0.4e1 * t1139 * t318 * t1161 + 0.128e3 * t1330 * t318 * t108 * t46 * t227 - 0.32e2 * t1336 * self->xc * t1338 + 0.4e1 * t1233 * self->ZA * t1161 * self->ZB - 0.8e1 * t1287 * t59 * t1128 * self->xc + 0.2e1 * t75 * t305 * t108 + 0.8e1 * t1199 * t127 * t59 * t1128 - 0.8e1 * t1283 * t1289 - 0.8e1 * t1293 * t560 * t1171 + 0.4e1 * t133 * t35 * t1158 + 0.8e1 * t157 * t184 * t19 * t11 * t1128 * self->xc;
- t1376 = t7 * t184;
- t1380 = t1176 * t1195;
- t1393 = t1330 * t35;
- t1411 = 0.16e2 * t1145 * t1154 + 0.8e1 * t1149 * t998 + 0.4e1 * t1376 * t35 * t48 + 0.32e2 * t1189 * t1380 + 0.32e2 * t1193 * t11 * t1195 * t15 - 0.64e2 * t1304 * self->xc * t111 * t1135 - 0.16e2 * t1123 * t1146 + 0.64e2 * t1393 * t28 * t1192 * self->xc - 0.16e2 * t1123 * t1135 * t127 - 0.8e1 * t1122 * self->xc * t1128 * t127 - 0.32e2 * t1193 * self->xc * t112 + 0.16e2 * t1252 * t1316 * t46;
- t1450 = 0.2e1 * t1376 * t767 * t1161 + 0.2e1 * t1376 * t111 * t108 + 0.4e1 * t223 * t311 * t108 + 0.4e1 * t109 * t35 * t520 * self->ZA + 0.16e2 * t1123 * t1135 * t997 - 0.64e2 * t1181 * t1380 + 0.8e1 * t1150 * t903 - 0.32e2 * t1393 * t11 * t1192 * self->xc - 0.16e2 * t157 * t2 * self->xc * t560 * t1124 + 0.8e1 * t223 * t184 * t317 * t46 + 0.32e2 * t1336 * t10 * t1338 - 0.4e1 * t75 * t1119;
- self->C3B = (t606 + t722 + t1089 + t781 + 0.16e2 * t48 * t51 + t978 + t868 + t507 - t304 * t256 + 0.8e1 * t9 * t22 + t752 + 0.4e1 * t174 * t144 - 0.2e1 * t81 * t469 + 0.6e1 * t139 * t166 + t362 + 0.2e1 * t98 * t211 + t925 + t137 - t290 * t184 + 0.12e2 * t81 * t83 + t842 + 0.8e1 * t74 * t77 + 0.16e2 * t98 * t12 * t162 - 0.4e1 * t33 * t28 * t443 - 0.8e1 * t27 * t70 - 0.2e1 * t33 * t34 * t36 - 0.8e1 * t27 * t30 + 0.2e1 * t58 * t67 - 0.4e1 * t40 * t43 + 0.2e1 * t58 * t63 + t1033 - t290 * t256 + t290 * t35 + t193 + t1113 + t578 + t442 + t474 + t544 + t329 + t679 + t401 + t953 + t811 + t644 + t894 + t289 + t240 + t1055 + t1003) / (t1170 + t1218 + 0.2e1 * t1236 + t1280 + t1323 + t1370 + t1411 + t1450);
- /****************************************************************************************/
- t1 = n * n;
- t2 = t1 * self->xc;
- t3 = self->ZB * self->ZB;
- t5 = t2 * 0.3141592654e1 * t3;
- t6 = nx * 0.3141592654e1;
- t7 = t6 * self->xc;
- t8 = cos(t7);
- t9 = nx * nx;
- t10 = t8 * t9;
- t11 = n * 0.3141592654e1;
- t12 = exp(t11);
- t13 = t12 * t12;
- t16 = exp( self->xc * n * 0.3141592654e1);
- t17 = t16 * t16;
- t18 = t17 * t16;
- t19 = t17 * t17;
- t20 = t19 * t18;
- t21 = t13 * t20;
- t22 = t10 * t21;
- t25 = self->ZA * self->ZA;
- t26 = t1 * t25;
- t27 = self->xc * 0.3141592654e1;
- t28 = t26 * t27;
- t29 = t19 * t16;
- t30 = t13 * t13;
- t31 = t29 * t30;
- t35 = t9 * nx;
- t36 = t3 * t35;
- t37 = sin(t6);
- t38 = t13 * t12;
- t39 = t37 * t38;
- t40 = t39 * t19;
- t42 = t1 * t1;
- t43 = nx * t42;
- t44 = self->xc * self->xc;
- t45 = t25 * t44;
- t46 = t43 * t45;
- t47 = 0.3141592654e1 * 0.3141592654e1;
- t48 = t47 * t37;
- t49 = t17 * t38;
- t54 = 0.3141592654e1 * t35;
- t55 = self->ZA * n * t54;
- t56 = t37 * self->ZB;
- t57 = t19 * t12;
- t61 = t25 * t8;
- t62 = t61 * t9;
- t63 = n * t30;
- t64 = t63 * t16;
- t67 = t1 * n;
- t69 = t47 * self->ZB;
- t70 = t67 * t44 * t69;
- t75 = nx * t3;
- t76 = t75 * t37;
- t77 = t67 * 0.3141592654e1;
- t78 = t19 * t19;
- t79 = t78 * t12;
- t80 = t77 * t79;
- t82 = t3 * t38;
- t84 = t54 * t37;
- t87 = sin(t7);
- t88 = t29 * t87;
- t89 = t47 * t44;
- t93 = nx * t25;
- t94 = t87 * t42;
- t95 = t93 * t94;
- t96 = t47 * self->xc;
- t97 = t13 * t29;
- t98 = t96 * t97;
- t101 = t87 * t67;
- t102 = t93 * t101;
- t103 = t13 * t18;
- t107 = t47 * t35;
- t108 = t26 * t107;
- t109 = t37 * t44;
- t110 = t19 * t17;
- t111 = t12 * t110;
- t116 = t37 * t19 * t12;
- t118 = t37 * self->xc;
- t119 = self->ZB * t19;
- t120 = t119 * t12;
- t121 = t118 * t120;
- t125 = self->xc * t3;
- t126 = t1 * t47 * t125;
- t127 = t35 * t37;
- t128 = t38 * t19;
- t129 = t127 * t128;
- t132 = t26 * 0.3141592654e1;
- t133 = t16 * t13;
- t134 = t10 * t133;
- t137 = 0.3141592654e1 * self->ZB;
- t138 = t2 * t137;
- t139 = self->ZA * t8;
- t140 = t9 * t13;
- t145 = t30 * t18;
- t146 = t10 * t145;
- t149 = t3 * t8;
- t150 = t149 * t9;
- t153 = 0.2e1 * t5 * t22 + 0.2e1 * t28 * t10 * t31 + t36 * t40 - 0.2e1 * t46 * t48 * t49 - 0.2e1 * t55 * t56 * t57 - 0.2e1 * t62 * t64 + 0.16e2 * t70 * t29 * self->ZA * t10 - t76 * t80 + t82 * n * t84 + 0.8e1 * t43 * t3 * t88 * t89 + 0.16e2 * t95 * t98 + 0.2e1 * t102 * t27 * t103 - 0.2e1 * t108 * t109 * t111 + t36 * t116 + 0.8e1 * t55 * t121 - 0.4e1 * t126 * t129 - 0.4e1 * t132 * t134 - 0.4e1 * t138 * t139 * t140 * t20 + 0.8e1 * t28 * t146 - 0.2e1 * t150 * t64;
- t154 = t42 * n;
- t155 = nx * t154;
- t156 = t44 * self->xc;
- t157 = t47 * 0.3141592654e1;
- t158 = t156 * t157;
- t159 = t155 * t158;
- t162 = t56 * self->ZA * t19 * t12;
- t165 = t77 * t49;
- t167 = t1 * t3;
- t168 = t167 * t89;
- t169 = t127 * t49;
- t172 = t37 * t67;
- t173 = t75 * t172;
- t174 = t38 * t110;
- t175 = t27 * t174;
- t179 = t47 * t25;
- t181 = t10 * t97;
- t184 = t27 * t31;
- t187 = t67 * t47;
- t188 = t44 * t3;
- t189 = t187 * t188;
- t192 = t25 * t35;
- t193 = t37 * t17;
- t194 = t193 * t12;
- t196 = nx * self->ZA;
- t197 = t196 * t172;
- t198 = self->ZB * t38;
- t199 = t198 * t19;
- t204 = t1 * t12 * t110;
- t207 = nx * self->ZB;
- t209 = t1 * self->ZA;
- t215 = t67 * t3;
- t216 = t47 * t8;
- t217 = t215 * t216;
- t218 = t9 * self->xc;
- t222 = nx * t67;
- t223 = t222 * t27;
- t224 = t3 * t87;
- t228 = t167 * t107;
- t232 = t26 * t96;
- t235 = t207 * t94;
- t236 = t47 * self->ZA;
- t243 = self->xc * t13;
- t244 = t243 * t29;
- t248 = t25 * n;
- t249 = t248 * 0.3141592654e1;
- t253 = self->ZB * self->ZA;
- t254 = t253 * t8;
- t255 = t9 * n;
- t256 = t30 * t16;
- t260 = 0.2e1 * t207 * t37 * t209 * t128 + 0.2e1 * t5 * t134 - 0.16e2 * t217 * t218 * t97 - 0.2e1 * t223 * t224 * t31 - 0.2e1 * t228 * t109 * t174 - 0.2e1 * t232 * t169 - 0.16e2 * t235 * t236 * t44 * t30 * t18 - 0.4e1 * t196 * t101 * t137 * t244 + t249 * t169 + 0.8e1 * t168 * t129 + 0.4e1 * t254 * t255 * t256;
- t263 = t43 * t179;
- t267 = t3 * n;
- t268 = t267 * t54;
- t269 = t118 * t57;
- t272 = t39 * t1;
- t274 = t67 * t25;
- t275 = t274 * t158;
- t278 = t75 * t87;
- t279 = t77 * t103;
- t282 = t25 * t38;
- t285 = self->ZA * t38;
- t290 = t267 * 0.3141592654e1;
- t296 = t77 * t111;
- t298 = t196 * t37;
- t299 = t1 * self->ZB;
- t303 = t37 * t42;
- t304 = t196 * t303;
- t308 = t77 * t57;
- t310 = t26 * t89;
- t313 = t77 * t128;
- t316 = t101 * t27;
- t319 = t93 * t87;
- t320 = t77 * t97;
- t323 = t127 * t57;
- t326 = t10 * n;
- t329 = t118 * t174;
- t332 = -0.8e1 * t263 * t109 * t57 - 0.4e1 * t268 * t269 + t93 * t272 + 0.8e1 * t275 * t129 - 0.4e1 * t278 * t279 + t282 * n * t84 - 0.2e1 * t285 * n * t54 * t56 - t290 * t169 - 0.2e1 * t196 * t38 * t172 * t137 + t76 * t296 - 0.2e1 * t298 * t299 * t79 + 0.8e1 * t304 * t96 * t120 + t76 * t308 - 0.2e1 * t310 * t169 - t76 * t313 + 0.2e1 * t75 * t18 * t316 + 0.4e1 * t319 * t320 + t249 * t323 - 0.2e1 * t25 * t18 * t326 + 0.2e1 * t228 * t329;
- t335 = t75 * t101;
- t336 = t27 * t21;
- t342 = t77 * t133;
- t347 = t209 * t137;
- t350 = t9 * t1;
- t351 = t149 * t350;
- t355 = t37 * t78 * t12;
- t359 = t93 * t303;
- t367 = t172 * 0.3141592654e1;
- t369 = t96 * t103;
- t376 = t209 * t107;
- t379 = t10 * t103;
- t383 = t207 * t101;
- t389 = 0.3141592654e1 * self->ZA;
- t390 = t222 * t389;
- t391 = t87 * self->ZB;
- t398 = -0.2e1 * t102 * t336 + t93 * t38 * t367 + 0.16e2 * t95 * t369 - t82 * t127 - 0.8e1 * t197 * t27 * t120 + 0.8e1 * t376 * t121 - 0.8e1 * t189 * t379 - t249 * t129 - 0.4e1 * t383 * t27 * self->ZA * t16 * t13 - 0.8e1 * t390 * t391 * t21 - 0.2e1 * t197 * t137 * t57;
- t402 = t39 * t110;
- t404 = t193 * t38;
- t406 = t127 * t174;
- t408 = t167 * 0.3141592654e1;
- t411 = t44 * t157;
- t412 = t155 * t411;
- t413 = t285 * t19;
- t414 = t56 * t413;
- t417 = self->ZA * t30;
- t424 = t93 * t37;
- t426 = t248 * t54;
- t427 = t17 * t12;
- t428 = t118 * t427;
- t431 = t77 * t21;
- t438 = self->ZA * t13;
- t443 = t93 * t172;
- t444 = t27 * t427;
- t448 = t1 * t78 * t12;
- t455 = t274 * t89;
- t461 = t118 * t111;
- t464 = -t36 * t402 + t36 * t404 - t249 * t406 - 0.4e1 * t408 * t134 + 0.16e2 * t412 * t414 - 0.4e1 * t383 * t27 * t417 * t18 + 0.2e1 * t28 * t22 - t424 * t80 - 0.2e1 * t426 * t428 + 0.4e1 * t278 * t431 + 0.4e1 * t254 * t255 * t103 + t290 * t323 + 0.4e1 * t383 * t27 * t438 * t20 + 0.2e1 * t443 * t444 + t424 * t448 - t36 * t194 - 0.32e2 * t235 * t236 * t243 * t18 + 0.8e1 * t455 * t181 - 0.4e1 * t359 * t96 * t128 - 0.2e1 * t426 * t461;
- t469 = n * t16 * t13;
- t474 = t1 * t38;
- t475 = t474 * t19;
- t480 = t89 * t103;
- t483 = t67 * self->ZA;
- t484 = t483 * t411;
- t485 = t127 * t120;
- t488 = t127 * t111;
- t497 = t77 * t427;
- t502 = t27 * t97;
- t508 = t1 * t19 * t12;
- t511 = t155 * t25 * t156;
- t512 = t157 * t37;
- t513 = t512 * t128;
- t527 = t1 * t17;
- t528 = t527 * t38;
- t530 = -t76 * t497 - 0.4e1 * t254 * t255 * t97 - 0.2e1 * t102 * t502 - 0.4e1 * t108 * t269 - t76 * t508 + 0.8e1 * t511 * t513 + 0.4e1 * t150 * t63 * t18 + 0.4e1 * t383 * t27 * t438 * t18 + 0.4e1 * t132 * t379 + 0.2e1 * t168 * t488 - t76 * t528;
- t535 = t44 * t13;
- t542 = t527 * t12;
- t544 = n * t13;
- t545 = t544 * t20;
- t548 = t75 * t303;
- t549 = t96 * t111;
- t552 = self->ZA * t35;
- t553 = t552 * t37;
- t562 = t43 * t96;
- t563 = t3 * t37;
- t564 = t563 * t128;
- t579 = t474 * t110;
- t590 = t9 * t30;
- t591 = t590 * t18;
- t595 = t127 * t427;
- t598 = t77 * t174;
- t600 = 0.4e1 * t5 * t146 + 0.16e2 * t235 * t236 * t535 * t18 + 0.8e1 * t455 * t146 + t76 * t542 - 0.2e1 * t150 * t545 + 0.2e1 * t548 * t549 - 0.2e1 * t553 * t120 + t290 * t488 - 0.8e1 * t274 * t47 * t44 * t29 * t10 - 0.4e1 * t562 * t564 - 0.2e1 * t132 * self->xc * t20 * t10 - 0.32e2 * t562 * self->ZA * t87 * self->ZB * t13 * t29 - 0.8e1 * t347 * t379 + t76 * t579 - 0.4e1 * t359 * t96 * t57 + 0.4e1 * t408 * t181 - 0.4e1 * t223 * t564 - 0.12e2 * t209 * t27 * self->ZB * t8 * t591 + 0.2e1 * t310 * t595 + t76 * t598;
- t601 = t27 * t49;
- t604 = t127 * t79;
- t606 = self->ZB * t29;
- t616 = t139 * t140 * t18;
- t638 = t10 * t256;
- t643 = t118 * t199;
- t653 = t544 * t29;
- t658 = t3 * t29;
- t660 = t350 * t27;
- t663 = -0.4e1 * t254 * t255 * t145 + 0.2e1 * t267 * t20 * t8 * t9 - 0.4e1 * t138 * t139 * t9 * t16 * t13 - 0.2e1 * t5 * t638 + 0.2e1 * t126 * t169 + 0.8e1 * t376 * t643 + 0.4e1 * t335 * t27 * t145 + 0.16e2 * t235 * t236 * t535 * t29 + 0.6e1 * t150 * t653 - 0.4e1 * t426 * t269 + 0.4e1 * t658 * t8 * t660;
- t670 = t274 * t411;
- t673 = t118 * t49;
- t694 = t155 * t45;
- t713 = n * t29 * t30;
- t717 = t20 * t87;
- t723 = t512 * t57;
- t728 = -0.2e1 * t443 * t175 - 0.8e1 * t670 * t129 + 0.2e1 * t426 * t673 - 0.16e2 * t207 * t88 * t42 * t47 * self->ZA * t44 + 0.4e1 * t254 * t255 * t21 + t249 * t595 + 0.8e1 * t25 * t29 * t8 * t660 + 0.2e1 * t268 * t461 + 0.8e1 * t189 * t181 - 0.8e1 * t694 * t513 + 0.2e1 * t198 * t553 - 0.12e2 * t606 * t139 * t660 - 0.2e1 * t359 * t549 + 0.4e1 * t138 * t139 * t590 * t16 + 0.8e1 * t93 * t29 * t94 * t89 - 0.2e1 * t150 * t713 + 0.2e1 * t222 * t3 * t717 * t27 + 0.8e1 * t670 * t323 + 0.8e1 * t694 * t723 - 0.2e1 * t62 * t653;
- t734 = t43 * t89;
- t735 = t563 * t427;
- t740 = t75 * t94;
- t744 = self->ZB * self->xc;
- t750 = t563 * t57;
- t754 = t218 * t103;
- t771 = t127 * t199;
- t776 = t89 * t174;
- t791 = -0.4e1 * t207 * t717 * t77 * self->xc * self->ZA + 0.4e1 * t443 * t27 * t57 + t192 * t40 - 0.8e1 * t55 * t643 - 0.16e2 * t209 * t89 * t771 - 0.8e1 * t275 * t323 + 0.2e1 * t359 * t776 + 0.16e2 * t304 * t89 * t199 + 0.4e1 * t278 * t320 + 0.2e1 * t207 * t172 * t389 * t79 - 0.8e1 * t390 * t391 * t97;
- t794 = t483 * t158;
- t801 = t2 * 0.3141592654e1;
- t818 = t215 * t411;
- t827 = t96 * t174;
- t837 = t37 * t12 * t110;
- t845 = 0.16e2 * t794 * t485 + 0.8e1 * t159 * t564 - 0.8e1 * t455 * t379 - 0.2e1 * t801 * t3 * t20 * t10 - 0.4e1 * t132 * t22 - 0.8e1 * t734 * t564 - 0.8e1 * t187 * t44 * t658 * t10 - 0.8e1 * t412 * t564 + 0.4e1 * t132 * t181 - 0.8e1 * t818 * t129 + 0.2e1 * t46 * t48 * t427 - 0.4e1 * t75 * t29 * t316 - 0.2e1 * t359 * t827 - t290 * t595 + 0.16e2 * t217 * t754 - t424 * t542 - 0.8e1 * t734 * t750 - t192 * t837 - 0.4e1 * t254 * t255 * t133 + 0.8e1 * t304 * t96 * t199;
- t864 = t544 * t18;
- t867 = t3 * t18;
- t884 = t27 * t256;
- t891 = t187 * t744;
- t894 = t563 * t49;
- t900 = -0.2e1 * t263 * t428 + 0.2e1 * t228 * t428 - 0.6e1 * t223 * t224 * t103 - t192 * t404 + 0.2e1 * t268 * t428 - 0.2e1 * t335 * t884 - t424 * t296 + 0.2e1 * t93 * t20 * t316 - 0.32e2 * t891 * t616 + 0.2e1 * t562 * t894 - 0.2e1 * t801 * t867 * t10;
- t904 = t27 * t111;
- t907 = t118 * t128;
- t915 = t89 * t145;
- t947 = t139 * t140 * t29;
- t952 = -0.2e1 * t173 * t904 + 0.4e1 * t426 * t907 + 0.12e2 * t253 * t10 * t1 * 0.3141592654e1 * t244 + 0.8e1 * t95 * t915 - t36 * t355 - 0.16e2 * t794 * t771 - 0.8e1 * t511 * t723 + 0.16e2 * t734 * t162 + t36 * t837 + 0.2e1 * t298 * t299 * t57 - 0.2e1 * t28 * t638 - 0.2e1 * t62 * t545 + 0.2e1 * t310 * t406 + 0.12e2 * t138 * t616 + 0.4e1 * t223 * t750 + t424 * t497 + 0.2e1 * t734 * t894 + 0.2e1 * t132 * self->xc * t18 * t10 - 0.16e2 * t70 * t947 + 0.32e2 * t891 * t947;
- t969 = t67 * t157 * t156 * t3;
- t974 = t27 * t133;
- t1001 = -0.8e1 * t159 * t750 - 0.16e2 * t412 * t162 - t290 * t129 + 0.8e1 * t310 * t323 - 0.4e1 * t319 * t342 + t75 * t272 + t192 * t402 - 0.8e1 * t359 * t89 * t128 - 0.10e2 * t61 * t350 * t502 + 0.8e1 * t818 * t323 - 0.4e1 * t108 * t907;
- t1042 = t89 * t97;
- t1055 = -0.2e1 * t168 * t595 + 0.16e2 * t484 * t771 + 0.4e1 * t11 * t125 * t129 - 0.2e1 * t173 * t444 + 0.2e1 * self->ZB * n * t54 * t37 * self->ZA * t79 - t424 * t475 + 0.2e1 * t562 * t735 - 0.2e1 * t548 * t776 + t424 * t204 + 0.2e1 * t25 * t20 * t326 + 0.8e1 * t383 * t389 * t133 + t75 * t38 * t367 + 0.2e1 * t62 * t469 + 0.2e1 * t197 * t137 * t128 - 0.2e1 * t102 * t884 - 0.2e1 * t5 * t379 - 0.8e1 * t740 * t1042 - 0.16e2 * t159 * t414 - 0.2e1 * self->ZB * t35 * t37 * t413 + 0.2e1 * t553 * self->ZB * t78 * t12;
- t1096 = 0.2e1 * t443 * t904 - 0.2e1 * t268 * t329 - 0.2e1 * t443 * t601 + 0.2e1 * t102 * t974 - 0.2e1 * t263 * t673 + t424 * t165 + 0.2e1 * t62 * t713 + t424 * t308 - t424 * t313 + 0.8e1 * t347 * t22 - t424 * t598;
- t1103 = t42 * t1 * t157;
- t1104 = t1103 * t25;
- t1108 = t3 * t19;
- t1112 = n * t47;
- t1113 = t9 * t9;
- t1118 = t42 * t157;
- t1119 = t1118 * t9;
- t1120 = t25 * self->xc;
- t1121 = t13 * t110;
- t1122 = t1120 * t1121;
- t1125 = t47 * t47;
- t1126 = t67 * t1125;
- t1127 = t1113 * self->ZA;
- t1128 = t1126 * t1127;
- t1129 = t19 * t13;
- t1130 = t744 * t1129;
- t1133 = t154 * t1125;
- t1134 = t1133 * t9;
- t1135 = t45 * t1129;
- t1138 = t154 * t47;
- t1139 = t25 * t30;
- t1142 = t1126 * t1113;
- t1145 = t125 * t1129;
- t1148 = t1103 * self->xc;
- t1149 = t3 * t13;
- t1150 = t1149 * t17;
- t1153 = t25 * t78;
- t1156 = -0.8e1 * t1104 * t243 * t17 + 0.4e1 * t187 * t1108 * t9 - 0.2e1 * t1112 * t3 * t1113 * t30 + 0.16e2 * t1119 * t1122 + 0.64e2 * t1128 * t1130 + 0.64e2 * t1134 * t1135 - 0.2e1 * t1138 * t1139 + 0.32e2 * t1142 * t1135 - 0.32e2 * t1142 * t1145 + 0.8e1 * t1148 * t1150 - 0.2e1 * t1138 * t1153;
- t1157 = t25 * t13;
- t1158 = t1157 * t17;
- t1161 = t13 * t17;
- t1162 = t1120 * t1161;
- t1165 = t3 * t78;
- t1170 = t42 * t67 * t1125;
- t1172 = t1108 * t13;
- t1175 = t1 * t157;
- t1176 = t1175 * t1113;
- t1182 = t1120 * t1129;
- t1189 = t110 * t9 * self->xc;
- t1192 = t1149 * t110;
- t1201 = 0.8e1 * t1103 * t1158 - 0.16e2 * t1119 * t1162 - 0.2e1 * t1112 * t1165 * t1113 + 0.32e2 * t1170 * t44 * t1172 - 0.8e1 * t1176 * t1162 + 0.8e1 * t1104 * t243 * t110 - 0.64e2 * t1134 * t1182 - 0.64e2 * t1134 * t1145 + 0.16e2 * t1118 * t3 * t1189 + 0.16e2 * t1119 * t1192 - 0.4e1 * t187 * t1165 * t9 - 0.4e1 * t187 * t1139 * t9;
- t1209 = t17 * t30;
- t1210 = t125 * t1209;
- t1213 = t1138 * self->ZA;
- t1214 = self->ZB * t30;
- t1218 = t1157 * t110;
- t1226 = t3 * t30;
- t1237 = t1170 * t25;
- t1242 = 0.4e1 * t1112 * self->ZA * t119 * t1113 - 0.16e2 * t1119 * t1150 - 0.8e1 * t1176 * t1210 + 0.4e1 * t1213 * t1214 * t19 - 0.16e2 * t1119 * t1218 - 0.32e2 * t1142 * t1182 - 0.8e1 * t1103 * t1120 * t110 - 0.4e1 * t187 * t1226 * t9 + 0.8e1 * t1103 * t1192 + 0.4e1 * t1112 * self->ZB * t1113 * t30 * self->ZA - 0.32e2 * t1237 * self->xc * t19 * t13;
- t1251 = t125 * t1121;
- t1260 = t1120 * t1209;
- t1263 = t1139 * t19;
- t1282 = 0.8e1 * t1103 * t110 * t3 * self->xc + 0.8e1 * t1104 * self->xc * t17 * t30 - 0.8e1 * t1176 * t1251 + 0.16e2 * t1119 * t1158 + 0.4e1 * t1112 * t78 * t1127 * self->ZB + 0.16e2 * t1119 * t1260 + 0.2e1 * t1138 * t1263 - 0.32e2 * t1170 * self->xc * t1172 - 0.16e2 * t1213 * t119 * t13 + 0.4e1 * t1138 * t1214 * self->ZA + 0.32e2 * t1237 * t44 * t19 * t13 - 0.16e2 * t1118 * t25 * t1189;
- t1287 = t188 * t1129;
- t1292 = t25 * t19;
- t1296 = t187 * t9;
- t1297 = t1226 * t19;
- t1311 = t1112 * t1113;
- t1317 = -0.8e1 * t1176 * t1150 + 0.32e2 * t1142 * t1287 - 0.8e1 * t1103 * t1150 + 0.2e1 * t1112 * t1292 * t1113 + 0.4e1 * t1296 * t1297 + 0.8e1 * t1176 * t1192 + 0.4e1 * t1296 * t1263 + 0.8e1 * t1176 * t1158 - 0.8e1 * t1175 * t25 * t1113 * self->xc * t110 + 0.2e1 * t1311 * t1297 + 0.2e1 * t1112 * t1108 * t1113;
- t1320 = t253 * t1129;
- t1328 = t253 * t30 * t19;
- t1333 = t125 * t1161;
- t1343 = self->ZB * t44 * t1129;
- t1350 = -0.8e1 * t1176 * t1218 - 0.16e2 * t1311 * t1320 + 0.8e1 * t1176 * t1260 - 0.16e2 * t1119 * t1210 + 0.4e1 * t1311 * t1328 + 0.2e1 * t1311 * t1263 + 0.8e1 * t1176 * t1333 + 0.8e1 * t187 * self->ZB * t417 * t9 - 0.2e1 * t1138 * t1165 - 0.64e2 * t1128 * t1343 + 0.64e2 * t1134 * t1287 + 0.2e1 * t1138 * t1108;
- t1369 = t1133 * t9 * self->ZA;
- t1378 = t187 * self->ZA;
- t1383 = t1170 * self->ZA;
- t1388 = 0.2e1 * t1138 * t1297 - 0.8e1 * t1148 * t1192 + 0.2e1 * t1138 * t1292 - 0.16e2 * t1119 * t1251 + 0.8e1 * t1175 * self->xc * t110 * t1113 * t3 - 0.2e1 * t1112 * t1153 * t1113 + 0.128e3 * t1369 * t1130 + 0.16e2 * t1119 * t1333 + 0.4e1 * t1138 * t78 * self->ZA * self->ZB + 0.8e1 * t1378 * t78 * t9 * self->ZB - 0.64e2 * t1383 * t1343 + 0.64e2 * t1383 * t1130;
- t1420 = 0.4e1 * t1138 * t119 * self->ZA - 0.128e3 * t1369 * t1343 - 0.4e1 * t187 * t1153 * t9 - 0.2e1 * t1138 * t1226 + 0.8e1 * t1296 * t1328 - 0.2e1 * t1112 * t1139 * t1113 - 0.8e1 * t1148 * t3 * t17 * t30 - 0.32e2 * t1296 * t1320 + 0.8e1 * t1176 * t1122 + 0.4e1 * t187 * t1292 * t9 + 0.8e1 * t1378 * t119 * t9 - 0.8e1 * t1103 * t1218;
-
- self->C4B = (-t424 * t508 + 0.8e1 * t412 * t750 - 0.2e1 * t232 * t595 - 0.4e1 * t126 * t323 + t1096 - t76 * t204 + t728 + 0.2e1 * t548 * t827 + 0.2e1 * t150 * t469 + t398 + 0.8e1 * t189 * t146 + t260 - 0.2e1 * t351 * t184 - 0.2e1 * t268 * t673 - 0.4e1 * t319 * t279 + t464 - 0.2e1 * t108 * t461 + 0.16e2 * t740 * t369 + 0.16e2 * t274 * t216 * t754 - 0.16e2 * t70 * t139 * t591 + 0.2e1 * t55 * t56 * t128 - 0.2e1 * t359 * t89 * t111 + 0.2e1 * t734 * t563 * t111 + 0.6e1 * t223 * t224 * t97 + 0.8e1 * t383 * t389 * t103 + 0.4e1 * t606 * self->ZA * t326 - 0.2e1 * t93 * t18 * t316 - 0.4e1 * t443 * t27 * t128 + 0.8e1 * t197 * t27 * t199 + 0.8e1 * t108 * t109 * t128 - t249 * t604 + 0.16e2 * t70 * t616 - 0.8e1 * t969 * t323 + t845 - t424 * t579 + 0.16e2 * t159 * t162 + t290 * t406 - 0.6e1 * t150 * t864 + t192 * t116 + 0.2e1 * t867 * t326 - 0.4e1 * t658 * t326 - 0.2e1 * t351 * t502 - t76 * t165 + t900 + 0.8e1 * t168 * t323 + t791 + 0.8e1 * t740 * t915 - 0.4e1 * t562 * t750 - 0.4e1 * t278 * t342 + 0.4e1 * t319 * t431 + 0.2e1 * t173 * t175 + t424 * t528 + 0.8e1 * t969 * t129 - 0.8e1 * t347 * t181 + t332 + t530 - 0.2e1 * t108 * t329 - 0.2e1 * t207 * t38 * t37 * t1 * self->ZA + t1001 + 0.4e1 * t408 * t379 + t76 * t448 + 0.2e1 * t102 * t184 + 0.2e1 * t426 * t329 + 0.16e2 * t740 * t98 - t282 * t127 - 0.16e2 * t1 * t44 * t69 * t552 * t116 + 0.2e1 * t168 * t169 + 0.2e1 * t28 * t134 - t290 * t604 - 0.16e2 * t484 * t485 - 0.8e1 * t740 * t480 + 0.2e1 * t173 * t601 - 0.2e1 * t335 * t336 + t600 + 0.2e1 * t62 * t864 + t952 + 0.8e1 * t347 * t134 - t192 * t355 + t192 * t194 + 0.2e1 * t228 * t461 + t663 + 0.4e1 * t383 * t27 * t417 * t16 + 0.4e1 * t138 * t20 * self->ZA * t10 - 0.4e1 * t20 * self->ZB * self->ZA * t326 + 0.4e1 * t196 * t88 * t77 * t744 - 0.16e2 * t67 * self->xc * t179 * t181 - 0.8e1 * t95 * t480 - t249 * t488 - t76 * t475 + t1055 - 0.4e1 * t408 * t22 - 0.10e2 * t28 * t379 + 0.2e1 * t335 * t974 + t153 - 0.8e1 * t95 * t1042 - 0.2e1 * t734 * t735) / (t1156 + t1201 + t1242 + t1282 + t1317 + t1350 + t1388 + t1420);
- /****************************************************************************************/
- /****************************************************************************************/
-}
-
-
-
-void ColumnViscosityAnalytic_VelocityFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* velocity ) {
- ColumnViscosityAnalytic *self = (ColumnViscosityAnalytic*)analyticSolution;
- double Z;
- double x,y;
- double C1,C2,C3,C4;
- double n, nx;
- double t1,t2,t3,t4,t5,t6,t7,t8,t11,t12,t13,t14,t15,t16,t18,t19,t20,t21,t23,t24,t25,t28,t29,t30,t31,t32,t33,t34,t36,t37;
- double t41,t45,t49,t51,t53,t55,t58,t59,t60,t63,t67,t68,t73;
- double t86,t87,t90,t91,t94,t106,t120;
- double t121,t129,t146,t155,t156,t158,t159;
-
- /* Find coordinate of node */
- x = coord[ I_AXIS ];
- y = coord[ J_AXIS ];
-
- /* del_rho = sin(ny*Pi*y)*cos(nx*Pi*x) n=nx gives only non-zero terms*/
- n = 1;
- /* only one n in Fourier series because del_rho has cos term */
- nx = n;
-
- if ( x > self->xc ) {
- C1 = self->C1B;
- C2 = self->C2B;
- C3 = self->C3B;
- C4 = self->C4B;
- Z = self->ZB;
- }
- else {
- C1 = self->C1A;
- C2 = self->C2A;
- C3 = self->C3A;
- C4 = self->C4A;
- Z = self->ZA;
- }
-
- /****************************************************************************************/
- /****************************************************************************************/
- t1 = n * n;
- t2 = t1 * t1;
- t3 = t2 * n;
- t4 = x * t3;
- t5 = 0.3141592654e1 * 0.3141592654e1;
- t6 = t5 * 0.3141592654e1;
- t11 = C3 * t6;
- t12 = x * n;
- t13 = nx * nx;
- t14 = t13 * t13;
- t15 = t12 * t14;
- t19 = exp(t12 * 0.3141592654e1);
- t20 = t19 * t19;
- t21 = t4 * t20;
- t24 = C1 * t5;
- t25 = Z * t20;
- t29 = C1 * t6;
- t30 = t29 * Z;
- t31 = t1 * n;
- t32 = x * t31;
- t33 = t32 * t13;
- t36 = t11 * x;
- t41 = n * t20;
- t45 = t6 * C4;
- t49 = t20 * t1;
- t51 = C2 * Z;
- t55 = -0.2e1 * t4 * t6 * C2 * Z - 0.2e1 * t11 * t15 - 0.2e1 * t11 * t21 + 0.2e1 * t24 * t25 * t14 - t13 + 0.4e1 * t30 * t33 - 0.4e1 * t36 * t31 * t20 * t13 - 0.2e1 * t36 * t41 * t14 - 0.2e1 * t4 * t45 * t20 - t49 - 0.2e1 * t4 * t6 * t51 * t20;
- t58 = t32 * t6;
- t59 = C4 * t20;
- t63 = t20 * t13;
- t67 = t12 * t6;
- t68 = t20 * t14;
- t87 = t49 * t13;
- t90 = -0.4e1 * t11 * t33 - 0.4e1 * t58 * t59 * t13 - 0.4e1 * t58 * t51 * t63 - 0.2e1 * t67 * t51 * t68 + 0.4e1 * t32 * t45 * t13 - 0.2e1 * t67 * t59 * t14 - 0.2e1 * t30 * t21 + t1 + 0.2e1 * t24 * t25 * t2 + 0.2e1 * t12 * t45 * t14 + 0.4e1 * t24 * Z * t87;
- t106 = C3 * t5;
- t120 = -0.4e1 * t30 * t32 * t63 + t63 + 0.4e1 * t24 * Z * t1 * t13 + 0.2e1 * t29 * Z * x * t3 - 0.4e1 * t58 * t51 * t13 - 0.2e1 * t106 * t2 + t32 * 0.3141592654e1 - 0.2e1 * t106 * t14 - 0.2e1 * t30 * t12 * t68 - 0.2e1 * t67 * t51 * t14 + 0.4e1 * t106 * t87;
- t129 = sin(nx * 0.3141592654e1 * x);
- t155 = 0.2e1 * t30 * t15 + x * 0.3141592654e1 * t41 * t13 - 0.4e1 * t19 * nx * t129 * n + t32 * 0.3141592654e1 * t20 + 0.2e1 * t106 * t68 + 0.2e1 * t106 * t20 * t2 - 0.4e1 * t106 * t1 * t13 - 0.2e1 * t11 * t4 + 0.2e1 * t4 * t45 + 0.2e1 * t24 * Z * t2 + 0.2e1 * t24 * Z * t14 + t12 * 0.3141592654e1 * t13;
- t158 = t5 * Z;
-
- velocity[ I_AXIS ] = (t55 + t90 + t120 + t155) / (0.4e1 * t158 * t19 * t2 + 0.8e1 * t158 * t19 * t1 * t13 + 0.4e1 * t158 * t19 * t14);
- velocity[ I_AXIS ] *= cos(n*M_PI*y);
-
- /****************************************************************************************/
- /****************************************************************************************/
- t1 = n * n;
- t2 = t1 * n;
- t3 = x * t2;
- t4 = 0.3141592654e1 * 0.3141592654e1;
- t5 = t4 * 0.3141592654e1;
- t6 = t3 * t5;
- t7 = C2 * Z;
- t8 = nx * nx;
- t12 = t1 * t1;
- t13 = t12 * n;
- t14 = x * t13;
- t15 = t5 * C4;
- t16 = x * n;
- t18 = exp(t16 * 0.3141592654e1);
- t19 = t18 * t18;
- t23 = t16 * t5;
- t24 = t8 * t8;
- t28 = C3 * t5;
- t29 = t14 * t19;
- t32 = C1 * t5;
- t33 = t32 * Z;
- t34 = t16 * t24;
- t37 = C4 * t19;
- t45 = C2 * t4;
- t53 = t19 * t8;
- t58 = C4 * t4;
- t60 = t1 * t19 * t8;
- t63 = t19 * t24;
- t67 = t3 * t8;
- t73 = n * t19;
- t86 = t28 * x;
- t91 = 0.4e1 * t58 * t60 + 0.2e1 * t33 * t16 * t63 + 0.4e1 * t33 * t67 + 0.2e1 * t33 * t29 - x * 0.3141592654e1 * t73 * t8 - 0.2e1 * t53 + 0.2e1 * t32 * Z * x * t13 - 0.2e1 * t58 * t12 - 0.2e1 * t58 * t24 + t3 * 0.3141592654e1 + 0.4e1 * t86 * t2 * t19 * t8;
- t94 = Z * t12;
- t121 = -0.2e1 * t8 + 0.2e1 * t45 * t94 * t19 + 0.2e1 * t14 * t5 * t7 * t19 + 0.4e1 * t6 * t7 * t53 + 0.2e1 * t23 * t7 * t63 - 0.4e1 * t28 * t67 + 0.2e1 * t45 * t94 + 0.2e1 * t58 * t12 * t19 + t16 * 0.3141592654e1 * t8 + 0.2e1 * t14 * t15 - 0.2e1 * t28 * t14;
- t146 = cos(nx * 0.3141592654e1 * x);
- t156 = -t3 * 0.3141592654e1 * t19 + 0.2e1 * t58 * t63 - 0.4e1 * t58 * t1 * t8 + 0.4e1 * t45 * Z * t1 * t8 - 0.2e1 * t28 * t34 + 0.2e1 * t86 * t73 * t24 + 0.4e1 * t3 * t15 * t8 + 0.4e1 * t45 * Z * t60 + 0.4e1 * t18 * t146 * t8 + 0.2e1 * t45 * Z * t24 + 0.2e1 * t16 * t15 * t24;
- t159 = t4 * Z;
-
- velocity[ J_AXIS ] = (-0.4e1 * t6 * t7 * t8 + 0.2e1 * t14 * t15 * t19 - 0.2e1 * t23 * t7 * t24 + 0.2e1 * t28 * t29 + 0.2e1 * t33 * t34 + 0.4e1 * t6 * t37 * t8 - 0.2e1 * t14 * t5 * C2 * Z + 0.2e1 * t45 * Z * t19 * t24 + 0.2e1 * t23 * t37 * t24 + 0.4e1 * t33 * t3 * t53 + t91 + t121 + t156) / (0.4e1 * t159 * t18 * t12 + 0.8e1 * t159 * t18 * t1 * t8 + 0.4e1 * t159 * t18 * t24);
- velocity[ J_AXIS ] *= sin(n*M_PI*y); /* y velocity */
-
-}
-
-
-void ColumnViscosityAnalytic_PressureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* pressure ) {
- ColumnViscosityAnalytic *self = (ColumnViscosityAnalytic*)analyticSolution;
- double Z;
- double x,y;
- double C1,C2,C3,C4;
- double n, nx;
- XYZ velocity;
- double u3;
- double t9, t17, t40, t44, t48, t52, t57, t61, t62, t78, t101, t102, t109, t110, t128;
- double t1,t2,t3,t4,t5,t6,t7,t8,t11,t12,t13,t14,t15,t16,t18,t19,t20,t23,t24,t28,t29,t30,t31,t32,t33,t34,t37;
- double t45,t53,t58,t60,t63,t67,t73;
- double t86,t90,t91,t94;
- double t121,t146,t156,t159;
-
- /* Find coordinate of node */
- x = coord[ I_AXIS ];
- y = coord[ J_AXIS ];
-
- /* del_rho = sin(ny*Pi*y)*cos(nx*Pi*x) n=nx gives only non-zero terms*/
- n = 1;
- /* only one n in Fourier series because del_rho has cos term */
- nx = n;
-
- if ( x > self->xc ) {
- C1 = self->C1B;
- C2 = self->C2B;
- C3 = self->C3B;
- C4 = self->C4B;
- Z = self->ZB;
- }
- else {
- C1 = self->C1A;
- C2 = self->C2A;
- C3 = self->C3A;
- C4 = self->C4A;
- Z = self->ZA;
- }
-
- /****************************************************************************************/
- /****************************************************************************************/
- t1 = n * n;
- t2 = t1 * n;
- t3 = x * t2;
- t4 = 0.3141592654e1 * 0.3141592654e1;
- t5 = t4 * 0.3141592654e1;
- t6 = t3 * t5;
- t7 = C2 * Z;
- t8 = nx * nx;
- t12 = t1 * t1;
- t13 = t12 * n;
- t14 = x * t13;
- t15 = t5 * C4;
- t16 = x * n;
- t18 = exp(t16 * 0.3141592654e1);
- t19 = t18 * t18;
- t23 = t16 * t5;
- t24 = t8 * t8;
- t28 = C3 * t5;
- t29 = t14 * t19;
- t32 = C1 * t5;
- t33 = t32 * Z;
- t34 = t16 * t24;
- t37 = C4 * t19;
- t45 = C2 * t4;
- t53 = t19 * t8;
- t58 = C4 * t4;
- t60 = t1 * t19 * t8;
- t63 = t19 * t24;
- t67 = t3 * t8;
- t73 = n * t19;
- t86 = t28 * x;
- t91 = 0.4e1 * t58 * t60 + 0.2e1 * t33 * t16 * t63 + 0.4e1 * t33 * t67 + 0.2e1 * t33 * t29 - x * 0.3141592654e1 * t73 * t8 - 0.2e1 * t53 + 0.2e1 * t32 * Z * x * t13 - 0.2e1 * t58 * t12 - 0.2e1 * t58 * t24 + t3 * 0.3141592654e1 + 0.4e1 * t86 * t2 * t19 * t8;
- t94 = Z * t12;
- t121 = -0.2e1 * t8 + 0.2e1 * t45 * t94 * t19 + 0.2e1 * t14 * t5 * t7 * t19 + 0.4e1 * t6 * t7 * t53 + 0.2e1 * t23 * t7 * t63 - 0.4e1 * t28 * t67 + 0.2e1 * t45 * t94 + 0.2e1 * t58 * t12 * t19 + t16 * 0.3141592654e1 * t8 + 0.2e1 * t14 * t15 - 0.2e1 * t28 * t14;
- t146 = cos(nx * 0.3141592654e1 * x);
- t156 = -t3 * 0.3141592654e1 * t19 + 0.2e1 * t58 * t63 - 0.4e1 * t58 * t1 * t8 + 0.4e1 * t45 * Z * t1 * t8 - 0.2e1 * t28 * t34 + 0.2e1 * t86 * t73 * t24 + 0.4e1 * t3 * t15 * t8 + 0.4e1 * t45 * Z * t60 + 0.4e1 * t18 * t146 * t8 + 0.2e1 * t45 * Z * t24 + 0.2e1 * t16 * t15 * t24;
- t159 = t4 * Z;
-
- velocity[ J_AXIS ] = (-0.4e1 * t6 * t7 * t8 + 0.2e1 * t14 * t15 * t19 - 0.2e1 * t23 * t7 * t24 + 0.2e1 * t28 * t29 + 0.2e1 * t33 * t34 + 0.4e1 * t6 * t37 * t8 - 0.2e1 * t14 * t5 * C2 * Z + 0.2e1 * t45 * Z * t19 * t24 + 0.2e1 * t23 * t37 * t24 + 0.4e1 * t33 * t3 * t53 + t91 + t121 + t156) / (0.4e1 * t159 * t18 * t12 + 0.8e1 * t159 * t18 * t1 * t8 + 0.4e1 * t159 * t18 * t24);
- velocity[ J_AXIS ] *= sin(n*M_PI*y); /* y velocity */
-
- /****************************************************************************************/
- /****************************************************************************************/
- t1 = 0.3141592654e1 * 0.3141592654e1;
- t2 = t1 * 0.3141592654e1;
- t3 = C1 * t2;
- t4 = t3 * Z;
- t5 = n * n;
- t6 = t5 * t5;
- t7 = t6 * n;
- t8 = x * t7;
- t9 = x * n;
- t11 = exp(t9 * 0.3141592654e1);
- t12 = t11 * t11;
- t13 = t8 * t12;
- t16 = t5 * n;
- t17 = x * t16;
- t18 = t17 * t2;
- t19 = C4 * t12;
- t20 = nx * nx;
- t24 = t2 * C4;
- t28 = C3 * t2;
- t29 = t28 * x;
- t30 = t12 * n;
- t31 = t20 * t20;
- t40 = C2 * Z;
- t44 = t9 * t2;
- t48 = t12 * t20;
- t52 = t17 * t20;
- t57 = -0.2e1 * t4 * t13 - 0.4e1 * t18 * t19 * t20 - 0.2e1 * t8 * t24 * t12 - 0.2e1 * t29 * t30 * t31 + 0.2e1 * t8 * t2 * C2 * Z - 0.2e1 * t8 * t2 * t40 * t12 - 0.2e1 * t44 * t19 * t31 - 0.4e1 * t18 * t40 * t48 + t20 + 0.4e1 * t28 * t52 + t17 * 0.3141592654e1 * t12;
- t58 = t9 * t31;
- t61 = C3 * t1;
- t62 = t12 * t31;
- t73 = t5 * t20;
- t78 = C1 * t1;
- t90 = Z * t12;
- t94 = 0.2e1 * t28 * t58 + 0.2e1 * t61 * t62 + 0.2e1 * t61 * t12 * t6 - 0.4e1 * t4 * t17 * t48 + 0.2e1 * t28 * t8 + 0.4e1 * t61 * t73 - 0.2e1 * t8 * t24 - 0.2e1 * t78 * Z * t6 - 0.2e1 * t44 * t40 * t62 - 0.2e1 * t78 * Z * t31 - t9 * 0.3141592654e1 * t20 + 0.2e1 * t78 * t90 * t6;
- t101 = cos(nx * 0.3141592654e1 * x);
- t102 = t11 * t101;
- t109 = t12 * t5;
- t110 = t109 * t20;
- t128 = 0.2e1 * t61 * t6 - t17 * 0.3141592654e1 + 0.2e1 * t102 * t5 - 0.4e1 * t17 * t24 * t20 + 0.4e1 * t78 * Z * t110 - 0.2e1 * t9 * t24 * t31 - 0.4e1 * t4 * t52 - 0.2e1 * t4 * t9 * t62 + x * 0.3141592654e1 * t30 * t20 - t5 - 0.4e1 * t78 * Z * t5 * t20;
- t156 = 0.2e1 * t78 * t90 * t31 - 0.2e1 * t3 * Z * x * t7 + t48 + 0.4e1 * t61 * t110 + 0.4e1 * t18 * t40 * t20 - 0.2e1 * t102 * t20 + 0.2e1 * t61 * t31 + 0.2e1 * t44 * t40 * t31 - t109 - 0.2e1 * t4 * t58 - 0.2e1 * t28 * t13 - 0.4e1 * t29 * t16 * t12 * t20;
- t159 = t1 * t11;
-
- u3 = (t57 + t94 + t128 + t156) / (0.4e1 * t159 * t6 + 0.8e1 * t159 * t73 + 0.4e1 * t159 * t31);
- /****************************************************************************************/
- /****************************************************************************************/
-
- *pressure = (double)(-2*Z*n*M_PI*velocity[ J_AXIS ]-u3*2*n*M_PI)*cos(n*M_PI*y);
-
-}
-
-void ColumnViscosityAnalytic_StressFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* stress ) {
- ColumnViscosityAnalytic *self = (ColumnViscosityAnalytic*)analyticSolution;
- double Z;
- double x,y;
- double C1,C2,C3,C4;
- double n, nx;
- double u2, u3, u4;
- double t1,t2,t3,t4,t5,t6,t7,t8,t9,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t23,t24,t28,t29,t30,t31,t32,t33,t34,t35,t37,t40;
- double t41,t44,t45,t47,t48,t52,t53,t54,t57,t58,t60,t61,t62,t63,t67,t69,t73,t75,t78,t79;
- double t83,t84,t86,t90,t91,t94,t95,t97,t101,t102,t106,t109,t110;
- double t121,t127,t128,t131,t135,t146,t156,t159;
- double t164;
-
- /* Find coordinate of node */
- x = coord[ I_AXIS ];
- y = coord[ J_AXIS ];
-
- /* del_rho = sin(ny*Pi*y)*cos(nx*Pi*x) n=nx gives only non-zero terms*/
- n = 1;
- /* only one n in Fourier series because del_rho has cos term */
- nx = n;
-
- if ( x > self->xc ) {
- C1 = self->C1B;
- C2 = self->C2B;
- C3 = self->C3B;
- C4 = self->C4B;
- Z = self->ZB;
- }
- else {
- C1 = self->C1A;
- C2 = self->C2A;
- C3 = self->C3A;
- C4 = self->C4A;
- Z = self->ZA;
- }
-
- t1 = n * n;
- t2 = t1 * n;
- t3 = x * t2;
- t4 = 0.3141592654e1 * 0.3141592654e1;
- t5 = t4 * 0.3141592654e1;
- t6 = t3 * t5;
- t7 = C2 * Z;
- t8 = nx * nx;
- t12 = t1 * t1;
- t13 = t12 * n;
- t14 = x * t13;
- t15 = t5 * C4;
- t16 = x * n;
- t18 = exp(t16 * 0.3141592654e1);
- t19 = t18 * t18;
- t23 = t16 * t5;
- t24 = t8 * t8;
- t28 = C3 * t5;
- t29 = t14 * t19;
- t32 = C1 * t5;
- t33 = t32 * Z;
- t34 = t16 * t24;
- t37 = C4 * t19;
- t45 = C2 * t4;
- t53 = t19 * t8;
- t58 = C4 * t4;
- t60 = t1 * t19 * t8;
- t63 = t19 * t24;
- t67 = t3 * t8;
- t73 = n * t19;
- t86 = t28 * x;
- t91 = 0.4e1 * t58 * t60 + 0.2e1 * t33 * t16 * t63 + 0.4e1 * t33 * t67 + 0.2e1 * t33 * t29 - x * 0.3141592654e1 * t73 * t8 - 0.2e1 * t53 + 0.2e1 * t32 * Z * x * t13 - 0.2e1 * t58 * t12 - 0.2e1 * t58 * t24 + t3 * 0.3141592654e1 + 0.4e1 * t86 * t2 * t19 * t8;
- t94 = Z * t12;
- t121 = -0.2e1 * t8 + 0.2e1 * t45 * t94 * t19 + 0.2e1 * t14 * t5 * t7 * t19 + 0.4e1 * t6 * t7 * t53 + 0.2e1 * t23 * t7 * t63 - 0.4e1 * t28 * t67 + 0.2e1 * t45 * t94 + 0.2e1 * t58 * t12 * t19 + t16 * 0.3141592654e1 * t8 + 0.2e1 * t14 * t15 - 0.2e1 * t28 * t14;
- t146 = cos(nx * 0.3141592654e1 * x);
- t156 = -t3 * 0.3141592654e1 * t19 + 0.2e1 * t58 * t63 - 0.4e1 * t58 * t1 * t8 + 0.4e1 * t45 * Z * t1 * t8 - 0.2e1 * t28 * t34 + 0.2e1 * t86 * t73 * t24 + 0.4e1 * t3 * t15 * t8 + 0.4e1 * t45 * Z * t60 + 0.4e1 * t18 * t146 * t8 + 0.2e1 * t45 * Z * t24 + 0.2e1 * t16 * t15 * t24;
- t159 = t4 * Z;
-
- u2 = (-0.4e1 * t6 * t7 * t8 + 0.2e1 * t14 * t15 * t19 - 0.2e1 * t23 * t7 * t24 + 0.2e1 * t28 * t29 + 0.2e1 * t33 * t34 + 0.4e1 * t6 * t37 * t8 - 0.2e1 * t14 * t5 * C2 * Z + 0.2e1 * t45 * Z * t19 * t24 + 0.2e1 * t23 * t37 * t24 + 0.4e1 * t33 * t3 * t53 + t91 + t121 + t156) / (0.4e1 * t159 * t18 * t12 + 0.8e1 * t159 * t18 * t1 * t8 + 0.4e1 * t159 * t18 * t24);
-
- /****************************************************************************************/
- /****************************************************************************************/
-
- t1 = 0.3141592654e1 * 0.3141592654e1;
- t2 = t1 * 0.3141592654e1;
- t3 = C1 * t2;
- t4 = t3 * Z;
- t5 = n * n;
- t6 = t5 * t5;
- t7 = t6 * n;
- t8 = x * t7;
- t9 = x * n;
- t11 = exp(t9 * 0.3141592654e1);
- t12 = t11 * t11;
- t13 = t8 * t12;
- t16 = t5 * n;
- t17 = x * t16;
- t18 = t17 * t2;
- t19 = C4 * t12;
- t20 = nx * nx;
- t24 = t2 * C4;
- t28 = C3 * t2;
- t29 = t28 * x;
- t30 = t12 * n;
- t31 = t20 * t20;
- t40 = C2 * Z;
- t44 = t9 * t2;
- t48 = t12 * t20;
- t52 = t17 * t20;
- t57 = -0.2e1 * t4 * t13 - 0.4e1 * t18 * t19 * t20 - 0.2e1 * t8 * t24 * t12 - 0.2e1 * t29 * t30 * t31 + 0.2e1 * t8 * t2 * C2 * Z - 0.2e1 * t8 * t2 * t40 * t12 - 0.2e1 * t44 * t19 * t31 - 0.4e1 * t18 * t40 * t48 + t20 + 0.4e1 * t28 * t52 + t17 * 0.3141592654e1 * t12;
- t58 = t9 * t31;
- t61 = C3 * t1;
- t62 = t12 * t31;
- t73 = t5 * t20;
- t78 = C1 * t1;
- t90 = Z * t12;
- t94 = 0.2e1 * t28 * t58 + 0.2e1 * t61 * t62 + 0.2e1 * t61 * t12 * t6 - 0.4e1 * t4 * t17 * t48 + 0.2e1 * t28 * t8 + 0.4e1 * t61 * t73 - 0.2e1 * t8 * t24 - 0.2e1 * t78 * Z * t6 - 0.2e1 * t44 * t40 * t62 - 0.2e1 * t78 * Z * t31 - t9 * 0.3141592654e1 * t20 + 0.2e1 * t78 * t90 * t6;
- t101 = cos(nx * 0.3141592654e1 * x);
- t102 = t11 * t101;
- t109 = t12 * t5;
- t110 = t109 * t20;
- t128 = 0.2e1 * t61 * t6 - t17 * 0.3141592654e1 + 0.2e1 * t102 * t5 - 0.4e1 * t17 * t24 * t20 + 0.4e1 * t78 * Z * t110 - 0.2e1 * t9 * t24 * t31 - 0.4e1 * t4 * t52 - 0.2e1 * t4 * t9 * t62 + x * 0.3141592654e1 * t30 * t20 - t5 - 0.4e1 * t78 * Z * t5 * t20;
- t156 = 0.2e1 * t78 * t90 * t31 - 0.2e1 * t3 * Z * x * t7 + t48 + 0.4e1 * t61 * t110 + 0.4e1 * t18 * t40 * t20 - 0.2e1 * t102 * t20 + 0.2e1 * t61 * t31 + 0.2e1 * t44 * t40 * t31 - t109 - 0.2e1 * t4 * t58 - 0.2e1 * t28 * t13 - 0.4e1 * t29 * t16 * t12 * t20;
- t159 = t1 * t11;
-
- u3 = (t57 + t94 + t128 + t156) / (0.4e1 * t159 * t6 + 0.8e1 * t159 * t73 + 0.4e1 * t159 * t31);
- /****************************************************************************************/
- /****************************************************************************************/
-
- t1 = C2 * Z;
- t2 = 0.3141592654e1 * 0.3141592654e1;
- t3 = t2 * 0.3141592654e1;
- t4 = n * n;
- t5 = t4 * t4;
- t6 = t5 * t4;
- t8 = t3 * t6 * x;
- t11 = x * t4;
- t12 = t11 * t3;
- t15 = exp(x * n * 0.3141592654e1);
- t16 = t15 * t15;
- t17 = C3 * t16;
- t18 = nx * nx;
- t19 = t18 * t18;
- t23 = t5 * n;
- t24 = t2 * t23;
- t28 = t1 * t3;
- t29 = t6 * x;
- t30 = t29 * t16;
- t33 = C4 * t3;
- t34 = t5 * x;
- t35 = t34 * t18;
- t41 = sin(nx * 0.3141592654e1 * x);
- t47 = t11 * t19;
- t54 = t3 * C3;
- t57 = 0.2e1 * t1 * t8 + 0.2e1 * t12 * t17 * t19 + 0.2e1 * t1 * t24 * t16 + 0.2e1 * t28 * t30 - 0.4e1 * t33 * t35 + 0.2e1 * t15 * nx * t41 * t4 + 0.4e1 * t28 * t35 - 0.2e1 * t33 * t47 - 0.2e1 * t1 * t24 - 0.2e1 * t33 * t29 + 0.2e1 * t29 * t54;
- t58 = 0.3141592654e1 * t16;
- t60 = t2 * C4;
- t69 = t4 * n;
- t73 = t1 * t2;
- t75 = t69 * t16 * t18;
- t79 = x * t16;
- t83 = n * t16;
- t84 = t83 * t19;
- t95 = -t34 * t58 + 0.2e1 * t60 * t23 * t16 + 0.2e1 * t60 * n * t19 - t11 * 0.3141592654e1 * t18 + 0.4e1 * t60 * t69 * t18 + 0.4e1 * t73 * t75 + 0.4e1 * t33 * t5 * t79 * t18 + 0.2e1 * t73 * t84 + 0.2e1 * t60 * t84 + 0.2e1 * t33 * t4 * t79 * t19 + 0.4e1 * t60 * t75;
- t97 = t34 * t3;
- t101 = Z * C1;
- t102 = t16 * t19;
- t106 = t16 * t18;
- t127 = t2 * t69;
- t131 = t2 * n;
- t135 = 0.4e1 * t97 * t17 * t18 + 0.2e1 * t12 * t101 * t102 + 0.4e1 * t28 * t34 * t106 + 0.2e1 * t28 * t11 * t102 - 0.2e1 * t29 * t3 * Z * C1 - 0.4e1 * t97 * t101 * t18 - 0.2e1 * t12 * t101 * t19 + 0.2e1 * t60 * t23 - 0.2e1 * t83 * t18 - 0.4e1 * t1 * t127 * t18 - 0.2e1 * t1 * t131 * t19;
- t164 = 0.2e1 * t28 * t47 + 0.2e1 * t11 * t54 * t19 + 0.2e1 * t8 * t101 * t16 + 0.2e1 * t33 * t30 - t11 * t58 * t18 + 0.2e1 * t29 * t54 * t16 + 0.4e1 * t34 * t54 * t18 + 0.4e1 * t97 * t101 * t106 - 0.2e1 * t15 * t18 * nx * t41 - t34 * 0.3141592654e1 + 0.2e1 * n * t18;
-
- u4 = (t57 + t95 + t135 + t164) / (0.4e1 * t24 * t15 + 0.8e1 * t127 * t15 * t18 + 0.4e1 * t131 * t15 * t19);
- /****************************************************************************************/
- /****************************************************************************************/
-
- stress[0] = (double)(u4*2*n*M_PI + 4*Z*n*M_PI*u2)*cos(n*M_PI*y); /* xx stress */
- stress[1] = 2*n*M_PI*cos(n*M_PI*y) * u3; /* yy stress */
- stress[2] = 2*n*M_PI*sin(n*M_PI*y) * u4; /* xy stress */
-}
-
-void _ColumnViscosityAnalytic_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- ColumnViscosityAnalytic* self = (ColumnViscosityAnalytic*)analyticSolution;
- AbstractContext* context;
- ConditionFunction* condFunc;
-
- /* Construct Parent */
- _AnalyticSolution_AssignFromXML( self, cf, data );
-
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
-
- /* Create Analytic Fields */
- self->velocityField = Stg_ComponentFactory_ConstructByName( cf, (Name)"VelocityField", FeVariable, True, data );
- self->pressureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"PressureField", FeVariable, True, data );
- self->stressField = Stg_ComponentFactory_ConstructByName( cf, (Name)"StressField", FeVariable, False, data );
-
- /* Add condition function for temperature */
- condFunc = ConditionFunction_New( ColumnViscosityAnalytic_TemperatureIC, (Name)"ColumnViscosityAnalytic_TemperatureIC" );
- ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
-
- /* Set up constants */
- self->ZA = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"leftViscosity", 1.0 );
- self->ZB = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"rightViscosity", 1.0 );
-
- /* top layer viscosity */
- self->xc = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"columnEnd", 0.5 );
- ColumnViscosityAnalytic_Constants( self );
-}
-
-void _ColumnViscosityAnalytic_Build( void* analyticSolution, void* data ) {
- ColumnViscosityAnalytic* self = (ColumnViscosityAnalytic*)analyticSolution;
-
- Build( self->velocityField, data, False );
- Build( self->pressureField, data, False );
- if( self->stressField )
- Build( self->stressField, data, False );
-
- AnalyticSolution_CreateAnalyticField( self, self->velocityField, ColumnViscosityAnalytic_VelocityFunction );
- AnalyticSolution_CreateAnalyticField( self, self->pressureField, ColumnViscosityAnalytic_PressureFunction );
- if( self->stressField )
- AnalyticSolution_CreateAnalyticField( self, self->stressField, ColumnViscosityAnalytic_StressFunction );
-
- _AnalyticSolution_Build( self, data );
-}
-
-void* _ColumnViscosityAnalytic_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(ColumnViscosityAnalytic);
- Type type = ColumnViscosityAnalytic_Type;
- Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
- Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
- Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _ColumnViscosityAnalytic_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _ColumnViscosityAnalytic_AssignFromXML;
- Stg_Component_BuildFunction* _build = _ColumnViscosityAnalytic_Build;
- Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
- Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
-}
-
-Index StgFEM_ColumnViscosityAnalytic_Register( PluginsManager* pluginsManager ) {
- return PluginsManager_Submit( pluginsManager, ColumnViscosityAnalytic_Type, (Name)"0", _ColumnViscosityAnalytic_DefaultNew );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Apps/ThermalConvection/tests/ColumnViscosityAnalytic/ColumnViscosityAnalytic.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Apps/ThermalConvection/tests/ColumnViscosityAnalytic/ColumnViscosityAnalytic.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,2637 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: ColumnViscosityAnalytic.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+#include <assert.h>
+
+const Type ColumnViscosityAnalytic_Type = "ColumnViscosityAnalytic";
+
+typedef struct {
+ __AnalyticSolution
+ double ZA;
+ double ZB;
+ double xc;
+ double C1A,C2A,C3A,C4A,C1B,C2B,C3B,C4B;
+ FeVariable* velocityField;
+ FeVariable* pressureField;
+ FeVariable* stressField;
+} ColumnViscosityAnalytic;
+
+#define SMALL 1.0e-5
+#define IS_ODD(A) ( (A) % 2 == 1 )
+
+
+/** Analytic Solution taken from
+ * Shijie Zhong. Analytic solutions for Stokes' flow with lateral variations in viscosity. Geophys. J. Int., 124:18-28, 1996.
+ * All equations refer to this paper */
+
+void ColumnViscosityAnalytic_TemperatureIC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ FeVariable* temperatureField = (FeVariable*) FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ FeMesh* mesh = temperatureField->feMesh;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double x;
+ double y;
+ double kx;
+ double ky;
+ int wavenumberX;
+ int wavenumberY;
+ double L;
+ double min[3], max[3];
+
+ /* Find coordinate of node */
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ /* Make sure that the box has right dimensions */
+ Mesh_GetGlobalCoordRange( mesh, min, max );
+ assert( ( max[ J_AXIS ] - min[ J_AXIS ] - 1.0 ) < SMALL );
+ L = max[ I_AXIS ] - min[ I_AXIS ];
+
+ x = coord[ I_AXIS ] - min[ I_AXIS ];
+ y = coord[ J_AXIS ] - min[ J_AXIS ];
+
+ wavenumberX = Dictionary_GetInt_WithDefault( dictionary, (Dictionary_Entry_Key)"wavenumberX", 1 );
+ wavenumberY = Dictionary_GetInt_WithDefault( dictionary, (Dictionary_Entry_Key)"wavenumberY", 1 );
+
+ kx = wavenumberX * M_PI/ L;
+ ky = wavenumberY * M_PI;
+
+ *result = sin( ky * y ) * cos( kx * x );
+}
+
+void ColumnViscosityAnalytic_Constants( void* analyticSolution ) {
+ ColumnViscosityAnalytic* self = (ColumnViscosityAnalytic* ) analyticSolution;
+ double n, nx;
+ double t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40;
+ double t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80;
+ double t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t115,t116,t117,t118,t119,t120;
+ double t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160;
+ double t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199;
+ double t201,t202,t203,t204,t206,t207,t208,t209,t210,t211,t212,t213,t215,t216,t217,t218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240;
+ double t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256,t257,t258,t259,t260,t261,t262,t263,t264,t265,t267,t268,t269,t270,t272,t273,t274,t275,t276,t277,t278,t279,t280;
+ double t281,t282,t283,t284,t285,t286,t288,t289,t290,t291,t292,t295,t296,t297,t298,t299,t300,t301,t303,t304,t305,t307,t308,t310,t311,t312,t313,t314,t315,t316,t317,t318,t319,t320;
+ double t321,t322,t323,t324,t325,t326,t327,t328,t329,t330,t331,t332,t334,t335,t336,t337,t338,t339,t340,t341,t342,t344,t345,t346,t347,t348,t349,t350,t351,t352,t353,t354,t355,t356,t358,t359,t360;
+ double t361,t362,t363,t364,t365,t366,t367,t368,t369,t370,t371,t372,t373,t374,t375,t376,t377,t378,t379,t380,t381,t382,t383,t384,t385,t386,t387,t389,t390,t391,t393,t394,t395,t396,t397,t398;
+ double t401,t402,t403,t404,t405,t406,t407,t408,t409,t410,t411,t412,t413,t414,t415,t416,t417,t418,t419,t421,t422,t423,t424,t425,t426,t427,t428,t429,t430,t431,t432,t433,t434,t436,t437,t438,t439,t440;
+ double t441,t442,t443,t444,t445,t446,t447,t448,t450,t451,t453,t454,t455,t456,t457,t458,t459,t461,t462,t463,t464,t465,t466,t468,t469,t470,t471,t474,t475,t478,t480;
+ double t482,t483,t484,t485,t488,t489,t490,t492,t493,t495,t497,t498,t499,t501,t502,t503,t504,t505,t507,t508,t509,t510,t511,t512,t513,t515,t518,t520;
+ double t522,t525,t527,t528,t529,t530,t532,t533,t534,t535,t536,t538,t539,t541,t542,t544,t545,t546,t547,t548,t549,t550,t551,t552,t553,t554,t555,t556,t557,t560;
+ double t561,t562,t563,t564,t567,t568,t571,t573,t575,t576,t578,t579,t583,t590,t591,t594,t595,t596,t597,t598,t600;
+ double t601,t602,t604,t606,t607,t608,t611,t613,t615,t616,t617,t619,t621,t623,t624,t625,t626,t627,t629,t630,t632,t633,t634,t638,t639,t640;
+ double t641,t642,t643,t644,t645,t647,t648,t649,t650,t651,t652,t653,t654,t655,t656,t657,t658,t659,t660,t662,t663,t665,t666,t667,t668,t670,t671,t672,t673,t674,t675,t676,t679,t680;
+ double t682,t683,t684,t685,t686,t688,t689,t690,t691,t693,t694,t695,t696,t697,t698,t699,t700,t701,t702,t704,t705,t708,t709,t711,t712,t713,t714,t717,t718,t719;
+ double t721,t722,t723,t726,t727,t728,t730,t733,t734,t735,t736,t737,t738,t739,t740,t741,t744,t745,t746,t749,t750,t752,t753,t754,t755,t757,t758,t759,t760;
+ double t761,t762,t763,t764,t766,t767,t768,t770,t771,t772,t773,t774,t775,t776,t777,t778,t780,t781,t782,t785,t786,t789,t790,t791,t792,t793,t794,t795,t796,t797,t798,t800;
+ double t801,t806,t807,t808,t809,t811,t812,t817,t818,t819,t821,t822,t824,t827,t828,t830,t834,t835,t837,t840;
+ double t842,t843,t844,t845,t846,t849,t850,t853,t854,t855,t857,t858,t859,t860,t863,t864,t867,t868,t869,t873,t874,t877,t878,t879,t880;
+ double t884,t888,t891,t894,t900,t901,t903,t904,t907,t908,t909,t911,t914,t915,t916,t919,t920;
+ double t923,t924,t925,t926,t927,t929,t932,t935,t937,t939,t942,t943,t944,t945,t947,t948,t949,t950,t952,t953,t954,t955,t956,t957;
+ double t961,t964,t965,t966,t967,t968,t969,t971,t972,t974,t977,t978,t981,t983,t987,t988,t992,t993,t994,t997,t998;
+ double t1001,t1003,t1005,t1006,t1009,t1010,t1012,t1013,t1015,t1016,t1017,t1018,t1020,t1021,t1029,t1031,t1032,t1033,t1040;
+ double t1041,t1042,t1044,t1047,t1050,t1054,t1055,t1057,t1058,t1063,t1068,t1069,t1070,t1079,t1080;
+ double t1088,t1089,t1091,t1092,t1094,t1096,t1101,t1102,t1103,t1104,t1105,t1108,t1112,t1113,t1118,t1119,t1120;
+ double t1121,t1122,t1123,t1124,t1125,t1126,t1127,t1128,t1129,t1130,t1132,t1133,t1134,t1135,t1138,t1139,t1140,t1141,t1142,t1145,t1146,t1148,t1149,t1150,t1153,t1154,t1156,t1157,t1158,t1159;
+ double t1161,t1162,t1165,t1166,t1170,t1171,t1172,t1173,t1175,t1176,t1178,t1180,t1181,t1182,t1185,t1189,t1192,t1193,t1195,t1196,t1199;
+ double t1201,t1203,t1209,t1210,t1211,t1213,t1214,t1218,t1221,t1224,t1225,t1226,t1228,t1233,t1234,t1235,t1236,t1237,t1240;
+ double t1241,t1242,t1243,t1244,t1245,t1248,t1251,t1252,t1257,t1258,t1259,t1260,t1263,t1268,t1269,t1272,t1280;
+ double t1282,t1283,t1284,t1285,t1287,t1288,t1289,t1292,t1293,t1296,t1297,t1300,t1304,t1307,t1310,t1311,t1312,t1316,t1317,t1320;
+ double t1321,t1323,t1328,t1330,t1331,t1332,t1333,t1336,t1338,t1343,t1344,t1346,t1349,t1350,t1354;
+ double t1366,t1369,t1370,t1371,t1376,t1378,t1380,t1383,t1386,t1387,t1388,t1391,t1393,t1399;
+ double t1411,t1412,t1420,t1427;
+ double t1450,t1456,t1468,t1472,t1474,t1478;
+ double t1504,t1511;
+ double t1545;
+ double t1564,t1583;
+
+
+ /* del_rho = sin(ny*Pi*y)*cos(nx*Pi*x) n=nx gives only non-zero terms*/
+ n = 1;
+ /* only one n in Fourier series because del_rho has cos term */
+ nx = n;
+
+ self->C1A = 0;
+ /****************************************************************************************/
+ t1 = nx * 0.3141592654e1;
+ t2 = sin(t1);
+ t3 = nx * t2;
+ t4 = n * n;
+ t5 = t4 * t4;
+ t6 = 0.3141592654e1 * 0.3141592654e1;
+ t8 = t3 * t5 * t6;
+ t9 = self->ZA * self->xc;
+ t12 = exp( self->xc * n * 0.3141592654e1);
+ t13 = t12 * t12;
+ t15 = n * 0.3141592654e1;
+ t16 = exp(t15);
+ t17 = t16 * t16;
+ t18 = t17 * t16;
+ t19 = self->ZB * t13 * t18;
+ t20 = t9 * t19;
+ t23 = self->ZA * self->ZA;
+ t24 = nx * nx;
+ t25 = t24 * nx;
+ t26 = t23 * t25;
+ t28 = t13 * t13;
+ t29 = t28 * t13;
+ t33 = nx * self->ZB;
+ t34 = t1 * self->xc;
+ t35 = sin(t34);
+ t36 = t4 * n;
+ t37 = t35 * t36;
+ t38 = t33 * t37;
+ t39 = 0.3141592654e1 * self->ZA;
+ t40 = t13 * t12;
+ t41 = t17 * t40;
+ t45 = self->ZB * self->ZB;
+ t46 = t45 * t24;
+ t47 = t46 * t4;
+ t48 = 0.3141592654e1 * self->xc;
+ t49 = t13 * t17;
+ t53 = self->xc * self->xc;
+ t54 = t36 * t53;
+ t56 = t54 * t6 * t45;
+ t57 = cos(t34);
+ t58 = t57 * t24;
+ t59 = t28 * t12;
+ t60 = t17 * t59;
+ t61 = t58 * t60;
+ t64 = t25 * t2;
+ t65 = t64 * t15;
+ t72 = nx * t23;
+ t74 = t72 * t2 * t5;
+ t75 = t6 * t53;
+ t76 = t16 * t29;
+ t80 = t23 * n;
+ t81 = t80 * 0.3141592654e1;
+ t82 = t18 * t28;
+ t86 = nx * t5;
+ t87 = t23 * t6;
+ t89 = self->xc * t2;
+ t90 = t13 * t18;
+ t91 = t89 * t90;
+ t94 = t28 * t28;
+ t96 = t24 * n;
+ t98 = t4 * t45;
+ t99 = t98 * 0.3141592654e1;
+ t100 = t58 * t41;
+ t104 = 0.3141592654e1 * t25;
+ t105 = self->ZA * n * t104;
+ t106 = t2 * self->ZB;
+ t110 = t17 * t17;
+ t111 = self->ZA * t110;
+ t116 = n * t28;
+ t122 = t64 * t4 * t6;
+ t126 = t23 * t29 * t4;
+ t128 = t24 * self->xc;
+ t132 = t36 * t23;
+ t133 = t6 * t57;
+ t135 = t128 * t41;
+ t138 = t6 * self->xc;
+ t142 = t72 * t2;
+ t147 = 0.4e1 * t8 * t20 - 0.2e1 * t26 * t2 * t16 * t29 - 0.8e1 * t38 * t39 * t41 + 0.4e1 * t47 * t48 * t49 - 0.8e1 * t56 * t61 - 0.4e1 * t65 * t20 + 0.2e1 * t26 * t2 * t18 * t28 - 0.4e1 * t74 * t75 * t76 - 0.2e1 * t81 * t64 * t82 - 0.4e1 * t86 * t87 * t91 - t23 * t94 * t96 + 0.8e1 * t99 * t100 - 0.2e1 * t105 * t106 * t82 - 0.4e1 * t38 * t48 * t111 * t12 + 0.2e1 * t116 * self->ZB * t111 * t24 + 0.4e1 * t122 * t20 + 0.4e1 * t126 * 0.3141592654e1 * t17 * t128 + 0.8e1 * t132 * t133 * t135 + 0.4e1 * t74 * t138 * t76 - 0.2e1 * t142 * t4 * t18 * t28;
+ t149 = self->ZA * t25 * t2;
+ t150 = self->ZB * t28;
+ t154 = t35 * t5;
+ t155 = t72 * t154;
+ t156 = t75 * t41;
+ t159 = nx * self->ZA;
+ t160 = t2 * t36;
+ t161 = t159 * t160;
+ t162 = 0.3141592654e1 * self->ZB;
+ t163 = t28 * t16;
+ t167 = t23 * t57;
+ t168 = t167 * t24;
+ t169 = n * t110;
+ t170 = t169 * t40;
+ t173 = self->ZA * self->ZB;
+ t174 = t173 * t90;
+ t177 = t36 * 0.3141592654e1;
+ t181 = t80 * t104;
+ t184 = n * t17;
+ t188 = t17 * t29;
+ t190 = t4 * 0.3141592654e1;
+ t191 = t190 * t24;
+ t206 = t138 * t60;
+ t209 = t23 * t4;
+ t211 = t209 * t6 * t25;
+ t212 = t89 * t76;
+ t216 = self->ZB * t16 * t29;
+ t217 = t9 * t216;
+ t220 = self->ZB * t110;
+ t221 = self->ZA * t24;
+ t222 = t221 * n;
+ t225 = t132 * t75;
+ t232 = t45 * t28;
+ t233 = t110 * t24;
+ t234 = t233 * n;
+ t236 = t209 * 0.3141592654e1;
+ t237 = t17 * self->xc;
+ t239 = t237 * t13 * t24;
+ t242 = -0.2e1 * t149 * t150 * t16 - 0.8e1 * t155 * t156 - 0.2e1 * t161 * t162 * t163 + 0.2e1 * t168 * t170 + 0.2e1 * t65 * t174 - 0.2e1 * t142 * t177 * t76 + 0.4e1 * t181 * t91 - 0.4e1 * t168 * t184 * t59 - 0.4e1 * t188 * t23 * t191 + 0.4e1 * t38 * t48 * self->ZA * t17 * t40 + 0.4e1 * t49 * t23 * t191 + 0.2e1 * t26 * t2 * t13 * t18 - 0.8e1 * t155 * t206 + 0.4e1 * t211 * t212 - 0.4e1 * t8 * t217 + 0.2e1 * t220 * t222 - 0.8e1 * t225 * t100 + 0.2e1 * t142 * t4 * t16 * t29 + t232 * t234 - 0.4e1 * t236 * t239;
+ t244 = nx * t45;
+ t245 = t244 * t37;
+ t246 = t110 * t40;
+ t251 = t237 * t59;
+ t256 = t64 * t90;
+ t260 = t36 * t45 * t133;
+ t263 = t45 * t57;
+ t264 = t263 * t24;
+ t265 = t169 * t12;
+ t269 = t6 * t36;
+ t270 = t17 * t24;
+ t274 = t110 * t13;
+ t276 = t190 * t128;
+ t279 = nx * t36;
+ t281 = t28 * t40;
+ t282 = t281 * t35;
+ t286 = t138 * t41;
+ t289 = t75 * t60;
+ t296 = t190 * t173;
+ t305 = t86 * t45 * t35;
+ t312 = t33 * t154;
+ t313 = t6 * self->ZA;
+ t324 = t232 * t270;
+ t327 = -0.2e1 * t245 * t48 * t246 + 0.4e1 * t159 * t37 * t162 * t251 + 0.4e1 * t209 * t75 * t256 + 0.8e1 * t260 * t135 + 0.2e1 * t264 * t265 + 0.32e2 * t9 * t150 * t269 * t270 + 0.4e1 * t274 * t23 * t276 + 0.2e1 * t279 * t45 * t282 * t48 + 0.8e1 * t155 * t286 + 0.8e1 * t155 * t289 - 0.8e1 * t150 * self->ZA * t96 * t17 + 0.8e1 * t296 * t61 - 0.2e1 * t105 * t106 * t163 - 0.2e1 * t81 * t256 - 0.8e1 * t305 * t156 - 0.4e1 * t33 * t282 * t177 * t9 - 0.16e2 * t312 * t313 * t237 * t40 - 0.4e1 * t168 * t184 * t40 + 0.2e1 * t168 * t265 + 0.16e2 * t269 * t53 * t324;
+ t328 = t3 * t4;
+ t331 = t72 * t37;
+ t332 = t48 * t60;
+ t335 = n * t94;
+ t345 = t72 * t35;
+ t349 = t173 * t57;
+ t355 = t53 * t17;
+ t364 = t54 * t6 * self->ZB;
+ t365 = t28 * t17;
+ t369 = self->xc * self->ZB;
+ t370 = t269 * t369;
+ t371 = self->ZA * t57;
+ t373 = t371 * t270 * t40;
+ t385 = nx * t35;
+ t396 = t4 * self->xc;
+ t397 = t396 * t162;
+ t415 = t37 * t48;
+ t418 = -0.32e2 * t364 * t365 * t221 - 0.16e2 * t370 * t373 - 0.4e1 * t331 * t48 * t41 + 0.4e1 * t86 * t23 * t53 * t6 * t2 * t90 + 0.2e1 * t385 * t177 * t23 * self->xc * t246 + 0.16e2 * t132 * t53 * t6 * t28 * t270 - 0.4e1 * t397 * t371 * t233 * t12 - 0.12e2 * t173 * t58 * t190 * t251 + 0.2e1 * t385 * t36 * 0.3141592654e1 * t23 * self->xc * t59 - 0.8e1 * t99 * t61 - 0.2e1 * t244 * t59 * t415;
+ t427 = t371 * t270 * t59;
+ t439 = t209 * t48;
+ t440 = t110 * t12;
+ t441 = t58 * t440;
+ t447 = t36 * self->xc;
+ t455 = t48 * t440;
+ t471 = self->ZB * t17;
+ t492 = 0.12e2 * t397 * t373 - 0.4e1 * t122 * t217 + 0.16e2 * t364 * t427 + 0.16e2 * t312 * t313 * t355 * t40 - 0.8e1 * t279 * t39 * t35 * self->ZB * t60 + 0.2e1 * t439 * t441 - 0.2e1 * t81 * t64 * t163 + 0.8e1 * t447 * t87 * t61 + 0.2e1 * t23 * t59 * t57 * t276 + 0.2e1 * t245 * t455 - 0.4e1 * t349 * t96 * t440 - 0.16e2 * t370 * t427 + 0.4e1 * t181 * t212 - 0.16e2 * t365 * t23 * t269 * t128 + 0.16e2 * t86 * t138 * self->ZA * t35 * t471 * t59 + 0.8e1 * t305 * t289 - 0.4e1 * t439 * t100 + 0.2e1 * self->ZB * t25 * t2 * self->ZA * t18 * t28 + 0.2e1 * t142 * t4 * t28 * t16 - 0.8e1 * t56 * t100;
+ t499 = self->ZA * t53 * t19;
+ t505 = t396 * 0.3141592654e1;
+ t518 = t173 * t53 * t16 * t29;
+ t533 = t23 * t28;
+ t535 = t188 * t45;
+ t538 = t24 * t4;
+ t545 = t3 * t177;
+ t546 = t173 * t76;
+ t555 = t45 * t110;
+ t557 = t72 * t160;
+ t561 = -0.8e1 * t225 * t61 - 0.2e1 * t161 * t162 * t82 + t533 * t234 + 0.4e1 * t535 * t191 + 0.4e1 * t167 * t538 * t332 + 0.4e1 * t349 * t96 * t60 + 0.2e1 * t545 * t546 - 0.2e1 * t264 * t170 + 0.4e1 * t397 * t281 * self->ZA * t58 - t555 * t96 - 0.4e1 * t557 * t48 * t76;
+ t567 = t396 * 0.3141592654e1 * t45;
+ t568 = t58 * t246;
+ t597 = t58 * n;
+ t615 = t13 * t45;
+ t616 = t615 * t233;
+ t619 = t94 * t45;
+ t621 = t45 * t59;
+ t625 = 0.2e1 * t149 * t216 + 0.2e1 * t567 * t568 - 0.16e2 * t269 * self->xc * t324 - 0.2e1 * t236 * self->xc * t281 * t58 - 0.2e1 * t142 * t177 * t90 - 0.8e1 * t567 * t100 + 0.2e1 * t65 * t546 - 0.8e1 * t305 * t206 + 0.2e1 * n * t45 * t281 * t57 * t24 - t23 * t110 * t96 - 0.8e1 * t296 * t100 + 0.2e1 * t23 * t281 * t597 + 0.4e1 * t545 * t20 + 0.2e1 * t159 * t2 * t4 * self->ZB * t163 - 0.4e1 * t557 * t48 * t90 + 0.4e1 * t122 * t518 + 0.8e1 * t263 * t538 * t332 - 0.4e1 * t505 * t616 - t619 * t96 - 0.2e1 * t621 * t57 * t276;
+ t626 = t49 * t45;
+ t660 = t29 * t45;
+ t685 = 0.2e1 * t545 * t174 - 0.4e1 * t126 * 0.3141592654e1 * t24 * self->xc - 0.4e1 * t47 * t48 * t188 + 0.4e1 * t505 * t660 * t24 - 0.2e1 * t142 * t177 * t163 - 0.2e1 * t142 * t4 * t13 * t18 + 0.8e1 * t260 * t128 * t60 - 0.2e1 * t328 * t546 - 0.2e1 * t26 * t2 * t28 * t16 + 0.4e1 * t545 * t217 - 0.4e1 * t209 * t138 * t256;
+ t690 = t6 * 0.3141592654e1;
+ t691 = self->ZA * t690;
+ t693 = t24 * t24;
+ t694 = t693 * self->xc;
+ t695 = t188 * t694;
+ t698 = t23 * self->ZA;
+ t699 = t698 * t690;
+ t700 = t699 * t5;
+ t704 = t5 * t4;
+ t705 = t691 * t704;
+ t709 = t691 * t5;
+ t713 = t5 * n;
+ t714 = t713 * self->ZB;
+ t718 = t698 * t6;
+ t719 = t713 * t28;
+ t722 = t699 * t704;
+ t726 = t713 * t94;
+ t733 = t713 * t45;
+ t736 = t87 * t36;
+ t740 = -0.4e1 * t691 * t98 * t695 + 0.8e1 * t700 * t270 * t13 + 0.4e1 * t705 * t660 * self->xc + 0.8e1 * t709 * t660 * t128 + 0.2e1 * t87 * t714 * t110 + t718 * t719 * t110 - 0.4e1 * t722 * t237 * t13 - t313 * t726 * t45 - 0.4e1 * t699 * t704 * self->xc * t29 + t313 * t733 * t28 + 0.4e1 * t736 * t150 * t233;
+ t746 = t313 * t36;
+ t752 = t6 * t6;
+ t753 = t23 * t752;
+ t759 = t698 * t752;
+ t760 = t759 * t36;
+ t761 = t17 * t693;
+ t762 = self->xc * t28;
+ t763 = t761 * t762;
+ t766 = t87 * t713;
+ t773 = t699 * t4;
+ t774 = t110 * t693;
+ t775 = self->xc * t13;
+ t785 = t704 * t17;
+ t789 = -0.16e2 * t736 * t150 * t270 + t718 * t116 * t693 - 0.2e1 * t746 * t555 * t24 + 0.4e1 * t705 * t535 + 0.64e2 * t753 * t713 * t17 * t150 * t128 - 0.16e2 * t760 * t763 + 0.2e1 * t766 * t150 * t110 + 0.4e1 * t722 * t274 * self->xc + 0.4e1 * t773 * t774 * t775 - 0.8e1 * t766 * t150 * t17 + 0.8e1 * t700 * t233 * t775 + 0.4e1 * t699 * t785 * t13;
+ t791 = t691 * t4;
+ t792 = t45 * t693;
+ t793 = t49 * t792;
+ t796 = t759 * t713;
+ t797 = t53 * t28;
+ t798 = t270 * t797;
+ t801 = t87 * n;
+ t818 = t5 * t36;
+ t819 = t753 * t818;
+ t827 = t753 * t36 * self->ZB;
+ t830 = self->xc * t45;
+ t834 = -0.4e1 * t791 * t793 + 0.32e2 * t796 * t798 + 0.2e1 * t801 * self->ZB * t693 * t110 + 0.2e1 * t718 * t36 * t28 * t24 - 0.8e1 * t700 * t128 * t29 - 0.8e1 * t700 * t239 - 0.8e1 * t801 * t150 * t761 + 0.32e2 * t819 * t365 * t369 - 0.64e2 * t753 * t714 * t798 + 0.32e2 * t827 * t763 + 0.4e1 * t705 * t830 * t49;
+ t842 = self->xc * t29;
+ t843 = t270 * t842;
+ t849 = t759 * t818;
+ t853 = t691 * t396;
+ t857 = t691 * t5 * t45;
+ t869 = t313 * n;
+ t874 = -0.2e1 * t718 * t36 * t94 * t24 - 0.4e1 * t773 * t761 * t29 + 0.8e1 * t700 * t843 + 0.2e1 * t87 * t726 * self->ZB + 0.16e2 * t849 * t797 * t17 + 0.4e1 * t853 * t793 + 0.8e1 * t857 * t239 + 0.2e1 * t801 * t150 * t693 - 0.8e1 * t700 * t270 * t29 - 0.8e1 * t709 * t49 * t46 - t869 * t619 * t693 + t869 * t232 * t693;
+ t877 = self->ZA * t752;
+ t878 = t877 * t818;
+ t911 = 0.16e2 * t878 * t53 * t45 * t365 - 0.4e1 * t699 * t785 * t29 - 0.4e1 * t705 * t188 * t830 + 0.2e1 * t801 * t94 * t693 * self->ZB - 0.8e1 * t857 * t843 - t718 * t726 + 0.4e1 * t773 * t761 * t13 - 0.4e1 * t705 * t775 * t555 + 0.2e1 * t746 * t232 * t233 - 0.16e2 * t878 * t830 * t365 - 0.2e1 * t746 * t619 * t24;
+ t916 = t110 * t28;
+ t945 = t28 * t693 * t45 * t17;
+ t948 = 0.32e2 * t877 * t733 * t798 + 0.2e1 * t718 * t36 * t916 * t24 - 0.4e1 * t705 * t626 + t718 * n * t916 * t693 - t869 * t792 * t110 - 0.4e1 * t773 * t761 * t775 + t718 * t719 + 0.2e1 * t746 * t232 * t24 - 0.16e2 * t849 * t365 * self->xc - t718 * t713 * t110 - 0.4e1 * t773 * t694 * t29 + 0.16e2 * t877 * t54 * t945;
+ t974 = t761 * t797;
+ t987 = 0.4e1 * t773 * t695 + 0.4e1 * t736 * t150 * t24 + 0.4e1 * t722 * t842 * t17 - 0.16e2 * t877 * t447 * t945 + 0.2e1 * t87 * t714 * t28 + t313 * t713 * t916 * t45 - 0.4e1 * t853 * t615 * t774 - 0.32e2 * t877 * t713 * self->xc * t324 + 0.16e2 * t760 * t974 + 0.4e1 * t736 * t94 * t24 * self->ZB + t869 * t792 * t916 - 0.8e1 * t691 * t5 * self->xc * t616;
+ t1021 = -t718 * t169 * t693 - 0.32e2 * t827 * t974 + 0.2e1 * t801 * t150 * t774 + 0.4e1 * t791 * t188 * t792 + 0.4e1 * t736 * t220 * t24 + 0.4e1 * t791 * t842 * t792 + 0.8e1 * t709 * t660 * t270 - t718 * t335 * t693 - 0.2e1 * t718 * t36 * t110 * t24 - 0.32e2 * t819 * t797 * t471 - t313 * t733 * t110 - 0.32e2 * t796 * t270 * t762;
+
+ self->C2A = (t147 - 0.4e1 * t65 * t217 + t418 + 0.2e1 * t150 * t222 + t327 - 0.2e1 * t149 * t19 + 0.2e1 * t335 * self->ZB * t24 * self->ZA - 0.16e2 * t312 * t313 * t355 * t59 - 0.4e1 * t281 * self->ZB * self->ZA * t597 - 0.2e1 * t505 * t45 * t281 * t58 - 0.4e1 * t211 * t2 * t53 * t76 + 0.8e1 * t305 * t286 - 0.4e1 * t122 * t499 - 0.4e1 * t331 * t332 + 0.8e1 * t345 * t177 * t60 - 0.2e1 * t142 * t177 * t82 + 0.2e1 * t72 * t281 * t415 + 0.4e1 * t349 * t96 * t41 - 0.2e1 * t81 * t64 * t76 + 0.2e1 * t58 * t80 * t59 + 0.8e1 * t345 * t177 * t41 - 0.4e1 * t8 * t499 + t242 + 0.4e1 * t8 * t518 + t625 + t685 + 0.2e1 * t328 * t174 + 0.2e1 * t331 * t455 - 0.2e1 * t33 * t2 * t4 * self->ZA * t82 - 0.4e1 * t626 * t191 + 0.16e2 * t364 * t373 - 0.2e1 * t621 * t597 - 0.2e1 * t439 * t568 + t492 + t533 * t96 + t232 * t96 + 0.2e1 * t567 * t441 + t561) / (t740 + t789 + t834 + t874 + t911 + t948 + t987 + t1021);
+ /****************************************************************************************/
+ t1 = n * n;
+ t2 = t1 * n;
+ t3 = t2 * 0.3141592654e1;
+ t4 = t3 * self->xc;
+ t5 = self->ZB * self->ZB;
+ t7 = exp(n * 0.3141592654e1);
+ t8 = t7 * t7;
+ t9 = t5 * t8;
+ t12 = exp( self->xc * n * 0.3141592654e1);
+ t13 = t12 * t12;
+ t14 = t13 * t13;
+ t15 = t14 * t13;
+ t19 = nx * nx;
+ t21 = nx * 0.3141592654e1;
+ t22 = sin(t21);
+ t23 = t19 * nx * t22;
+ t24 = t23 * 0.3141592654e1;
+ t25 = self->ZA * self->ZB;
+ t26 = t7 * t15;
+ t27 = t25 * t26;
+ t30 = t21 * self->xc;
+ t31 = sin(t30);
+ t32 = t31 * nx;
+ t33 = t32 * n;
+ t34 = self->ZA * self->ZA;
+ t35 = t8 * t8;
+ t36 = t34 * t35;
+ t40 = t2 * t34;
+ t41 = 0.3141592654e1 * t8;
+ t42 = t41 * t15;
+ t45 = t1 * t5;
+ t46 = t14 * t14;
+ t49 = t19 * t5;
+ t51 = t19 * t46;
+ t53 = t19 * t34;
+ t55 = t8 * t7;
+ t56 = t13 * t55;
+ t57 = t25 * t56;
+ t60 = t2 * nx;
+ t61 = 0.3141592654e1 * 0.3141592654e1;
+ t63 = t60 * t31 * t61;
+ t64 = self->xc * self->xc;
+ t65 = self->ZA * t64;
+ t66 = self->ZB * t8;
+ t67 = t14 * t12;
+ t68 = t66 * t67;
+ t69 = t65 * t68;
+ t72 = -0.4e1 * t4 * t9 * t15 + 0.4e1 * t24 * t27 + 0.4e1 * t33 * t36 * t12 - 0.4e1 * t40 * t42 - t45 * t46 + t45 * t14 - t49 * t14 + t51 * t5 - t53 * t14 + 0.4e1 * t24 * t57 + 0.32e2 * t63 * t69;
+ t73 = t1 * nx;
+ t75 = t73 * t31 * 0.3141592654e1;
+ t76 = t8 * t67;
+ t77 = t25 * t76;
+ t80 = t1 * t1;
+ t81 = t80 * t34;
+ t83 = t61 * t14;
+ t87 = t1 * t19;
+ t88 = cos(t30);
+ t90 = t87 * t88 * t61;
+ t91 = t5 * t64;
+ t92 = t13 * t12;
+ t93 = t8 * t92;
+ t94 = t91 * t93;
+ t100 = self->ZB * t64 * self->ZA * t8 * t92;
+ t103 = n * t19;
+ t105 = t103 * t88 * 0.3141592654e1;
+ t106 = self->ZA * self->xc;
+ t107 = self->ZB * t35;
+ t109 = t106 * t107 * t12;
+ t112 = t34 * self->xc;
+ t113 = t112 * t93;
+ t116 = t35 * t14;
+ t118 = t1 * self->ZA;
+ t119 = self->ZB * t14;
+ t122 = t1 * t46;
+ t125 = t19 * self->ZB;
+ t126 = t35 * self->ZA;
+ t127 = t125 * t126;
+ t129 = t1 * self->ZB;
+ t132 = -0.16e2 * t75 * t77 + 0.16e2 * t81 * t64 * t83 * t8 + 0.16e2 * t90 * t94 - 0.32e2 * t90 * t100 + 0.8e1 * t105 * t109 - 0.8e1 * t75 * t113 + t45 * t116 + 0.2e1 * t118 * t119 + 0.2e1 * t122 * t25 - 0.2e1 * t127 + 0.2e1 * t129 * t126;
+ t134 = t1 * t34;
+ t136 = t34 * t64;
+ t137 = t136 * t76;
+ t141 = t91 * t76;
+ t145 = t103 * t34;
+ t146 = 0.3141592654e1 * self->xc;
+ t147 = t8 * t13;
+ t153 = t14 * self->ZA;
+ t156 = self->xc * t5;
+ t157 = t156 * t93;
+ t160 = t103 * t5;
+ t162 = t146 * t8 * t15;
+ t166 = t34 * t7 * t15;
+ t169 = t134 * t116 - 0.16e2 * t63 * t137 - t49 * t116 - 0.16e2 * t63 * t141 - t53 * t116 + 0.4e1 * t145 * t146 * t147 - 0.2e1 * t51 * t25 - 0.2e1 * t125 * t153 - 0.16e2 * t75 * t157 + 0.4e1 * t160 * t162 - 0.4e1 * t24 * t166;
+ t170 = t106 * t68;
+ t177 = t35 * t92;
+ t178 = t112 * t177;
+ t181 = t156 * t76;
+ t186 = t35 * t12;
+ t187 = t112 * t186;
+ t193 = t5 * 0.3141592654e1;
+ t206 = t34 * t14;
+ t207 = t206 * t7;
+ t210 = -0.32e2 * t63 * t170 + 0.32e2 * t90 * t170 + 0.8e1 * t75 * t109 + 0.4e1 * t105 * t178 - 0.16e2 * t75 * t181 - 0.16e2 * t90 * t113 - 0.4e1 * t75 * t187 + 0.16e2 * t90 * t141 - 0.4e1 * t103 * t15 * t193 * self->xc + 0.16e2 * t73 * t22 * t34 * t146 * t26 + 0.4e1 * t32 * n * t34 * t67 + 0.4e1 * t24 * t207;
+ t217 = t106 * t66 * t92;
+ t226 = t88 * t19 * n;
+ t227 = 0.3141592654e1 * t34;
+ t229 = t227 * self->xc * t67;
+ t232 = t73 * t31;
+ t234 = t146 * t5 * t67;
+ t238 = t61 * self->ZB;
+ t239 = t14 * t8;
+ t240 = t238 * t239;
+ t243 = t136 * t93;
+ t246 = -0.8e1 * t33 * t25 * t186 + 0.32e2 * t90 * t217 - t45 * t35 + t53 * t35 - t134 * t35 - t134 * t46 + t134 * t14 - 0.4e1 * t226 * t229 + 0.4e1 * t232 * t234 + 0.32e2 * t87 * t65 * t240 + 0.16e2 * t63 * t243;
+ t247 = t14 * t92;
+ t249 = t227 * t247 * self->xc;
+ t254 = t73 * t22;
+ t259 = t60 * t22 * t61;
+ t260 = t112 * t26;
+ t264 = t146 * t247 * t5;
+ t268 = self->xc * t14;
+ t274 = t5 * t14;
+ t275 = t274 * t8;
+ t280 = n * nx;
+ t281 = t280 * t22;
+ t282 = t55 * t14;
+ t283 = t25 * t282;
+ t290 = self->ZA * t247 * self->xc * self->ZB;
+ t295 = t22 * nx * t1 * 0.3141592654e1;
+ t298 = -0.4e1 * t232 * t249 + 0.8e1 * t105 * t217 - 0.4e1 * t254 * t227 * t26 - 0.8e1 * t259 * t260 - 0.4e1 * t232 * t264 - 0.16e2 * t81 * t61 * t268 * t8 + 0.16e2 * t80 * t64 * t61 * t275 - 0.4e1 * t232 * t229 + 0.8e1 * t281 * t283 - 0.4e1 * t105 * t187 + 0.8e1 * t75 * t290 + 0.4e1 * t295 * t27;
+ t301 = t61 * t5;
+ t307 = t87 * t34;
+ t312 = t61 * self->xc;
+ t313 = t312 * t239;
+ t317 = t34 * t55 * t14;
+ t329 = self->ZB * t13 * t55;
+ t330 = t65 * t329;
+ t337 = -0.16e2 * t87 * t64 * t301 * t239 - 0.32e2 * t90 * t69 - 0.16e2 * t307 * t64 * t61 * t239 + 0.16e2 * t307 * t313 + 0.4e1 * t24 * t317 + t53 * t46 + t49 * t35 - 0.32e2 * t63 * t100 - 0.4e1 * t280 * t31 * t34 * t247 + 0.8e1 * t259 * t330 - 0.4e1 * t280 * t31 * t247 * t5;
+ t340 = t5 * t35;
+ t344 = t25 * t93;
+ t356 = t41 * t13;
+ t360 = t23 * n * t61;
+ t363 = t25 * t64 * t7 * t15;
+ t366 = t156 * t177;
+ t369 = t14 * t7;
+ t370 = t25 * t369;
+ t373 = t156 * t186;
+ t378 = 0.4e1 * t24 * t283 + 0.4e1 * t33 * t340 * t12 - 0.16e2 * t75 * t344 - 0.4e1 * t280 * t31 * t5 * t67 + 0.8e1 * t33 * t25 * t247 + 0.32e2 * t63 * t217 + 0.4e1 * t40 * t356 - 0.8e1 * t360 * t363 + 0.4e1 * t75 * t366 + 0.4e1 * t295 * t370 - 0.4e1 * t75 * t373 - 0.4e1 * t105 * t366;
+ t382 = t112 * t76;
+ t387 = t80 * t61;
+ t391 = t136 * t26;
+ t409 = 0.16e2 * t63 * t382 + 0.4e1 * t226 * t234 - 0.16e2 * t387 * self->xc * t275 + 0.8e1 * t259 * t391 - 0.16e2 * t105 * t344 + 0.4e1 * t226 * t264 - 0.8e1 * t105 * t170 + 0.16e2 * t232 * t193 * t76 + 0.8e1 * t360 * t330 - 0.8e1 * t105 * t290 + 0.16e2 * t90 * t243;
+ t423 = t153 * t8;
+ t426 = t34 * t13;
+ t427 = t426 * t55;
+ t430 = t34 * t8;
+ t437 = t80 * self->ZA;
+ t441 = 0.4e1 * t145 * t42 - 0.16e2 * t90 * t157 + 0.24e2 * t75 * t217 + 0.4e1 * t226 * t249 + 0.4e1 * t254 * t227 * t282 + 0.4e1 * t160 * t356 - 0.8e1 * t129 * t423 - 0.8e1 * t281 * t427 - 0.8e1 * t33 * t430 * t67 + 0.8e1 * t33 * t430 * t92 + 0.32e2 * t437 * self->ZB * t313;
+ t453 = t106 * self->ZB * t7 * t15;
+ t456 = t2 * t5;
+ t459 = t112 * t56;
+ t462 = t126 * t14;
+ t474 = t40 * 0.3141592654e1;
+ t475 = self->xc * t8;
+ t480 = t146 * t13 * t35;
+ t483 = -0.4e1 * t103 * self->xc * t193 * t147 + 0.16e2 * t87 * t61 * t156 * t239 + 0.8e1 * t259 * t453 - 0.4e1 * t456 * t356 + 0.8e1 * t259 * t459 - 0.2e1 * t125 * t462 - 0.8e1 * t281 * t207 + 0.16e2 * t295 * t459 - 0.8e1 * t60 * t22 * self->ZA * t312 * t329 + 0.4e1 * t474 * t475 * t15 + 0.4e1 * t160 * t480;
+ t497 = t136 * t56;
+ t504 = t9 * t13;
+ t509 = t475 * t13;
+ t512 = -0.8e1 * t105 * t113 - 0.4e1 * t254 * t227 * t56 + 0.8e1 * t281 * t57 + 0.4e1 * t295 * t283 + 0.2e1 * t129 * t462 + 0.4e1 * t24 * t370 - 0.8e1 * t360 * t497 - 0.4e1 * t24 * t427 - 0.4e1 * t145 * t162 + 0.4e1 * t4 * t504 - 0.8e1 * t281 * t370 - 0.4e1 * t474 * t509;
+ t528 = t5 * t13;
+ t529 = t528 * t35;
+ t532 = t106 * t329;
+ t542 = -0.16e2 * t295 * t453 - 0.32e2 * t437 * t64 * t240 + 0.8e1 * t281 * t317 + 0.24e2 * t75 * t170 - 0.4e1 * t75 * t178 + 0.8e1 * t360 * t453 - 0.4e1 * t4 * t529 - 0.16e2 * t295 * t532 - 0.8e1 * t33 * t344 - 0.16e2 * t90 * t181 + 0.4e1 * t33 * t340 * t92;
+ t557 = t146 * t15;
+ t562 = self->xc * t15;
+ t563 = t562 * t5;
+ t573 = 0.16e2 * t232 * t193 * t93 - 0.8e1 * t259 * t363 - 0.8e1 * t259 * t497 + 0.8e1 * t33 * t77 + 0.8e1 * t360 * t391 + 0.4e1 * t254 * t227 * t369 + 0.4e1 * t145 * t557 + 0.8e1 * t281 * t166 + 0.4e1 * t3 * t563 + 0.8e1 * t105 * t382 - 0.4e1 * t145 * t480 - 0.4e1 * t33 * t36 * t92;
+ t600 = 0.4e1 * t456 * t42 - 0.8e1 * t360 * t260 - 0.4e1 * t40 * t557 - 0.4e1 * t105 * t373 + 0.16e2 * t226 * t227 * t93 - 0.16e2 * t90 * t382 - 0.4e1 * t145 * t356 - 0.16e2 * t63 * t157 - 0.32e2 * t87 * t25 * t313 - 0.16e2 * t226 * t227 * t76 - 0.16e2 * t63 * t113;
+ t623 = self->xc * t13;
+ t627 = 0.8e1 * t125 * t423 - 0.8e1 * t360 * t532 + 0.16e2 * t90 * t137 - 0.4e1 * t160 * t42 + 0.16e2 * t63 * t94 + 0.16e2 * t63 * t181 - 0.8e1 * t281 * t27 - 0.8e1 * t75 * t382 + 0.8e1 * t360 * t459 + 0.4e1 * t295 * t57 + 0.16e2 * t105 * t77 + 0.4e1 * t474 * t623 * t35;
+ t632 = t61 * 0.3141592654e1;
+ t633 = t632 * t8;
+ t634 = t80 * n;
+ t638 = t632 * t634;
+ t639 = t638 * self->xc;
+ t642 = t61 * t34;
+ t643 = t122 * t19;
+ t649 = t61 * t61;
+ t650 = t649 * t1;
+ t652 = t19 * t19;
+ t653 = t14 * t652;
+ t654 = t653 * t9;
+ t657 = t14 * t1;
+ t658 = t657 * t19;
+ t665 = t632 * t34;
+ t666 = t665 * t2;
+ t667 = t8 * t19;
+ t668 = t667 * t623;
+ t674 = t665 * n;
+ t675 = t652 * self->xc;
+ t682 = 0.8e1 * t633 * t426 * t634 - 0.8e1 * t639 * t529 - 0.4e1 * t642 * t643 + 0.2e1 * t642 * t116 * t80 + 0.32e2 * t650 * t64 * t654 + 0.4e1 * t301 * t658 + 0.4e1 * t387 * t46 * self->ZA * self->ZB - 0.16e2 * t666 * t668 - 0.16e2 * t666 * t667 * t15 - 0.8e1 * t674 * t675 * t15 + 0.4e1 * t238 * t153 * t80;
+ t683 = t46 * t652;
+ t686 = t633 * t15;
+ t691 = t35 * t80;
+ t698 = t35 * t652;
+ t705 = t14 * t80;
+ t708 = t61 * t35;
+ t717 = -0.2e1 * t642 * t683 - 0.8e1 * t686 * t5 * t634 * self->xc - 0.2e1 * t301 * t691 + 0.8e1 * t638 * t563 - 0.2e1 * t642 * t691 - 0.2e1 * t642 * t698 - 0.2e1 * t301 * t698 - 0.2e1 * t301 * t683 + 0.2e1 * t642 * t705 + 0.2e1 * t708 * t274 * t80 + 0.2e1 * t301 * t653 - 0.2e1 * t642 * t80 * t46;
+ t727 = t61 * t46;
+ t737 = t649 * t34;
+ t738 = t737 * t1;
+ t739 = t8 * t652;
+ t740 = t739 * t268;
+ t746 = t61 * self->ZA;
+ t754 = t632 * n * self->xc;
+ t758 = 0.2e1 * t301 * t705 + 0.2e1 * t642 * t653 - 0.8e1 * t665 * self->xc * t634 * t15 - 0.2e1 * t727 * t5 * t80 - 0.32e2 * t650 * self->xc * t654 + 0.2e1 * t301 * t698 * t14 - 0.32e2 * t738 * t740 + 0.8e1 * t674 * t739 * t562 + 0.4e1 * t746 * t119 * t652 + 0.8e1 * t674 * t698 * t623 - 0.8e1 * t754 * t528 * t698;
+ t762 = t633 * t13;
+ t764 = t5 * n * t652;
+ t767 = t80 * t1;
+ t768 = t649 * t767;
+ t772 = t649 * self->ZA;
+ t773 = t772 * t129;
+ t777 = t35 * t1 * t19;
+ t780 = t632 * t5;
+ t781 = t780 * t15;
+ t786 = t698 * self->ZA;
+ t790 = t64 * t14;
+ t800 = t649 * t8;
+ t809 = 0.4e1 * t238 * t126 * t80 - 0.8e1 * t762 * t764 - 0.32e2 * t768 * self->xc * t275 + 0.64e2 * t773 * t740 - 0.4e1 * t301 * t777 - 0.8e1 * t781 * n * t8 * t675 + 0.4e1 * t238 * t786 + 0.32e2 * t768 * t34 * t790 * t8 - 0.8e1 * t633 * t528 * t634 + 0.8e1 * t754 * t528 * t739 + 0.128e3 * t800 * t119 * t80 * t19 * t106 + 0.8e1 * t674 * t739 * t13;
+ t812 = t649 * t80;
+ t817 = t83 * self->ZB;
+ t824 = t746 * self->ZB;
+ t828 = t800 * t14;
+ t855 = -0.64e2 * t812 * self->xc * t274 * t667 + 0.4e1 * t817 * t786 + 0.4e1 * t727 * self->ZA * t652 * self->ZB - 0.32e2 * t824 * t657 * t667 - 0.32e2 * t828 * t34 * t767 * self->xc - 0.8e1 * t633 * t15 * t34 * t634 - 0.8e1 * t674 * t739 * t15 + 0.32e2 * t768 * t64 * t275 + 0.4e1 * t708 * t14 * t307 + 0.2e1 * t708 * t206 * t652 + 0.8e1 * t632 * t35 * t13 * t34 * t634 * self->xc;
+ t858 = t35 * t19;
+ t873 = t2 * t8;
+ t878 = t61 * t1;
+ t901 = -0.16e2 * t632 * t2 * self->xc * t528 * t858 + 0.8e1 * t824 * t658 + 0.4e1 * t301 * t14 * t777 - 0.8e1 * t665 * t634 * t509 - 0.8e1 * t674 * t739 * t623 - 0.16e2 * t781 * t873 * t19 * self->xc + 0.8e1 * t878 * t14 * t127 + 0.8e1 * t878 * self->ZA * t51 * self->ZB + 0.8e1 * t686 * t764 + 0.8e1 * t665 * self->xc * t634 * t15 * t8 + 0.8e1 * t633 * t15 * t5 * t634 + 0.4e1 * t387 * t14 * t107 * self->ZA;
+ t903 = t739 * t790;
+ t923 = t737 * t80;
+ t924 = t667 * t790;
+ t927 = t780 * t2;
+ t937 = t15 * t19 * self->xc;
+ t943 = 0.32e2 * t738 * t903 + 0.16e2 * t781 * t873 * t19 + 0.8e1 * t754 * t15 * t652 * t5 + 0.16e2 * t666 * t858 * t623 + 0.64e2 * t828 * t25 * t767 * self->xc - 0.16e2 * t762 * t456 * t19 + 0.64e2 * t923 * t924 + 0.16e2 * t927 * t668 - 0.64e2 * t768 * self->ZA * t790 * t66 - 0.64e2 * t773 * t903 + 0.16e2 * t927 * t937 + 0.16e2 * t666 * t667 * t562;
+ t977 = 0.64e2 * t812 * t5 * t924 + 0.8e1 * t639 * t504 + 0.8e1 * t238 * t35 * t118 * t19 + 0.4e1 * t642 * t658 - 0.16e2 * t817 * t437 * t8 - 0.128e3 * t772 * self->ZB * t80 * t924 + 0.16e2 * t666 * t667 * t13 - 0.4e1 * t301 * t643 - 0.16e2 * t824 * t653 * t8 - 0.4e1 * t642 * t777 - 0.64e2 * t923 * t667 * t268 - 0.16e2 * t666 * t937;
+
+ self->C3A = (t72 + t132 + t169 + t210 + t246 + t298 + t337 + t378 + t409 + t441 + t483 + t512 + t542 + t573 + t600 + t627) / (t682 + t717 + t758 + t809 + t855 + t901 + t943 + t977);
+ /****************************************************************************************/
+ self->C4A = 0;
+ /****************************************************************************************/
+ t1 = nx * 0.3141592654e1;
+ t2 = t1 * self->xc;
+ t3 = cos(t2);
+ t4 = nx * nx;
+ t6 = n * 0.3141592654e1;
+ t7 = t3 * t4 * t6;
+ t8 = self->ZA * self->ZB;
+ t9 = exp(t6);
+ t10 = t9 * t9;
+ t11 = self->xc * n;
+ t13 = exp(t11 * 0.3141592654e1);
+ t14 = t13 * t13;
+ t15 = t14 * t13;
+ t16 = t14 * t14;
+ t17 = t16 * t15;
+ t18 = t10 * t17;
+ t19 = t8 * t18;
+ t22 = sin(t2);
+ t23 = nx * t22;
+ t24 = t23 * n;
+ t25 = self->ZB * self->ZB;
+ t30 = n * n;
+ t31 = t30 * n;
+ t32 = t31 * nx;
+ t33 = 0.3141592654e1 * 0.3141592654e1;
+ t35 = t32 * t22 * t33;
+ t36 = self->ZA * self->ZA;
+ t37 = t36 * self->xc;
+ t38 = t16 * t13;
+ t39 = t10 * t38;
+ t40 = t37 * t39;
+ t43 = sin(t1);
+ t44 = nx * t43;
+ t45 = t30 * 0.3141592654e1;
+ t46 = t44 * t45;
+ t47 = self->ZA * self->xc;
+ t49 = self->ZB * t16 * t9;
+ t54 = t4 * nx * t43;
+ t55 = self->xc * self->xc;
+ t57 = t54 * t30 * t55;
+ t58 = t33 * 0.3141592654e1;
+ t59 = t58 * t25;
+ t60 = t16 * t9;
+ t61 = t59 * t60;
+ t64 = self->xc * t25;
+ t65 = t14 * t9;
+ t66 = t64 * t65;
+ t70 = t44 * t31 * t33;
+ t71 = t37 * t65;
+ t74 = t10 * t15;
+ t75 = t64 * t74;
+ t78 = t25 * t10;
+ t83 = t54 * n * t33;
+ t84 = t55 * t25;
+ t85 = t10 * t9;
+ t86 = t14 * t85;
+ t87 = t84 * t86;
+ t90 = t30 * t30;
+ t92 = t44 * t90 * t58;
+ t93 = t55 * self->xc;
+ t94 = t93 * t25;
+ t95 = t85 * t16;
+ t96 = t94 * t95;
+ t102 = t23 * t45;
+ t103 = t10 * t10;
+ t104 = self->ZB * t103;
+ t106 = t47 * t104 * t15;
+ t111 = t54 * 0.3141592654e1;
+ t112 = t25 * t85;
+ t113 = t112 * t16;
+ t115 = t8 * t39;
+ t118 = t16 * t14;
+ t119 = t85 * t118;
+ t120 = t37 * t119;
+ t123 = t16 * t16;
+ t124 = t36 * t123;
+ t125 = t124 * t9;
+ t127 = -0.8e1 * t7 * t19 + 0.2e1 * t24 * t25 * t13 * t10 - 0.16e2 * t35 * t40 - 0.16e2 * t46 * t47 * t49 - 0.8e1 * t57 * t61 + 0.4e1 * t46 * t66 + 0.2e1 * t70 * t71 - 0.16e2 * t35 * t75 + 0.6e1 * t24 * t78 * t38 - 0.2e1 * t83 * t87 - 0.8e1 * t92 * t96 - 0.8e1 * t46 * t37 * t95 - 0.12e2 * t102 * t106 + 0.2e1 * t83 * t71 + t111 * t113 + 0.8e1 * t7 * t115 + 0.2e1 * t83 * t120 + t111 * t125;
+ t128 = t37 * t74;
+ t131 = t44 * n;
+ t133 = t25 * t9 * t118;
+ t136 = t36 * t14;
+ t137 = t136 * t9;
+ t140 = t30 * t4;
+ t142 = t140 * t3 * t33;
+ t143 = t64 * t39;
+ t147 = t30 * nx * t43;
+ t148 = 0.3141592654e1 * t36;
+ t149 = t9 * t118;
+ t153 = t44 * t31 * self->ZA;
+ t154 = t33 * self->xc;
+ t155 = t154 * t49;
+ t160 = self->ZA * t17 * self->xc * self->ZB;
+ t163 = t103 * t13;
+ t164 = t64 * t163;
+ t170 = t44 * t90 * t55;
+ t171 = t58 * self->ZB;
+ t172 = self->ZA * t16;
+ t174 = t171 * t172 * t9;
+ t177 = t36 * t55;
+ t178 = t177 * t149;
+ t181 = t54 * t11;
+ t182 = t33 * t25;
+ t186 = t25 * t14;
+ t187 = t186 * t9;
+ t193 = t186 * t85;
+ t198 = self->ZB * t55;
+ t199 = self->ZA * t103;
+ t201 = t198 * t199 * t15;
+ t204 = 0.2e1 * t7 * t128 - 0.2e1 * t131 * t133 - 0.2e1 * t131 * t137 + 0.16e2 * t142 * t143 - t147 * t148 * t149 + 0.8e1 * t153 * t155 - 0.4e1 * t7 * t160 + 0.2e1 * t7 * t164 + 0.10e2 * t102 * t40 + 0.16e2 * t170 * t174 + 0.2e1 * t83 * t178 - 0.2e1 * t181 * t182 * t65 - t111 * t187 - 0.2e1 * t70 * t87 + 0.4e1 * t102 * t160 - 0.2e1 * t131 * t193 - 0.16e2 * t142 * t75 + 0.16e2 * t35 * t201;
+ t210 = t32 * t22;
+ t211 = t33 * t55;
+ t212 = t25 * t38;
+ t213 = t211 * t212;
+ t216 = n * nx;
+ t217 = t22 * t25;
+ t222 = self->ZB * t85 * t16;
+ t226 = t23 * t30;
+ t227 = t13 * t10;
+ t228 = t148 * t227;
+ t233 = t37 * t163;
+ t237 = n * t4 * t3;
+ t238 = t148 * t74;
+ t241 = t64 * t86;
+ t245 = t148 * self->xc * t15;
+ t248 = t112 * t118;
+ t250 = t22 * t36;
+ t256 = 0.3141592654e1 * t25;
+ t257 = t256 * t39;
+ t262 = t38 * t103;
+ t263 = t37 * t262;
+ t267 = t148 * t17 * self->xc;
+ t270 = -0.6e1 * t7 * t143 - 0.4e1 * t24 * t19 - 0.8e1 * t210 * t213 - 0.2e1 * t216 * t217 * t15 - 0.32e2 * t153 * t211 * t222 + 0.4e1 * t226 * t228 + 0.16e2 * t142 * t201 + 0.2e1 * t7 * t233 - 0.4e1 * t237 * t238 - 0.2e1 * t83 * t241 - 0.2e1 * t237 * t245 + t111 * t248 + 0.2e1 * t216 * t250 * t15 - 0.2e1 * t131 * t125 - 0.4e1 * t226 * t257 + t147 * t148 * t95 - 0.2e1 * t102 * t263 + 0.2e1 * t237 * t267;
+ t273 = t37 * t149;
+ t277 = t47 * t104 * t13;
+ t285 = t31 * t36;
+ t286 = t44 * t285;
+ t291 = t25 * t123 * t9;
+ t304 = 0.3141592654e1 * self->xc;
+ t305 = t304 * t212;
+ t312 = t256 * t18;
+ t315 = t8 * t60;
+ t319 = t54 * t30 * t58;
+ t323 = t90 * t36;
+ t324 = t44 * t323;
+ t325 = t55 * t58;
+ t326 = t325 * t60;
+ t329 = 0.2e1 * t102 * t164 + 0.2e1 * t83 * t273 - 0.4e1 * t102 * t277 - 0.2e1 * t7 * t263 + 0.4e1 * t24 * t8 * t17 - 0.4e1 * t286 * t154 * t60 - 0.2e1 * t131 * t291 - t147 * t148 * t119 + 0.2e1 * t24 * t78 * t17 + 0.2e1 * t54 * t85 * 0.3141592654e1 * self->ZA * self->ZB - 0.4e1 * t226 * t305 - 0.2e1 * t70 * t66 + t147 * t256 * t95 + 0.4e1 * t237 * t312 + 0.2e1 * t111 * t315 - 0.8e1 * t319 * t96 - t111 * t193 - 0.8e1 * t324 * t326;
+ t332 = t8 * t95;
+ t335 = t136 * t85;
+ t337 = t256 * t227;
+ t340 = t177 * t119;
+ t346 = t37 * t86;
+ t351 = t103 * t15;
+ t352 = t177 * t351;
+ t355 = t64 * t119;
+ t358 = t8 * t227;
+ t361 = t85 * 0.3141592654e1;
+ t365 = t84 * t39;
+ t372 = self->ZB * t10;
+ t373 = t372 * t38;
+ t374 = t47 * t373;
+ t379 = t177 * t39;
+ t384 = -0.2e1 * t46 * t332 + t111 * t335 + 0.4e1 * t237 * t337 - 0.2e1 * t83 * t340 + 0.16e2 * t286 * t211 * t95 + 0.2e1 * t70 * t346 - 0.8e1 * t170 * t61 - 0.8e1 * t142 * t352 - 0.2e1 * t83 * t355 - 0.4e1 * t24 * t358 + 0.2e1 * t147 * t361 * t8 + 0.8e1 * t35 * t365 - 0.2e1 * t226 * t267 + 0.8e1 * t102 * t115 - 0.12e2 * t102 * t374 + 0.16e2 * t142 * t40 - 0.8e1 * t142 * t379 + 0.4e1 * t237 * t228;
+ t386 = t54 * t30 * t93;
+ t387 = self->ZA * t85;
+ t389 = t171 * t387 * t16;
+ t394 = t64 * t60;
+ t398 = t304 * t25 * t15;
+ t401 = t361 * t25;
+ t405 = t84 * t65;
+ t410 = t148 * t18;
+ t414 = t25 * t16 * t9;
+ t417 = t84 * t74;
+ t422 = t177 * t86;
+ t428 = self->ZB * t38;
+ t429 = t47 * t428;
+ t432 = t148 * t39;
+ t439 = 0.16e2 * t386 * t389 - 0.16e2 * t386 * t174 + 0.8e1 * t46 * t394 + 0.2e1 * t237 * t398 - t147 * t401 + 0.4e1 * t7 * t374 + 0.2e1 * t83 * t405 - 0.4e1 * t46 * t241 - 0.4e1 * t226 * t410 + 0.2e1 * t131 * t414 + 0.8e1 * t35 * t417 - 0.8e1 * t142 * t365 + 0.2e1 * t70 * t422 - 0.4e1 * t181 * t182 * t60 + 0.12e2 * t102 * t429 - 0.4e1 * t226 * t432 + 0.32e2 * t35 * t374 - 0.4e1 * t7 * t106;
+ t442 = t36 * t9 * t118;
+ t444 = t123 * t9;
+ t445 = t8 * t444;
+ t448 = t361 * t36;
+ t451 = t47 * t372 * t17;
+ t454 = t94 * t60;
+ t457 = t25 * t103;
+ t465 = t47 * t372 * t15;
+ t468 = t36 * t85;
+ t469 = t468 * t16;
+ t474 = t43 * t85;
+ t478 = t8 * t74;
+ t484 = t256 * t74;
+ t489 = t198 * self->ZA * t10 * t15;
+ t501 = -t111 * t442 + 0.4e1 * t131 * t445 - t147 * t448 + 0.4e1 * t7 * t451 + 0.8e1 * t92 * t454 - 0.2e1 * t24 * t457 * t13 - 0.2e1 * t286 * t211 * t65 + 0.4e1 * t7 * t465 + t111 * t469 - 0.2e1 * t216 * t250 * t17 - 0.2e1 * t216 * t474 * t25 - 0.4e1 * t24 * t478 + 0.4e1 * t24 * t8 * t38 + 0.4e1 * t226 * t484 - 0.16e2 * t142 * t489 - 0.2e1 * t24 * t212 * t103 - 0.2e1 * t216 * t22 * t17 * t25 + 0.2e1 * t70 * t120;
+ t504 = t33 * t36 * t55 * t38;
+ t507 = t37 * t18;
+ t512 = t47 * self->ZB * t13 * t10;
+ t518 = t59 * t95;
+ t530 = t84 * t351;
+ t534 = t37 * t227;
+ t549 = -0.8e1 * t210 * t504 + 0.2e1 * t102 * t507 + 0.4e1 * t7 * t512 + t111 * t133 - 0.16e2 * t35 * t489 + 0.8e1 * t170 * t518 + 0.2e1 * t24 * t36 * t13 * t10 + 0.4e1 * t131 * t387 * self->ZB + 0.12e2 * t102 * t465 - 0.8e1 * t142 * t530 + t111 * t291 - 0.2e1 * t102 * t534 - 0.4e1 * t70 * t394 - 0.10e2 * t102 * t128 + 0.4e1 * t237 * t305 + 0.8e1 * t102 * t19 + 0.2e1 * t83 * t346 - 0.16e2 * t35 * t128;
+ t557 = t468 * t118;
+ t562 = t93 * t58;
+ t563 = t562 * t60;
+ t567 = t44 * t90 * t93;
+ t575 = self->ZA * t55;
+ t576 = t575 * t428;
+ t583 = t37 * t60;
+ t590 = t140 * t3;
+ t601 = -0.2e1 * t226 * t398 - 0.2e1 * t70 * t340 - 0.2e1 * t131 * t557 - 0.4e1 * t24 * t115 + 0.8e1 * t324 * t563 + 0.16e2 * t567 * t389 + 0.16e2 * t70 * t84 * t95 + 0.2e1 * t70 * t178 - 0.16e2 * t142 * t576 - 0.4e1 * t237 * t257 - 0.4e1 * t226 * t312 + 0.8e1 * t46 * t583 + 0.2e1 * t24 * t36 * t38 * t103 + 0.8e1 * t590 * t213 + 0.2e1 * t102 * t143 - 0.16e2 * t35 * t143 + 0.2e1 * t131 * t248 + 0.4e1 * t46 * t346;
+ t604 = n * t36;
+ t606 = t154 * t95;
+ t625 = t36 * t103;
+ t640 = t30 * t36;
+ t641 = t54 * t640;
+ t642 = t325 * t95;
+ t647 = -0.4e1 * t131 * t315 - 0.4e1 * t54 * t604 * t606 - t147 * t148 * t60 + 0.16e2 * t35 * t576 - 0.8e1 * t102 * t478 + 0.32e2 * t142 * t465 - 0.4e1 * t237 * t484 - 0.2e1 * t70 * t355 + 0.2e1 * t70 * t273 + 0.2e1 * t102 * t233 - 0.2e1 * t24 * t625 * t13 - 0.8e1 * t7 * t358 - 0.2e1 * t111 * t445 - 0.4e1 * t7 * t429 + 0.16e2 * t46 * t47 * t222 + 0.2e1 * t131 * t113 + 0.8e1 * t641 * t642 - 0.2e1 * t7 * t534;
+ t652 = t36 * t16;
+ t653 = t652 * t9;
+ t655 = t64 * t227;
+ t658 = t182 * t95;
+ t663 = t562 * t95;
+ t684 = t64 * t351;
+ t689 = t36 * t10;
+ t695 = t154 * t222;
+ t698 = -0.4e1 * t216 * t217 * t38 - t111 * t653 - 0.2e1 * t7 * t655 - 0.4e1 * t181 * t658 + 0.2e1 * t131 * t469 - 0.8e1 * t641 * t663 - 0.4e1 * t83 * t583 - 0.2e1 * t83 * t177 * t65 - 0.4e1 * t24 * t457 * t15 + 0.16e2 * t70 * t84 * t60 + 0.8e1 * t57 * t518 - 0.32e2 * t142 * t374 + 0.4e1 * t24 * t8 * t351 + 0.4e1 * t102 * t684 - t147 * t256 * t86 - 0.2e1 * t24 * t689 * t15 - 0.2e1 * t70 * t241 + 0.8e1 * t153 * t695;
+ t711 = t575 * t373;
+ t717 = t304 * t17 * t25;
+ t736 = t177 * t74;
+ t739 = 0.2e1 * t226 * t245 - 0.8e1 * t102 * t358 - 0.16e2 * t57 * t389 - 0.2e1 * t102 * t655 + 0.8e1 * t590 * t504 - 0.8e1 * t641 * t326 - 0.16e2 * t35 * t711 - t111 * t557 + t111 * t137 - 0.2e1 * t226 * t717 + 0.8e1 * t102 * t37 * t351 + 0.2e1 * t131 * t335 - 0.4e1 * t131 * t332 - 0.2e1 * t216 * t474 * t36 - 0.2e1 * t111 * t332 + 0.16e2 * t142 * t711 - t147 * t256 * t60 + 0.8e1 * t142 * t736;
+ t750 = t64 * t262;
+ t763 = t44 * t640;
+ t770 = t84 * t119;
+ t782 = 0.4e1 * t102 * t512 + 0.8e1 * t142 * t417 + 0.8e1 * t641 * t563 - 0.2e1 * t7 * t507 + 0.2e1 * t7 * t750 - 0.8e1 * t35 * t352 + 0.4e1 * t237 * t410 + 0.4e1 * t7 * t684 - 0.2e1 * t46 * t445 + t147 * t148 * t65 + 0.4e1 * t763 * t304 * t119 + 0.16e2 * t70 * t177 * t60 + 0.2e1 * t70 * t770 - t111 * t414 - 0.16e2 * t567 * t174 - 0.4e1 * t46 * t71 - 0.4e1 * t46 * t355 - 0.4e1 * t7 * t277;
+ t797 = t64 * t149;
+ t821 = -t54 * t448 + 0.2e1 * t131 * t442 + 0.8e1 * t7 * t478 + 0.8e1 * t35 * t379 - 0.2e1 * t181 * t182 * t149 + 0.2e1 * t70 * t405 + 0.2e1 * t83 * t770 - 0.2e1 * t70 * t797 - 0.6e1 * t7 * t75 - 0.4e1 * t286 * t606 - 0.4e1 * t237 * t432 + t147 * t256 * t149 - 0.4e1 * t763 * t304 * t149 - 0.2e1 * t102 * t75 + 0.2e1 * t237 * t717 + 0.8e1 * t324 * t642 - 0.16e2 * t170 * t389 + 0.2e1 * t83 * t422;
+ t827 = t84 * t149;
+ t846 = t54 * n * self->ZA;
+ t854 = t64 * t18;
+ t867 = -0.16e2 * t142 * t128 + 0.32e2 * t35 * t465 - 0.2e1 * t83 * t827 + 0.2e1 * t46 * t315 + t147 * t148 * t86 - 0.4e1 * t102 * t451 - 0.8e1 * t226 * t148 * self->xc * t38 - 0.2e1 * t24 * t689 * t38 + 0.2e1 * t131 * t187 + 0.8e1 * t846 * t155 + 0.8e1 * t35 * t736 + 0.2e1 * t24 * t689 * t17 - 0.2e1 * t7 * t854 + t147 * t256 * t119 + 0.2e1 * t102 * t854 - 0.8e1 * t35 * t530 + 0.4e1 * t46 * t797 + 0.2e1 * t102 * t750;
+ t909 = -0.8e1 * t324 * t663 + t147 * t256 * t444 - t147 * t256 * t65 + 0.4e1 * t226 * t238 + 0.2e1 * t7 * t40 - t54 * t401 + 0.16e2 * t57 * t174 + 0.4e1 * t226 * t337 + 0.4e1 * t24 * t8 * t163 + 0.8e1 * t846 * t695 + 0.8e1 * t319 * t454 + 0.2e1 * t131 * t653 - 0.8e1 * t46 * t64 * t95 + 0.6e1 * t24 * t78 * t15 - 0.4e1 * t44 * t31 * self->xc * t658 - 0.32e2 * t153 * t211 * t49 - 0.2e1 * t70 * t827 + t147 * t148 * t444;
+ t914 = t25 * self->ZB;
+ t915 = t33 * t914;
+ t919 = t4 * t4;
+ t920 = t16 * t919;
+ t929 = t123 * t90;
+ t932 = t919 * t103;
+ t935 = t33 * self->ZB;
+ t939 = t652 * t919;
+ t942 = t16 * t30;
+ t943 = t942 * t4;
+ t949 = t103 * t16;
+ t950 = t949 * t90;
+ t953 = -0.2e1 * t915 * t103 * t90 + 0.2e1 * t915 * t920 - 0.2e1 * t915 * t123 * t919 + 0.2e1 * t915 * t16 * t90 - 0.2e1 * t915 * t929 - 0.2e1 * t915 * t932 - 0.2e1 * t935 * t323 * t123 + 0.2e1 * t935 * t939 + 0.4e1 * t915 * t943 + 0.4e1 * t182 * t172 * t90 + 0.2e1 * t915 * t950;
+ t954 = t171 * t36;
+ t955 = t90 * n;
+ t956 = self->xc * t955;
+ t957 = t118 * t10;
+ t964 = t33 * t33;
+ t965 = t964 * self->ZB;
+ t966 = t965 * t640;
+ t967 = t10 * t919;
+ t968 = t55 * t16;
+ t969 = t967 * t968;
+ t972 = t935 * t36;
+ t974 = t103 * t30 * t4;
+ t977 = self->xc * t16;
+ t978 = t967 * t977;
+ t981 = t90 * t30;
+ t983 = t16 * t10;
+ t987 = t182 * self->ZA;
+ t988 = t4 * t10;
+ t992 = t171 * t604;
+ t993 = self->xc * t14;
+ t994 = t932 * t993;
+ t997 = t182 * t30;
+ t1005 = t171 * t285;
+ t1006 = t988 * t993;
+ t1009 = t58 * t914;
+ t1010 = t1009 * t31;
+ t1013 = 0.8e1 * t954 * t956 * t957 + 0.2e1 * t915 * t932 * t16 + 0.32e2 * t966 * t969 - 0.4e1 * t972 * t974 - 0.32e2 * t966 * t978 + 0.32e2 * t965 * t981 * t177 * t983 - 0.32e2 * t987 * t942 * t988 + 0.8e1 * t992 * t994 + 0.8e1 * t997 * t949 * self->ZA * t4 - 0.2e1 * t935 * t124 * t919 - 0.16e2 * t1005 * t1006 + 0.16e2 * t1010 * t1006;
+ t1015 = t964 * t25;
+ t1016 = self->ZA * t30;
+ t1017 = t1015 * t1016;
+ t1020 = t967 * t993;
+ t1031 = t1009 * t118;
+ t1032 = t31 * t10;
+ t1040 = t964 * t914;
+ t1041 = t1040 * t90;
+ t1044 = t55 * t10 * t4 * t16;
+ t1047 = t1040 * t30;
+ t1050 = t123 * self->ZA;
+ t1054 = t977 * t988;
+ t1057 = 0.64e2 * t1017 * t978 - 0.8e1 * t992 * t1020 + 0.2e1 * t972 * t950 + 0.4e1 * t182 * t929 * self->ZA + 0.4e1 * t182 * t199 * t90 - 0.16e2 * t1031 * t1032 * t4 * self->xc + 0.4e1 * t182 * t172 * t919 + 0.64e2 * t1041 * t1044 + 0.32e2 * t1047 * t969 + 0.4e1 * t182 * t1050 * t919 - 0.64e2 * t1041 * t1054;
+ t1058 = t1009 * n;
+ t1063 = t932 * self->ZA;
+ t1069 = t123 * t30 * t4;
+ t1080 = t993 * t103 * t4;
+ t1088 = t935 * t103;
+ t1094 = -0.8e1 * t1058 * t994 - 0.32e2 * t1047 * t978 + 0.4e1 * t182 * t1063 - 0.4e1 * t915 * t974 - 0.4e1 * t915 * t1069 - 0.2e1 * t935 * t625 * t90 - 0.8e1 * t1009 * t10 * t14 * t955 - 0.16e2 * t1010 * t1080 - 0.2e1 * t935 * t625 * t919 - 0.64e2 * t1017 * t969 + 0.2e1 * t1088 * t939 + 0.8e1 * t1009 * t957 * t955;
+ t1113 = t955 * t118 * self->xc;
+ t1120 = t4 * t118;
+ t1125 = t981 * self->xc;
+ t1133 = n * t10;
+ t1140 = -0.8e1 * t954 * t955 * t10 * t993 + 0.2e1 * t935 * t652 * t90 - 0.64e2 * t1015 * t981 * t575 * t983 + 0.8e1 * t182 * t103 * t1016 * t4 + 0.8e1 * t1009 * t1113 + 0.16e2 * t954 * t1032 * t4 * t14 - 0.16e2 * t954 * t1032 * t1120 + 0.64e2 * t1015 * t10 * t172 * t1125 + 0.8e1 * t171 * t103 * t136 * t956 - 0.8e1 * t1031 * t1133 * t919 * self->xc + 0.8e1 * t1058 * t1020;
+ t1153 = self->xc * t118;
+ t1165 = t182 * t16;
+ t1170 = t171 * t10;
+ t1178 = self->ZA * t90;
+ t1182 = 0.4e1 * t1088 * t652 * t140 + 0.8e1 * t954 * t1133 * t919 * t14 + 0.4e1 * t972 * t943 - 0.4e1 * t972 * t1069 - 0.16e2 * t954 * t31 * t4 * t1153 - 0.8e1 * t954 * n * t919 * t1153 - 0.8e1 * t954 * t1133 * t919 * t118 + 0.4e1 * t1165 * t1063 + 0.16e2 * t1005 * t1080 - 0.8e1 * t1170 * t118 * t36 * t955 - 0.16e2 * t987 * t920 * t10 - 0.16e2 * t1165 * t1178 * t10;
+ t1195 = t1040 * t981;
+ t1199 = t1009 * t955;
+ t1203 = t1009 * t10;
+ t1211 = t965 * t323;
+ t1225 = -0.32e2 * t965 * t10 * t652 * t1125 + 0.4e1 * t915 * t16 * t974 + 0.4e1 * t182 * t90 * t949 * self->ZA + 0.32e2 * t1195 * t968 * t10 - 0.8e1 * t1199 * t993 * t103 + 0.8e1 * t1203 * t118 * n * t919 + 0.8e1 * t1170 * t136 * t955 + 0.64e2 * t1211 * t1044 + 0.16e2 * t1031 * t1032 * t4 + 0.8e1 * t987 * t943 + 0.8e1 * t1199 * t993 * t10 + 0.8e1 * t997 * t1050 * t4;
+ t1263 = -0.128e3 * t1015 * t1178 * t1044 + 0.16e2 * t1005 * t988 * t1153 + 0.8e1 * t1058 * t1153 * t919 + 0.16e2 * t1010 * t1120 * self->xc - 0.8e1 * t954 * t1113 - 0.8e1 * t1203 * t14 * n * t919 - 0.16e2 * t1203 * t14 * t31 * t4 - 0.8e1 * t1203 * t1113 - 0.32e2 * t1195 * t977 * t10 - 0.64e2 * t1211 * t1054 + 0.8e1 * t992 * t967 * t1153 + 0.128e3 * t1015 * t983 * t90 * t4 * t47;
+
+ self->C1B = (t127 + t204 + t270 + t329 + t384 + t439 + t501 + t549 + t601 + t647 + t698 + t739 + t782 + t821 + t867 + t909) / (t953 + t1013 + t1057 + t1094 + t1140 + t1182 + t1225 + t1263);
+ /****************************************************************************************/
+ t1 = n * n;
+ t2 = t1 * n;
+ t3 = nx * t2;
+ t4 = 0.3141592654e1 * self->ZA;
+ t5 = t3 * t4;
+ t6 = nx * 0.3141592654e1;
+ t7 = t6 * self->xc;
+ t8 = sin(t7);
+ t9 = t8 * self->ZB;
+ t10 = n * 0.3141592654e1;
+ t11 = exp(t10);
+ t12 = t11 * t11;
+ t15 = exp( self->xc * n * 0.3141592654e1);
+ t16 = t15 * t15;
+ t17 = t16 * t16;
+ t18 = t17 * t15;
+ t19 = t12 * t18;
+ t23 = t1 * t1;
+ t24 = nx * t23;
+ t25 = self->ZB * self->ZB;
+ t27 = t18 * t8;
+ t28 = 0.3141592654e1 * 0.3141592654e1;
+ t29 = self->xc * self->xc;
+ t30 = t28 * t29;
+ t34 = t1 * self->xc;
+ t35 = 0.3141592654e1 * self->ZB;
+ t36 = t34 * t35;
+ t37 = cos(t7);
+ t38 = self->ZA * t37;
+ t39 = nx * nx;
+ t40 = t39 * t12;
+ t41 = t16 * t15;
+ t43 = t38 * t40 * t41;
+ t46 = t25 * n;
+ t47 = t46 * 0.3141592654e1;
+ t48 = t39 * nx;
+ t49 = sin(t6);
+ t50 = t48 * t49;
+ t51 = t12 * t11;
+ t52 = t51 * t17;
+ t53 = t50 * t52;
+ t56 = t34 * 0.3141592654e1 * t25;
+ t57 = t37 * t39;
+ t58 = t17 * t41;
+ t59 = t12 * t58;
+ t60 = t57 * t59;
+ t63 = t25 * t18;
+ t64 = t57 * n;
+ t67 = self->ZA * self->ZA;
+ t68 = t67 * n;
+ t69 = 0.3141592654e1 * t48;
+ t70 = t68 * t69;
+ t71 = t49 * self->xc;
+ t72 = t17 * t16;
+ t73 = t11 * t72;
+ t74 = t71 * t73;
+ t77 = t1 * t67;
+ t78 = t77 * 0.3141592654e1;
+ t81 = nx * t25;
+ t82 = t81 * t49;
+ t83 = t17 * t17;
+ t85 = t1 * t83 * t11;
+ t87 = nx * self->ZB;
+ t88 = t8 * t2;
+ t89 = t87 * t88;
+ t90 = 0.3141592654e1 * self->xc;
+ t91 = t12 * t12;
+ t92 = self->ZA * t91;
+ t97 = self->ZB * self->ZA;
+ t98 = t97 * t37;
+ t99 = t39 * n;
+ t100 = t12 * t41;
+ t104 = 0.8e1 * t5 * t9 * t19 + 0.8e1 * t24 * t25 * t27 * t30 + 0.12e2 * t36 * t43 - t47 * t53 - 0.2e1 * t56 * t60 - 0.4e1 * t63 * t64 + 0.6e1 * t70 * t74 + 0.4e1 * t78 * t60 - t82 * t85 + 0.4e1 * t89 * t90 * t92 * t41 + 0.4e1 * t98 * t99 * t100;
+ t105 = t67 * t48;
+ t106 = t49 * t51;
+ t107 = t106 * t72;
+ t109 = t1 * 0.3141592654e1;
+ t110 = t109 * self->xc;
+ t115 = nx * t67;
+ t116 = t115 * t49;
+ t117 = t1 * t16;
+ t118 = t117 * t11;
+ t120 = t2 * t25;
+ t121 = t28 * 0.3141592654e1;
+ t122 = t121 * t29;
+ t123 = t120 * t122;
+ t129 = t1 * self->ZB;
+ t130 = t129 * t4;
+ t131 = t57 * t100;
+ t134 = t12 * t16;
+ t136 = t109 * t39;
+ t139 = self->ZB * t18;
+ t141 = t39 * t1;
+ t142 = t141 * t90;
+ t145 = t77 * t90;
+ t146 = t91 * t41;
+ t147 = t57 * t146;
+ t151 = t25 * t39 * t1;
+ t152 = t72 * t12;
+ t156 = t49 * t2;
+ t158 = t83 * t11;
+ t162 = -t105 * t107 + 0.8e1 * t110 * t72 * t25 * t39 - t116 * t118 + 0.8e1 * t123 * t53 + 0.8e1 * t5 * t9 * t59 - 0.8e1 * t130 * t131 - 0.8e1 * t134 * t25 * t136 - 0.12e2 * t139 * t38 * t142 - 0.8e1 * t145 * t147 - 0.8e1 * t151 * t90 * t152 - 0.2e1 * t87 * t156 * t4 * t158;
+ t164 = t115 * t88;
+ t165 = t90 * t19;
+ t168 = t25 * t48;
+ t169 = t49 * t16;
+ t170 = t169 * t11;
+ t174 = self->ZA * n * t69;
+ t175 = self->ZB * t51;
+ t176 = t175 * t17;
+ t177 = t71 * t176;
+ t180 = t1 * t29;
+ t181 = t28 * t25;
+ t182 = t180 * t181;
+ t183 = t50 * t73;
+ t186 = self->ZA * t1;
+ t187 = t28 * t48;
+ t188 = t186 * t187;
+ t189 = self->ZB * t17;
+ t190 = t189 * t11;
+ t191 = t71 * t190;
+ t194 = t50 * t158;
+ t196 = t115 * t156;
+ t197 = t90 * t73;
+ t201 = t49 * t17 * t11;
+ t204 = t88 * t90;
+ t207 = t68 * 0.3141592654e1;
+ t208 = t17 * t11;
+ t209 = t50 * t208;
+ t211 = -0.2e1 * t164 * t165 - t168 * t170 + t168 * t107 + 0.8e1 * t174 * t177 + 0.2e1 * t182 * t183 + 0.8e1 * t188 * t191 + t47 * t194 - 0.6e1 * t196 * t197 - t168 * t201 - 0.4e1 * t81 * t18 * t204 - t207 * t209;
+ t212 = t2 * 0.3141592654e1;
+ t213 = t212 * t52;
+ t215 = t81 * t8;
+ t216 = t212 * t59;
+ t219 = t3 * t90;
+ t220 = t25 * t8;
+ t221 = t18 * t91;
+ t225 = t71 * t52;
+ t231 = t16 * t51;
+ t232 = t50 * t231;
+ t237 = self->ZA * t12;
+ t243 = t67 * t28;
+ t244 = t24 * t243;
+ t245 = t71 * t231;
+ t249 = -t116 * t213 - 0.4e1 * t215 * t216 + 0.2e1 * t219 * t220 * t221 - 0.4e1 * t70 * t225 + 0.4e1 * t98 * t99 * t146 + t47 * t232 - 0.2e1 * t145 * t57 * t221 + 0.4e1 * t89 * t90 * t237 * t41 - t105 * t201 - 0.6e1 * t244 * t245 + t105 * t170;
+ t252 = t25 * t37;
+ t253 = t252 * t39;
+ t255 = n * t15 * t12;
+ t258 = t2 * t29;
+ t259 = self->ZB * t28;
+ t260 = t258 * t259;
+ t263 = t106 * t17;
+ t265 = self->xc * t25;
+ t269 = t25 * t49;
+ t270 = t269 * t52;
+ t273 = t1 * t25;
+ t274 = t273 * 0.3141592654e1;
+ t275 = t57 * t19;
+ t278 = t24 * t30;
+ t288 = t1 * t11 * t72;
+ t290 = t212 * t208;
+ t292 = t2 * self->xc;
+ t296 = 0.2e1 * t253 * t255 + 0.16e2 * t260 * t43 + t105 * t263 - 0.4e1 * t10 * t265 * t53 + 0.4e1 * t219 * t270 - 0.12e2 * t274 * t275 + 0.8e1 * t278 * t270 - 0.2e1 * self->ZB * n * t69 * t49 * self->ZA * t158 - t82 * t288 - t116 * t290 + 0.16e2 * t292 * t243 * t275;
+ t301 = t50 * t176;
+ t304 = t51 * t72;
+ t305 = t71 * t304;
+ t308 = t25 * t41;
+ t311 = self->ZA * t48;
+ t312 = t311 * t49;
+ t317 = t91 * t15;
+ t318 = t57 * t317;
+ t321 = t81 * t88;
+ t322 = t90 * t59;
+ t325 = t212 * t231;
+ t327 = t15 * t12;
+ t328 = t57 * t327;
+ t331 = t77 * t187;
+ t334 = t2 * self->ZA;
+ t335 = t334 * t122;
+ t336 = t50 * t190;
+ t339 = 0.8e1 * t151 * t90 * t134 + 0.16e2 * t186 * t30 * t301 - 0.2e1 * t70 * t305 + 0.2e1 * t308 * t64 - 0.2e1 * t312 * self->ZB * t83 * t11 + 0.2e1 * t56 * t318 + 0.2e1 * t321 * t322 - t116 * t325 - 0.4e1 * t274 * t328 + 0.2e1 * t331 * t305 - 0.16e2 * t335 * t336;
+ t341 = t169 * t51;
+ t344 = t49 * t11 * t72;
+ t346 = t77 * t30;
+ t347 = t50 * t304;
+ t350 = t25 * t51;
+ t352 = nx * self->ZA;
+ t353 = t49 * t23;
+ t354 = t352 * t353;
+ t355 = t28 * self->xc;
+ t362 = t25 * t91;
+ t365 = t23 * n;
+ t366 = nx * t365;
+ t367 = t366 * t122;
+ t368 = self->ZB * t49;
+ t369 = self->ZA * t51;
+ t370 = t369 * t17;
+ t371 = t368 * t370;
+ t374 = t115 * t353;
+ t375 = t355 * t73;
+ t381 = t105 * t341 - t105 * t344 - 0.2e1 * t346 * t347 - t350 * t50 - 0.8e1 * t354 * t355 * t176 - 0.4e1 * t98 * t99 * t317 - 0.2e1 * t362 * t99 - 0.16e2 * t367 * t371 + 0.6e1 * t374 * t375 - 0.8e1 * t182 * t53 - t82 * t290;
+ t382 = t71 * t208;
+ t394 = t2 * t67;
+ t395 = t394 * t122;
+ t398 = t352 * t156;
+ t402 = t17 * t12;
+ t403 = t39 * self->ZA;
+ t404 = t402 * t403;
+ t407 = t269 * t208;
+ t411 = t49 * t83 * t11;
+ t413 = t46 * t69;
+ t419 = -0.4e1 * t331 * t382 + 0.2e1 * t115 * t58 * t204 - 0.2e1 * t145 * t60 + 0.12e2 * t274 * t131 + 0.2e1 * t346 * t232 + 0.8e1 * t395 * t53 - 0.8e1 * t398 * t90 * t176 - 0.64e2 * t260 * t404 + 0.4e1 * t219 * t407 + t168 * t411 - 0.6e1 * t413 * t74 - 0.2e1 * t110 * t308 * t57;
+ t424 = t16 * t11;
+ t425 = t212 * t424;
+ t427 = t258 * t181;
+ t430 = t67 * t29;
+ t431 = t366 * t430;
+ t432 = t121 * t49;
+ t433 = t432 * t52;
+ t436 = n * t12;
+ t437 = t436 * t18;
+ t440 = t29 * self->xc;
+ t441 = t440 * t121;
+ t442 = t394 * t441;
+ t445 = t67 * t37;
+ t446 = t445 * t39;
+ t448 = n * t18 * t91;
+ t453 = t352 * t49;
+ t458 = t8 * t23;
+ t462 = t81 * t458;
+ t463 = t30 * t19;
+ t466 = -t47 * t209 + t116 * t425 - 0.8e1 * t427 * t275 + 0.8e1 * t431 * t433 - 0.2e1 * t253 * t437 - 0.8e1 * t442 * t53 - 0.2e1 * t446 * t448 + 0.2e1 * t175 * t312 + 0.6e1 * t453 * t129 * t208 + 0.8e1 * t115 * t18 * t458 * t30 + 0.8e1 * t462 * t463;
+ t470 = t436 * t58;
+ t475 = t2 * t121 * t440 * t25;
+ t485 = t212 * t73;
+ t488 = t67 * t72 * t1;
+ t490 = t39 * self->xc;
+ t501 = 0.4e1 * t374 * t355 * t52 + 0.2e1 * t446 * t470 - 0.8e1 * t475 * t53 - 0.2e1 * t446 * t437 - 0.4e1 * t36 * t38 * t39 * t15 * t12 - t116 * t485 + 0.8e1 * t488 * 0.3141592654e1 * t12 * t490 - t207 * t183 - 0.2e1 * t182 * t232 - 0.6e1 * t413 * t245 - 0.4e1 * t413 * t382;
+ t503 = t115 * t8;
+ t510 = t355 * t19;
+ t513 = t432 * t208;
+ t525 = t38 * t40 * t18;
+ t533 = -0.4e1 * t503 * t216 - 0.4e1 * t89 * t90 * t92 * t15 - 0.16e2 * t462 * t510 + 0.8e1 * t431 * t513 - 0.4e1 * t78 * t131 + t47 * t183 - 0.2e1 * t67 * t83 * t99 + 0.4e1 * t331 * t225 + 0.16e2 * t260 * t525 - 0.4e1 * t89 * t90 * t237 * t58 - t207 * t53;
+ t536 = t28 * t37;
+ t538 = t490 * t100;
+ t541 = t334 * t441;
+ t547 = t394 * t30;
+ t550 = t212 * t19;
+ t553 = t366 * t441;
+ t556 = n * t17;
+ t571 = -0.8e1 * t427 * t131 + 0.16e2 * t394 * t536 * t538 + 0.16e2 * t541 * t336 + 0.2e1 * t453 * t129 * t158 - 0.8e1 * t547 * t147 + 0.4e1 * t503 * t550 - 0.8e1 * t553 * t270 + 0.4e1 * t556 * self->ZB * t92 * t39 - 0.2e1 * t67 * t91 * t99 - t82 * t425 + 0.4e1 * t78 * t275 + 0.2e1 * t78 * self->xc * t41 * t57;
+ t583 = t90 * t317;
+ t594 = t212 * t158;
+ t596 = t152 * t67;
+ t602 = t67 * t17;
+ t607 = 0.8e1 * t367 * t407 - 0.4e1 * t98 * t99 * t59 + 0.16e2 * t260 * t18 * self->ZA * t57 + 0.2e1 * t321 * t583 - 0.6e1 * t174 * t368 * t52 - 0.4e1 * t89 * t90 * self->ZA * t15 * t12 + t116 * t594 - 0.8e1 * t596 * t136 - 0.4e1 * t98 * t99 * t327 + 0.2e1 * t602 * t99 + 0.2e1 * t164 * t583;
+ t613 = t83 * t25;
+ t616 = t81 * t156;
+ t627 = t90 * t231;
+ t630 = t91 * t16;
+ t638 = 0.4e1 * t196 * t90 * t208 - 0.8e1 * t130 * t60 - 0.2e1 * t613 * t99 + 0.6e1 * t616 * t197 - 0.8e1 * t547 * t131 + 0.8e1 * t67 * t18 * t37 * t142 + 0.2e1 * t145 * t328 - 0.6e1 * t196 * t627 + 0.8e1 * t630 * t67 * t142 - 0.8e1 * t547 * t275 + 0.8e1 * t395 * t209;
+ t643 = t77 * t355;
+ t648 = t115 * t458;
+ t651 = t134 * t67;
+ t657 = t30 * t304;
+ t660 = t30 * t146;
+ t665 = t25 * t17;
+ t668 = t50 * t424;
+ t671 = -0.4e1 * t321 * t90 * t146 - 0.6e1 * t643 * t232 + 0.8e1 * t182 * t209 - 0.16e2 * t648 * t510 + 0.8e1 * t651 * t136 + 0.8e1 * t89 * t4 * t100 - 0.2e1 * t374 * t657 - 0.8e1 * t648 * t660 + 0.8e1 * t130 * t328 + 0.2e1 * t665 * t99 + 0.2e1 * t346 * t668;
+ t672 = t90 * t424;
+ t676 = t120 * t536;
+ t680 = t436 * t41;
+ t688 = t366 * t67 * t440;
+ t696 = self->xc * t12;
+ t697 = t696 * t18;
+ t701 = t252 * t141;
+ t702 = t90 * t221;
+ t705 = 0.2e1 * t196 * t672 - t47 * t347 + 0.16e2 * t676 * t538 - t116 * t85 - 0.2e1 * t253 * t680 + t207 * t194 + 0.4e1 * t98 * t99 * t19 - 0.8e1 * t688 * t433 + 0.16e2 * t541 * t301 - 0.6e1 * t312 * t190 + 0.4e1 * t352 * t88 * t35 * t697 + 0.2e1 * t701 * t702;
+ t712 = t24 * t430;
+ t713 = t28 * t49;
+ t721 = t1 * t17 * t11;
+ t726 = self->ZB * self->xc;
+ t737 = n * t91;
+ t741 = 0.8e1 * t346 * t209 + 0.2e1 * t712 * t713 * t424 + 0.8e1 * t130 * t275 - t47 * t668 + t116 * t721 - 0.8e1 * t688 * t513 + 0.4e1 * t352 * t27 * t212 * t726 + 0.8e1 * t648 * t463 + 0.4e1 * t274 * t60 - 0.4e1 * t374 * t355 * t208 - 0.4e1 * t253 * t737 * t41;
+ t745 = t269 * t231;
+ t749 = t1 * t28 * t265;
+ t757 = t16 * t39;
+ t758 = t696 * t757;
+ t762 = t69 * t49;
+ t772 = t355 * t100;
+ t775 = t81 * t353;
+ t778 = -0.8e1 * t398 * t90 * t190 - 0.2e1 * t278 * t745 + 0.4e1 * t749 * t53 + 0.32e2 * t394 * t29 * t28 * t17 * t40 - 0.8e1 * t78 * t758 + t350 * n * t762 - 0.6e1 * t87 * t49 * t186 * t52 - 0.8e1 * t553 * t407 - 0.4e1 * t749 * t209 + 0.16e2 * t648 * t772 - 0.6e1 * t775 * t375;
+ t790 = t212 * t304;
+ t793 = t156 * 0.3141592654e1;
+ t795 = t355 * t304;
+ t800 = t91 * t39;
+ t801 = t800 * n;
+ t807 = t2 * t28;
+ t808 = t807 * t726;
+ t811 = -0.2e1 * t616 * t672 - 0.2e1 * t446 * t680 - 0.2e1 * t78 * self->xc * t58 * t57 + 0.8e1 * t367 * t270 - t82 * t790 + t115 * t51 * t793 - 0.2e1 * t775 * t795 + 0.8e1 * t123 * t209 + 0.2e1 * t665 * t801 - 0.2e1 * t67 * t41 * t64 - 0.32e2 * t808 * t43;
+ t812 = t117 * t51;
+ t821 = t24 * t355;
+ t827 = t90 * t304;
+ t840 = t800 * t41;
+ t844 = -t116 * t812 - 0.2e1 * t110 * t25 * t58 * t57 - 0.4e1 * t78 * t328 + t82 * t485 - 0.4e1 * t821 * t407 + 0.4e1 * t196 * t90 * t52 + 0.2e1 * t196 * t827 + t82 * t325 + 0.2e1 * t253 * t448 - 0.32e2 * t402 * t67 * t807 * t490 - t207 * t232 + 0.12e2 * t186 * t90 * self->ZB * t37 * t840;
+ t849 = t1 * t51;
+ t850 = t849 * t17;
+ t860 = t269 * t424;
+ t863 = t273 * t187;
+ t874 = 0.16e2 * t462 * t772 - t116 * t850 + 0.16e2 * t553 * t371 + t116 * t288 - 0.12e2 * t97 * t57 * t109 * t697 + t82 * t594 - 0.2e1 * t278 * t860 - 0.2e1 * t863 * t305 - 0.16e2 * t180 * t259 * t311 * t201 - 0.6e1 * t863 * t74 + 0.8e1 * t174 * t191;
+ t879 = self->xc * self->ZA;
+ t888 = t67 * t51;
+ t901 = self->ZA * t17;
+ t903 = t368 * t901 * t11;
+ t908 = -0.2e1 * t352 * t51 * t156 * t35 + 0.64e2 * t879 * t189 * t807 * t40 + 0.2e1 * t46 * t58 * t37 * t39 - t888 * t50 + t105 * t411 - 0.16e2 * t335 * t301 + 0.8e1 * t152 * t25 * t136 - 0.8e1 * t278 * t407 + 0.2e1 * t712 * t713 * t231 - 0.16e2 * t367 * t903 + 0.2e1 * t145 * t318;
+ t923 = t71 * t424;
+ t926 = t87 * t458;
+ t927 = t28 * self->ZA;
+ t944 = 0.8e1 * t354 * t355 * t190 - 0.8e1 * t110 * t16 * t25 * t800 - 0.2e1 * t374 * t30 * t73 - 0.16e2 * t354 * t30 * t176 - 0.2e1 * t244 * t923 - 0.32e2 * t926 * t927 * t696 * t41 - 0.32e2 * t808 * t525 + 0.6e1 * t749 * t232 - 0.8e1 * t188 * t177 + 0.4e1 * t36 * t58 * self->ZA * t57 + 0.4e1 * t821 * t270;
+ t948 = t90 * t327;
+ t961 = t30 * t100;
+ t964 = t29 * t49;
+ t981 = t106 * t1;
+ t983 = -0.2e1 * t219 * t220 * t100 + 0.2e1 * t321 * t948 - 0.16e2 * t189 * self->ZA * t99 * t12 - 0.2e1 * t369 * n * t69 * t368 + 0.2e1 * t374 * t795 - 0.8e1 * t462 * t961 - 0.8e1 * t244 * t964 * t208 + 0.2e1 * t413 * t923 + 0.4e1 * t36 * t38 * t40 * t58 - 0.2e1 * t87 * t51 * t49 * t1 * self->ZA + t888 * n * t762 + t115 * t981;
+ t1012 = 0.6e1 * t616 * t627 - t82 * t213 + 0.2e1 * t775 * t657 - 0.12e2 * t215 * t550 - 0.6e1 * t145 * t131 + 0.2e1 * t81 * t41 * t204 + 0.6e1 * self->ZB * t48 * t49 * t370 - 0.4e1 * t70 * t382 + 0.2e1 * t446 * t255 + 0.8e1 * t89 * t4 * t327 - 0.4e1 * t56 * t147;
+ t1018 = t212 * t100;
+ t1029 = t212 * t327;
+ t1040 = 0.6e1 * t70 * t245 + 0.2e1 * t56 * t328 + t207 * t668 + 0.4e1 * t503 * t1018 + 0.2e1 * t253 * t470 - 0.6e1 * t398 * t35 * t208 - 0.8e1 * t331 * t964 * t52 - 0.4e1 * t503 * t1029 + 0.6e1 * t821 * t745 + 0.4e1 * t63 * t37 * t142 + 0.16e2 * t260 * t38 * t840;
+ t1068 = t207 * t347 - 0.2e1 * t164 * t702 - 0.2e1 * t331 * t964 * t73 + 0.8e1 * t374 * t30 * t52 + 0.16e2 * t278 * t903 + 0.2e1 * t863 * t923 + 0.6e1 * t445 * t141 * t165 - 0.2e1 * t164 * t90 * t100 + 0.6e1 * t331 * t74 - 0.2e1 * t182 * t668 - 0.2e1 * t115 * t41 * t204;
+ t1079 = t58 * t8;
+ t1091 = t807 * t29;
+ t1092 = t665 * t40;
+ t1101 = self->ZB * t91;
+ t1102 = t403 * n;
+ t1105 = -0.4e1 * t58 * self->ZB * self->ZA * t64 - t82 * t850 + 0.2e1 * t821 * t860 + t81 * t51 * t793 + 0.2e1 * t3 * t25 * t1079 * t90 + t82 * t721 - 0.2e1 * t643 * t668 + 0.16e2 * t926 * t927 * t29 * t91 * t41 + 0.32e2 * t1091 * t1092 - 0.2e1 * t219 * t220 * t19 + 0.4e1 * t139 * self->ZA * t64 + 0.4e1 * t1101 * t1102;
+ t1108 = t849 * t72;
+ t1121 = t737 * t15;
+ t1124 = t29 * t12;
+ t1133 = t116 * t1108 - 0.8e1 * t475 * t209 - 0.32e2 * t807 * self->xc * t1092 + 0.2e1 * t278 * t269 * t73 + t82 * t812 - 0.6e1 * t56 * t131 + 0.2e1 * t253 * t1121 + 0.16e2 * t926 * t927 * t1124 * t41 + t168 * t263 - 0.2e1 * t616 * t827 + t81 * t981;
+ t1134 = t394 * t28;
+ t1159 = -0.8e1 * t1134 * t29 * t18 * t57 + t82 * t118 - 0.12e2 * t215 * t1018 + 0.2e1 * t602 * t801 - t168 * t341 + 0.2e1 * t67 * t58 * t64 + t168 * t344 - 0.6e1 * t174 * t368 * t208 + 0.16e2 * t553 * t903 + t116 * t790 - 0.4e1 * t36 * t38 * t800 * t15;
+ t1161 = n * t83;
+ t1173 = self->ZB * t12;
+ t1196 = 0.4e1 * t1161 * self->ZB * t39 * self->ZA - 0.4e1 * t215 * t1029 - 0.8e1 * t488 * 0.3141592654e1 * t39 * self->xc + 0.32e2 * t821 * self->ZA * t8 * t1173 * t18 - 0.8e1 * t427 * t147 + 0.6e1 * t701 * t165 - 0.16e2 * t926 * t927 * t1124 * t18 - 0.8e1 * t1091 * t63 * t57 - 0.8e1 * t442 * t209 - 0.8e1 * t462 * t660 - 0.6e1 * t398 * t35 * t52;
+ t1228 = 0.2e1 * t413 * t305 - 0.8e1 * t648 * t961 - 0.16e2 * t87 * t27 * t23 * t28 * self->ZA * t29 + 0.4e1 * t189 * t1102 - 0.4e1 * t87 * t1079 * t212 * t879 + 0.2e1 * t164 * t948 - 0.2e1 * t70 * t923 + 0.2e1 * t164 * t322 + 0.2e1 * t446 * t1121 + 0.2e1 * t863 * t964 * t304 - t82 * t1108 + 0.16e2 * t676 * t490 * t19;
+ t1234 = t25 * self->ZB;
+ t1235 = t1234 * t28;
+ t1236 = t365 * t91;
+ t1240 = self->ZB * t121;
+ t1241 = t1240 * t77;
+ t1242 = t39 * t39;
+ t1243 = t12 * t1242;
+ t1244 = self->xc * t72;
+ t1245 = t1243 * t1244;
+ t1248 = t365 * t25;
+ t1252 = t243 * n;
+ t1257 = t23 * t1;
+ t1258 = t1240 * t1257;
+ t1259 = t67 * t12;
+ t1260 = self->xc * t16;
+ t1268 = t1234 * t121;
+ t1269 = t1268 * t23;
+ t1272 = t1242 * t91;
+ t1280 = t67 * self->xc;
+ t1284 = t28 * t28;
+ t1285 = t67 * t1284;
+ t1287 = t1285 * t2 * self->ZB;
+ t1288 = t17 * self->xc;
+ t1289 = t1243 * t1288;
+ t1292 = 0.2e1 * t1235 * t1236 * t17 + 0.8e1 * t1241 * t1245 + 0.4e1 * t927 * t1248 * t91 - 0.2e1 * t1252 * self->ZB * t1242 * t91 - 0.8e1 * t1258 * t1259 * t1260 - 0.4e1 * t1235 * t2 * t83 * t39 + 0.16e2 * t1269 * t758 + 0.2e1 * t1252 * t189 * t1272 - 0.2e1 * t1252 * t83 * t1242 * self->ZB + 0.8e1 * t1258 * t630 * t1280 - 0.32e2 * t1287 * t1289;
+ t1293 = t365 * t83;
+ t1300 = self->ZA * t1284;
+ t1304 = t17 * t1242 * t25 * t12;
+ t1307 = t927 * t2;
+ t1311 = t23 * t2;
+ t1312 = t1300 * t1311;
+ t1316 = t1234 * t1284;
+ t1317 = t1316 * t1311;
+ t1321 = t1240 * t23;
+ t1331 = t1240 * t23 * t67;
+ t1332 = t40 * t1244;
+ t1338 = t1243 * t1260;
+ t1344 = -0.2e1 * t1235 * t1293 - 0.16e2 * t181 * t365 * t901 * t12 - 0.64e2 * t1300 * t258 * t1304 + 0.8e1 * t1307 * t613 * t39 + 0.64e2 * t1312 * t265 * t402 - 0.32e2 * t1317 * t1288 * t12 - 0.16e2 * t1321 * t67 * t39 * t1244 + 0.2e1 * t1235 * n * t1272 * t17 + 0.16e2 * t1331 * t1332 + 0.64e2 * t1300 * t292 * t1304 - 0.8e1 * t1241 * t1338 - 0.2e1 * t243 * t1293 * self->ZB;
+ t1346 = t1316 * t2;
+ t1349 = t927 * n;
+ t1350 = t25 * t1242;
+ t1354 = t1268 * t1257;
+ t1366 = t1268 * t1;
+ t1370 = t29 * t17;
+ t1371 = t1243 * t1370;
+ t1386 = -0.32e2 * t1346 * t1289 + 0.4e1 * t1349 * t1350 * t91 + 0.8e1 * t1354 * t1260 * t12 - 0.16e2 * t181 * n * t901 * t1243 - 0.4e1 * t1235 * t2 * t91 * t39 + 0.8e1 * t1366 * t152 * t1242 + 0.32e2 * t1287 * t1371 + 0.8e1 * t1258 * t1280 * t152 - 0.8e1 * t1354 * t1260 * t91 + 0.128e3 * t1300 * t365 * self->xc * t1092 + 0.8e1 * t1366 * t1338;
+ t1387 = t1257 * t12;
+ t1391 = t1240 * t1;
+ t1399 = t1272 * t1260;
+ t1412 = t1285 * t1311;
+ t1427 = -0.8e1 * t1268 * t1387 * t16 - 0.8e1 * t1391 * t67 * t1242 * t1244 - 0.4e1 * t1134 * t1101 * t39 + 0.8e1 * t1241 * t1399 - 0.8e1 * t1258 * t596 + 0.4e1 * t927 * t1293 * t25 - 0.16e2 * t1331 * t758 + 0.8e1 * t1307 * t665 * t39 + 0.32e2 * t1412 * t1370 * t1173 + 0.8e1 * t1307 * t665 * t800 + 0.8e1 * t1391 * t1259 * t1242 * t16 - 0.8e1 * t1391 * t1259 * t1242 * t72;
+ t1456 = t365 * self->ZB;
+ t1468 = 0.4e1 * t927 * t1248 * t17 - 0.2e1 * t1235 * n * t1242 * t91 + 0.8e1 * t1366 * t1244 * t1242 - 0.16e2 * t1269 * t134 * t39 + 0.8e1 * t1268 * t1257 * t72 * self->xc + 0.16e2 * t1321 * t1259 * t757 + 0.32e2 * t1317 * t1370 * t12 + 0.4e1 * t1349 * t613 * t1242 + 0.2e1 * t243 * t1456 * t17 - 0.64e2 * t1285 * t365 * t12 * t189 * t490 - 0.8e1 * t1354 * t152 * self->xc;
+ t1472 = t1316 * t365;
+ t1474 = t1124 * t39 * t17;
+ t1478 = t17 * t91;
+ t1504 = t72 * t39;
+ t1511 = 0.4e1 * t1134 * t189 * t800 + 0.64e2 * t1472 * t1474 + 0.4e1 * t1235 * t2 * t1478 * t39 + 0.4e1 * t1349 * t665 * t1242 - 0.8e1 * t1258 * t1280 * t72 + 0.2e1 * t1252 * t189 * t1242 + 0.2e1 * t243 * t365 * t189 * t91 + 0.4e1 * t927 * t365 * t1478 * t25 - 0.128e3 * t1300 * t1248 * t1474 - 0.2e1 * t1235 * t1236 + 0.16e2 * t1269 * t1504 * self->xc + 0.2e1 * t1235 * t365 * t17;
+ t1545 = -0.2e1 * t1235 * t1161 * t1242 + 0.4e1 * t1349 * t1350 * t1478 - 0.8e1 * t1366 * t1245 + 0.2e1 * t1235 * t556 * t1242 - 0.32e2 * t1412 * t402 * t726 - 0.8e1 * t1366 * t1399 + 0.8e1 * t1258 * t651 - 0.2e1 * t243 * t1456 * t91 + 0.8e1 * t1268 * t1387 * t72 - 0.16e2 * t1269 * t1332 + 0.4e1 * t1134 * t189 * t39 + 0.16e2 * t1269 * t152 * t39;
+ t1564 = t1260 * t800;
+ t1583 = 0.64e2 * t1285 * t1456 * t1474 - 0.64e2 * t1472 * t1288 * t40 - 0.8e1 * t1366 * t134 * t1242 + 0.8e1 * t1307 * t362 * t39 + 0.4e1 * t1235 * t2 * t17 * t39 + 0.32e2 * t1346 * t1371 - 0.16e2 * t1269 * t1564 - 0.16e2 * t1321 * t1259 * t1504 + 0.16e2 * t1331 * t1564 - 0.64e2 * t1312 * t29 * t25 * t402 - 0.4e1 * t1134 * t83 * t39 * self->ZB - 0.32e2 * t181 * t2 * t404;
+
+ self->C2B = (t1133 + t1196 + t1068 + t811 + t466 + t1012 + t381 + t162 + t249 + t533 + t844 + t104 + t1159 + t571 + t211 + t874 + t607 + t339 + t296 + t638 + t908 + t671 + t419 + t983 + t705 + t1105 + t501 + t778 + t1040 + t1228 + t741 + t944) / (t1292 + t1344 + t1386 + t1427 + t1468 + t1511 + t1545 + t1583);
+ /****************************************************************************************/
+ t1 = n * n;
+ t2 = t1 * n;
+ t3 = t2 * nx;
+ t4 = nx * 0.3141592654e1;
+ t5 = t4 * self->xc;
+ t6 = sin(t5);
+ t7 = 0.3141592654e1 * 0.3141592654e1;
+ t9 = t3 * t6 * t7;
+ t10 = self->xc * self->xc;
+ t11 = self->ZA * self->ZA;
+ t12 = t10 * t11;
+ t13 = n * 0.3141592654e1;
+ t14 = exp(t13);
+ t15 = t14 * t14;
+ t16 = self->xc * n;
+ t18 = exp(t16 * 0.3141592654e1);
+ t19 = t18 * t18;
+ t20 = t19 * t18;
+ t21 = t15 * t20;
+ t22 = t12 * t21;
+ t25 = nx * t6;
+ t26 = t1 * 0.3141592654e1;
+ t27 = t25 * t26;
+ t28 = self->ZA * self->ZB;
+ t29 = t18 * t15;
+ t30 = t28 * t29;
+ t33 = t25 * n;
+ t34 = t11 * t15;
+ t35 = t19 * t19;
+ t36 = t35 * t18;
+ t40 = t25 * t1;
+ t41 = 0.3141592654e1 * t11;
+ t42 = t15 * t36;
+ t43 = t41 * t42;
+ t46 = nx * nx;
+ t47 = t1 * t46;
+ t48 = t47 * t11;
+ t49 = t7 * self->xc;
+ t50 = t35 * t15;
+ t51 = t49 * t50;
+ t55 = sin(t4);
+ t56 = t46 * nx * t55;
+ t58 = t56 * n * t7;
+ t59 = self->ZB * self->ZB;
+ t60 = t10 * t59;
+ t61 = t15 * t14;
+ t62 = t19 * t61;
+ t63 = t60 * t62;
+ t66 = t19 * t14;
+ t67 = t60 * t66;
+ t70 = t28 * t42;
+ t73 = cos(t5);
+ t74 = t47 * t73;
+ t75 = t7 * t11;
+ t77 = t75 * t10 * t36;
+ t80 = t73 * t46;
+ t81 = t80 * n;
+ t82 = 0.3141592654e1 * t59;
+ t83 = t82 * t42;
+ t87 = self->xc * t11;
+ t88 = t87 * t62;
+ t91 = n * nx;
+ t92 = t55 * t61;
+ t96 = nx * t55;
+ t98 = t96 * t2 * t7;
+ t101 = self->xc * t59;
+ t102 = t101 * t62;
+ t108 = t1 * t1;
+ t109 = t108 * t7;
+ t111 = t59 * t35;
+ t112 = t111 * t15;
+ t115 = t35 * t20;
+ t123 = t1 * nx * t55;
+ t124 = t61 * t35;
+ t127 = t35 * t19;
+ t128 = t61 * t127;
+ t129 = t60 * t128;
+ t132 = t56 * t16;
+ t133 = t7 * t59;
+ t134 = t133 * t124;
+ t137 = 0.6e1 * t58 * t88 - 0.2e1 * t91 * t92 * t11 + 0.2e1 * t98 * t63 - 0.6e1 * t58 * t102 - 0.2e1 * t91 * t92 * t59 - 0.16e2 * t109 * self->xc * t112 - 0.2e1 * t91 * t6 * t115 * t59 + 0.12e2 * t40 * t83 + t123 * t41 * t124 - 0.2e1 * t58 * t129 + 0.4e1 * t132 * t134;
+ t139 = t56 * 0.3141592654e1;
+ t140 = t111 * t14;
+ t144 = t49 * t124;
+ t147 = t91 * t55;
+ t148 = t61 * self->ZA;
+ t154 = self->ZA * t115 * self->xc * self->ZB;
+ t157 = t7 * 0.3141592654e1;
+ t159 = t96 * t108 * t157;
+ t160 = t10 * self->xc;
+ t161 = t160 * t59;
+ t162 = t35 * t14;
+ t163 = t161 * t162;
+ t166 = t28 * t162;
+ t169 = t80 * t13;
+ t170 = t101 * t42;
+ t173 = t2 * t11;
+ t174 = t96 * t173;
+ t175 = t7 * t10;
+ t179 = t59 * t15;
+ t184 = t15 * t15;
+ t193 = t139 * t140 + 0.4e1 * t56 * n * t11 * t144 + 0.4e1 * t147 * t148 * self->ZB + 0.4e1 * t27 * t154 + 0.8e1 * t159 * t163 - 0.12e2 * t147 * t166 + 0.2e1 * t169 * t170 - 0.16e2 * t174 * t175 * t124 + 0.2e1 * t33 * t179 * t20 - 0.2e1 * t33 * t11 * t36 * t184 + 0.2e1 * t56 * t61 * 0.3141592654e1 * self->ZA * self->ZB;
+ t194 = t173 * 0.3141592654e1;
+ t195 = self->xc * t15;
+ t196 = t195 * t19;
+ t202 = t15 * t115;
+ t203 = t28 * t202;
+ t206 = t96 * t26;
+ t207 = t14 * t127;
+ t208 = t101 * t207;
+ t211 = t12 * t128;
+ t218 = t11 * t61;
+ t219 = t218 * t35;
+ t221 = t108 * self->ZA;
+ t223 = t7 * self->ZB;
+ t224 = t223 * t50;
+ t227 = self->ZA * self->xc;
+ t228 = self->ZB * t15;
+ t229 = t228 * t36;
+ t230 = t227 * t229;
+ t233 = t87 * t207;
+ t236 = t6 * t11;
+ t240 = -0.4e1 * t194 * t196 + 0.4e1 * t194 * t195 * t127 + 0.4e1 * t33 * t203 - 0.12e2 * t206 * t208 + 0.2e1 * t58 * t211 - 0.16e2 * t47 * t10 * t133 * t50 + t139 * t219 - 0.32e2 * t221 * t10 * t224 - 0.4e1 * t169 * t230 - 0.6e1 * t98 * t233 + 0.2e1 * t91 * t236 * t20;
+ t244 = t227 * t228 * t20;
+ t252 = t184 * t18;
+ t253 = t101 * t252;
+ t256 = t35 * t35;
+ t257 = t256 * t14;
+ t258 = t28 * t257;
+ t261 = t108 * t11;
+ t263 = t7 * t35;
+ t268 = self->ZB * t61 * t35;
+ t273 = t96 * t108 * t160;
+ t274 = t157 * self->ZB;
+ t276 = t274 * t148 * t35;
+ t279 = t101 * t21;
+ t282 = 0.3141592654e1 * self->xc;
+ t283 = t59 * t36;
+ t284 = t282 * t283;
+ t289 = 0.4e1 * t169 * t244 - 0.4e1 * t132 * t133 * t162 - 0.2e1 * t147 * t140 - 0.2e1 * t27 * t253 + 0.2e1 * t139 * t258 + 0.16e2 * t261 * t10 * t263 * t15 - 0.16e2 * t206 * t227 * t268 - 0.16e2 * t273 * t276 - 0.6e1 * t27 * t279 - 0.4e1 * t40 * t284 - 0.32e2 * t9 * t230;
+ t290 = t1 * t11;
+ t291 = t96 * t290;
+ t297 = t59 * t61;
+ t298 = t297 * t127;
+ t300 = self->ZB * t36;
+ t301 = t227 * t300;
+ t304 = t1 * t59;
+ t305 = t184 * t35;
+ t310 = t46 * self->ZB;
+ t311 = t184 * self->ZA;
+ t312 = t310 * t311;
+ t314 = t60 * t21;
+ t317 = t1 * self->ZA;
+ t318 = self->ZB * t35;
+ t321 = t1 * t256;
+ t324 = t96 * t261;
+ t325 = t10 * t157;
+ t326 = t325 * t124;
+ t329 = -0.4e1 * t291 * t282 * t128 + t123 * t82 * t62 - t139 * t298 + 0.12e2 * t27 * t301 + t304 * t305 - 0.2e1 * t58 * t12 * t66 - 0.2e1 * t312 + 0.8e1 * t9 * t314 + 0.2e1 * t317 * t318 + 0.2e1 * t321 * t28 - 0.8e1 * t324 * t326;
+ t331 = t28 * t124;
+ t334 = 0.3141592654e1 * t15;
+ t335 = t334 * t127;
+ t338 = t35 * self->ZA;
+ t341 = t46 * t256;
+ t344 = t46 * t11;
+ t346 = t46 * t59;
+ t348 = t297 * t35;
+ t351 = self->ZA * t10;
+ t352 = t351 * t300;
+ t355 = t1 * self->ZB;
+ t362 = 0.12e2 * t147 * t331 - 0.4e1 * t173 * t335 - 0.2e1 * t310 * t338 - 0.2e1 * t341 * t28 - t344 * t305 - t346 * t305 + 0.2e1 * t147 * t348 + 0.16e2 * t9 * t352 + 0.2e1 * t355 * t311 + t290 * t305 + 0.2e1 * t33 * t34 * t20;
+ t363 = t36 * t184;
+ t364 = t87 * t363;
+ t368 = t47 * t73 * t7;
+ t373 = t160 * t157;
+ t374 = t373 * t124;
+ t377 = t311 * t35;
+ t380 = t12 * t62;
+ t386 = self->ZB * t10 * self->ZA * t15 * t20;
+ t389 = t87 * t66;
+ t393 = t56 * t1 * t10;
+ t401 = 0.2e1 * t27 * t364 - 0.16e2 * t368 * t279 - t123 * t41 * t257 + 0.8e1 * t324 * t374 + 0.2e1 * t355 * t377 - 0.2e1 * t98 * t380 - 0.16e2 * t9 * t386 + 0.2e1 * t58 * t389 + 0.16e2 * t393 * t276 + t123 * t82 * t162 - 0.2e1 * t33 * t179 * t36;
+ t412 = t11 * t14 * t127;
+ t416 = t11 * t19;
+ t417 = t416 * t61;
+ t421 = t96 * t2 * self->ZA;
+ t426 = t56 * n * self->ZA;
+ t427 = t318 * t14;
+ t428 = t49 * t427;
+ t431 = t82 * t29;
+ t434 = t87 * t21;
+ t442 = 0.2e1 * t33 * t11 * t184 * t18 + 0.4e1 * t81 * t284 - t139 * t412 + 0.2e1 * t147 * t219 - 0.2e1 * t147 * t417 + 0.32e2 * t421 * t175 * t268 + 0.8e1 * t426 * t428 + 0.4e1 * t81 * t431 - 0.2e1 * t169 * t434 - 0.2e1 * t98 * t129 - 0.32e2 * t47 * t28 * t51;
+ t443 = t184 * t20;
+ t447 = t61 * 0.3141592654e1;
+ t448 = t447 * t11;
+ t450 = t49 * t268;
+ t453 = t60 * t42;
+ t456 = t41 * t202;
+ t463 = t101 * t443;
+ t469 = t41 * self->xc * t20;
+ t474 = -0.8e1 * t27 * t87 * t443 - t56 * t448 - 0.8e1 * t426 * t450 + 0.8e1 * t368 * t453 + 0.4e1 * t40 * t456 + 0.4e1 * t40 * t431 - 0.4e1 * t81 * t456 - 0.4e1 * t27 * t463 + 0.6e1 * t139 * t331 + 0.2e1 * t40 * t469 - 0.16e2 * t9 * t434;
+ t482 = t108 * t10;
+ t492 = n * t46;
+ t493 = t492 * t11;
+ t495 = t282 * t19 * t184;
+ t498 = t56 * t290;
+ t499 = t325 * t162;
+ t502 = t416 * t14;
+ t504 = t60 * t207;
+ t507 = -t123 * t82 * t257 - 0.4e1 * t169 * t301 + t123 * t41 * t162 + 0.16e2 * t482 * t7 * t112 - 0.12e2 * t206 * t102 - t123 * t82 * t66 - 0.4e1 * t147 * t258 - 0.4e1 * t493 * t495 - 0.8e1 * t498 * t499 + t139 * t502 - 0.2e1 * t98 * t504;
+ t508 = t101 * t162;
+ t512 = t41 * t115 * self->xc;
+ t515 = t87 * t42;
+ t520 = self->ZB * t184;
+ t522 = t227 * t520 * t18;
+ t525 = t492 * t59;
+ t528 = t6 * t59;
+ t532 = t520 * t20;
+ t533 = t351 * t532;
+ t539 = t447 * t59;
+ t544 = 0.8e1 * t206 * t508 - 0.2e1 * t40 * t512 - 0.16e2 * t368 * t515 + 0.12e2 * t206 * t88 + 0.4e1 * t27 * t522 + 0.4e1 * t525 * t495 - 0.4e1 * t91 * t528 * t36 - 0.16e2 * t368 * t533 - 0.16e2 * t206 * t227 * t427 - t56 * t539 - 0.2e1 * t132 * t133 * t66;
+ t551 = t87 * t162;
+ t554 = t351 * t229;
+ t560 = t59 * t19;
+ t561 = t560 * t14;
+ t564 = t101 * t202;
+ t567 = t87 * t252;
+ t573 = t227 * t228 * t115;
+ t578 = 0.4e1 * t33 * t70 + 0.4e1 * t493 * t335 - 0.4e1 * t58 * t551 + 0.16e2 * t9 * t554 - 0.4e1 * t33 * t28 * t252 + 0.2e1 * t147 * t561 + 0.2e1 * t169 * t564 - 0.2e1 * t27 * t567 - 0.8e1 * t324 * t499 - 0.4e1 * t169 * t573 + 0.12e2 * t27 * t244;
+ t579 = t82 * t202;
+ t591 = t282 * t115 * t59;
+ t598 = t101 * t66;
+ t606 = -0.4e1 * t81 * t579 - 0.2e1 * t169 * t567 - 0.6e1 * t27 * t170 + 0.8e1 * t169 * t203 + 0.2e1 * t98 * t67 + 0.2e1 * t81 * t591 + 0.32e2 * t368 * t244 - 0.2e1 * t27 * t564 + 0.4e1 * t206 * t598 + 0.16e2 * t9 * t170 + 0.2e1 * t33 * t283 * t184;
+ t608 = t373 * t162;
+ t611 = t59 * t184;
+ t617 = t101 * t29;
+ t624 = t227 * self->ZB * t18 * t15;
+ t629 = t157 * t59;
+ t630 = t629 * t124;
+ t633 = t3 * t6;
+ t634 = t175 * t283;
+ t644 = 0.8e1 * t498 * t608 + 0.2e1 * t33 * t611 * t18 - 0.4e1 * t206 * t389 - 0.2e1 * t27 * t617 - 0.4e1 * t169 * t154 + 0.4e1 * t27 * t624 + 0.12e2 * t27 * t230 - 0.8e1 * t393 * t630 - 0.8e1 * t633 * t634 + 0.16e2 * t47 * t7 * t101 * t50 + 0.2e1 * t123 * t447 * t28;
+ t645 = t41 * t29;
+ t648 = t2 * 0.3141592654e1;
+ t649 = t648 * self->xc;
+ t650 = t560 * t184;
+ t656 = t56 * t1 * t157;
+ t659 = t87 * t128;
+ t662 = t96 * t482;
+ t663 = t629 * t162;
+ t671 = t161 * t124;
+ t674 = t218 * t127;
+ t679 = 0.4e1 * t81 * t645 - 0.4e1 * t649 * t650 - 0.8e1 * t169 * t70 + 0.8e1 * t656 * t163 - 0.2e1 * t98 * t659 - 0.8e1 * t662 * t663 - 0.32e2 * t421 * t175 * t427 - 0.2e1 * t147 * t502 + 0.8e1 * t656 * t671 + 0.2e1 * t147 * t674 - 0.16e2 * t368 * t386;
+ t714 = t334 * t19;
+ t719 = t12 * t42;
+ t722 = t304 * t35 - t346 * t35 + t341 * t59 - t344 * t35 + t344 * t256 + t346 * t184 - 0.16e2 * t368 * t554 - 0.16e2 * t48 * t175 * t50 + 0.4e1 * t525 * t714 - 0.2e1 * t58 * t659 + 0.8e1 * t368 * t719;
+ t730 = self->xc * t19;
+ t735 = t59 * t256 * t14;
+ t752 = 0.4e1 * t173 * t714 - 0.6e1 * t27 * t515 - 0.16e2 * t9 * t279 + 0.4e1 * t194 * t730 * t184 - t139 * t735 - 0.4e1 * t492 * t127 * t82 * self->xc - 0.4e1 * t98 * t508 - t123 * t41 * t207 - 0.2e1 * t147 * t298 + 0.8e1 * t368 * t314 + 0.6e1 * t132 * t133 * t207;
+ t755 = t28 * t21;
+ t759 = t274 * t338 * t14;
+ t767 = t11 * t35;
+ t768 = t767 * t14;
+ t778 = t560 * t61;
+ t781 = -0.2e1 * t58 * t504 - 0.8e1 * t27 * t755 + 0.16e2 * t662 * t759 + 0.12e2 * t291 * t282 * t207 - 0.6e1 * t27 * t434 + t139 * t768 - 0.8e1 * t498 * t326 + 0.4e1 * t33 * t611 * t20 + 0.2e1 * t81 * t512 - t139 * t561 + 0.2e1 * t147 * t778;
+ t786 = t12 * t443;
+ t790 = t282 * t59 * t20;
+ t796 = t59 * t14 * t127;
+ t806 = t41 * t21;
+ t811 = -0.8e1 * t393 * t663 + 0.8e1 * t368 * t786 + 0.2e1 * t81 * t790 + 0.4e1 * t169 * t624 + t139 * t796 + 0.2e1 * t206 * t258 - 0.2e1 * t40 * t591 - 0.8e1 * t662 * t630 - 0.4e1 * t33 * t30 - 0.4e1 * t40 * t806 + 0.8e1 * t9 * t786;
+ t819 = t282 * t15 * t127;
+ t822 = t101 * t363;
+ t830 = t11 * t256 * t14;
+ t835 = t227 * t532;
+ t842 = 0.2e1 * t33 * t11 * t18 * t15 + t123 * t41 * t66 - 0.4e1 * t493 * t819 - 0.2e1 * t27 * t822 - 0.16e2 * t368 * t170 - 0.4e1 * t169 * t463 - t139 * t830 - 0.4e1 * t649 * t179 * t127 + 0.12e2 * t27 * t835 - 0.16e2 * t368 * t434 - 0.2e1 * t40 * t790;
+ t845 = t87 * t202;
+ t854 = t338 * t15;
+ t859 = t12 * t207;
+ t868 = t139 * t348 - 0.2e1 * t27 * t845 + 0.8e1 * t169 * t755 - 0.2e1 * t58 * t380 + 0.6e1 * t206 * t331 + 0.8e1 * t310 * t854 - 0.2e1 * t169 * t822 + 0.2e1 * t98 * t859 + 0.8e1 * t159 * t671 + 0.8e1 * t74 * t634 - 0.2e1 * t169 * t253;
+ t880 = t60 * t443;
+ t891 = t101 * t128;
+ t894 = -t123 * t539 - 0.2e1 * t147 * t796 + 0.32e2 * t368 * t230 + t139 * t674 - 0.16e2 * t98 * t60 * t124 + 0.32e2 * t9 * t244 + 0.8e1 * t368 * t880 - 0.8e1 * t40 * t41 * self->xc * t36 - t123 * t82 * t128 - 0.6e1 * t58 * t233 + 0.2e1 * t58 * t891;
+ t903 = t179 * t19;
+ t920 = t56 * t1 * t160;
+ t925 = -0.2e1 * t174 * t175 * t66 - 0.4e1 * t493 * t714 + 0.4e1 * t649 * t903 - 0.4e1 * t81 * t43 + t123 * t82 * t207 + 0.4e1 * t206 * t891 - 0.16e2 * t273 * t759 - 0.8e1 * t27 * t203 + 0.32e2 * t221 * self->ZB * t51 - 0.16e2 * t920 * t759 - 0.8e1 * t9 * t453;
+ t932 = t87 * t29;
+ t945 = t82 * t21;
+ t953 = -0.16e2 * t920 * t276 - 0.8e1 * t169 * t30 - 0.8e1 * t633 * t77 - 0.2e1 * t27 * t932 - 0.4e1 * t174 * t49 * t162 + 0.8e1 * t206 * t87 * t124 - 0.2e1 * t147 * t768 + 0.4e1 * t169 * t522 - 0.12e2 * t81 * t945 + 0.4e1 * t33 * t28 * t115 + 0.4e1 * t525 * t819;
+ t971 = t282 * t127;
+ t978 = -0.6e1 * t98 * t102 + 0.2e1 * t169 * t515 - 0.2e1 * t310 * t377 + 0.2e1 * t147 * t830 + 0.8e1 * t368 * t22 - 0.2e1 * t169 * t617 + 0.16e2 * t662 * t276 - 0.8e1 * t355 * t854 + 0.4e1 * t493 * t971 - 0.16e2 * t9 * t533 - 0.2e1 * t169 * t279;
+ t997 = self->xc * t127;
+ t998 = t997 * t59;
+ t1003 = 0.4e1 * t40 * t579 + 0.2e1 * t169 * t845 + 0.16e2 * t9 * t515 + 0.8e1 * t206 * t551 + t123 * t41 * t128 + 0.16e2 * t98 * t60 * t162 + 0.2e1 * t169 * t364 - 0.2e1 * t169 * t932 + t139 * t778 + 0.4e1 * t648 * t998 + 0.2e1 * t147 * t412;
+ t1006 = t2 * t59;
+ t1017 = self->xc * t35;
+ t1033 = 0.4e1 * t1006 * t335 + 0.4e1 * t81 * t806 - 0.2e1 * t33 * t34 * t115 + 0.8e1 * t498 * t374 - 0.16e2 * t261 * t7 * t1017 * t15 + 0.8e1 * t206 * t101 * t124 - t123 * t448 + 0.2e1 * t147 * t735 + 0.6e1 * t98 * t208 + 0.6e1 * t98 * t88 - 0.4e1 * t33 * t755;
+ t1055 = -0.4e1 * t173 * t971 + 0.2e1 * t98 * t891 + 0.8e1 * t9 * t880 + 0.4e1 * t169 * t835 - t304 * t184 + t344 * t184 - t123 * t41 * t62 - 0.2e1 * t98 * t598 + 0.2e1 * t58 * t859 + 0.32e2 * t47 * t351 * t224 + 0.2e1 * t98 * t389;
+ t1070 = t15 * t19;
+ t1089 = -0.16e2 * t368 * t352 - 0.8e1 * t9 * t719 + 0.4e1 * t96 * t2 * self->xc * t134 - 0.2e1 * t91 * t236 * t115 + 0.4e1 * t27 * t573 + 0.4e1 * t493 * t282 * t1070 + 0.2e1 * t33 * t59 * t18 * t15 + 0.12e2 * t40 * t945 - 0.4e1 * t492 * self->xc * t82 * t1070 - 0.2e1 * t91 * t528 * t20 + 0.8e1 * t324 * t608;
+ t1113 = t123 * t82 * t124 + 0.8e1 * t421 * t428 - t139 * t417 + 0.4e1 * t40 * t645 + 0.16e2 * t393 * t759 - 0.2e1 * t33 * t179 * t115 - 0.4e1 * t525 * t335 + 0.4e1 * t33 * t28 * t36 - 0.4e1 * t1006 * t714 + 0.6e1 * t206 * t166 - 0.8e1 * t421 * t450;
+ t1119 = t321 * t46;
+ t1122 = t157 * t11;
+ t1123 = t1122 * t2;
+ t1124 = t184 * t46;
+ t1128 = t108 * n;
+ t1132 = t7 * t7;
+ t1133 = t1132 * t11;
+ t1134 = t1133 * t108;
+ t1135 = t15 * t46;
+ t1139 = t7 * self->ZA;
+ t1140 = t1139 * self->ZB;
+ t1141 = t1 * t35;
+ t1145 = t629 * t2;
+ t1146 = t1135 * t730;
+ t1149 = t157 * t1128;
+ t1150 = t1149 * self->xc;
+ t1153 = t46 * self->xc;
+ t1154 = t1153 * t127;
+ t1158 = t184 * t1 * t46;
+ t1161 = t46 * t46;
+ t1162 = t35 * t1161;
+ t1166 = t7 * t1;
+ t1170 = -0.4e1 * t133 * t1119 + 0.16e2 * t1123 * t1124 * t730 - 0.8e1 * t1122 * t1128 * t196 - 0.64e2 * t1134 * t1135 * t1017 - 0.32e2 * t1140 * t1141 * t1135 + 0.16e2 * t1145 * t1146 - 0.8e1 * t1150 * t650 - 0.16e2 * t1123 * t1154 - 0.4e1 * t133 * t1158 - 0.16e2 * t1140 * t1162 * t15 + 0.8e1 * t1166 * t35 * t312;
+ t1171 = t1161 * t184;
+ t1175 = t1122 * n;
+ t1176 = t15 * t1161;
+ t1180 = t1132 * self->ZA;
+ t1181 = t1180 * t355;
+ t1182 = t1176 * t1017;
+ t1185 = t1161 * self->xc;
+ t1189 = t1133 * t1;
+ t1192 = t108 * t1;
+ t1193 = t1132 * t1192;
+ t1195 = t10 * t35;
+ t1199 = t157 * t15;
+ t1203 = t1141 * t46;
+ t1211 = t184 * t108;
+ t1218 = 0.2e1 * t133 * t1171 * t35 + 0.8e1 * t1175 * t1176 * t997 + 0.64e2 * t1181 * t1182 - 0.8e1 * t1175 * t1185 * t127 - 0.32e2 * t1189 * t1182 - 0.64e2 * t1193 * self->ZA * t1195 * t228 + 0.8e1 * t1199 * t416 * t1128 + 0.8e1 * t1140 * t1203 - 0.4e1 * t75 * t1158 - 0.8e1 * t1199 * t560 * t1128 - 0.2e1 * t133 * t1211 - 0.8e1 * t1199 * t127 * t11 * t1128;
+ t1221 = t256 * t1161;
+ t1224 = t35 * t108;
+ t1233 = t7 * t256;
+ t1236 = -t75 * t1211 - t75 * t1221 - t133 * t1221 + t75 * t1224 - t75 * t1171 - t133 * t1171 + t133 * t1224 + t75 * t1162 - t75 * t108 * t256 + t133 * t1162 - t1233 * t59 * t108;
+ t1240 = t1135 * t1195;
+ t1252 = t629 * t127;
+ t1263 = t1171 * self->ZA;
+ t1280 = -0.128e3 * t1180 * self->ZB * t108 * t1240 + 0.32e2 * t1193 * t10 * t112 + 0.4e1 * t133 * t1203 + 0.4e1 * t109 * t256 * self->ZA * self->ZB - 0.8e1 * t1252 * n * t15 * t1185 + 0.8e1 * t1175 * t1171 * t730 - 0.8e1 * t1175 * t1176 * t127 + 0.4e1 * t223 * t1263 - 0.8e1 * t1175 * t1176 * t730 + 0.8e1 * t1166 * self->ZA * t341 * self->ZB + 0.64e2 * t1134 * t1240 + 0.8e1 * t1122 * self->xc * t1128 * t127 * t15;
+ t1283 = t1199 * t19;
+ t1287 = t1199 * t127;
+ t1289 = t59 * n * t1161;
+ t1293 = t157 * n * self->xc;
+ t1304 = t1132 * t108;
+ t1310 = t263 * self->ZB;
+ t1316 = t2 * t15;
+ t1323 = -0.16e2 * t1283 * t1006 * t46 + 0.8e1 * t1287 * t1289 + 0.8e1 * t1293 * t127 * t1161 * t59 + 0.16e2 * t1123 * t1135 * t19 + 0.8e1 * t1293 * t560 * t1176 + 0.64e2 * t1304 * t59 * t1240 + 0.4e1 * t75 * t1203 + 0.4e1 * t1310 * t1263 + 0.4e1 * t223 * t338 * t108 - 0.16e2 * t1252 * t1316 * t1153 - 0.16e2 * t1310 * t221 * t15;
+ t1330 = t1132 * t15;
+ t1336 = t1132 * t1;
+ t1338 = t1162 * t179;
+ t1370 = 0.8e1 * t1175 * t1176 * t19 + 0.4e1 * t1139 * t318 * t1161 + 0.128e3 * t1330 * t318 * t108 * t46 * t227 - 0.32e2 * t1336 * self->xc * t1338 + 0.4e1 * t1233 * self->ZA * t1161 * self->ZB - 0.8e1 * t1287 * t59 * t1128 * self->xc + 0.2e1 * t75 * t305 * t108 + 0.8e1 * t1199 * t127 * t59 * t1128 - 0.8e1 * t1283 * t1289 - 0.8e1 * t1293 * t560 * t1171 + 0.4e1 * t133 * t35 * t1158 + 0.8e1 * t157 * t184 * t19 * t11 * t1128 * self->xc;
+ t1376 = t7 * t184;
+ t1380 = t1176 * t1195;
+ t1393 = t1330 * t35;
+ t1411 = 0.16e2 * t1145 * t1154 + 0.8e1 * t1149 * t998 + 0.4e1 * t1376 * t35 * t48 + 0.32e2 * t1189 * t1380 + 0.32e2 * t1193 * t11 * t1195 * t15 - 0.64e2 * t1304 * self->xc * t111 * t1135 - 0.16e2 * t1123 * t1146 + 0.64e2 * t1393 * t28 * t1192 * self->xc - 0.16e2 * t1123 * t1135 * t127 - 0.8e1 * t1122 * self->xc * t1128 * t127 - 0.32e2 * t1193 * self->xc * t112 + 0.16e2 * t1252 * t1316 * t46;
+ t1450 = 0.2e1 * t1376 * t767 * t1161 + 0.2e1 * t1376 * t111 * t108 + 0.4e1 * t223 * t311 * t108 + 0.4e1 * t109 * t35 * t520 * self->ZA + 0.16e2 * t1123 * t1135 * t997 - 0.64e2 * t1181 * t1380 + 0.8e1 * t1150 * t903 - 0.32e2 * t1393 * t11 * t1192 * self->xc - 0.16e2 * t157 * t2 * self->xc * t560 * t1124 + 0.8e1 * t223 * t184 * t317 * t46 + 0.32e2 * t1336 * t10 * t1338 - 0.4e1 * t75 * t1119;
+ self->C3B = (t606 + t722 + t1089 + t781 + 0.16e2 * t48 * t51 + t978 + t868 + t507 - t304 * t256 + 0.8e1 * t9 * t22 + t752 + 0.4e1 * t174 * t144 - 0.2e1 * t81 * t469 + 0.6e1 * t139 * t166 + t362 + 0.2e1 * t98 * t211 + t925 + t137 - t290 * t184 + 0.12e2 * t81 * t83 + t842 + 0.8e1 * t74 * t77 + 0.16e2 * t98 * t12 * t162 - 0.4e1 * t33 * t28 * t443 - 0.8e1 * t27 * t70 - 0.2e1 * t33 * t34 * t36 - 0.8e1 * t27 * t30 + 0.2e1 * t58 * t67 - 0.4e1 * t40 * t43 + 0.2e1 * t58 * t63 + t1033 - t290 * t256 + t290 * t35 + t193 + t1113 + t578 + t442 + t474 + t544 + t329 + t679 + t401 + t953 + t811 + t644 + t894 + t289 + t240 + t1055 + t1003) / (t1170 + t1218 + 0.2e1 * t1236 + t1280 + t1323 + t1370 + t1411 + t1450);
+ /****************************************************************************************/
+ t1 = n * n;
+ t2 = t1 * self->xc;
+ t3 = self->ZB * self->ZB;
+ t5 = t2 * 0.3141592654e1 * t3;
+ t6 = nx * 0.3141592654e1;
+ t7 = t6 * self->xc;
+ t8 = cos(t7);
+ t9 = nx * nx;
+ t10 = t8 * t9;
+ t11 = n * 0.3141592654e1;
+ t12 = exp(t11);
+ t13 = t12 * t12;
+ t16 = exp( self->xc * n * 0.3141592654e1);
+ t17 = t16 * t16;
+ t18 = t17 * t16;
+ t19 = t17 * t17;
+ t20 = t19 * t18;
+ t21 = t13 * t20;
+ t22 = t10 * t21;
+ t25 = self->ZA * self->ZA;
+ t26 = t1 * t25;
+ t27 = self->xc * 0.3141592654e1;
+ t28 = t26 * t27;
+ t29 = t19 * t16;
+ t30 = t13 * t13;
+ t31 = t29 * t30;
+ t35 = t9 * nx;
+ t36 = t3 * t35;
+ t37 = sin(t6);
+ t38 = t13 * t12;
+ t39 = t37 * t38;
+ t40 = t39 * t19;
+ t42 = t1 * t1;
+ t43 = nx * t42;
+ t44 = self->xc * self->xc;
+ t45 = t25 * t44;
+ t46 = t43 * t45;
+ t47 = 0.3141592654e1 * 0.3141592654e1;
+ t48 = t47 * t37;
+ t49 = t17 * t38;
+ t54 = 0.3141592654e1 * t35;
+ t55 = self->ZA * n * t54;
+ t56 = t37 * self->ZB;
+ t57 = t19 * t12;
+ t61 = t25 * t8;
+ t62 = t61 * t9;
+ t63 = n * t30;
+ t64 = t63 * t16;
+ t67 = t1 * n;
+ t69 = t47 * self->ZB;
+ t70 = t67 * t44 * t69;
+ t75 = nx * t3;
+ t76 = t75 * t37;
+ t77 = t67 * 0.3141592654e1;
+ t78 = t19 * t19;
+ t79 = t78 * t12;
+ t80 = t77 * t79;
+ t82 = t3 * t38;
+ t84 = t54 * t37;
+ t87 = sin(t7);
+ t88 = t29 * t87;
+ t89 = t47 * t44;
+ t93 = nx * t25;
+ t94 = t87 * t42;
+ t95 = t93 * t94;
+ t96 = t47 * self->xc;
+ t97 = t13 * t29;
+ t98 = t96 * t97;
+ t101 = t87 * t67;
+ t102 = t93 * t101;
+ t103 = t13 * t18;
+ t107 = t47 * t35;
+ t108 = t26 * t107;
+ t109 = t37 * t44;
+ t110 = t19 * t17;
+ t111 = t12 * t110;
+ t116 = t37 * t19 * t12;
+ t118 = t37 * self->xc;
+ t119 = self->ZB * t19;
+ t120 = t119 * t12;
+ t121 = t118 * t120;
+ t125 = self->xc * t3;
+ t126 = t1 * t47 * t125;
+ t127 = t35 * t37;
+ t128 = t38 * t19;
+ t129 = t127 * t128;
+ t132 = t26 * 0.3141592654e1;
+ t133 = t16 * t13;
+ t134 = t10 * t133;
+ t137 = 0.3141592654e1 * self->ZB;
+ t138 = t2 * t137;
+ t139 = self->ZA * t8;
+ t140 = t9 * t13;
+ t145 = t30 * t18;
+ t146 = t10 * t145;
+ t149 = t3 * t8;
+ t150 = t149 * t9;
+ t153 = 0.2e1 * t5 * t22 + 0.2e1 * t28 * t10 * t31 + t36 * t40 - 0.2e1 * t46 * t48 * t49 - 0.2e1 * t55 * t56 * t57 - 0.2e1 * t62 * t64 + 0.16e2 * t70 * t29 * self->ZA * t10 - t76 * t80 + t82 * n * t84 + 0.8e1 * t43 * t3 * t88 * t89 + 0.16e2 * t95 * t98 + 0.2e1 * t102 * t27 * t103 - 0.2e1 * t108 * t109 * t111 + t36 * t116 + 0.8e1 * t55 * t121 - 0.4e1 * t126 * t129 - 0.4e1 * t132 * t134 - 0.4e1 * t138 * t139 * t140 * t20 + 0.8e1 * t28 * t146 - 0.2e1 * t150 * t64;
+ t154 = t42 * n;
+ t155 = nx * t154;
+ t156 = t44 * self->xc;
+ t157 = t47 * 0.3141592654e1;
+ t158 = t156 * t157;
+ t159 = t155 * t158;
+ t162 = t56 * self->ZA * t19 * t12;
+ t165 = t77 * t49;
+ t167 = t1 * t3;
+ t168 = t167 * t89;
+ t169 = t127 * t49;
+ t172 = t37 * t67;
+ t173 = t75 * t172;
+ t174 = t38 * t110;
+ t175 = t27 * t174;
+ t179 = t47 * t25;
+ t181 = t10 * t97;
+ t184 = t27 * t31;
+ t187 = t67 * t47;
+ t188 = t44 * t3;
+ t189 = t187 * t188;
+ t192 = t25 * t35;
+ t193 = t37 * t17;
+ t194 = t193 * t12;
+ t196 = nx * self->ZA;
+ t197 = t196 * t172;
+ t198 = self->ZB * t38;
+ t199 = t198 * t19;
+ t204 = t1 * t12 * t110;
+ t207 = nx * self->ZB;
+ t209 = t1 * self->ZA;
+ t215 = t67 * t3;
+ t216 = t47 * t8;
+ t217 = t215 * t216;
+ t218 = t9 * self->xc;
+ t222 = nx * t67;
+ t223 = t222 * t27;
+ t224 = t3 * t87;
+ t228 = t167 * t107;
+ t232 = t26 * t96;
+ t235 = t207 * t94;
+ t236 = t47 * self->ZA;
+ t243 = self->xc * t13;
+ t244 = t243 * t29;
+ t248 = t25 * n;
+ t249 = t248 * 0.3141592654e1;
+ t253 = self->ZB * self->ZA;
+ t254 = t253 * t8;
+ t255 = t9 * n;
+ t256 = t30 * t16;
+ t260 = 0.2e1 * t207 * t37 * t209 * t128 + 0.2e1 * t5 * t134 - 0.16e2 * t217 * t218 * t97 - 0.2e1 * t223 * t224 * t31 - 0.2e1 * t228 * t109 * t174 - 0.2e1 * t232 * t169 - 0.16e2 * t235 * t236 * t44 * t30 * t18 - 0.4e1 * t196 * t101 * t137 * t244 + t249 * t169 + 0.8e1 * t168 * t129 + 0.4e1 * t254 * t255 * t256;
+ t263 = t43 * t179;
+ t267 = t3 * n;
+ t268 = t267 * t54;
+ t269 = t118 * t57;
+ t272 = t39 * t1;
+ t274 = t67 * t25;
+ t275 = t274 * t158;
+ t278 = t75 * t87;
+ t279 = t77 * t103;
+ t282 = t25 * t38;
+ t285 = self->ZA * t38;
+ t290 = t267 * 0.3141592654e1;
+ t296 = t77 * t111;
+ t298 = t196 * t37;
+ t299 = t1 * self->ZB;
+ t303 = t37 * t42;
+ t304 = t196 * t303;
+ t308 = t77 * t57;
+ t310 = t26 * t89;
+ t313 = t77 * t128;
+ t316 = t101 * t27;
+ t319 = t93 * t87;
+ t320 = t77 * t97;
+ t323 = t127 * t57;
+ t326 = t10 * n;
+ t329 = t118 * t174;
+ t332 = -0.8e1 * t263 * t109 * t57 - 0.4e1 * t268 * t269 + t93 * t272 + 0.8e1 * t275 * t129 - 0.4e1 * t278 * t279 + t282 * n * t84 - 0.2e1 * t285 * n * t54 * t56 - t290 * t169 - 0.2e1 * t196 * t38 * t172 * t137 + t76 * t296 - 0.2e1 * t298 * t299 * t79 + 0.8e1 * t304 * t96 * t120 + t76 * t308 - 0.2e1 * t310 * t169 - t76 * t313 + 0.2e1 * t75 * t18 * t316 + 0.4e1 * t319 * t320 + t249 * t323 - 0.2e1 * t25 * t18 * t326 + 0.2e1 * t228 * t329;
+ t335 = t75 * t101;
+ t336 = t27 * t21;
+ t342 = t77 * t133;
+ t347 = t209 * t137;
+ t350 = t9 * t1;
+ t351 = t149 * t350;
+ t355 = t37 * t78 * t12;
+ t359 = t93 * t303;
+ t367 = t172 * 0.3141592654e1;
+ t369 = t96 * t103;
+ t376 = t209 * t107;
+ t379 = t10 * t103;
+ t383 = t207 * t101;
+ t389 = 0.3141592654e1 * self->ZA;
+ t390 = t222 * t389;
+ t391 = t87 * self->ZB;
+ t398 = -0.2e1 * t102 * t336 + t93 * t38 * t367 + 0.16e2 * t95 * t369 - t82 * t127 - 0.8e1 * t197 * t27 * t120 + 0.8e1 * t376 * t121 - 0.8e1 * t189 * t379 - t249 * t129 - 0.4e1 * t383 * t27 * self->ZA * t16 * t13 - 0.8e1 * t390 * t391 * t21 - 0.2e1 * t197 * t137 * t57;
+ t402 = t39 * t110;
+ t404 = t193 * t38;
+ t406 = t127 * t174;
+ t408 = t167 * 0.3141592654e1;
+ t411 = t44 * t157;
+ t412 = t155 * t411;
+ t413 = t285 * t19;
+ t414 = t56 * t413;
+ t417 = self->ZA * t30;
+ t424 = t93 * t37;
+ t426 = t248 * t54;
+ t427 = t17 * t12;
+ t428 = t118 * t427;
+ t431 = t77 * t21;
+ t438 = self->ZA * t13;
+ t443 = t93 * t172;
+ t444 = t27 * t427;
+ t448 = t1 * t78 * t12;
+ t455 = t274 * t89;
+ t461 = t118 * t111;
+ t464 = -t36 * t402 + t36 * t404 - t249 * t406 - 0.4e1 * t408 * t134 + 0.16e2 * t412 * t414 - 0.4e1 * t383 * t27 * t417 * t18 + 0.2e1 * t28 * t22 - t424 * t80 - 0.2e1 * t426 * t428 + 0.4e1 * t278 * t431 + 0.4e1 * t254 * t255 * t103 + t290 * t323 + 0.4e1 * t383 * t27 * t438 * t20 + 0.2e1 * t443 * t444 + t424 * t448 - t36 * t194 - 0.32e2 * t235 * t236 * t243 * t18 + 0.8e1 * t455 * t181 - 0.4e1 * t359 * t96 * t128 - 0.2e1 * t426 * t461;
+ t469 = n * t16 * t13;
+ t474 = t1 * t38;
+ t475 = t474 * t19;
+ t480 = t89 * t103;
+ t483 = t67 * self->ZA;
+ t484 = t483 * t411;
+ t485 = t127 * t120;
+ t488 = t127 * t111;
+ t497 = t77 * t427;
+ t502 = t27 * t97;
+ t508 = t1 * t19 * t12;
+ t511 = t155 * t25 * t156;
+ t512 = t157 * t37;
+ t513 = t512 * t128;
+ t527 = t1 * t17;
+ t528 = t527 * t38;
+ t530 = -t76 * t497 - 0.4e1 * t254 * t255 * t97 - 0.2e1 * t102 * t502 - 0.4e1 * t108 * t269 - t76 * t508 + 0.8e1 * t511 * t513 + 0.4e1 * t150 * t63 * t18 + 0.4e1 * t383 * t27 * t438 * t18 + 0.4e1 * t132 * t379 + 0.2e1 * t168 * t488 - t76 * t528;
+ t535 = t44 * t13;
+ t542 = t527 * t12;
+ t544 = n * t13;
+ t545 = t544 * t20;
+ t548 = t75 * t303;
+ t549 = t96 * t111;
+ t552 = self->ZA * t35;
+ t553 = t552 * t37;
+ t562 = t43 * t96;
+ t563 = t3 * t37;
+ t564 = t563 * t128;
+ t579 = t474 * t110;
+ t590 = t9 * t30;
+ t591 = t590 * t18;
+ t595 = t127 * t427;
+ t598 = t77 * t174;
+ t600 = 0.4e1 * t5 * t146 + 0.16e2 * t235 * t236 * t535 * t18 + 0.8e1 * t455 * t146 + t76 * t542 - 0.2e1 * t150 * t545 + 0.2e1 * t548 * t549 - 0.2e1 * t553 * t120 + t290 * t488 - 0.8e1 * t274 * t47 * t44 * t29 * t10 - 0.4e1 * t562 * t564 - 0.2e1 * t132 * self->xc * t20 * t10 - 0.32e2 * t562 * self->ZA * t87 * self->ZB * t13 * t29 - 0.8e1 * t347 * t379 + t76 * t579 - 0.4e1 * t359 * t96 * t57 + 0.4e1 * t408 * t181 - 0.4e1 * t223 * t564 - 0.12e2 * t209 * t27 * self->ZB * t8 * t591 + 0.2e1 * t310 * t595 + t76 * t598;
+ t601 = t27 * t49;
+ t604 = t127 * t79;
+ t606 = self->ZB * t29;
+ t616 = t139 * t140 * t18;
+ t638 = t10 * t256;
+ t643 = t118 * t199;
+ t653 = t544 * t29;
+ t658 = t3 * t29;
+ t660 = t350 * t27;
+ t663 = -0.4e1 * t254 * t255 * t145 + 0.2e1 * t267 * t20 * t8 * t9 - 0.4e1 * t138 * t139 * t9 * t16 * t13 - 0.2e1 * t5 * t638 + 0.2e1 * t126 * t169 + 0.8e1 * t376 * t643 + 0.4e1 * t335 * t27 * t145 + 0.16e2 * t235 * t236 * t535 * t29 + 0.6e1 * t150 * t653 - 0.4e1 * t426 * t269 + 0.4e1 * t658 * t8 * t660;
+ t670 = t274 * t411;
+ t673 = t118 * t49;
+ t694 = t155 * t45;
+ t713 = n * t29 * t30;
+ t717 = t20 * t87;
+ t723 = t512 * t57;
+ t728 = -0.2e1 * t443 * t175 - 0.8e1 * t670 * t129 + 0.2e1 * t426 * t673 - 0.16e2 * t207 * t88 * t42 * t47 * self->ZA * t44 + 0.4e1 * t254 * t255 * t21 + t249 * t595 + 0.8e1 * t25 * t29 * t8 * t660 + 0.2e1 * t268 * t461 + 0.8e1 * t189 * t181 - 0.8e1 * t694 * t513 + 0.2e1 * t198 * t553 - 0.12e2 * t606 * t139 * t660 - 0.2e1 * t359 * t549 + 0.4e1 * t138 * t139 * t590 * t16 + 0.8e1 * t93 * t29 * t94 * t89 - 0.2e1 * t150 * t713 + 0.2e1 * t222 * t3 * t717 * t27 + 0.8e1 * t670 * t323 + 0.8e1 * t694 * t723 - 0.2e1 * t62 * t653;
+ t734 = t43 * t89;
+ t735 = t563 * t427;
+ t740 = t75 * t94;
+ t744 = self->ZB * self->xc;
+ t750 = t563 * t57;
+ t754 = t218 * t103;
+ t771 = t127 * t199;
+ t776 = t89 * t174;
+ t791 = -0.4e1 * t207 * t717 * t77 * self->xc * self->ZA + 0.4e1 * t443 * t27 * t57 + t192 * t40 - 0.8e1 * t55 * t643 - 0.16e2 * t209 * t89 * t771 - 0.8e1 * t275 * t323 + 0.2e1 * t359 * t776 + 0.16e2 * t304 * t89 * t199 + 0.4e1 * t278 * t320 + 0.2e1 * t207 * t172 * t389 * t79 - 0.8e1 * t390 * t391 * t97;
+ t794 = t483 * t158;
+ t801 = t2 * 0.3141592654e1;
+ t818 = t215 * t411;
+ t827 = t96 * t174;
+ t837 = t37 * t12 * t110;
+ t845 = 0.16e2 * t794 * t485 + 0.8e1 * t159 * t564 - 0.8e1 * t455 * t379 - 0.2e1 * t801 * t3 * t20 * t10 - 0.4e1 * t132 * t22 - 0.8e1 * t734 * t564 - 0.8e1 * t187 * t44 * t658 * t10 - 0.8e1 * t412 * t564 + 0.4e1 * t132 * t181 - 0.8e1 * t818 * t129 + 0.2e1 * t46 * t48 * t427 - 0.4e1 * t75 * t29 * t316 - 0.2e1 * t359 * t827 - t290 * t595 + 0.16e2 * t217 * t754 - t424 * t542 - 0.8e1 * t734 * t750 - t192 * t837 - 0.4e1 * t254 * t255 * t133 + 0.8e1 * t304 * t96 * t199;
+ t864 = t544 * t18;
+ t867 = t3 * t18;
+ t884 = t27 * t256;
+ t891 = t187 * t744;
+ t894 = t563 * t49;
+ t900 = -0.2e1 * t263 * t428 + 0.2e1 * t228 * t428 - 0.6e1 * t223 * t224 * t103 - t192 * t404 + 0.2e1 * t268 * t428 - 0.2e1 * t335 * t884 - t424 * t296 + 0.2e1 * t93 * t20 * t316 - 0.32e2 * t891 * t616 + 0.2e1 * t562 * t894 - 0.2e1 * t801 * t867 * t10;
+ t904 = t27 * t111;
+ t907 = t118 * t128;
+ t915 = t89 * t145;
+ t947 = t139 * t140 * t29;
+ t952 = -0.2e1 * t173 * t904 + 0.4e1 * t426 * t907 + 0.12e2 * t253 * t10 * t1 * 0.3141592654e1 * t244 + 0.8e1 * t95 * t915 - t36 * t355 - 0.16e2 * t794 * t771 - 0.8e1 * t511 * t723 + 0.16e2 * t734 * t162 + t36 * t837 + 0.2e1 * t298 * t299 * t57 - 0.2e1 * t28 * t638 - 0.2e1 * t62 * t545 + 0.2e1 * t310 * t406 + 0.12e2 * t138 * t616 + 0.4e1 * t223 * t750 + t424 * t497 + 0.2e1 * t734 * t894 + 0.2e1 * t132 * self->xc * t18 * t10 - 0.16e2 * t70 * t947 + 0.32e2 * t891 * t947;
+ t969 = t67 * t157 * t156 * t3;
+ t974 = t27 * t133;
+ t1001 = -0.8e1 * t159 * t750 - 0.16e2 * t412 * t162 - t290 * t129 + 0.8e1 * t310 * t323 - 0.4e1 * t319 * t342 + t75 * t272 + t192 * t402 - 0.8e1 * t359 * t89 * t128 - 0.10e2 * t61 * t350 * t502 + 0.8e1 * t818 * t323 - 0.4e1 * t108 * t907;
+ t1042 = t89 * t97;
+ t1055 = -0.2e1 * t168 * t595 + 0.16e2 * t484 * t771 + 0.4e1 * t11 * t125 * t129 - 0.2e1 * t173 * t444 + 0.2e1 * self->ZB * n * t54 * t37 * self->ZA * t79 - t424 * t475 + 0.2e1 * t562 * t735 - 0.2e1 * t548 * t776 + t424 * t204 + 0.2e1 * t25 * t20 * t326 + 0.8e1 * t383 * t389 * t133 + t75 * t38 * t367 + 0.2e1 * t62 * t469 + 0.2e1 * t197 * t137 * t128 - 0.2e1 * t102 * t884 - 0.2e1 * t5 * t379 - 0.8e1 * t740 * t1042 - 0.16e2 * t159 * t414 - 0.2e1 * self->ZB * t35 * t37 * t413 + 0.2e1 * t553 * self->ZB * t78 * t12;
+ t1096 = 0.2e1 * t443 * t904 - 0.2e1 * t268 * t329 - 0.2e1 * t443 * t601 + 0.2e1 * t102 * t974 - 0.2e1 * t263 * t673 + t424 * t165 + 0.2e1 * t62 * t713 + t424 * t308 - t424 * t313 + 0.8e1 * t347 * t22 - t424 * t598;
+ t1103 = t42 * t1 * t157;
+ t1104 = t1103 * t25;
+ t1108 = t3 * t19;
+ t1112 = n * t47;
+ t1113 = t9 * t9;
+ t1118 = t42 * t157;
+ t1119 = t1118 * t9;
+ t1120 = t25 * self->xc;
+ t1121 = t13 * t110;
+ t1122 = t1120 * t1121;
+ t1125 = t47 * t47;
+ t1126 = t67 * t1125;
+ t1127 = t1113 * self->ZA;
+ t1128 = t1126 * t1127;
+ t1129 = t19 * t13;
+ t1130 = t744 * t1129;
+ t1133 = t154 * t1125;
+ t1134 = t1133 * t9;
+ t1135 = t45 * t1129;
+ t1138 = t154 * t47;
+ t1139 = t25 * t30;
+ t1142 = t1126 * t1113;
+ t1145 = t125 * t1129;
+ t1148 = t1103 * self->xc;
+ t1149 = t3 * t13;
+ t1150 = t1149 * t17;
+ t1153 = t25 * t78;
+ t1156 = -0.8e1 * t1104 * t243 * t17 + 0.4e1 * t187 * t1108 * t9 - 0.2e1 * t1112 * t3 * t1113 * t30 + 0.16e2 * t1119 * t1122 + 0.64e2 * t1128 * t1130 + 0.64e2 * t1134 * t1135 - 0.2e1 * t1138 * t1139 + 0.32e2 * t1142 * t1135 - 0.32e2 * t1142 * t1145 + 0.8e1 * t1148 * t1150 - 0.2e1 * t1138 * t1153;
+ t1157 = t25 * t13;
+ t1158 = t1157 * t17;
+ t1161 = t13 * t17;
+ t1162 = t1120 * t1161;
+ t1165 = t3 * t78;
+ t1170 = t42 * t67 * t1125;
+ t1172 = t1108 * t13;
+ t1175 = t1 * t157;
+ t1176 = t1175 * t1113;
+ t1182 = t1120 * t1129;
+ t1189 = t110 * t9 * self->xc;
+ t1192 = t1149 * t110;
+ t1201 = 0.8e1 * t1103 * t1158 - 0.16e2 * t1119 * t1162 - 0.2e1 * t1112 * t1165 * t1113 + 0.32e2 * t1170 * t44 * t1172 - 0.8e1 * t1176 * t1162 + 0.8e1 * t1104 * t243 * t110 - 0.64e2 * t1134 * t1182 - 0.64e2 * t1134 * t1145 + 0.16e2 * t1118 * t3 * t1189 + 0.16e2 * t1119 * t1192 - 0.4e1 * t187 * t1165 * t9 - 0.4e1 * t187 * t1139 * t9;
+ t1209 = t17 * t30;
+ t1210 = t125 * t1209;
+ t1213 = t1138 * self->ZA;
+ t1214 = self->ZB * t30;
+ t1218 = t1157 * t110;
+ t1226 = t3 * t30;
+ t1237 = t1170 * t25;
+ t1242 = 0.4e1 * t1112 * self->ZA * t119 * t1113 - 0.16e2 * t1119 * t1150 - 0.8e1 * t1176 * t1210 + 0.4e1 * t1213 * t1214 * t19 - 0.16e2 * t1119 * t1218 - 0.32e2 * t1142 * t1182 - 0.8e1 * t1103 * t1120 * t110 - 0.4e1 * t187 * t1226 * t9 + 0.8e1 * t1103 * t1192 + 0.4e1 * t1112 * self->ZB * t1113 * t30 * self->ZA - 0.32e2 * t1237 * self->xc * t19 * t13;
+ t1251 = t125 * t1121;
+ t1260 = t1120 * t1209;
+ t1263 = t1139 * t19;
+ t1282 = 0.8e1 * t1103 * t110 * t3 * self->xc + 0.8e1 * t1104 * self->xc * t17 * t30 - 0.8e1 * t1176 * t1251 + 0.16e2 * t1119 * t1158 + 0.4e1 * t1112 * t78 * t1127 * self->ZB + 0.16e2 * t1119 * t1260 + 0.2e1 * t1138 * t1263 - 0.32e2 * t1170 * self->xc * t1172 - 0.16e2 * t1213 * t119 * t13 + 0.4e1 * t1138 * t1214 * self->ZA + 0.32e2 * t1237 * t44 * t19 * t13 - 0.16e2 * t1118 * t25 * t1189;
+ t1287 = t188 * t1129;
+ t1292 = t25 * t19;
+ t1296 = t187 * t9;
+ t1297 = t1226 * t19;
+ t1311 = t1112 * t1113;
+ t1317 = -0.8e1 * t1176 * t1150 + 0.32e2 * t1142 * t1287 - 0.8e1 * t1103 * t1150 + 0.2e1 * t1112 * t1292 * t1113 + 0.4e1 * t1296 * t1297 + 0.8e1 * t1176 * t1192 + 0.4e1 * t1296 * t1263 + 0.8e1 * t1176 * t1158 - 0.8e1 * t1175 * t25 * t1113 * self->xc * t110 + 0.2e1 * t1311 * t1297 + 0.2e1 * t1112 * t1108 * t1113;
+ t1320 = t253 * t1129;
+ t1328 = t253 * t30 * t19;
+ t1333 = t125 * t1161;
+ t1343 = self->ZB * t44 * t1129;
+ t1350 = -0.8e1 * t1176 * t1218 - 0.16e2 * t1311 * t1320 + 0.8e1 * t1176 * t1260 - 0.16e2 * t1119 * t1210 + 0.4e1 * t1311 * t1328 + 0.2e1 * t1311 * t1263 + 0.8e1 * t1176 * t1333 + 0.8e1 * t187 * self->ZB * t417 * t9 - 0.2e1 * t1138 * t1165 - 0.64e2 * t1128 * t1343 + 0.64e2 * t1134 * t1287 + 0.2e1 * t1138 * t1108;
+ t1369 = t1133 * t9 * self->ZA;
+ t1378 = t187 * self->ZA;
+ t1383 = t1170 * self->ZA;
+ t1388 = 0.2e1 * t1138 * t1297 - 0.8e1 * t1148 * t1192 + 0.2e1 * t1138 * t1292 - 0.16e2 * t1119 * t1251 + 0.8e1 * t1175 * self->xc * t110 * t1113 * t3 - 0.2e1 * t1112 * t1153 * t1113 + 0.128e3 * t1369 * t1130 + 0.16e2 * t1119 * t1333 + 0.4e1 * t1138 * t78 * self->ZA * self->ZB + 0.8e1 * t1378 * t78 * t9 * self->ZB - 0.64e2 * t1383 * t1343 + 0.64e2 * t1383 * t1130;
+ t1420 = 0.4e1 * t1138 * t119 * self->ZA - 0.128e3 * t1369 * t1343 - 0.4e1 * t187 * t1153 * t9 - 0.2e1 * t1138 * t1226 + 0.8e1 * t1296 * t1328 - 0.2e1 * t1112 * t1139 * t1113 - 0.8e1 * t1148 * t3 * t17 * t30 - 0.32e2 * t1296 * t1320 + 0.8e1 * t1176 * t1122 + 0.4e1 * t187 * t1292 * t9 + 0.8e1 * t1378 * t119 * t9 - 0.8e1 * t1103 * t1218;
+
+ self->C4B = (-t424 * t508 + 0.8e1 * t412 * t750 - 0.2e1 * t232 * t595 - 0.4e1 * t126 * t323 + t1096 - t76 * t204 + t728 + 0.2e1 * t548 * t827 + 0.2e1 * t150 * t469 + t398 + 0.8e1 * t189 * t146 + t260 - 0.2e1 * t351 * t184 - 0.2e1 * t268 * t673 - 0.4e1 * t319 * t279 + t464 - 0.2e1 * t108 * t461 + 0.16e2 * t740 * t369 + 0.16e2 * t274 * t216 * t754 - 0.16e2 * t70 * t139 * t591 + 0.2e1 * t55 * t56 * t128 - 0.2e1 * t359 * t89 * t111 + 0.2e1 * t734 * t563 * t111 + 0.6e1 * t223 * t224 * t97 + 0.8e1 * t383 * t389 * t103 + 0.4e1 * t606 * self->ZA * t326 - 0.2e1 * t93 * t18 * t316 - 0.4e1 * t443 * t27 * t128 + 0.8e1 * t197 * t27 * t199 + 0.8e1 * t108 * t109 * t128 - t249 * t604 + 0.16e2 * t70 * t616 - 0.8e1 * t969 * t323 + t845 - t424 * t579 + 0.16e2 * t159 * t162 + t290 * t406 - 0.6e1 * t150 * t864 + t192 * t116 + 0.2e1 * t867 * t326 - 0.4e1 * t658 * t326 - 0.2e1 * t351 * t502 - t76 * t165 + t900 + 0.8e1 * t168 * t323 + t791 + 0.8e1 * t740 * t915 - 0.4e1 * t562 * t750 - 0.4e1 * t278 * t342 + 0.4e1 * t319 * t431 + 0.2e1 * t173 * t175 + t424 * t528 + 0.8e1 * t969 * t129 - 0.8e1 * t347 * t181 + t332 + t530 - 0.2e1 * t108 * t329 - 0.2e1 * t207 * t38 * t37 * t1 * self->ZA + t1001 + 0.4e1 * t408 * t379 + t76 * t448 + 0.2e1 * t102 * t184 + 0.2e1 * t426 * t329 + 0.16e2 * t740 * t98 - t282 * t127 - 0.16e2 * t1 * t44 * t69 * t552 * t116 + 0.2e1 * t168 * t169 + 0.2e1 * t28 * t134 - t290 * t604 - 0.16e2 * t484 * t485 - 0.8e1 * t740 * t480 + 0.2e1 * t173 * t601 - 0.2e1 * t335 * t336 + t600 + 0.2e1 * t62 * t864 + t952 + 0.8e1 * t347 * t134 - t192 * t355 + t192 * t194 + 0.2e1 * t228 * t461 + t663 + 0.4e1 * t383 * t27 * t417 * t16 + 0.4e1 * t138 * t20 * self->ZA * t10 - 0.4e1 * t20 * self->ZB * self->ZA * t326 + 0.4e1 * t196 * t88 * t77 * t744 - 0.16e2 * t67 * self->xc * t179 * t181 - 0.8e1 * t95 * t480 - t249 * t488 - t76 * t475 + t1055 - 0.4e1 * t408 * t22 - 0.10e2 * t28 * t379 + 0.2e1 * t335 * t974 + t153 - 0.8e1 * t95 * t1042 - 0.2e1 * t734 * t735) / (t1156 + t1201 + t1242 + t1282 + t1317 + t1350 + t1388 + t1420);
+ /****************************************************************************************/
+ /****************************************************************************************/
+}
+
+
+
+void ColumnViscosityAnalytic_VelocityFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* velocity ) {
+ ColumnViscosityAnalytic *self = (ColumnViscosityAnalytic*)analyticSolution;
+ double Z;
+ double x,y;
+ double C1,C2,C3,C4;
+ double n, nx;
+ double t1,t2,t3,t4,t5,t6,t7,t8,t11,t12,t13,t14,t15,t16,t18,t19,t20,t21,t23,t24,t25,t28,t29,t30,t31,t32,t33,t34,t36,t37;
+ double t41,t45,t49,t51,t53,t55,t58,t59,t60,t63,t67,t68,t73;
+ double t86,t87,t90,t91,t94,t106,t120;
+ double t121,t129,t146,t155,t156,t158,t159;
+
+ /* Find coordinate of node */
+ x = coord[ I_AXIS ];
+ y = coord[ J_AXIS ];
+
+ /* del_rho = sin(ny*Pi*y)*cos(nx*Pi*x) n=nx gives only non-zero terms*/
+ n = 1;
+ /* only one n in Fourier series because del_rho has cos term */
+ nx = n;
+
+ if ( x > self->xc ) {
+ C1 = self->C1B;
+ C2 = self->C2B;
+ C3 = self->C3B;
+ C4 = self->C4B;
+ Z = self->ZB;
+ }
+ else {
+ C1 = self->C1A;
+ C2 = self->C2A;
+ C3 = self->C3A;
+ C4 = self->C4A;
+ Z = self->ZA;
+ }
+
+ /****************************************************************************************/
+ /****************************************************************************************/
+ t1 = n * n;
+ t2 = t1 * t1;
+ t3 = t2 * n;
+ t4 = x * t3;
+ t5 = 0.3141592654e1 * 0.3141592654e1;
+ t6 = t5 * 0.3141592654e1;
+ t11 = C3 * t6;
+ t12 = x * n;
+ t13 = nx * nx;
+ t14 = t13 * t13;
+ t15 = t12 * t14;
+ t19 = exp(t12 * 0.3141592654e1);
+ t20 = t19 * t19;
+ t21 = t4 * t20;
+ t24 = C1 * t5;
+ t25 = Z * t20;
+ t29 = C1 * t6;
+ t30 = t29 * Z;
+ t31 = t1 * n;
+ t32 = x * t31;
+ t33 = t32 * t13;
+ t36 = t11 * x;
+ t41 = n * t20;
+ t45 = t6 * C4;
+ t49 = t20 * t1;
+ t51 = C2 * Z;
+ t55 = -0.2e1 * t4 * t6 * C2 * Z - 0.2e1 * t11 * t15 - 0.2e1 * t11 * t21 + 0.2e1 * t24 * t25 * t14 - t13 + 0.4e1 * t30 * t33 - 0.4e1 * t36 * t31 * t20 * t13 - 0.2e1 * t36 * t41 * t14 - 0.2e1 * t4 * t45 * t20 - t49 - 0.2e1 * t4 * t6 * t51 * t20;
+ t58 = t32 * t6;
+ t59 = C4 * t20;
+ t63 = t20 * t13;
+ t67 = t12 * t6;
+ t68 = t20 * t14;
+ t87 = t49 * t13;
+ t90 = -0.4e1 * t11 * t33 - 0.4e1 * t58 * t59 * t13 - 0.4e1 * t58 * t51 * t63 - 0.2e1 * t67 * t51 * t68 + 0.4e1 * t32 * t45 * t13 - 0.2e1 * t67 * t59 * t14 - 0.2e1 * t30 * t21 + t1 + 0.2e1 * t24 * t25 * t2 + 0.2e1 * t12 * t45 * t14 + 0.4e1 * t24 * Z * t87;
+ t106 = C3 * t5;
+ t120 = -0.4e1 * t30 * t32 * t63 + t63 + 0.4e1 * t24 * Z * t1 * t13 + 0.2e1 * t29 * Z * x * t3 - 0.4e1 * t58 * t51 * t13 - 0.2e1 * t106 * t2 + t32 * 0.3141592654e1 - 0.2e1 * t106 * t14 - 0.2e1 * t30 * t12 * t68 - 0.2e1 * t67 * t51 * t14 + 0.4e1 * t106 * t87;
+ t129 = sin(nx * 0.3141592654e1 * x);
+ t155 = 0.2e1 * t30 * t15 + x * 0.3141592654e1 * t41 * t13 - 0.4e1 * t19 * nx * t129 * n + t32 * 0.3141592654e1 * t20 + 0.2e1 * t106 * t68 + 0.2e1 * t106 * t20 * t2 - 0.4e1 * t106 * t1 * t13 - 0.2e1 * t11 * t4 + 0.2e1 * t4 * t45 + 0.2e1 * t24 * Z * t2 + 0.2e1 * t24 * Z * t14 + t12 * 0.3141592654e1 * t13;
+ t158 = t5 * Z;
+
+ velocity[ I_AXIS ] = (t55 + t90 + t120 + t155) / (0.4e1 * t158 * t19 * t2 + 0.8e1 * t158 * t19 * t1 * t13 + 0.4e1 * t158 * t19 * t14);
+ velocity[ I_AXIS ] *= cos(n*M_PI*y);
+
+ /****************************************************************************************/
+ /****************************************************************************************/
+ t1 = n * n;
+ t2 = t1 * n;
+ t3 = x * t2;
+ t4 = 0.3141592654e1 * 0.3141592654e1;
+ t5 = t4 * 0.3141592654e1;
+ t6 = t3 * t5;
+ t7 = C2 * Z;
+ t8 = nx * nx;
+ t12 = t1 * t1;
+ t13 = t12 * n;
+ t14 = x * t13;
+ t15 = t5 * C4;
+ t16 = x * n;
+ t18 = exp(t16 * 0.3141592654e1);
+ t19 = t18 * t18;
+ t23 = t16 * t5;
+ t24 = t8 * t8;
+ t28 = C3 * t5;
+ t29 = t14 * t19;
+ t32 = C1 * t5;
+ t33 = t32 * Z;
+ t34 = t16 * t24;
+ t37 = C4 * t19;
+ t45 = C2 * t4;
+ t53 = t19 * t8;
+ t58 = C4 * t4;
+ t60 = t1 * t19 * t8;
+ t63 = t19 * t24;
+ t67 = t3 * t8;
+ t73 = n * t19;
+ t86 = t28 * x;
+ t91 = 0.4e1 * t58 * t60 + 0.2e1 * t33 * t16 * t63 + 0.4e1 * t33 * t67 + 0.2e1 * t33 * t29 - x * 0.3141592654e1 * t73 * t8 - 0.2e1 * t53 + 0.2e1 * t32 * Z * x * t13 - 0.2e1 * t58 * t12 - 0.2e1 * t58 * t24 + t3 * 0.3141592654e1 + 0.4e1 * t86 * t2 * t19 * t8;
+ t94 = Z * t12;
+ t121 = -0.2e1 * t8 + 0.2e1 * t45 * t94 * t19 + 0.2e1 * t14 * t5 * t7 * t19 + 0.4e1 * t6 * t7 * t53 + 0.2e1 * t23 * t7 * t63 - 0.4e1 * t28 * t67 + 0.2e1 * t45 * t94 + 0.2e1 * t58 * t12 * t19 + t16 * 0.3141592654e1 * t8 + 0.2e1 * t14 * t15 - 0.2e1 * t28 * t14;
+ t146 = cos(nx * 0.3141592654e1 * x);
+ t156 = -t3 * 0.3141592654e1 * t19 + 0.2e1 * t58 * t63 - 0.4e1 * t58 * t1 * t8 + 0.4e1 * t45 * Z * t1 * t8 - 0.2e1 * t28 * t34 + 0.2e1 * t86 * t73 * t24 + 0.4e1 * t3 * t15 * t8 + 0.4e1 * t45 * Z * t60 + 0.4e1 * t18 * t146 * t8 + 0.2e1 * t45 * Z * t24 + 0.2e1 * t16 * t15 * t24;
+ t159 = t4 * Z;
+
+ velocity[ J_AXIS ] = (-0.4e1 * t6 * t7 * t8 + 0.2e1 * t14 * t15 * t19 - 0.2e1 * t23 * t7 * t24 + 0.2e1 * t28 * t29 + 0.2e1 * t33 * t34 + 0.4e1 * t6 * t37 * t8 - 0.2e1 * t14 * t5 * C2 * Z + 0.2e1 * t45 * Z * t19 * t24 + 0.2e1 * t23 * t37 * t24 + 0.4e1 * t33 * t3 * t53 + t91 + t121 + t156) / (0.4e1 * t159 * t18 * t12 + 0.8e1 * t159 * t18 * t1 * t8 + 0.4e1 * t159 * t18 * t24);
+ velocity[ J_AXIS ] *= sin(n*M_PI*y); /* y velocity */
+
+}
+
+
+void ColumnViscosityAnalytic_PressureFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* pressure ) {
+ ColumnViscosityAnalytic *self = (ColumnViscosityAnalytic*)analyticSolution;
+ double Z;
+ double x,y;
+ double C1,C2,C3,C4;
+ double n, nx;
+ XYZ velocity;
+ double u3;
+ double t9, t17, t40, t44, t48, t52, t57, t61, t62, t78, t101, t102, t109, t110, t128;
+ double t1,t2,t3,t4,t5,t6,t7,t8,t11,t12,t13,t14,t15,t16,t18,t19,t20,t23,t24,t28,t29,t30,t31,t32,t33,t34,t37;
+ double t45,t53,t58,t60,t63,t67,t73;
+ double t86,t90,t91,t94;
+ double t121,t146,t156,t159;
+
+ /* Find coordinate of node */
+ x = coord[ I_AXIS ];
+ y = coord[ J_AXIS ];
+
+ /* del_rho = sin(ny*Pi*y)*cos(nx*Pi*x) n=nx gives only non-zero terms*/
+ n = 1;
+ /* only one n in Fourier series because del_rho has cos term */
+ nx = n;
+
+ if ( x > self->xc ) {
+ C1 = self->C1B;
+ C2 = self->C2B;
+ C3 = self->C3B;
+ C4 = self->C4B;
+ Z = self->ZB;
+ }
+ else {
+ C1 = self->C1A;
+ C2 = self->C2A;
+ C3 = self->C3A;
+ C4 = self->C4A;
+ Z = self->ZA;
+ }
+
+ /****************************************************************************************/
+ /****************************************************************************************/
+ t1 = n * n;
+ t2 = t1 * n;
+ t3 = x * t2;
+ t4 = 0.3141592654e1 * 0.3141592654e1;
+ t5 = t4 * 0.3141592654e1;
+ t6 = t3 * t5;
+ t7 = C2 * Z;
+ t8 = nx * nx;
+ t12 = t1 * t1;
+ t13 = t12 * n;
+ t14 = x * t13;
+ t15 = t5 * C4;
+ t16 = x * n;
+ t18 = exp(t16 * 0.3141592654e1);
+ t19 = t18 * t18;
+ t23 = t16 * t5;
+ t24 = t8 * t8;
+ t28 = C3 * t5;
+ t29 = t14 * t19;
+ t32 = C1 * t5;
+ t33 = t32 * Z;
+ t34 = t16 * t24;
+ t37 = C4 * t19;
+ t45 = C2 * t4;
+ t53 = t19 * t8;
+ t58 = C4 * t4;
+ t60 = t1 * t19 * t8;
+ t63 = t19 * t24;
+ t67 = t3 * t8;
+ t73 = n * t19;
+ t86 = t28 * x;
+ t91 = 0.4e1 * t58 * t60 + 0.2e1 * t33 * t16 * t63 + 0.4e1 * t33 * t67 + 0.2e1 * t33 * t29 - x * 0.3141592654e1 * t73 * t8 - 0.2e1 * t53 + 0.2e1 * t32 * Z * x * t13 - 0.2e1 * t58 * t12 - 0.2e1 * t58 * t24 + t3 * 0.3141592654e1 + 0.4e1 * t86 * t2 * t19 * t8;
+ t94 = Z * t12;
+ t121 = -0.2e1 * t8 + 0.2e1 * t45 * t94 * t19 + 0.2e1 * t14 * t5 * t7 * t19 + 0.4e1 * t6 * t7 * t53 + 0.2e1 * t23 * t7 * t63 - 0.4e1 * t28 * t67 + 0.2e1 * t45 * t94 + 0.2e1 * t58 * t12 * t19 + t16 * 0.3141592654e1 * t8 + 0.2e1 * t14 * t15 - 0.2e1 * t28 * t14;
+ t146 = cos(nx * 0.3141592654e1 * x);
+ t156 = -t3 * 0.3141592654e1 * t19 + 0.2e1 * t58 * t63 - 0.4e1 * t58 * t1 * t8 + 0.4e1 * t45 * Z * t1 * t8 - 0.2e1 * t28 * t34 + 0.2e1 * t86 * t73 * t24 + 0.4e1 * t3 * t15 * t8 + 0.4e1 * t45 * Z * t60 + 0.4e1 * t18 * t146 * t8 + 0.2e1 * t45 * Z * t24 + 0.2e1 * t16 * t15 * t24;
+ t159 = t4 * Z;
+
+ velocity[ J_AXIS ] = (-0.4e1 * t6 * t7 * t8 + 0.2e1 * t14 * t15 * t19 - 0.2e1 * t23 * t7 * t24 + 0.2e1 * t28 * t29 + 0.2e1 * t33 * t34 + 0.4e1 * t6 * t37 * t8 - 0.2e1 * t14 * t5 * C2 * Z + 0.2e1 * t45 * Z * t19 * t24 + 0.2e1 * t23 * t37 * t24 + 0.4e1 * t33 * t3 * t53 + t91 + t121 + t156) / (0.4e1 * t159 * t18 * t12 + 0.8e1 * t159 * t18 * t1 * t8 + 0.4e1 * t159 * t18 * t24);
+ velocity[ J_AXIS ] *= sin(n*M_PI*y); /* y velocity */
+
+ /****************************************************************************************/
+ /****************************************************************************************/
+ t1 = 0.3141592654e1 * 0.3141592654e1;
+ t2 = t1 * 0.3141592654e1;
+ t3 = C1 * t2;
+ t4 = t3 * Z;
+ t5 = n * n;
+ t6 = t5 * t5;
+ t7 = t6 * n;
+ t8 = x * t7;
+ t9 = x * n;
+ t11 = exp(t9 * 0.3141592654e1);
+ t12 = t11 * t11;
+ t13 = t8 * t12;
+ t16 = t5 * n;
+ t17 = x * t16;
+ t18 = t17 * t2;
+ t19 = C4 * t12;
+ t20 = nx * nx;
+ t24 = t2 * C4;
+ t28 = C3 * t2;
+ t29 = t28 * x;
+ t30 = t12 * n;
+ t31 = t20 * t20;
+ t40 = C2 * Z;
+ t44 = t9 * t2;
+ t48 = t12 * t20;
+ t52 = t17 * t20;
+ t57 = -0.2e1 * t4 * t13 - 0.4e1 * t18 * t19 * t20 - 0.2e1 * t8 * t24 * t12 - 0.2e1 * t29 * t30 * t31 + 0.2e1 * t8 * t2 * C2 * Z - 0.2e1 * t8 * t2 * t40 * t12 - 0.2e1 * t44 * t19 * t31 - 0.4e1 * t18 * t40 * t48 + t20 + 0.4e1 * t28 * t52 + t17 * 0.3141592654e1 * t12;
+ t58 = t9 * t31;
+ t61 = C3 * t1;
+ t62 = t12 * t31;
+ t73 = t5 * t20;
+ t78 = C1 * t1;
+ t90 = Z * t12;
+ t94 = 0.2e1 * t28 * t58 + 0.2e1 * t61 * t62 + 0.2e1 * t61 * t12 * t6 - 0.4e1 * t4 * t17 * t48 + 0.2e1 * t28 * t8 + 0.4e1 * t61 * t73 - 0.2e1 * t8 * t24 - 0.2e1 * t78 * Z * t6 - 0.2e1 * t44 * t40 * t62 - 0.2e1 * t78 * Z * t31 - t9 * 0.3141592654e1 * t20 + 0.2e1 * t78 * t90 * t6;
+ t101 = cos(nx * 0.3141592654e1 * x);
+ t102 = t11 * t101;
+ t109 = t12 * t5;
+ t110 = t109 * t20;
+ t128 = 0.2e1 * t61 * t6 - t17 * 0.3141592654e1 + 0.2e1 * t102 * t5 - 0.4e1 * t17 * t24 * t20 + 0.4e1 * t78 * Z * t110 - 0.2e1 * t9 * t24 * t31 - 0.4e1 * t4 * t52 - 0.2e1 * t4 * t9 * t62 + x * 0.3141592654e1 * t30 * t20 - t5 - 0.4e1 * t78 * Z * t5 * t20;
+ t156 = 0.2e1 * t78 * t90 * t31 - 0.2e1 * t3 * Z * x * t7 + t48 + 0.4e1 * t61 * t110 + 0.4e1 * t18 * t40 * t20 - 0.2e1 * t102 * t20 + 0.2e1 * t61 * t31 + 0.2e1 * t44 * t40 * t31 - t109 - 0.2e1 * t4 * t58 - 0.2e1 * t28 * t13 - 0.4e1 * t29 * t16 * t12 * t20;
+ t159 = t1 * t11;
+
+ u3 = (t57 + t94 + t128 + t156) / (0.4e1 * t159 * t6 + 0.8e1 * t159 * t73 + 0.4e1 * t159 * t31);
+ /****************************************************************************************/
+ /****************************************************************************************/
+
+ *pressure = (double)(-2*Z*n*M_PI*velocity[ J_AXIS ]-u3*2*n*M_PI)*cos(n*M_PI*y);
+
+}
+
+void ColumnViscosityAnalytic_StressFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* stress ) {
+ ColumnViscosityAnalytic *self = (ColumnViscosityAnalytic*)analyticSolution;
+ double Z;
+ double x,y;
+ double C1,C2,C3,C4;
+ double n, nx;
+ double u2, u3, u4;
+ double t1,t2,t3,t4,t5,t6,t7,t8,t9,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t23,t24,t28,t29,t30,t31,t32,t33,t34,t35,t37,t40;
+ double t41,t44,t45,t47,t48,t52,t53,t54,t57,t58,t60,t61,t62,t63,t67,t69,t73,t75,t78,t79;
+ double t83,t84,t86,t90,t91,t94,t95,t97,t101,t102,t106,t109,t110;
+ double t121,t127,t128,t131,t135,t146,t156,t159;
+ double t164;
+
+ /* Find coordinate of node */
+ x = coord[ I_AXIS ];
+ y = coord[ J_AXIS ];
+
+ /* del_rho = sin(ny*Pi*y)*cos(nx*Pi*x) n=nx gives only non-zero terms*/
+ n = 1;
+ /* only one n in Fourier series because del_rho has cos term */
+ nx = n;
+
+ if ( x > self->xc ) {
+ C1 = self->C1B;
+ C2 = self->C2B;
+ C3 = self->C3B;
+ C4 = self->C4B;
+ Z = self->ZB;
+ }
+ else {
+ C1 = self->C1A;
+ C2 = self->C2A;
+ C3 = self->C3A;
+ C4 = self->C4A;
+ Z = self->ZA;
+ }
+
+ t1 = n * n;
+ t2 = t1 * n;
+ t3 = x * t2;
+ t4 = 0.3141592654e1 * 0.3141592654e1;
+ t5 = t4 * 0.3141592654e1;
+ t6 = t3 * t5;
+ t7 = C2 * Z;
+ t8 = nx * nx;
+ t12 = t1 * t1;
+ t13 = t12 * n;
+ t14 = x * t13;
+ t15 = t5 * C4;
+ t16 = x * n;
+ t18 = exp(t16 * 0.3141592654e1);
+ t19 = t18 * t18;
+ t23 = t16 * t5;
+ t24 = t8 * t8;
+ t28 = C3 * t5;
+ t29 = t14 * t19;
+ t32 = C1 * t5;
+ t33 = t32 * Z;
+ t34 = t16 * t24;
+ t37 = C4 * t19;
+ t45 = C2 * t4;
+ t53 = t19 * t8;
+ t58 = C4 * t4;
+ t60 = t1 * t19 * t8;
+ t63 = t19 * t24;
+ t67 = t3 * t8;
+ t73 = n * t19;
+ t86 = t28 * x;
+ t91 = 0.4e1 * t58 * t60 + 0.2e1 * t33 * t16 * t63 + 0.4e1 * t33 * t67 + 0.2e1 * t33 * t29 - x * 0.3141592654e1 * t73 * t8 - 0.2e1 * t53 + 0.2e1 * t32 * Z * x * t13 - 0.2e1 * t58 * t12 - 0.2e1 * t58 * t24 + t3 * 0.3141592654e1 + 0.4e1 * t86 * t2 * t19 * t8;
+ t94 = Z * t12;
+ t121 = -0.2e1 * t8 + 0.2e1 * t45 * t94 * t19 + 0.2e1 * t14 * t5 * t7 * t19 + 0.4e1 * t6 * t7 * t53 + 0.2e1 * t23 * t7 * t63 - 0.4e1 * t28 * t67 + 0.2e1 * t45 * t94 + 0.2e1 * t58 * t12 * t19 + t16 * 0.3141592654e1 * t8 + 0.2e1 * t14 * t15 - 0.2e1 * t28 * t14;
+ t146 = cos(nx * 0.3141592654e1 * x);
+ t156 = -t3 * 0.3141592654e1 * t19 + 0.2e1 * t58 * t63 - 0.4e1 * t58 * t1 * t8 + 0.4e1 * t45 * Z * t1 * t8 - 0.2e1 * t28 * t34 + 0.2e1 * t86 * t73 * t24 + 0.4e1 * t3 * t15 * t8 + 0.4e1 * t45 * Z * t60 + 0.4e1 * t18 * t146 * t8 + 0.2e1 * t45 * Z * t24 + 0.2e1 * t16 * t15 * t24;
+ t159 = t4 * Z;
+
+ u2 = (-0.4e1 * t6 * t7 * t8 + 0.2e1 * t14 * t15 * t19 - 0.2e1 * t23 * t7 * t24 + 0.2e1 * t28 * t29 + 0.2e1 * t33 * t34 + 0.4e1 * t6 * t37 * t8 - 0.2e1 * t14 * t5 * C2 * Z + 0.2e1 * t45 * Z * t19 * t24 + 0.2e1 * t23 * t37 * t24 + 0.4e1 * t33 * t3 * t53 + t91 + t121 + t156) / (0.4e1 * t159 * t18 * t12 + 0.8e1 * t159 * t18 * t1 * t8 + 0.4e1 * t159 * t18 * t24);
+
+ /****************************************************************************************/
+ /****************************************************************************************/
+
+ t1 = 0.3141592654e1 * 0.3141592654e1;
+ t2 = t1 * 0.3141592654e1;
+ t3 = C1 * t2;
+ t4 = t3 * Z;
+ t5 = n * n;
+ t6 = t5 * t5;
+ t7 = t6 * n;
+ t8 = x * t7;
+ t9 = x * n;
+ t11 = exp(t9 * 0.3141592654e1);
+ t12 = t11 * t11;
+ t13 = t8 * t12;
+ t16 = t5 * n;
+ t17 = x * t16;
+ t18 = t17 * t2;
+ t19 = C4 * t12;
+ t20 = nx * nx;
+ t24 = t2 * C4;
+ t28 = C3 * t2;
+ t29 = t28 * x;
+ t30 = t12 * n;
+ t31 = t20 * t20;
+ t40 = C2 * Z;
+ t44 = t9 * t2;
+ t48 = t12 * t20;
+ t52 = t17 * t20;
+ t57 = -0.2e1 * t4 * t13 - 0.4e1 * t18 * t19 * t20 - 0.2e1 * t8 * t24 * t12 - 0.2e1 * t29 * t30 * t31 + 0.2e1 * t8 * t2 * C2 * Z - 0.2e1 * t8 * t2 * t40 * t12 - 0.2e1 * t44 * t19 * t31 - 0.4e1 * t18 * t40 * t48 + t20 + 0.4e1 * t28 * t52 + t17 * 0.3141592654e1 * t12;
+ t58 = t9 * t31;
+ t61 = C3 * t1;
+ t62 = t12 * t31;
+ t73 = t5 * t20;
+ t78 = C1 * t1;
+ t90 = Z * t12;
+ t94 = 0.2e1 * t28 * t58 + 0.2e1 * t61 * t62 + 0.2e1 * t61 * t12 * t6 - 0.4e1 * t4 * t17 * t48 + 0.2e1 * t28 * t8 + 0.4e1 * t61 * t73 - 0.2e1 * t8 * t24 - 0.2e1 * t78 * Z * t6 - 0.2e1 * t44 * t40 * t62 - 0.2e1 * t78 * Z * t31 - t9 * 0.3141592654e1 * t20 + 0.2e1 * t78 * t90 * t6;
+ t101 = cos(nx * 0.3141592654e1 * x);
+ t102 = t11 * t101;
+ t109 = t12 * t5;
+ t110 = t109 * t20;
+ t128 = 0.2e1 * t61 * t6 - t17 * 0.3141592654e1 + 0.2e1 * t102 * t5 - 0.4e1 * t17 * t24 * t20 + 0.4e1 * t78 * Z * t110 - 0.2e1 * t9 * t24 * t31 - 0.4e1 * t4 * t52 - 0.2e1 * t4 * t9 * t62 + x * 0.3141592654e1 * t30 * t20 - t5 - 0.4e1 * t78 * Z * t5 * t20;
+ t156 = 0.2e1 * t78 * t90 * t31 - 0.2e1 * t3 * Z * x * t7 + t48 + 0.4e1 * t61 * t110 + 0.4e1 * t18 * t40 * t20 - 0.2e1 * t102 * t20 + 0.2e1 * t61 * t31 + 0.2e1 * t44 * t40 * t31 - t109 - 0.2e1 * t4 * t58 - 0.2e1 * t28 * t13 - 0.4e1 * t29 * t16 * t12 * t20;
+ t159 = t1 * t11;
+
+ u3 = (t57 + t94 + t128 + t156) / (0.4e1 * t159 * t6 + 0.8e1 * t159 * t73 + 0.4e1 * t159 * t31);
+ /****************************************************************************************/
+ /****************************************************************************************/
+
+ t1 = C2 * Z;
+ t2 = 0.3141592654e1 * 0.3141592654e1;
+ t3 = t2 * 0.3141592654e1;
+ t4 = n * n;
+ t5 = t4 * t4;
+ t6 = t5 * t4;
+ t8 = t3 * t6 * x;
+ t11 = x * t4;
+ t12 = t11 * t3;
+ t15 = exp(x * n * 0.3141592654e1);
+ t16 = t15 * t15;
+ t17 = C3 * t16;
+ t18 = nx * nx;
+ t19 = t18 * t18;
+ t23 = t5 * n;
+ t24 = t2 * t23;
+ t28 = t1 * t3;
+ t29 = t6 * x;
+ t30 = t29 * t16;
+ t33 = C4 * t3;
+ t34 = t5 * x;
+ t35 = t34 * t18;
+ t41 = sin(nx * 0.3141592654e1 * x);
+ t47 = t11 * t19;
+ t54 = t3 * C3;
+ t57 = 0.2e1 * t1 * t8 + 0.2e1 * t12 * t17 * t19 + 0.2e1 * t1 * t24 * t16 + 0.2e1 * t28 * t30 - 0.4e1 * t33 * t35 + 0.2e1 * t15 * nx * t41 * t4 + 0.4e1 * t28 * t35 - 0.2e1 * t33 * t47 - 0.2e1 * t1 * t24 - 0.2e1 * t33 * t29 + 0.2e1 * t29 * t54;
+ t58 = 0.3141592654e1 * t16;
+ t60 = t2 * C4;
+ t69 = t4 * n;
+ t73 = t1 * t2;
+ t75 = t69 * t16 * t18;
+ t79 = x * t16;
+ t83 = n * t16;
+ t84 = t83 * t19;
+ t95 = -t34 * t58 + 0.2e1 * t60 * t23 * t16 + 0.2e1 * t60 * n * t19 - t11 * 0.3141592654e1 * t18 + 0.4e1 * t60 * t69 * t18 + 0.4e1 * t73 * t75 + 0.4e1 * t33 * t5 * t79 * t18 + 0.2e1 * t73 * t84 + 0.2e1 * t60 * t84 + 0.2e1 * t33 * t4 * t79 * t19 + 0.4e1 * t60 * t75;
+ t97 = t34 * t3;
+ t101 = Z * C1;
+ t102 = t16 * t19;
+ t106 = t16 * t18;
+ t127 = t2 * t69;
+ t131 = t2 * n;
+ t135 = 0.4e1 * t97 * t17 * t18 + 0.2e1 * t12 * t101 * t102 + 0.4e1 * t28 * t34 * t106 + 0.2e1 * t28 * t11 * t102 - 0.2e1 * t29 * t3 * Z * C1 - 0.4e1 * t97 * t101 * t18 - 0.2e1 * t12 * t101 * t19 + 0.2e1 * t60 * t23 - 0.2e1 * t83 * t18 - 0.4e1 * t1 * t127 * t18 - 0.2e1 * t1 * t131 * t19;
+ t164 = 0.2e1 * t28 * t47 + 0.2e1 * t11 * t54 * t19 + 0.2e1 * t8 * t101 * t16 + 0.2e1 * t33 * t30 - t11 * t58 * t18 + 0.2e1 * t29 * t54 * t16 + 0.4e1 * t34 * t54 * t18 + 0.4e1 * t97 * t101 * t106 - 0.2e1 * t15 * t18 * nx * t41 - t34 * 0.3141592654e1 + 0.2e1 * n * t18;
+
+ u4 = (t57 + t95 + t135 + t164) / (0.4e1 * t24 * t15 + 0.8e1 * t127 * t15 * t18 + 0.4e1 * t131 * t15 * t19);
+ /****************************************************************************************/
+ /****************************************************************************************/
+
+ stress[0] = (double)(u4*2*n*M_PI + 4*Z*n*M_PI*u2)*cos(n*M_PI*y); /* xx stress */
+ stress[1] = 2*n*M_PI*cos(n*M_PI*y) * u3; /* yy stress */
+ stress[2] = 2*n*M_PI*sin(n*M_PI*y) * u4; /* xy stress */
+}
+
+void _ColumnViscosityAnalytic_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ ColumnViscosityAnalytic* self = (ColumnViscosityAnalytic*)analyticSolution;
+ AbstractContext* context;
+ ConditionFunction* condFunc;
+
+ /* Construct Parent */
+ _AnalyticSolution_AssignFromXML( self, cf, data );
+
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+
+ /* Create Analytic Fields */
+ self->velocityField = Stg_ComponentFactory_ConstructByName( cf, (Name)"VelocityField", FeVariable, True, data );
+ self->pressureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"PressureField", FeVariable, True, data );
+ self->stressField = Stg_ComponentFactory_ConstructByName( cf, (Name)"StressField", FeVariable, False, data );
+
+ /* Add condition function for temperature */
+ condFunc = ConditionFunction_New( ColumnViscosityAnalytic_TemperatureIC, (Name)"ColumnViscosityAnalytic_TemperatureIC" );
+ ConditionFunction_Register_Add( context->condFunc_Register, condFunc );
+
+ /* Set up constants */
+ self->ZA = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"leftViscosity", 1.0 );
+ self->ZB = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"rightViscosity", 1.0 );
+
+ /* top layer viscosity */
+ self->xc = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"columnEnd", 0.5 );
+ ColumnViscosityAnalytic_Constants( self );
+}
+
+void _ColumnViscosityAnalytic_Build( void* analyticSolution, void* data ) {
+ ColumnViscosityAnalytic* self = (ColumnViscosityAnalytic*)analyticSolution;
+
+ Build( self->velocityField, data, False );
+ Build( self->pressureField, data, False );
+ if( self->stressField )
+ Build( self->stressField, data, False );
+
+ AnalyticSolution_CreateAnalyticField( self, self->velocityField, ColumnViscosityAnalytic_VelocityFunction );
+ AnalyticSolution_CreateAnalyticField( self, self->pressureField, ColumnViscosityAnalytic_PressureFunction );
+ if( self->stressField )
+ AnalyticSolution_CreateAnalyticField( self, self->stressField, ColumnViscosityAnalytic_StressFunction );
+
+ _AnalyticSolution_Build( self, data );
+}
+
+void* _ColumnViscosityAnalytic_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(ColumnViscosityAnalytic);
+ Type type = ColumnViscosityAnalytic_Type;
+ Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
+ Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
+ Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _ColumnViscosityAnalytic_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _ColumnViscosityAnalytic_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _ColumnViscosityAnalytic_Build;
+ Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
+ Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
+}
+
+Index StgFEM_ColumnViscosityAnalytic_Register( PluginsManager* pluginsManager ) {
+ return PluginsManager_Submit( pluginsManager, ColumnViscosityAnalytic_Type, (Name)"0", _ColumnViscosityAnalytic_DefaultNew );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/DivergenceMatrixTerm.c
--- a/Assembly/src/DivergenceMatrixTerm.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,255 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: DivergenceMatrixTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/SLE/SLE.h>
-
-#include "types.h"
-#include "DivergenceMatrixTerm.h"
-
-#include <assert.h>
-#include <string.h>
-
-/* Textual name of this class */
-const Type DivergenceMatrixTerm_Type = "DivergenceMatrixTerm";
-
-DivergenceMatrixTerm* DivergenceMatrixTerm_New(
- Name name,
- FiniteElementContext* context,
- StiffnessMatrix* stiffnessMatrix,
- Swarm* integrationSwarm )
-{
- DivergenceMatrixTerm* self = (DivergenceMatrixTerm*) _DivergenceMatrixTerm_DefaultNew( name );
-
- self->isConstructed = True;
- _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
- _DivergenceMatrixTerm_Init( self );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-DivergenceMatrixTerm* _DivergenceMatrixTerm_New( DIVERGENCEMATRIXTERM_DEFARGS )
-{
- DivergenceMatrixTerm* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(DivergenceMatrixTerm) );
- self = (DivergenceMatrixTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
-
- /* Virtual info */
-
- return self;
-}
-
-void _DivergenceMatrixTerm_Init( void* matrixTerm ) {
- DivergenceMatrixTerm* self = (DivergenceMatrixTerm*)matrixTerm;
-
- self->max_nElNodes_col = 0;
- self->Ni_col = NULL;
-}
-
-void _DivergenceMatrixTerm_Delete( void* matrixTerm ) {
- DivergenceMatrixTerm* self = (DivergenceMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Delete( self );
-
- Memory_Free( self->Ni_col );
-}
-
-void _DivergenceMatrixTerm_Print( void* matrixTerm, Stream* stream ) {
- DivergenceMatrixTerm* self = (DivergenceMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Print( self, stream );
-
- /* General info */
-}
-
-void* _DivergenceMatrixTerm_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(DivergenceMatrixTerm);
- Type type = DivergenceMatrixTerm_Type;
- Stg_Class_DeleteFunction* _delete = _DivergenceMatrixTerm_Delete;
- Stg_Class_PrintFunction* _print = _DivergenceMatrixTerm_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _DivergenceMatrixTerm_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _DivergenceMatrixTerm_AssignFromXML;
- Stg_Component_BuildFunction* _build = _DivergenceMatrixTerm_Build;
- Stg_Component_InitialiseFunction* _initialise = _DivergenceMatrixTerm_Initialise;
- Stg_Component_ExecuteFunction* _execute = _DivergenceMatrixTerm_Execute;
- Stg_Component_DestroyFunction* _destroy = _DivergenceMatrixTerm_Destroy;
- StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _DivergenceMatrixTerm_AssembleElement;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_DivergenceMatrixTerm_New( DIVERGENCEMATRIXTERM_PASSARGS );
-}
-
-void _DivergenceMatrixTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
- DivergenceMatrixTerm* self = (DivergenceMatrixTerm*)matrixTerm;
-
- /* Construct Parent */
- _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
-
- _DivergenceMatrixTerm_Init( self );
-}
-
-void _DivergenceMatrixTerm_Build( void* matrixTerm, void* data ) {
- DivergenceMatrixTerm* self = (DivergenceMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Build( self, data );
-}
-
-void _DivergenceMatrixTerm_Initialise( void* matrixTerm, void* data ) {
- DivergenceMatrixTerm* self = (DivergenceMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Initialise( self, data );
-}
-
-void _DivergenceMatrixTerm_Execute( void* matrixTerm, void* data ) {
- _StiffnessMatrixTerm_Execute( matrixTerm, data );
-}
-
-void _DivergenceMatrixTerm_Destroy( void* matrixTerm, void* data ) {
- DivergenceMatrixTerm* self = (DivergenceMatrixTerm*) matrixTerm;
-
- if( self->Ni_col) Memory_Free( self->Ni_col );
- _StiffnessMatrixTerm_Destroy( matrixTerm, data );
-}
-
-void _DivergenceMatrixTerm_AssembleElement(
- void* matrixTerm,
- StiffnessMatrix* stiffnessMatrix,
- Element_LocalIndex lElement_I,
- SystemLinearEquations* sle,
- FiniteElementContext* context,
- double** elStiffMat )
-{
- DivergenceMatrixTerm* self = Stg_CheckType( matrixTerm, DivergenceMatrixTerm );
- Swarm* swarm = self->integrationSwarm;
- FeVariable* variable_row = stiffnessMatrix->columnVariable;
- FeVariable* variable_col = stiffnessMatrix->rowVariable;
- Dimension_Index dim = stiffnessMatrix->dim;
- double* xi;
- double weight;
- Particle_InCellIndex cParticle_I, cellParticleCount;
- Node_ElementLocalIndex nodesPerEl_row;
- Node_ElementLocalIndex nodesPerEl_col;
- Dof_Index totalDofsThisElement_row, totalDofsThisElement_col;
-
- Dof_Index dofPerNode_row, dofPerNode_col;
- Index row, col; /* Indices into the stiffness matrix */
- Node_ElementLocalIndex rowNode_I;
- Node_ElementLocalIndex colNode_I;
- Dof_Index rowDof_I, colDof_I;
- double** GNx_row;
- double* Ni_col;
- double detJac;
- IntegrationPoint* currIntegrationPoint;
-
- Cell_Index cell_I;
- ElementType* elementType_row;
- ElementType* elementType_col;
-
- /* Set the element type */
- elementType_row = FeMesh_GetElementType( variable_row->feMesh, lElement_I );
- nodesPerEl_row = elementType_row->nodeCount;
-
- elementType_col = FeMesh_GetElementType( variable_col->feMesh, lElement_I );
- nodesPerEl_col = elementType_col->nodeCount;
-
- dofPerNode_row = dim; /* velocity */
- dofPerNode_col = 1; /* pressure */
-
- totalDofsThisElement_row = nodesPerEl_row * dofPerNode_row;
- totalDofsThisElement_col = nodesPerEl_col * dofPerNode_col;
-
- if( nodesPerEl_row > self->max_nElNodes ) {
- /* reallocate */
- self->GNx = ReallocArray2D( self->GNx, double, dim, nodesPerEl_row );
- self->max_nElNodes = nodesPerEl_row;
- }
- GNx_row = self->GNx;
-
- if( nodesPerEl_col > self->max_nElNodes_col ) {
- /* allocate */
- self->Ni_col = ReallocArray( self->Ni_col, double, nodesPerEl_col );
- self->max_nElNodes_col = nodesPerEl_col;
- }
- Ni_col = self->Ni_col;
-
- cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
- cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
-
- for ( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
- currIntegrationPoint = (IntegrationPoint*)Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
- xi = currIntegrationPoint->xi;
- weight = currIntegrationPoint->weight;
-
- /* get shape function derivs for the row (ie. velocity) */
- ElementType_ShapeFunctionsGlobalDerivs( elementType_row, variable_row->feMesh, lElement_I, xi, dim, &detJac, GNx_row );
-
- /* get the shape functions for the col. (ie. pressure) */
- ElementType_EvaluateShapeFunctionsAt( elementType_col, xi, Ni_col );
-
- /* build stiffness matrix */
- for ( rowNode_I = 0; rowNode_I < nodesPerEl_row ; rowNode_I++) {
- for( rowDof_I=0; rowDof_I<dofPerNode_row; rowDof_I++) {
- row = rowNode_I*dofPerNode_row + rowDof_I;
-
- for (colNode_I = 0; colNode_I < nodesPerEl_col; colNode_I++ ) {
- for( colDof_I=0; colDof_I<dofPerNode_col; colDof_I++) {
- col = colNode_I*dofPerNode_col + colDof_I;
-
- elStiffMat[col][row] += + weight * ( -detJac ) * ( GNx_row[rowDof_I][rowNode_I] * Ni_col[colNode_I] );
- }
- }
- }
- }
- }
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/DivergenceMatrixTerm.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Assembly/src/DivergenceMatrixTerm.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,255 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: DivergenceMatrixTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include <StgFEM/SLE/SLE.h>
+
+#include "types.h"
+#include "DivergenceMatrixTerm.h"
+
+#include <assert.h>
+#include <string.h>
+
+/* Textual name of this class */
+const Type DivergenceMatrixTerm_Type = "DivergenceMatrixTerm";
+
+DivergenceMatrixTerm* DivergenceMatrixTerm_New(
+ Name name,
+ FiniteElementContext* context,
+ StiffnessMatrix* stiffnessMatrix,
+ Swarm* integrationSwarm )
+{
+ DivergenceMatrixTerm* self = (DivergenceMatrixTerm*) _DivergenceMatrixTerm_DefaultNew( name );
+
+ self->isConstructed = True;
+ _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
+ _DivergenceMatrixTerm_Init( self );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+DivergenceMatrixTerm* _DivergenceMatrixTerm_New( DIVERGENCEMATRIXTERM_DEFARGS )
+{
+ DivergenceMatrixTerm* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(DivergenceMatrixTerm) );
+ self = (DivergenceMatrixTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _DivergenceMatrixTerm_Init( void* matrixTerm ) {
+ DivergenceMatrixTerm* self = (DivergenceMatrixTerm*)matrixTerm;
+
+ self->max_nElNodes_col = 0;
+ self->Ni_col = NULL;
+}
+
+void _DivergenceMatrixTerm_Delete( void* matrixTerm ) {
+ DivergenceMatrixTerm* self = (DivergenceMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Delete( self );
+
+ Memory_Free( self->Ni_col );
+}
+
+void _DivergenceMatrixTerm_Print( void* matrixTerm, Stream* stream ) {
+ DivergenceMatrixTerm* self = (DivergenceMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Print( self, stream );
+
+ /* General info */
+}
+
+void* _DivergenceMatrixTerm_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(DivergenceMatrixTerm);
+ Type type = DivergenceMatrixTerm_Type;
+ Stg_Class_DeleteFunction* _delete = _DivergenceMatrixTerm_Delete;
+ Stg_Class_PrintFunction* _print = _DivergenceMatrixTerm_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _DivergenceMatrixTerm_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _DivergenceMatrixTerm_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _DivergenceMatrixTerm_Build;
+ Stg_Component_InitialiseFunction* _initialise = _DivergenceMatrixTerm_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _DivergenceMatrixTerm_Execute;
+ Stg_Component_DestroyFunction* _destroy = _DivergenceMatrixTerm_Destroy;
+ StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _DivergenceMatrixTerm_AssembleElement;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_DivergenceMatrixTerm_New( DIVERGENCEMATRIXTERM_PASSARGS );
+}
+
+void _DivergenceMatrixTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
+ DivergenceMatrixTerm* self = (DivergenceMatrixTerm*)matrixTerm;
+
+ /* Construct Parent */
+ _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
+
+ _DivergenceMatrixTerm_Init( self );
+}
+
+void _DivergenceMatrixTerm_Build( void* matrixTerm, void* data ) {
+ DivergenceMatrixTerm* self = (DivergenceMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Build( self, data );
+}
+
+void _DivergenceMatrixTerm_Initialise( void* matrixTerm, void* data ) {
+ DivergenceMatrixTerm* self = (DivergenceMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Initialise( self, data );
+}
+
+void _DivergenceMatrixTerm_Execute( void* matrixTerm, void* data ) {
+ _StiffnessMatrixTerm_Execute( matrixTerm, data );
+}
+
+void _DivergenceMatrixTerm_Destroy( void* matrixTerm, void* data ) {
+ DivergenceMatrixTerm* self = (DivergenceMatrixTerm*) matrixTerm;
+
+ if( self->Ni_col) Memory_Free( self->Ni_col );
+ _StiffnessMatrixTerm_Destroy( matrixTerm, data );
+}
+
+void _DivergenceMatrixTerm_AssembleElement(
+ void* matrixTerm,
+ StiffnessMatrix* stiffnessMatrix,
+ Element_LocalIndex lElement_I,
+ SystemLinearEquations* sle,
+ FiniteElementContext* context,
+ double** elStiffMat )
+{
+ DivergenceMatrixTerm* self = Stg_CheckType( matrixTerm, DivergenceMatrixTerm );
+ Swarm* swarm = self->integrationSwarm;
+ FeVariable* variable_row = stiffnessMatrix->columnVariable;
+ FeVariable* variable_col = stiffnessMatrix->rowVariable;
+ Dimension_Index dim = stiffnessMatrix->dim;
+ double* xi;
+ double weight;
+ Particle_InCellIndex cParticle_I, cellParticleCount;
+ Node_ElementLocalIndex nodesPerEl_row;
+ Node_ElementLocalIndex nodesPerEl_col;
+ Dof_Index totalDofsThisElement_row, totalDofsThisElement_col;
+
+ Dof_Index dofPerNode_row, dofPerNode_col;
+ Index row, col; /* Indices into the stiffness matrix */
+ Node_ElementLocalIndex rowNode_I;
+ Node_ElementLocalIndex colNode_I;
+ Dof_Index rowDof_I, colDof_I;
+ double** GNx_row;
+ double* Ni_col;
+ double detJac;
+ IntegrationPoint* currIntegrationPoint;
+
+ Cell_Index cell_I;
+ ElementType* elementType_row;
+ ElementType* elementType_col;
+
+ /* Set the element type */
+ elementType_row = FeMesh_GetElementType( variable_row->feMesh, lElement_I );
+ nodesPerEl_row = elementType_row->nodeCount;
+
+ elementType_col = FeMesh_GetElementType( variable_col->feMesh, lElement_I );
+ nodesPerEl_col = elementType_col->nodeCount;
+
+ dofPerNode_row = dim; /* velocity */
+ dofPerNode_col = 1; /* pressure */
+
+ totalDofsThisElement_row = nodesPerEl_row * dofPerNode_row;
+ totalDofsThisElement_col = nodesPerEl_col * dofPerNode_col;
+
+ if( nodesPerEl_row > self->max_nElNodes ) {
+ /* reallocate */
+ self->GNx = ReallocArray2D( self->GNx, double, dim, nodesPerEl_row );
+ self->max_nElNodes = nodesPerEl_row;
+ }
+ GNx_row = self->GNx;
+
+ if( nodesPerEl_col > self->max_nElNodes_col ) {
+ /* allocate */
+ self->Ni_col = ReallocArray( self->Ni_col, double, nodesPerEl_col );
+ self->max_nElNodes_col = nodesPerEl_col;
+ }
+ Ni_col = self->Ni_col;
+
+ cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
+ cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
+
+ for ( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
+ currIntegrationPoint = (IntegrationPoint*)Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
+ xi = currIntegrationPoint->xi;
+ weight = currIntegrationPoint->weight;
+
+ /* get shape function derivs for the row (ie. velocity) */
+ ElementType_ShapeFunctionsGlobalDerivs( elementType_row, variable_row->feMesh, lElement_I, xi, dim, &detJac, GNx_row );
+
+ /* get the shape functions for the col. (ie. pressure) */
+ ElementType_EvaluateShapeFunctionsAt( elementType_col, xi, Ni_col );
+
+ /* build stiffness matrix */
+ for ( rowNode_I = 0; rowNode_I < nodesPerEl_row ; rowNode_I++) {
+ for( rowDof_I=0; rowDof_I<dofPerNode_row; rowDof_I++) {
+ row = rowNode_I*dofPerNode_row + rowDof_I;
+
+ for (colNode_I = 0; colNode_I < nodesPerEl_col; colNode_I++ ) {
+ for( colDof_I=0; colDof_I<dofPerNode_col; colDof_I++) {
+ col = colNode_I*dofPerNode_col + colDof_I;
+
+ elStiffMat[col][row] += + weight * ( -detJac ) * ( GNx_row[rowDof_I][rowNode_I] * Ni_col[colNode_I] );
+ }
+ }
+ }
+ }
+ }
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/Finalise.c
--- a/Assembly/src/Finalise.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SLE.h"
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "Finalise.h"
-
-#include <stdio.h>
-
-Bool StgFEM_Assembly_Finalise( void ) {
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- Stream_IndentBranch( StgFEM_Debug );
- Stream_UnIndentBranch( StgFEM_Debug );
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/Finalise.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Assembly/src/Finalise.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,62 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SLE.h"
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "Finalise.h"
+
+#include <stdio.h>
+
+Bool StgFEM_Assembly_Finalise( void ) {
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ Stream_IndentBranch( StgFEM_Debug );
+ Stream_UnIndentBranch( StgFEM_Debug );
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/GradientStiffnessMatrixTerm.c
--- a/Assembly/src/GradientStiffnessMatrixTerm.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,257 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: GradientStiffnessMatrixTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/SLE/SLE.h>
-
-#include "types.h"
-#include "GradientStiffnessMatrixTerm.h"
-
-#include <assert.h>
-#include <string.h>
-
-/* Textual name of this class */
-const Type GradientStiffnessMatrixTerm_Type = "GradientStiffnessMatrixTerm";
-
-GradientStiffnessMatrixTerm* GradientStiffnessMatrixTerm_New(
- Name name,
- FiniteElementContext* context,
- StiffnessMatrix* stiffnessMatrix,
- Swarm* integrationSwarm )
-{
- GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*) _GradientStiffnessMatrixTerm_DefaultNew( name );
-
- self->isConstructed = True;
- _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
- _GradientStiffnessMatrixTerm_Init( self );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-GradientStiffnessMatrixTerm* _GradientStiffnessMatrixTerm_New( GRADIENTSTIFFNESSMATRIXTERM_DEFARGS )
-{
- GradientStiffnessMatrixTerm* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(GradientStiffnessMatrixTerm) );
- self = (GradientStiffnessMatrixTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
-
- /* Virtual info */
-
- return self;
-}
-
-void _GradientStiffnessMatrixTerm_Init( void* matrixTerm ) {
- GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
-
- self->max_nElNodes_col = 0;
- self->Ni_col = NULL;
-}
-
-void _GradientStiffnessMatrixTerm_Delete( void* matrixTerm ) {
- GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Delete( self );
-}
-
-void _GradientStiffnessMatrixTerm_Print( void* matrixTerm, Stream* stream ) {
- GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Print( self, stream );
-
- /* General info */
-}
-
-void* _GradientStiffnessMatrixTerm_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(GradientStiffnessMatrixTerm);
- Type type = GradientStiffnessMatrixTerm_Type;
- Stg_Class_DeleteFunction* _delete = _GradientStiffnessMatrixTerm_Delete;
- Stg_Class_PrintFunction* _print = _GradientStiffnessMatrixTerm_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _GradientStiffnessMatrixTerm_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _GradientStiffnessMatrixTerm_AssignFromXML;
- Stg_Component_BuildFunction* _build = _GradientStiffnessMatrixTerm_Build;
- Stg_Component_InitialiseFunction* _initialise = _GradientStiffnessMatrixTerm_Initialise;
- Stg_Component_ExecuteFunction* _execute = _GradientStiffnessMatrixTerm_Execute;
- Stg_Component_DestroyFunction* _destroy = _GradientStiffnessMatrixTerm_Destroy;
- StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _GradientStiffnessMatrixTerm_AssembleElement;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_GradientStiffnessMatrixTerm_New( GRADIENTSTIFFNESSMATRIXTERM_PASSARGS );
-}
-
-void _GradientStiffnessMatrixTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
- GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
-
- /* Construct Parent */
- _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
-
- _GradientStiffnessMatrixTerm_Init( self );
-}
-
-void _GradientStiffnessMatrixTerm_Build( void* matrixTerm, void* data ) {
- GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Build( self, data );
-}
-
-void _GradientStiffnessMatrixTerm_Initialise( void* matrixTerm, void* data ) {
- GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Initialise( self, data );
-}
-
-void _GradientStiffnessMatrixTerm_Execute( void* matrixTerm, void* data ) {
- _StiffnessMatrixTerm_Execute( matrixTerm, data );
-}
-
-void _GradientStiffnessMatrixTerm_Destroy( void* matrixTerm, void* data ) {
- GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
-
- if( self->Ni_col ) Memory_Free( self->Ni_col );
- _StiffnessMatrixTerm_Destroy( matrixTerm, data );
-}
-
-void _GradientStiffnessMatrixTerm_AssembleElement(
- void* matrixTerm,
- StiffnessMatrix* stiffnessMatrix,
- Element_LocalIndex lElement_I,
- SystemLinearEquations* sle,
- FiniteElementContext* context,
- double** elStiffMat )
-{
- GradientStiffnessMatrixTerm* self = Stg_CheckType( matrixTerm, GradientStiffnessMatrixTerm );
- Swarm* swarm = self->integrationSwarm;
- FeVariable* variable_row = stiffnessMatrix->rowVariable;
- FeVariable* variable_col = stiffnessMatrix->columnVariable;
- Dimension_Index dim = stiffnessMatrix->dim;
- double* xi;
- double weight;
- Particle_InCellIndex cParticle_I, cellParticleCount;
- Node_ElementLocalIndex nodesPerEl_row;
- Node_ElementLocalIndex nodesPerEl_col;
- Dof_Index totalDofsThisElement_row, totalDofsThisElement_col;
-
- Dof_Index dofPerNode_row, dofPerNode_col;
- Index row, col; /* Indices into the stiffness matrix */
- Node_ElementLocalIndex rowNode_I;
- Node_ElementLocalIndex colNode_I;
- Dof_Index rowDof_I, colDof_I;
- double** GNx_row;
- double* Ni_col;
- double detJac;
- IntegrationPoint* currIntegrationPoint;
-
- Cell_Index cell_I;
- ElementType* elementType_row;
- ElementType* elementType_col;
-
- /* Set the element type */
- elementType_row = FeMesh_GetElementType( variable_row->feMesh, lElement_I );
- nodesPerEl_row = elementType_row->nodeCount;
-
- elementType_col = FeMesh_GetElementType( variable_col->feMesh, lElement_I );
- nodesPerEl_col = elementType_col->nodeCount;
-
- dofPerNode_row = dim; /* velocity */
- dofPerNode_col = 1; /* pressure */
-
- totalDofsThisElement_row = nodesPerEl_row * dofPerNode_row;
- totalDofsThisElement_col = nodesPerEl_col * dofPerNode_col;
-
- if( nodesPerEl_row > self->max_nElNodes ) {
- /* reallocate */
- self->GNx = ReallocArray2D( self->GNx, double, dim, nodesPerEl_row );
- self->max_nElNodes = nodesPerEl_row;
- }
- GNx_row = self->GNx;
-
- if( nodesPerEl_col > self->max_nElNodes_col ) {
- /* allocate */
- self->Ni_col = ReallocArray( self->Ni_col, double, nodesPerEl_col );
- self->max_nElNodes_col = nodesPerEl_col;
- }
- Ni_col = self->Ni_col;
-
- cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
- cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
-
- for ( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
- currIntegrationPoint = (IntegrationPoint*)Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
- xi = currIntegrationPoint->xi;
- weight = currIntegrationPoint->weight;
-
- /* get shape function derivs for the row (ie. velocity) */
- ElementType_ShapeFunctionsGlobalDerivs(
- elementType_row,
- variable_row->feMesh, lElement_I,
- xi, dim, &detJac, GNx_row );
-
- /* get the shape functions for the col. (ie. pressure) */
- ElementType_EvaluateShapeFunctionsAt( elementType_col, xi, Ni_col );
-
- /* build stiffness matrix */
- for ( rowNode_I = 0; rowNode_I < nodesPerEl_row ; rowNode_I++) {
- for( rowDof_I=0; rowDof_I<dofPerNode_row; rowDof_I++) {
- row = rowNode_I*dofPerNode_row + rowDof_I;
-
- for (colNode_I = 0; colNode_I < nodesPerEl_col; colNode_I++ ) {
- for( colDof_I=0; colDof_I<dofPerNode_col; colDof_I++) {
- col = colNode_I*dofPerNode_col + colDof_I;
-
- elStiffMat[row][col] +=
- + weight * ( - detJac ) * ( GNx_row[rowDof_I][rowNode_I] * Ni_col[colNode_I] );
- }
- }
- }
- }
- }
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/GradientStiffnessMatrixTerm.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Assembly/src/GradientStiffnessMatrixTerm.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,257 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: GradientStiffnessMatrixTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include <StgFEM/SLE/SLE.h>
+
+#include "types.h"
+#include "GradientStiffnessMatrixTerm.h"
+
+#include <assert.h>
+#include <string.h>
+
+/* Textual name of this class */
+const Type GradientStiffnessMatrixTerm_Type = "GradientStiffnessMatrixTerm";
+
+GradientStiffnessMatrixTerm* GradientStiffnessMatrixTerm_New(
+ Name name,
+ FiniteElementContext* context,
+ StiffnessMatrix* stiffnessMatrix,
+ Swarm* integrationSwarm )
+{
+ GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*) _GradientStiffnessMatrixTerm_DefaultNew( name );
+
+ self->isConstructed = True;
+ _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
+ _GradientStiffnessMatrixTerm_Init( self );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+GradientStiffnessMatrixTerm* _GradientStiffnessMatrixTerm_New( GRADIENTSTIFFNESSMATRIXTERM_DEFARGS )
+{
+ GradientStiffnessMatrixTerm* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(GradientStiffnessMatrixTerm) );
+ self = (GradientStiffnessMatrixTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _GradientStiffnessMatrixTerm_Init( void* matrixTerm ) {
+ GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
+
+ self->max_nElNodes_col = 0;
+ self->Ni_col = NULL;
+}
+
+void _GradientStiffnessMatrixTerm_Delete( void* matrixTerm ) {
+ GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Delete( self );
+}
+
+void _GradientStiffnessMatrixTerm_Print( void* matrixTerm, Stream* stream ) {
+ GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Print( self, stream );
+
+ /* General info */
+}
+
+void* _GradientStiffnessMatrixTerm_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(GradientStiffnessMatrixTerm);
+ Type type = GradientStiffnessMatrixTerm_Type;
+ Stg_Class_DeleteFunction* _delete = _GradientStiffnessMatrixTerm_Delete;
+ Stg_Class_PrintFunction* _print = _GradientStiffnessMatrixTerm_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _GradientStiffnessMatrixTerm_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _GradientStiffnessMatrixTerm_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _GradientStiffnessMatrixTerm_Build;
+ Stg_Component_InitialiseFunction* _initialise = _GradientStiffnessMatrixTerm_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _GradientStiffnessMatrixTerm_Execute;
+ Stg_Component_DestroyFunction* _destroy = _GradientStiffnessMatrixTerm_Destroy;
+ StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _GradientStiffnessMatrixTerm_AssembleElement;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_GradientStiffnessMatrixTerm_New( GRADIENTSTIFFNESSMATRIXTERM_PASSARGS );
+}
+
+void _GradientStiffnessMatrixTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
+ GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
+
+ /* Construct Parent */
+ _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
+
+ _GradientStiffnessMatrixTerm_Init( self );
+}
+
+void _GradientStiffnessMatrixTerm_Build( void* matrixTerm, void* data ) {
+ GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Build( self, data );
+}
+
+void _GradientStiffnessMatrixTerm_Initialise( void* matrixTerm, void* data ) {
+ GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Initialise( self, data );
+}
+
+void _GradientStiffnessMatrixTerm_Execute( void* matrixTerm, void* data ) {
+ _StiffnessMatrixTerm_Execute( matrixTerm, data );
+}
+
+void _GradientStiffnessMatrixTerm_Destroy( void* matrixTerm, void* data ) {
+ GradientStiffnessMatrixTerm* self = (GradientStiffnessMatrixTerm*)matrixTerm;
+
+ if( self->Ni_col ) Memory_Free( self->Ni_col );
+ _StiffnessMatrixTerm_Destroy( matrixTerm, data );
+}
+
+void _GradientStiffnessMatrixTerm_AssembleElement(
+ void* matrixTerm,
+ StiffnessMatrix* stiffnessMatrix,
+ Element_LocalIndex lElement_I,
+ SystemLinearEquations* sle,
+ FiniteElementContext* context,
+ double** elStiffMat )
+{
+ GradientStiffnessMatrixTerm* self = Stg_CheckType( matrixTerm, GradientStiffnessMatrixTerm );
+ Swarm* swarm = self->integrationSwarm;
+ FeVariable* variable_row = stiffnessMatrix->rowVariable;
+ FeVariable* variable_col = stiffnessMatrix->columnVariable;
+ Dimension_Index dim = stiffnessMatrix->dim;
+ double* xi;
+ double weight;
+ Particle_InCellIndex cParticle_I, cellParticleCount;
+ Node_ElementLocalIndex nodesPerEl_row;
+ Node_ElementLocalIndex nodesPerEl_col;
+ Dof_Index totalDofsThisElement_row, totalDofsThisElement_col;
+
+ Dof_Index dofPerNode_row, dofPerNode_col;
+ Index row, col; /* Indices into the stiffness matrix */
+ Node_ElementLocalIndex rowNode_I;
+ Node_ElementLocalIndex colNode_I;
+ Dof_Index rowDof_I, colDof_I;
+ double** GNx_row;
+ double* Ni_col;
+ double detJac;
+ IntegrationPoint* currIntegrationPoint;
+
+ Cell_Index cell_I;
+ ElementType* elementType_row;
+ ElementType* elementType_col;
+
+ /* Set the element type */
+ elementType_row = FeMesh_GetElementType( variable_row->feMesh, lElement_I );
+ nodesPerEl_row = elementType_row->nodeCount;
+
+ elementType_col = FeMesh_GetElementType( variable_col->feMesh, lElement_I );
+ nodesPerEl_col = elementType_col->nodeCount;
+
+ dofPerNode_row = dim; /* velocity */
+ dofPerNode_col = 1; /* pressure */
+
+ totalDofsThisElement_row = nodesPerEl_row * dofPerNode_row;
+ totalDofsThisElement_col = nodesPerEl_col * dofPerNode_col;
+
+ if( nodesPerEl_row > self->max_nElNodes ) {
+ /* reallocate */
+ self->GNx = ReallocArray2D( self->GNx, double, dim, nodesPerEl_row );
+ self->max_nElNodes = nodesPerEl_row;
+ }
+ GNx_row = self->GNx;
+
+ if( nodesPerEl_col > self->max_nElNodes_col ) {
+ /* allocate */
+ self->Ni_col = ReallocArray( self->Ni_col, double, nodesPerEl_col );
+ self->max_nElNodes_col = nodesPerEl_col;
+ }
+ Ni_col = self->Ni_col;
+
+ cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
+ cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
+
+ for ( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
+ currIntegrationPoint = (IntegrationPoint*)Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
+ xi = currIntegrationPoint->xi;
+ weight = currIntegrationPoint->weight;
+
+ /* get shape function derivs for the row (ie. velocity) */
+ ElementType_ShapeFunctionsGlobalDerivs(
+ elementType_row,
+ variable_row->feMesh, lElement_I,
+ xi, dim, &detJac, GNx_row );
+
+ /* get the shape functions for the col. (ie. pressure) */
+ ElementType_EvaluateShapeFunctionsAt( elementType_col, xi, Ni_col );
+
+ /* build stiffness matrix */
+ for ( rowNode_I = 0; rowNode_I < nodesPerEl_row ; rowNode_I++) {
+ for( rowDof_I=0; rowDof_I<dofPerNode_row; rowDof_I++) {
+ row = rowNode_I*dofPerNode_row + rowDof_I;
+
+ for (colNode_I = 0; colNode_I < nodesPerEl_col; colNode_I++ ) {
+ for( colDof_I=0; colDof_I<dofPerNode_col; colDof_I++) {
+ col = colNode_I*dofPerNode_col + colDof_I;
+
+ elStiffMat[row][col] +=
+ + weight * ( - detJac ) * ( GNx_row[rowDof_I][rowNode_I] * Ni_col[colNode_I] );
+ }
+ }
+ }
+ }
+ }
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/Init.c
--- a/Assembly/src/Init.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Init.c 1209 2008-08-25 01:16:22Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/SLE/SLE.h>
-
-#include "Assembly.h"
-
-#include <stdio.h>
-
-Stream* StgFEM_Assembly_Debug = NULL;
-
-/** Initialises the Linear Algebra package, then any init for this package
-such as streams etc */
-Bool StgFEM_Assembly_Init( int* argc, char** argv[] ) {
- Stg_ComponentRegister* componentRegister = Stg_ComponentRegister_Get_ComponentRegister();
- int tmp;
-
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
- tmp = Stream_GetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ) );
- Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), 0 );
- Journal_Printf( /* DO NOT CHANGE OR REMOVE */
- Journal_Register( InfoStream_Type, (Name)"Context" ),
- "StGermain FEM Assembly Library revision %s. Copyright (C) 2003-2005 VPAC.\n", VERSION );
- Stream_Flush( Journal_Register( InfoStream_Type, (Name)"Context" ) );
- Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), tmp );
-
- /* initialise this level's streams */
- StgFEM_Assembly_Debug = Stream_RegisterChild( StgFEM_Debug, "Assembly" );
-
- Stg_ComponentRegister_Add( componentRegister, ThermalBuoyancyForceTerm_Type, (Name)"0", _ThermalBuoyancyForceTerm_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, GradientStiffnessMatrixTerm_Type, (Name)"0", _GradientStiffnessMatrixTerm_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, DivergenceMatrixTerm_Type, (Name)"0", _DivergenceMatrixTerm_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, LaplacianStiffnessMatrixTerm_Type, (Name)"0", _LaplacianStiffnessMatrixTerm_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, IsoviscousStressTensorTerm_Type, (Name)"0", _IsoviscousStressTensorTerm_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, PressureGradMatrixTerm_Type, (Name)"0", _PressureGradMatrixTerm_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, PressureGradForceTerm_Type, (Name)"0", _PressureGradForceTerm_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, MassMatrixTerm_Type, (Name)"0", _MassMatrixTerm_DefaultNew );
-
- RegisterParent( ThermalBuoyancyForceTerm_Type, ForceTerm_Type );
- RegisterParent( GradientStiffnessMatrixTerm_Type, StiffnessMatrixTerm_Type );
- RegisterParent( DivergenceMatrixTerm_Type, StiffnessMatrixTerm_Type );
- RegisterParent( LaplacianStiffnessMatrixTerm_Type, StiffnessMatrixTerm_Type );
- RegisterParent( IsoviscousStressTensorTerm_Type, StiffnessMatrixTerm_Type );
- RegisterParent( PressureGradMatrixTerm_Type, StiffnessMatrixTerm_Type );
- RegisterParent( PressureGradForceTerm_Type, ForceTerm_Type );
- RegisterParent( MassMatrixTerm_Type, StiffnessMatrixTerm_Type );
-
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/Init.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Assembly/src/Init.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,93 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Init.c 1209 2008-08-25 01:16:22Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include <StgFEM/SLE/SLE.h>
+
+#include "Assembly.h"
+
+#include <stdio.h>
+
+Stream* StgFEM_Assembly_Debug = NULL;
+
+/** Initialises the Linear Algebra package, then any init for this package
+such as streams etc */
+Bool StgFEM_Assembly_Init( int* argc, char** argv[] ) {
+ Stg_ComponentRegister* componentRegister = Stg_ComponentRegister_Get_ComponentRegister();
+ int tmp;
+
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+ tmp = Stream_GetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ) );
+ Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), 0 );
+ Journal_Printf( /* DO NOT CHANGE OR REMOVE */
+ Journal_Register( InfoStream_Type, (Name)"Context" ),
+ "StGermain FEM Assembly Library revision %s. Copyright (C) 2003-2005 VPAC.\n", VERSION );
+ Stream_Flush( Journal_Register( InfoStream_Type, (Name)"Context" ) );
+ Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), tmp );
+
+ /* initialise this level's streams */
+ StgFEM_Assembly_Debug = Stream_RegisterChild( StgFEM_Debug, "Assembly" );
+
+ Stg_ComponentRegister_Add( componentRegister, ThermalBuoyancyForceTerm_Type, (Name)"0", _ThermalBuoyancyForceTerm_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, GradientStiffnessMatrixTerm_Type, (Name)"0", _GradientStiffnessMatrixTerm_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, DivergenceMatrixTerm_Type, (Name)"0", _DivergenceMatrixTerm_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, LaplacianStiffnessMatrixTerm_Type, (Name)"0", _LaplacianStiffnessMatrixTerm_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, IsoviscousStressTensorTerm_Type, (Name)"0", _IsoviscousStressTensorTerm_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, PressureGradMatrixTerm_Type, (Name)"0", _PressureGradMatrixTerm_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, PressureGradForceTerm_Type, (Name)"0", _PressureGradForceTerm_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, MassMatrixTerm_Type, (Name)"0", _MassMatrixTerm_DefaultNew );
+
+ RegisterParent( ThermalBuoyancyForceTerm_Type, ForceTerm_Type );
+ RegisterParent( GradientStiffnessMatrixTerm_Type, StiffnessMatrixTerm_Type );
+ RegisterParent( DivergenceMatrixTerm_Type, StiffnessMatrixTerm_Type );
+ RegisterParent( LaplacianStiffnessMatrixTerm_Type, StiffnessMatrixTerm_Type );
+ RegisterParent( IsoviscousStressTensorTerm_Type, StiffnessMatrixTerm_Type );
+ RegisterParent( PressureGradMatrixTerm_Type, StiffnessMatrixTerm_Type );
+ RegisterParent( PressureGradForceTerm_Type, ForceTerm_Type );
+ RegisterParent( MassMatrixTerm_Type, StiffnessMatrixTerm_Type );
+
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/IsoviscousStressTensorTerm.c
--- a/Assembly/src/IsoviscousStressTensorTerm.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,259 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: IsoviscousStressTensorTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/SLE/SLE.h>
-
-#include "types.h"
-#include "IsoviscousStressTensorTerm.h"
-
-#include <assert.h>
-#include <string.h>
-
-/* Textual name of this class */
-const Type IsoviscousStressTensorTerm_Type = "IsoviscousStressTensorTerm";
-
-IsoviscousStressTensorTerm* IsoviscousStressTensorTerm_New(
- Name name,
- FiniteElementContext* context,
- StiffnessMatrix* stiffnessMatrix,
- Swarm* integrationSwarm,
- double viscosity )
-{
- IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*) _IsoviscousStressTensorTerm_DefaultNew( name );
-
- self->isConstructed = True;
- _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
- _IsoviscousStressTensorTerm_Init( self, viscosity );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-IsoviscousStressTensorTerm* _IsoviscousStressTensorTerm_New( ISOVISCOUSSTRESSTENSORTERM_DEFARGS )
-{
- IsoviscousStressTensorTerm* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(IsoviscousStressTensorTerm) );
- self = (IsoviscousStressTensorTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
-
- /* Virtual info */
-
- return self;
-}
-
-void _IsoviscousStressTensorTerm_Init( void* matrixTerm, double viscosity ) {
- IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*)matrixTerm;
- self->viscosity = viscosity;
-}
-
-void _IsoviscousStressTensorTerm_Delete( void* matrixTerm ) {
- IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Delete( self );
-}
-
-void _IsoviscousStressTensorTerm_Print( void* matrixTerm, Stream* stream ) {
- IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Print( self, stream );
-
- /* General info */
- Journal_PrintValue( stream, self->viscosity );
-}
-
-void* _IsoviscousStressTensorTerm_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(IsoviscousStressTensorTerm);
- Type type = IsoviscousStressTensorTerm_Type;
- Stg_Class_DeleteFunction* _delete = _IsoviscousStressTensorTerm_Delete;
- Stg_Class_PrintFunction* _print = _IsoviscousStressTensorTerm_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _IsoviscousStressTensorTerm_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _IsoviscousStressTensorTerm_AssignFromXML;
- Stg_Component_BuildFunction* _build = _IsoviscousStressTensorTerm_Build;
- Stg_Component_InitialiseFunction* _initialise = _IsoviscousStressTensorTerm_Initialise;
- Stg_Component_ExecuteFunction* _execute = _IsoviscousStressTensorTerm_Execute;
- Stg_Component_DestroyFunction* _destroy = _IsoviscousStressTensorTerm_Destroy;
- StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _IsoviscousStressTensorTerm_AssembleElement;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_IsoviscousStressTensorTerm_New( ISOVISCOUSSTRESSTENSORTERM_PASSARGS );
-}
-
-void _IsoviscousStressTensorTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
- IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*)matrixTerm;
-
- /* Construct Parent */
- _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
-
- _IsoviscousStressTensorTerm_Init( self, Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"viscosity", 1.0 ) );
-}
-
-void _IsoviscousStressTensorTerm_Build( void* matrixTerm, void* data ) {
- IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Build( self, data );
-}
-
-void _IsoviscousStressTensorTerm_Initialise( void* matrixTerm, void* data ) {
- IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Initialise( self, data );
-}
-
-void _IsoviscousStressTensorTerm_Execute( void* matrixTerm, void* data ) {
- _StiffnessMatrixTerm_Execute( matrixTerm, data );
-}
-
-void _IsoviscousStressTensorTerm_Destroy( void* matrixTerm, void* data ) {
- _StiffnessMatrixTerm_Destroy( matrixTerm, data );
-}
-
-
-void _IsoviscousStressTensorTerm_AssembleElement(
- void* matrixTerm,
- StiffnessMatrix* stiffnessMatrix,
- Element_LocalIndex lElement_I,
- SystemLinearEquations* sle,
- FiniteElementContext* context,
- double** elStiffMat )
-{
- IsoviscousStressTensorTerm* self = Stg_CheckType( matrixTerm, IsoviscousStressTensorTerm );
- Swarm* swarm = self->integrationSwarm;
- FeVariable* variable1 = stiffnessMatrix->rowVariable;
- Dimension_Index dim = stiffnessMatrix->dim;
-
- IntegrationPoint* currIntegrationPoint;
- double* xi;
- double weight;
- Particle_InCellIndex cParticle_I, cellParticleCount;
- Index nodesPerEl;
- Node_ElementLocalIndex rowNode_I;
- Node_ElementLocalIndex colNode_I;
- double** GNx;
- double detJac;
- double visc = self->viscosity;
-
- Cell_Index cell_I;
- ElementType* elementType;
- int nodalDofs;
- Dof_Index diagDof_I;
- Dof_Index rowDof_I;
- Dof_Index colDof_I;
- Dof_Index d;
- Dof_Index dofsPerNode;
- Index rowIndex;
- Index colIndex;
-
- /* Set the element type */
- elementType = FeMesh_GetElementType( variable1->feMesh, lElement_I );
- nodesPerEl = elementType->nodeCount;
-
- /* assumes constant number of dofs per element */
- nodalDofs = nodesPerEl * dim;
- dofsPerNode = dim;
-
- if( nodesPerEl > self->max_nElNodes ) {
- /* reallocate */
- self->GNx = ReallocArray2D( self->GNx, double, dim, nodesPerEl );
- self->max_nElNodes = nodesPerEl;
- }
- GNx = self->GNx;
-
- cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
- cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
-
- for( cParticle_I=0; cParticle_I < cellParticleCount; cParticle_I++ ) {
-
- currIntegrationPoint = (IntegrationPoint*)Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
- xi = currIntegrationPoint->xi;
- weight = currIntegrationPoint->weight;
-
- ElementType_ShapeFunctionsGlobalDerivs(
- elementType,
- variable1->feMesh, lElement_I,
- xi, dim, &detJac, GNx );
-
- /* Initially just build the diagonal (from a Dof perspective) entries */
- for( rowNode_I=0; rowNode_I < nodesPerEl; rowNode_I++ ) {
- for( colNode_I=0; colNode_I < nodesPerEl; colNode_I++ ) {
- for( diagDof_I=0; diagDof_I < dofsPerNode; diagDof_I++ ) {
- rowIndex = rowNode_I*dofsPerNode + diagDof_I;
- colIndex = colNode_I*dofsPerNode + diagDof_I;
- elStiffMat[rowIndex][colIndex] +=
- detJac * visc * weight * ( GNx[diagDof_I][rowNode_I] * GNx[diagDof_I][colNode_I] );
- for( d=0; d<dofsPerNode; d++ ) {
- elStiffMat[rowIndex][colIndex] +=
- detJac * visc * weight * ( GNx[d][rowNode_I] * GNx[d][colNode_I] );
- }
- }
- }
- }
-
- /* then build one set of the off diagonal blocks of K, and copy to the other off diags using symmetry */
- for( rowNode_I=0; rowNode_I < nodesPerEl; rowNode_I++ ) {
- for( rowDof_I=0; rowDof_I < dofsPerNode-1; rowDof_I++ ) { /* dont need to do anything in last row */
- for( colNode_I=0; colNode_I < nodesPerEl; colNode_I++ ) {
- for( colDof_I=rowDof_I+1; colDof_I < dofsPerNode; colDof_I++ ) {
- rowIndex = rowNode_I*dofsPerNode + rowDof_I;
- colIndex = colNode_I*dofsPerNode + colDof_I;
- elStiffMat[rowIndex][colIndex] += detJac * visc * weight *
- ( GNx[colDof_I][rowNode_I] * GNx[rowDof_I][colNode_I] );
- /* symmetry */
- elStiffMat[colIndex][rowIndex] = elStiffMat[rowIndex][colIndex];
- }
- }
- }
- }
- }
-
- return;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/IsoviscousStressTensorTerm.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Assembly/src/IsoviscousStressTensorTerm.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,259 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: IsoviscousStressTensorTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include <StgFEM/SLE/SLE.h>
+
+#include "types.h"
+#include "IsoviscousStressTensorTerm.h"
+
+#include <assert.h>
+#include <string.h>
+
+/* Textual name of this class */
+const Type IsoviscousStressTensorTerm_Type = "IsoviscousStressTensorTerm";
+
+IsoviscousStressTensorTerm* IsoviscousStressTensorTerm_New(
+ Name name,
+ FiniteElementContext* context,
+ StiffnessMatrix* stiffnessMatrix,
+ Swarm* integrationSwarm,
+ double viscosity )
+{
+ IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*) _IsoviscousStressTensorTerm_DefaultNew( name );
+
+ self->isConstructed = True;
+ _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
+ _IsoviscousStressTensorTerm_Init( self, viscosity );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+IsoviscousStressTensorTerm* _IsoviscousStressTensorTerm_New( ISOVISCOUSSTRESSTENSORTERM_DEFARGS )
+{
+ IsoviscousStressTensorTerm* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(IsoviscousStressTensorTerm) );
+ self = (IsoviscousStressTensorTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _IsoviscousStressTensorTerm_Init( void* matrixTerm, double viscosity ) {
+ IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*)matrixTerm;
+ self->viscosity = viscosity;
+}
+
+void _IsoviscousStressTensorTerm_Delete( void* matrixTerm ) {
+ IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Delete( self );
+}
+
+void _IsoviscousStressTensorTerm_Print( void* matrixTerm, Stream* stream ) {
+ IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Print( self, stream );
+
+ /* General info */
+ Journal_PrintValue( stream, self->viscosity );
+}
+
+void* _IsoviscousStressTensorTerm_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(IsoviscousStressTensorTerm);
+ Type type = IsoviscousStressTensorTerm_Type;
+ Stg_Class_DeleteFunction* _delete = _IsoviscousStressTensorTerm_Delete;
+ Stg_Class_PrintFunction* _print = _IsoviscousStressTensorTerm_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _IsoviscousStressTensorTerm_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _IsoviscousStressTensorTerm_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _IsoviscousStressTensorTerm_Build;
+ Stg_Component_InitialiseFunction* _initialise = _IsoviscousStressTensorTerm_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _IsoviscousStressTensorTerm_Execute;
+ Stg_Component_DestroyFunction* _destroy = _IsoviscousStressTensorTerm_Destroy;
+ StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _IsoviscousStressTensorTerm_AssembleElement;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_IsoviscousStressTensorTerm_New( ISOVISCOUSSTRESSTENSORTERM_PASSARGS );
+}
+
+void _IsoviscousStressTensorTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
+ IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*)matrixTerm;
+
+ /* Construct Parent */
+ _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
+
+ _IsoviscousStressTensorTerm_Init( self, Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"viscosity", 1.0 ) );
+}
+
+void _IsoviscousStressTensorTerm_Build( void* matrixTerm, void* data ) {
+ IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Build( self, data );
+}
+
+void _IsoviscousStressTensorTerm_Initialise( void* matrixTerm, void* data ) {
+ IsoviscousStressTensorTerm* self = (IsoviscousStressTensorTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Initialise( self, data );
+}
+
+void _IsoviscousStressTensorTerm_Execute( void* matrixTerm, void* data ) {
+ _StiffnessMatrixTerm_Execute( matrixTerm, data );
+}
+
+void _IsoviscousStressTensorTerm_Destroy( void* matrixTerm, void* data ) {
+ _StiffnessMatrixTerm_Destroy( matrixTerm, data );
+}
+
+
+void _IsoviscousStressTensorTerm_AssembleElement(
+ void* matrixTerm,
+ StiffnessMatrix* stiffnessMatrix,
+ Element_LocalIndex lElement_I,
+ SystemLinearEquations* sle,
+ FiniteElementContext* context,
+ double** elStiffMat )
+{
+ IsoviscousStressTensorTerm* self = Stg_CheckType( matrixTerm, IsoviscousStressTensorTerm );
+ Swarm* swarm = self->integrationSwarm;
+ FeVariable* variable1 = stiffnessMatrix->rowVariable;
+ Dimension_Index dim = stiffnessMatrix->dim;
+
+ IntegrationPoint* currIntegrationPoint;
+ double* xi;
+ double weight;
+ Particle_InCellIndex cParticle_I, cellParticleCount;
+ Index nodesPerEl;
+ Node_ElementLocalIndex rowNode_I;
+ Node_ElementLocalIndex colNode_I;
+ double** GNx;
+ double detJac;
+ double visc = self->viscosity;
+
+ Cell_Index cell_I;
+ ElementType* elementType;
+ int nodalDofs;
+ Dof_Index diagDof_I;
+ Dof_Index rowDof_I;
+ Dof_Index colDof_I;
+ Dof_Index d;
+ Dof_Index dofsPerNode;
+ Index rowIndex;
+ Index colIndex;
+
+ /* Set the element type */
+ elementType = FeMesh_GetElementType( variable1->feMesh, lElement_I );
+ nodesPerEl = elementType->nodeCount;
+
+ /* assumes constant number of dofs per element */
+ nodalDofs = nodesPerEl * dim;
+ dofsPerNode = dim;
+
+ if( nodesPerEl > self->max_nElNodes ) {
+ /* reallocate */
+ self->GNx = ReallocArray2D( self->GNx, double, dim, nodesPerEl );
+ self->max_nElNodes = nodesPerEl;
+ }
+ GNx = self->GNx;
+
+ cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
+ cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
+
+ for( cParticle_I=0; cParticle_I < cellParticleCount; cParticle_I++ ) {
+
+ currIntegrationPoint = (IntegrationPoint*)Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
+ xi = currIntegrationPoint->xi;
+ weight = currIntegrationPoint->weight;
+
+ ElementType_ShapeFunctionsGlobalDerivs(
+ elementType,
+ variable1->feMesh, lElement_I,
+ xi, dim, &detJac, GNx );
+
+ /* Initially just build the diagonal (from a Dof perspective) entries */
+ for( rowNode_I=0; rowNode_I < nodesPerEl; rowNode_I++ ) {
+ for( colNode_I=0; colNode_I < nodesPerEl; colNode_I++ ) {
+ for( diagDof_I=0; diagDof_I < dofsPerNode; diagDof_I++ ) {
+ rowIndex = rowNode_I*dofsPerNode + diagDof_I;
+ colIndex = colNode_I*dofsPerNode + diagDof_I;
+ elStiffMat[rowIndex][colIndex] +=
+ detJac * visc * weight * ( GNx[diagDof_I][rowNode_I] * GNx[diagDof_I][colNode_I] );
+ for( d=0; d<dofsPerNode; d++ ) {
+ elStiffMat[rowIndex][colIndex] +=
+ detJac * visc * weight * ( GNx[d][rowNode_I] * GNx[d][colNode_I] );
+ }
+ }
+ }
+ }
+
+ /* then build one set of the off diagonal blocks of K, and copy to the other off diags using symmetry */
+ for( rowNode_I=0; rowNode_I < nodesPerEl; rowNode_I++ ) {
+ for( rowDof_I=0; rowDof_I < dofsPerNode-1; rowDof_I++ ) { /* dont need to do anything in last row */
+ for( colNode_I=0; colNode_I < nodesPerEl; colNode_I++ ) {
+ for( colDof_I=rowDof_I+1; colDof_I < dofsPerNode; colDof_I++ ) {
+ rowIndex = rowNode_I*dofsPerNode + rowDof_I;
+ colIndex = colNode_I*dofsPerNode + colDof_I;
+ elStiffMat[rowIndex][colIndex] += detJac * visc * weight *
+ ( GNx[colDof_I][rowNode_I] * GNx[rowDof_I][colNode_I] );
+ /* symmetry */
+ elStiffMat[colIndex][rowIndex] = elStiffMat[rowIndex][colIndex];
+ }
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/LaplacianStiffnessMatrixTerm.c
--- a/Assembly/src/LaplacianStiffnessMatrixTerm.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: LaplacianStiffnessMatrixTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/SLE/SLE.h>
-
-#include "types.h"
-#include "LaplacianStiffnessMatrixTerm.h"
-
-#include <assert.h>
-#include <string.h>
-
-/* Textual name of this class */
-const Type LaplacianStiffnessMatrixTerm_Type = "LaplacianStiffnessMatrixTerm";
-
-LaplacianStiffnessMatrixTerm* LaplacianStiffnessMatrixTerm_New(
- Name name,
- FiniteElementContext* context,
- StiffnessMatrix* stiffnessMatrix,
- Swarm* integrationSwarm )
-{
- LaplacianStiffnessMatrixTerm* self = (LaplacianStiffnessMatrixTerm*) _LaplacianStiffnessMatrixTerm_DefaultNew( name );
-
- self->isConstructed = False;
- _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
- _LaplacianStiffnessMatrixTerm_Init( self );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-LaplacianStiffnessMatrixTerm* _LaplacianStiffnessMatrixTerm_New( LAPLACIANSTIFFNESSMATRIXTERM_DEFARGS )
-{
- LaplacianStiffnessMatrixTerm* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(LaplacianStiffnessMatrixTerm) );
- self = (LaplacianStiffnessMatrixTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
-
- /* Virtual info */
-
- return self;
-}
-
-void _LaplacianStiffnessMatrixTerm_Init( void* matrixTerm ) {
-}
-
-void _LaplacianStiffnessMatrixTerm_Delete( void* matrixTerm ) {
- LaplacianStiffnessMatrixTerm* self = (LaplacianStiffnessMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Delete( self );
-}
-
-void _LaplacianStiffnessMatrixTerm_Print( void* matrixTerm, Stream* stream ) {
- LaplacianStiffnessMatrixTerm* self = (LaplacianStiffnessMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Print( self, stream );
-
- /* General info */
-}
-
-void* _LaplacianStiffnessMatrixTerm_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(LaplacianStiffnessMatrixTerm);
- Type type = LaplacianStiffnessMatrixTerm_Type;
- Stg_Class_DeleteFunction* _delete = _LaplacianStiffnessMatrixTerm_Delete;
- Stg_Class_PrintFunction* _print = _LaplacianStiffnessMatrixTerm_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LaplacianStiffnessMatrixTerm_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _LaplacianStiffnessMatrixTerm_AssignFromXML;
- Stg_Component_BuildFunction* _build = _LaplacianStiffnessMatrixTerm_Build;
- Stg_Component_InitialiseFunction* _initialise = _LaplacianStiffnessMatrixTerm_Initialise;
- Stg_Component_ExecuteFunction* _execute = _LaplacianStiffnessMatrixTerm_Execute;
- Stg_Component_DestroyFunction* _destroy = _LaplacianStiffnessMatrixTerm_Destroy;
- StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _LaplacianStiffnessMatrixTerm_AssembleElement;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_LaplacianStiffnessMatrixTerm_New( LAPLACIANSTIFFNESSMATRIXTERM_PASSARGS );
-}
-
-void _LaplacianStiffnessMatrixTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
- LaplacianStiffnessMatrixTerm* self = (LaplacianStiffnessMatrixTerm*)matrixTerm;
-
- /* Construct Parent */
- _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
-
- _LaplacianStiffnessMatrixTerm_Init( self );
-}
-
-void _LaplacianStiffnessMatrixTerm_Build( void* matrixTerm, void* data ) {
- LaplacianStiffnessMatrixTerm* self = (LaplacianStiffnessMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Build( self, data );
-}
-
-void _LaplacianStiffnessMatrixTerm_Initialise( void* matrixTerm, void* data ) {
- LaplacianStiffnessMatrixTerm* self = (LaplacianStiffnessMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Initialise( self, data );
-}
-
-void _LaplacianStiffnessMatrixTerm_Execute( void* matrixTerm, void* data ) {
- _StiffnessMatrixTerm_Execute( matrixTerm, data );
-}
-
-void _LaplacianStiffnessMatrixTerm_Destroy( void* matrixTerm, void* data ) {
- _StiffnessMatrixTerm_Destroy( matrixTerm, data );
-}
-
-void _LaplacianStiffnessMatrixTerm_AssembleElement(
- void* matrixTerm,
- StiffnessMatrix* stiffnessMatrix,
- Element_LocalIndex lElement_I,
- SystemLinearEquations* sle,
- FiniteElementContext* context,
- double** elStiffMat )
-{
- LaplacianStiffnessMatrixTerm* self = Stg_CheckType( matrixTerm, LaplacianStiffnessMatrixTerm );
- Swarm* swarm = self->integrationSwarm;
- FeVariable* variable1 = stiffnessMatrix->rowVariable;
- Dimension_Index dim = stiffnessMatrix->dim;
- IntegrationPoint* currIntegrationPoint;
- double* xi;
- double weight;
- Particle_InCellIndex cParticle_I, cellParticleCount;
- Index nodesPerEl;
- Index i,j;
- Dimension_Index dim_I;
- double** GNx;
- double detJac;
-
- Cell_Index cell_I;
- ElementType* elementType;
-
- /* Set the element type */
- elementType = FeMesh_GetElementType( variable1->feMesh, lElement_I );
- nodesPerEl = elementType->nodeCount;
-
- if( nodesPerEl > self->max_nElNodes ) {
- /* reallocate */
- self->GNx = ReallocArray2D( self->GNx, double, dim, nodesPerEl );
- self->max_nElNodes = nodesPerEl;
- }
- GNx = self->GNx;
-
- cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
- cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
-
- /* Slap the laplacian together */
- for( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
-
- currIntegrationPoint = (IntegrationPoint*)Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
-
- xi = currIntegrationPoint->xi;
- weight = currIntegrationPoint->weight;
-
- ElementType_ShapeFunctionsGlobalDerivs(
- elementType,
- variable1->feMesh, lElement_I,
- xi, dim, &detJac, GNx );
-
- for( i=0; i<nodesPerEl; i++ ) {
- for( j=0; j<nodesPerEl; j++ ) {
- for ( dim_I = 0; dim_I < dim ; dim_I++ ) {
- elStiffMat[i][j] += detJac * weight * GNx[dim_I][i] * GNx[dim_I][j];
- }
- }
- }
- }
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/LaplacianStiffnessMatrixTerm.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Assembly/src/LaplacianStiffnessMatrixTerm.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,216 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: LaplacianStiffnessMatrixTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include <StgFEM/SLE/SLE.h>
+
+#include "types.h"
+#include "LaplacianStiffnessMatrixTerm.h"
+
+#include <assert.h>
+#include <string.h>
+
+/* Textual name of this class */
+const Type LaplacianStiffnessMatrixTerm_Type = "LaplacianStiffnessMatrixTerm";
+
+LaplacianStiffnessMatrixTerm* LaplacianStiffnessMatrixTerm_New(
+ Name name,
+ FiniteElementContext* context,
+ StiffnessMatrix* stiffnessMatrix,
+ Swarm* integrationSwarm )
+{
+ LaplacianStiffnessMatrixTerm* self = (LaplacianStiffnessMatrixTerm*) _LaplacianStiffnessMatrixTerm_DefaultNew( name );
+
+ self->isConstructed = False;
+ _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
+ _LaplacianStiffnessMatrixTerm_Init( self );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+LaplacianStiffnessMatrixTerm* _LaplacianStiffnessMatrixTerm_New( LAPLACIANSTIFFNESSMATRIXTERM_DEFARGS )
+{
+ LaplacianStiffnessMatrixTerm* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(LaplacianStiffnessMatrixTerm) );
+ self = (LaplacianStiffnessMatrixTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _LaplacianStiffnessMatrixTerm_Init( void* matrixTerm ) {
+}
+
+void _LaplacianStiffnessMatrixTerm_Delete( void* matrixTerm ) {
+ LaplacianStiffnessMatrixTerm* self = (LaplacianStiffnessMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Delete( self );
+}
+
+void _LaplacianStiffnessMatrixTerm_Print( void* matrixTerm, Stream* stream ) {
+ LaplacianStiffnessMatrixTerm* self = (LaplacianStiffnessMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Print( self, stream );
+
+ /* General info */
+}
+
+void* _LaplacianStiffnessMatrixTerm_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(LaplacianStiffnessMatrixTerm);
+ Type type = LaplacianStiffnessMatrixTerm_Type;
+ Stg_Class_DeleteFunction* _delete = _LaplacianStiffnessMatrixTerm_Delete;
+ Stg_Class_PrintFunction* _print = _LaplacianStiffnessMatrixTerm_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LaplacianStiffnessMatrixTerm_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _LaplacianStiffnessMatrixTerm_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _LaplacianStiffnessMatrixTerm_Build;
+ Stg_Component_InitialiseFunction* _initialise = _LaplacianStiffnessMatrixTerm_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _LaplacianStiffnessMatrixTerm_Execute;
+ Stg_Component_DestroyFunction* _destroy = _LaplacianStiffnessMatrixTerm_Destroy;
+ StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _LaplacianStiffnessMatrixTerm_AssembleElement;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_LaplacianStiffnessMatrixTerm_New( LAPLACIANSTIFFNESSMATRIXTERM_PASSARGS );
+}
+
+void _LaplacianStiffnessMatrixTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
+ LaplacianStiffnessMatrixTerm* self = (LaplacianStiffnessMatrixTerm*)matrixTerm;
+
+ /* Construct Parent */
+ _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
+
+ _LaplacianStiffnessMatrixTerm_Init( self );
+}
+
+void _LaplacianStiffnessMatrixTerm_Build( void* matrixTerm, void* data ) {
+ LaplacianStiffnessMatrixTerm* self = (LaplacianStiffnessMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Build( self, data );
+}
+
+void _LaplacianStiffnessMatrixTerm_Initialise( void* matrixTerm, void* data ) {
+ LaplacianStiffnessMatrixTerm* self = (LaplacianStiffnessMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Initialise( self, data );
+}
+
+void _LaplacianStiffnessMatrixTerm_Execute( void* matrixTerm, void* data ) {
+ _StiffnessMatrixTerm_Execute( matrixTerm, data );
+}
+
+void _LaplacianStiffnessMatrixTerm_Destroy( void* matrixTerm, void* data ) {
+ _StiffnessMatrixTerm_Destroy( matrixTerm, data );
+}
+
+void _LaplacianStiffnessMatrixTerm_AssembleElement(
+ void* matrixTerm,
+ StiffnessMatrix* stiffnessMatrix,
+ Element_LocalIndex lElement_I,
+ SystemLinearEquations* sle,
+ FiniteElementContext* context,
+ double** elStiffMat )
+{
+ LaplacianStiffnessMatrixTerm* self = Stg_CheckType( matrixTerm, LaplacianStiffnessMatrixTerm );
+ Swarm* swarm = self->integrationSwarm;
+ FeVariable* variable1 = stiffnessMatrix->rowVariable;
+ Dimension_Index dim = stiffnessMatrix->dim;
+ IntegrationPoint* currIntegrationPoint;
+ double* xi;
+ double weight;
+ Particle_InCellIndex cParticle_I, cellParticleCount;
+ Index nodesPerEl;
+ Index i,j;
+ Dimension_Index dim_I;
+ double** GNx;
+ double detJac;
+
+ Cell_Index cell_I;
+ ElementType* elementType;
+
+ /* Set the element type */
+ elementType = FeMesh_GetElementType( variable1->feMesh, lElement_I );
+ nodesPerEl = elementType->nodeCount;
+
+ if( nodesPerEl > self->max_nElNodes ) {
+ /* reallocate */
+ self->GNx = ReallocArray2D( self->GNx, double, dim, nodesPerEl );
+ self->max_nElNodes = nodesPerEl;
+ }
+ GNx = self->GNx;
+
+ cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
+ cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
+
+ /* Slap the laplacian together */
+ for( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
+
+ currIntegrationPoint = (IntegrationPoint*)Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
+
+ xi = currIntegrationPoint->xi;
+ weight = currIntegrationPoint->weight;
+
+ ElementType_ShapeFunctionsGlobalDerivs(
+ elementType,
+ variable1->feMesh, lElement_I,
+ xi, dim, &detJac, GNx );
+
+ for( i=0; i<nodesPerEl; i++ ) {
+ for( j=0; j<nodesPerEl; j++ ) {
+ for ( dim_I = 0; dim_I < dim ; dim_I++ ) {
+ elStiffMat[i][j] += detJac * weight * GNx[dim_I][i] * GNx[dim_I][j];
+ }
+ }
+ }
+ }
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/MassMatrixTerm.c
--- a/Assembly/src/MassMatrixTerm.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,233 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: MassMatrixTerm.c 822 2007-04-27 06:20:35Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
-#include <assert.h>
-#include <string.h>
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/SLE/SLE.h>
-
-#include "types.h"
-#include "MassMatrixTerm.h"
-
-/* Textual name of this class */
-const Type MassMatrixTerm_Type = "MassMatrixTerm";
-
-MassMatrixTerm* MassMatrixTerm_New(
- Name name,
- FiniteElementContext* context,
- StiffnessMatrix* stiffnessMatrix,
- Swarm* integrationSwarm,
- FeVariable* field )
-{
- MassMatrixTerm* self = (MassMatrixTerm*) _MassMatrixTerm_DefaultNew( name );
-
- self->isConstructed = True;
- _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
- _MassMatrixTerm_Init( self, field );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-MassMatrixTerm* _MassMatrixTerm_New( MASSMATRIXTERM_DEFARGS )
-{
- MassMatrixTerm* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(MassMatrixTerm) );
- self = (MassMatrixTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
-
- /* Virtual info */
-
- return self;
-}
-
-void _MassMatrixTerm_Init( void* matrixTerm, FeVariable* field ) {
- MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
-
- self->field = field;
-}
-
-void _MassMatrixTerm_Delete( void* matrixTerm ) {
- MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Delete( self );
-}
-
-void _MassMatrixTerm_Print( void* matrixTerm, Stream* stream ) {
- MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Print( self, stream );
-
- /* General info */
- Journal_PrintPointer( stream, self->field );
-}
-
-void* _MassMatrixTerm_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(MassMatrixTerm);
- Type type = MassMatrixTerm_Type;
- Stg_Class_DeleteFunction* _delete = _MassMatrixTerm_Delete;
- Stg_Class_PrintFunction* _print = _MassMatrixTerm_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _MassMatrixTerm_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _MassMatrixTerm_AssignFromXML;
- Stg_Component_BuildFunction* _build = _MassMatrixTerm_Build;
- Stg_Component_InitialiseFunction* _initialise = _MassMatrixTerm_Initialise;
- Stg_Component_ExecuteFunction* _execute = _MassMatrixTerm_Execute;
- Stg_Component_DestroyFunction* _destroy = _MassMatrixTerm_Destroy;
- StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _MassMatrixTerm_AssembleElement;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_MassMatrixTerm_New( MASSMATRIXTERM_PASSARGS );
-}
-
-void _MassMatrixTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
- MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
- FeVariable* field;
-
- /* Construct Parent */
- _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
-
- field = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"field", FeVariable, True, data ) ;
-
- _MassMatrixTerm_Init( self, field );
-}
-
-void _MassMatrixTerm_Build( void* matrixTerm, void* data ) {
- MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Build( self, data );
- Stg_Component_Build( self->field, data, False );
-}
-
-void _MassMatrixTerm_Initialise( void* matrixTerm, void* data ) {
- MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Initialise( self, data );
- Stg_Component_Initialise( self->field, data, False );
-}
-
-void _MassMatrixTerm_Execute( void* matrixTerm, void* data ) {
- _StiffnessMatrixTerm_Execute( matrixTerm, data );
-}
-
-void _MassMatrixTerm_Destroy( void* matrixTerm, void* data ) {
- MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
-
- Stg_Component_Destroy( self->field, data, False );
- _StiffnessMatrixTerm_Destroy( matrixTerm, data );
-}
-
-
-void _MassMatrixTerm_AssembleElement(
- void* matrixTerm,
- StiffnessMatrix* stiffMat,
- Element_LocalIndex lElement_I,
- SystemLinearEquations* sle,
- FiniteElementContext* context,
- double** elStiffMat )
-{
- MassMatrixTerm* self = Stg_CheckType( matrixTerm, MassMatrixTerm );
- StiffnessMatrix *stiffnessMatrix = self->stiffnessMatrix;
- Swarm* swarm = self->integrationSwarm;
- FeVariable* variable1 = stiffnessMatrix->rowVariable;
- Dimension_Index dim = stiffnessMatrix->dim;
- int num_node_dofs = self->field->fieldComponentCount;
- IntegrationPoint* currIntegrationPoint;
- double* xi;
- double weight;
- Particle_InCellIndex cParticle_I, cellParticleCount;
- Index nodesPerEl;
- Index i,j, k;
- double** GNx, *N;
- double detJac;
-
- Cell_Index cell_I;
- ElementType* elementType;
-
- /* Set the element type */
- elementType = FeMesh_GetElementType( variable1->feMesh, lElement_I );
- nodesPerEl = elementType->nodeCount;
-
- if( nodesPerEl > self->max_nElNodes ) {
- /* reallocate */
- self->GNx = ReallocArray2D( self->GNx, double, dim, nodesPerEl );
- self->N = ReallocArray( self->N, double, nodesPerEl );
- self->max_nElNodes = nodesPerEl;
- }
- GNx = self->GNx;
- N = self->N;
-
- cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
- cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
-
- /* Slap the laplacian together */
- for( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
-
- currIntegrationPoint = (IntegrationPoint*)Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
-
- xi = currIntegrationPoint->xi;
- weight = currIntegrationPoint->weight;
-
- ElementType_ShapeFunctionsGlobalDerivs(
- elementType,
- variable1->feMesh, lElement_I,
- xi, dim, &detJac, GNx );
-
- ElementType_EvaluateShapeFunctionsAt( elementType, xi, N );
-
- for( i=0; i<nodesPerEl; i++ ) {
- for( j=0; j<nodesPerEl; j++ ) {
- for( k = 0; k < num_node_dofs; k++)
- elStiffMat[num_node_dofs*i + k][num_node_dofs*j + k] += detJac * weight * N[i] * N[j];
- }
- }
- }
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/MassMatrixTerm.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Assembly/src/MassMatrixTerm.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,233 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: MassMatrixTerm.c 822 2007-04-27 06:20:35Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+#include <assert.h>
+#include <string.h>
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include <StgFEM/SLE/SLE.h>
+
+#include "types.h"
+#include "MassMatrixTerm.h"
+
+/* Textual name of this class */
+const Type MassMatrixTerm_Type = "MassMatrixTerm";
+
+MassMatrixTerm* MassMatrixTerm_New(
+ Name name,
+ FiniteElementContext* context,
+ StiffnessMatrix* stiffnessMatrix,
+ Swarm* integrationSwarm,
+ FeVariable* field )
+{
+ MassMatrixTerm* self = (MassMatrixTerm*) _MassMatrixTerm_DefaultNew( name );
+
+ self->isConstructed = True;
+ _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
+ _MassMatrixTerm_Init( self, field );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+MassMatrixTerm* _MassMatrixTerm_New( MASSMATRIXTERM_DEFARGS )
+{
+ MassMatrixTerm* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(MassMatrixTerm) );
+ self = (MassMatrixTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _MassMatrixTerm_Init( void* matrixTerm, FeVariable* field ) {
+ MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
+
+ self->field = field;
+}
+
+void _MassMatrixTerm_Delete( void* matrixTerm ) {
+ MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Delete( self );
+}
+
+void _MassMatrixTerm_Print( void* matrixTerm, Stream* stream ) {
+ MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Print( self, stream );
+
+ /* General info */
+ Journal_PrintPointer( stream, self->field );
+}
+
+void* _MassMatrixTerm_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(MassMatrixTerm);
+ Type type = MassMatrixTerm_Type;
+ Stg_Class_DeleteFunction* _delete = _MassMatrixTerm_Delete;
+ Stg_Class_PrintFunction* _print = _MassMatrixTerm_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _MassMatrixTerm_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _MassMatrixTerm_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _MassMatrixTerm_Build;
+ Stg_Component_InitialiseFunction* _initialise = _MassMatrixTerm_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _MassMatrixTerm_Execute;
+ Stg_Component_DestroyFunction* _destroy = _MassMatrixTerm_Destroy;
+ StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _MassMatrixTerm_AssembleElement;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_MassMatrixTerm_New( MASSMATRIXTERM_PASSARGS );
+}
+
+void _MassMatrixTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
+ MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
+ FeVariable* field;
+
+ /* Construct Parent */
+ _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
+
+ field = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"field", FeVariable, True, data ) ;
+
+ _MassMatrixTerm_Init( self, field );
+}
+
+void _MassMatrixTerm_Build( void* matrixTerm, void* data ) {
+ MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Build( self, data );
+ Stg_Component_Build( self->field, data, False );
+}
+
+void _MassMatrixTerm_Initialise( void* matrixTerm, void* data ) {
+ MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Initialise( self, data );
+ Stg_Component_Initialise( self->field, data, False );
+}
+
+void _MassMatrixTerm_Execute( void* matrixTerm, void* data ) {
+ _StiffnessMatrixTerm_Execute( matrixTerm, data );
+}
+
+void _MassMatrixTerm_Destroy( void* matrixTerm, void* data ) {
+ MassMatrixTerm* self = (MassMatrixTerm*)matrixTerm;
+
+ Stg_Component_Destroy( self->field, data, False );
+ _StiffnessMatrixTerm_Destroy( matrixTerm, data );
+}
+
+
+void _MassMatrixTerm_AssembleElement(
+ void* matrixTerm,
+ StiffnessMatrix* stiffMat,
+ Element_LocalIndex lElement_I,
+ SystemLinearEquations* sle,
+ FiniteElementContext* context,
+ double** elStiffMat )
+{
+ MassMatrixTerm* self = Stg_CheckType( matrixTerm, MassMatrixTerm );
+ StiffnessMatrix *stiffnessMatrix = self->stiffnessMatrix;
+ Swarm* swarm = self->integrationSwarm;
+ FeVariable* variable1 = stiffnessMatrix->rowVariable;
+ Dimension_Index dim = stiffnessMatrix->dim;
+ int num_node_dofs = self->field->fieldComponentCount;
+ IntegrationPoint* currIntegrationPoint;
+ double* xi;
+ double weight;
+ Particle_InCellIndex cParticle_I, cellParticleCount;
+ Index nodesPerEl;
+ Index i,j, k;
+ double** GNx, *N;
+ double detJac;
+
+ Cell_Index cell_I;
+ ElementType* elementType;
+
+ /* Set the element type */
+ elementType = FeMesh_GetElementType( variable1->feMesh, lElement_I );
+ nodesPerEl = elementType->nodeCount;
+
+ if( nodesPerEl > self->max_nElNodes ) {
+ /* reallocate */
+ self->GNx = ReallocArray2D( self->GNx, double, dim, nodesPerEl );
+ self->N = ReallocArray( self->N, double, nodesPerEl );
+ self->max_nElNodes = nodesPerEl;
+ }
+ GNx = self->GNx;
+ N = self->N;
+
+ cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
+ cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
+
+ /* Slap the laplacian together */
+ for( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
+
+ currIntegrationPoint = (IntegrationPoint*)Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
+
+ xi = currIntegrationPoint->xi;
+ weight = currIntegrationPoint->weight;
+
+ ElementType_ShapeFunctionsGlobalDerivs(
+ elementType,
+ variable1->feMesh, lElement_I,
+ xi, dim, &detJac, GNx );
+
+ ElementType_EvaluateShapeFunctionsAt( elementType, xi, N );
+
+ for( i=0; i<nodesPerEl; i++ ) {
+ for( j=0; j<nodesPerEl; j++ ) {
+ for( k = 0; k < num_node_dofs; k++)
+ elStiffMat[num_node_dofs*i + k][num_node_dofs*j + k] += detJac * weight * N[i] * N[j];
+ }
+ }
+ }
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/PressureGradForceTerm.c
--- a/Assembly/src/PressureGradForceTerm.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,219 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: PressureGradForceTerm.c 822 2007-04-27 06:20:35Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
-#include <assert.h>
-#include <string.h>
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/SLE/SLE.h>
-
-#include "types.h"
-#include "PressureGradForceTerm.h"
-
-/* Textual name of this class */
-const Type PressureGradForceTerm_Type = "PressureGradForceTerm";
-
-PressureGradForceTerm* PressureGradForceTerm_New(
- Name name,
- FiniteElementContext* context,
- ForceVector* forceVector,
- Swarm* integrationSwarm,
- FeVariable* gradField,
- FeVariable* pressureField )
-{
- PressureGradForceTerm* self = (PressureGradForceTerm*) _PressureGradForceTerm_DefaultNew( name );
-
- self->isConstructed = True;
- _ForceTerm_Init( self, context, forceVector, integrationSwarm, NULL );
- _PressureGradForceTerm_Init( self, pressureField, gradField );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-PressureGradForceTerm* _PressureGradForceTerm_New( PRESSUREGRADFORCETERM_DEFARGS )
-{
- PressureGradForceTerm* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(PressureGradForceTerm) );
- /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
- /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
- and so should be set to ZERO in any children of this class. */
- nameAllocationType = NON_GLOBAL;
-
- self = (PressureGradForceTerm*) _ForceTerm_New( FORCETERM_PASSARGS );
-
- /* Virtual info */
-
- return self;
-}
-
-void _PressureGradForceTerm_Init( void* forceTerm, FeVariable* pressureField, FeVariable* gradField ) {
- PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
-
- self->asmb = Assembler_New();
- Assembler_SetCallbacks( self->asmb,
- NULL,
- NULL,
- (Assembler_CallbackType*)PressureGradForceTerm_RowCB,
- (Assembler_CallbackType*)PressureGradForceTerm_ColCB,
- (Assembler_CallbackType*)PressureGradForceTerm_ColCB,
- self );
- self->pressureField = pressureField;
- self->gradField = gradField;
- self->forceVector = NULL;
- self->elForceVec = NULL;
- self->factor = 0.0;
-}
-
-void _PressureGradForceTerm_Delete( void* forceTerm ) {
- PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
-
- _ForceTerm_Delete( self );
-}
-
-void _PressureGradForceTerm_Print( void* forceTerm, Stream* stream ) {
- PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
-
- _ForceTerm_Print( self, stream );
-
- /* General info */
- Journal_PrintPointer( stream, self->pressureField );
-}
-
-void* _PressureGradForceTerm_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(PressureGradForceTerm);
- Type type = PressureGradForceTerm_Type;
- Stg_Class_DeleteFunction* _delete = _PressureGradForceTerm_Delete;
- Stg_Class_PrintFunction* _print = _PressureGradForceTerm_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _PressureGradForceTerm_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _PressureGradForceTerm_AssignFromXML;
- Stg_Component_BuildFunction* _build = _PressureGradForceTerm_Build;
- Stg_Component_InitialiseFunction* _initialise = _PressureGradForceTerm_Initialise;
- Stg_Component_ExecuteFunction* _execute = _PressureGradForceTerm_Execute;
- Stg_Component_DestroyFunction* _destroy = _PressureGradForceTerm_Destroy;
- ForceTerm_AssembleElementFunction* _assembleElement = _PressureGradForceTerm_AssembleElement;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_PressureGradForceTerm_New( PRESSUREGRADFORCETERM_PASSARGS );
-}
-
-void _PressureGradForceTerm_AssignFromXML( void* forceTerm, Stg_ComponentFactory* cf, void* data ) {
- PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
-
- /* Construct Parent */
- _ForceTerm_AssignFromXML( self, cf, data );
-
- _PressureGradForceTerm_Init(
- self,
- Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"PressureField", FeVariable, True, data ),
- Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"PressureGradField", FeVariable, True, data ) );
-}
-
-void _PressureGradForceTerm_Build( void* forceTerm, void* data ) {
- PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
-
- _ForceTerm_Build( self, data );
- Stg_Component_Build( self->pressureField, data, False );
- Stg_Component_Build( self->gradField, data, False );
- Assembler_SetVariables( self->asmb, self->gradField, self->pressureField );
- Assembler_SetIntegrationSwarm( self->asmb, self->integrationSwarm );
-}
-
-void _PressureGradForceTerm_Initialise( void* forceTerm, void* data ) {
- PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
-
- Stg_Component_Initialise( self->pressureField, data, False );
- Stg_Component_Initialise( self->gradField, data, False );
- _ForceTerm_Initialise( self, data );
-}
-
-void _PressureGradForceTerm_Execute( void* forceTerm, void* data ) {
- PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
-
- _ForceTerm_Execute( self, data );
-}
-
-void _PressureGradForceTerm_Destroy( void* forceTerm, void* data ) {
- PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
-
- Stg_Component_Destroy( self->pressureField, data, False );
- Stg_Component_Destroy( self->gradField, data, False );
- _ForceTerm_Destroy( self, data );
-}
-
-
-void _PressureGradForceTerm_AssembleElement( void* forceTerm, ForceVector* forceVector, Element_LocalIndex lElement_I, double* elForceVec ) {
- PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
-
- assert( self );
-
- self->forceVector = forceVector;
- self->elForceVec = elForceVec;
- Assembler_IntegrateMatrixElement( self->asmb, lElement_I );
-}
-
-Bool PressureGradForceTerm_RowCB( PressureGradForceTerm* self, Assembler* assm ) {
- self->factor = assm->particle->weight * assm->detJac;
- return True;
-}
-
-Bool PressureGradForceTerm_ColCB( PressureGradForceTerm* self, Assembler* assm ) {
- double val;
-
- FeVariable_GetValueAtNode( self->pressureField, assm->colNodeInd, &val );
- self->elForceVec[assm->rowInd] +=
- val *
- assm->shapeFuncs[assm->rowElNodeInd] *
- assm->globalDerivs[assm->rowDofInd][assm->colElNodeInd] *
- self->factor;
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/PressureGradForceTerm.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Assembly/src/PressureGradForceTerm.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,219 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: PressureGradForceTerm.c 822 2007-04-27 06:20:35Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+#include <assert.h>
+#include <string.h>
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include <StgFEM/SLE/SLE.h>
+
+#include "types.h"
+#include "PressureGradForceTerm.h"
+
+/* Textual name of this class */
+const Type PressureGradForceTerm_Type = "PressureGradForceTerm";
+
+PressureGradForceTerm* PressureGradForceTerm_New(
+ Name name,
+ FiniteElementContext* context,
+ ForceVector* forceVector,
+ Swarm* integrationSwarm,
+ FeVariable* gradField,
+ FeVariable* pressureField )
+{
+ PressureGradForceTerm* self = (PressureGradForceTerm*) _PressureGradForceTerm_DefaultNew( name );
+
+ self->isConstructed = True;
+ _ForceTerm_Init( self, context, forceVector, integrationSwarm, NULL );
+ _PressureGradForceTerm_Init( self, pressureField, gradField );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+PressureGradForceTerm* _PressureGradForceTerm_New( PRESSUREGRADFORCETERM_DEFARGS )
+{
+ PressureGradForceTerm* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(PressureGradForceTerm) );
+ /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
+ /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
+ and so should be set to ZERO in any children of this class. */
+ nameAllocationType = NON_GLOBAL;
+
+ self = (PressureGradForceTerm*) _ForceTerm_New( FORCETERM_PASSARGS );
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _PressureGradForceTerm_Init( void* forceTerm, FeVariable* pressureField, FeVariable* gradField ) {
+ PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
+
+ self->asmb = Assembler_New();
+ Assembler_SetCallbacks( self->asmb,
+ NULL,
+ NULL,
+ (Assembler_CallbackType*)PressureGradForceTerm_RowCB,
+ (Assembler_CallbackType*)PressureGradForceTerm_ColCB,
+ (Assembler_CallbackType*)PressureGradForceTerm_ColCB,
+ self );
+ self->pressureField = pressureField;
+ self->gradField = gradField;
+ self->forceVector = NULL;
+ self->elForceVec = NULL;
+ self->factor = 0.0;
+}
+
+void _PressureGradForceTerm_Delete( void* forceTerm ) {
+ PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
+
+ _ForceTerm_Delete( self );
+}
+
+void _PressureGradForceTerm_Print( void* forceTerm, Stream* stream ) {
+ PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
+
+ _ForceTerm_Print( self, stream );
+
+ /* General info */
+ Journal_PrintPointer( stream, self->pressureField );
+}
+
+void* _PressureGradForceTerm_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(PressureGradForceTerm);
+ Type type = PressureGradForceTerm_Type;
+ Stg_Class_DeleteFunction* _delete = _PressureGradForceTerm_Delete;
+ Stg_Class_PrintFunction* _print = _PressureGradForceTerm_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _PressureGradForceTerm_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _PressureGradForceTerm_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _PressureGradForceTerm_Build;
+ Stg_Component_InitialiseFunction* _initialise = _PressureGradForceTerm_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _PressureGradForceTerm_Execute;
+ Stg_Component_DestroyFunction* _destroy = _PressureGradForceTerm_Destroy;
+ ForceTerm_AssembleElementFunction* _assembleElement = _PressureGradForceTerm_AssembleElement;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_PressureGradForceTerm_New( PRESSUREGRADFORCETERM_PASSARGS );
+}
+
+void _PressureGradForceTerm_AssignFromXML( void* forceTerm, Stg_ComponentFactory* cf, void* data ) {
+ PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
+
+ /* Construct Parent */
+ _ForceTerm_AssignFromXML( self, cf, data );
+
+ _PressureGradForceTerm_Init(
+ self,
+ Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"PressureField", FeVariable, True, data ),
+ Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"PressureGradField", FeVariable, True, data ) );
+}
+
+void _PressureGradForceTerm_Build( void* forceTerm, void* data ) {
+ PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
+
+ _ForceTerm_Build( self, data );
+ Stg_Component_Build( self->pressureField, data, False );
+ Stg_Component_Build( self->gradField, data, False );
+ Assembler_SetVariables( self->asmb, self->gradField, self->pressureField );
+ Assembler_SetIntegrationSwarm( self->asmb, self->integrationSwarm );
+}
+
+void _PressureGradForceTerm_Initialise( void* forceTerm, void* data ) {
+ PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
+
+ Stg_Component_Initialise( self->pressureField, data, False );
+ Stg_Component_Initialise( self->gradField, data, False );
+ _ForceTerm_Initialise( self, data );
+}
+
+void _PressureGradForceTerm_Execute( void* forceTerm, void* data ) {
+ PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
+
+ _ForceTerm_Execute( self, data );
+}
+
+void _PressureGradForceTerm_Destroy( void* forceTerm, void* data ) {
+ PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
+
+ Stg_Component_Destroy( self->pressureField, data, False );
+ Stg_Component_Destroy( self->gradField, data, False );
+ _ForceTerm_Destroy( self, data );
+}
+
+
+void _PressureGradForceTerm_AssembleElement( void* forceTerm, ForceVector* forceVector, Element_LocalIndex lElement_I, double* elForceVec ) {
+ PressureGradForceTerm* self = (PressureGradForceTerm*)forceTerm;
+
+ assert( self );
+
+ self->forceVector = forceVector;
+ self->elForceVec = elForceVec;
+ Assembler_IntegrateMatrixElement( self->asmb, lElement_I );
+}
+
+Bool PressureGradForceTerm_RowCB( PressureGradForceTerm* self, Assembler* assm ) {
+ self->factor = assm->particle->weight * assm->detJac;
+ return True;
+}
+
+Bool PressureGradForceTerm_ColCB( PressureGradForceTerm* self, Assembler* assm ) {
+ double val;
+
+ FeVariable_GetValueAtNode( self->pressureField, assm->colNodeInd, &val );
+ self->elForceVec[assm->rowInd] +=
+ val *
+ assm->shapeFuncs[assm->rowElNodeInd] *
+ assm->globalDerivs[assm->rowDofInd][assm->colElNodeInd] *
+ self->factor;
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/PressureGradMatrixTerm.c
--- a/Assembly/src/PressureGradMatrixTerm.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,213 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: PressureGradMatrixTerm.c 822 2007-04-27 06:20:35Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
-#include <assert.h>
-#include <string.h>
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/SLE/SLE.h>
-
-#include "types.h"
-#include "PressureGradMatrixTerm.h"
-
-/* Textual name of this class */
-const Type PressureGradMatrixTerm_Type = "PressureGradMatrixTerm";
-
-PressureGradMatrixTerm* PressureGradMatrixTerm_New(
- Name name,
- FiniteElementContext* context,
- StiffnessMatrix* stiffnessMatrix,
- Swarm* integrationSwarm,
- FeVariable* gradField )
-{
- PressureGradMatrixTerm* self = (PressureGradMatrixTerm*) _PressureGradMatrixTerm_DefaultNew( name );
-
- self->isConstructed = True;
- _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
- _PressureGradMatrixTerm_Init( self, gradField );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-PressureGradMatrixTerm* _PressureGradMatrixTerm_New( PRESSUREGRADMATRIXTERM_DEFARGS )
-{
- PressureGradMatrixTerm* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(PressureGradMatrixTerm) );
- self = (PressureGradMatrixTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
-
- /* Virtual info */
-
- return self;
-}
-
-void _PressureGradMatrixTerm_Init( void* matrixTerm, FeVariable* gradField ) {
- PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
-
- self->assm = Assembler_New();
- Assembler_SetCallbacks( self->assm,
- NULL,
- NULL,
- (Assembler_CallbackType*)PressureGradMatrixTerm_RowCB,
- (Assembler_CallbackType*)PressureGradMatrixTerm_ColCB,
- (Assembler_CallbackType*)PressureGradMatrixTerm_ColCB,
- self );
- self->gradField = gradField;
- self->stiffnessMatrix = NULL;
- self->elStiffMat = NULL;
- self->factor = 0.0;
-}
-
-void _PressureGradMatrixTerm_Delete( void* matrixTerm ) {
- PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Delete( self );
-}
-
-void _PressureGradMatrixTerm_Print( void* matrixTerm, Stream* stream ) {
- PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Print( self, stream );
-
- /* General info */
- Journal_PrintPointer( stream, self->gradField );
-}
-
-void* _PressureGradMatrixTerm_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(PressureGradMatrixTerm);
- Type type = PressureGradMatrixTerm_Type;
- Stg_Class_DeleteFunction* _delete = _PressureGradMatrixTerm_Delete;
- Stg_Class_PrintFunction* _print = _PressureGradMatrixTerm_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _PressureGradMatrixTerm_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _PressureGradMatrixTerm_AssignFromXML;
- Stg_Component_BuildFunction* _build = _PressureGradMatrixTerm_Build;
- Stg_Component_InitialiseFunction* _initialise = _PressureGradMatrixTerm_Initialise;
- Stg_Component_ExecuteFunction* _execute = _PressureGradMatrixTerm_Execute;
- Stg_Component_DestroyFunction* _destroy = _PressureGradMatrixTerm_Destroy;
- StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _PressureGradMatrixTerm_AssembleElement;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_PressureGradMatrixTerm_New( PRESSUREGRADMATRIXTERM_PASSARGS );
-}
-
-void _PressureGradMatrixTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
- PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
- FeVariable* gradField;
-
- /* Construct Parent */
- _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
-
- gradField = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"PressureGradField", FeVariable, True, data ) ;
-
- _PressureGradMatrixTerm_Init( self, gradField );
-}
-
-void _PressureGradMatrixTerm_Build( void* matrixTerm, void* data ) {
- PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Build( self, data );
- Stg_Component_Build( self->gradField, data, False );
- Assembler_SetVariables( self->assm, self->gradField, self->gradField );
- Assembler_SetIntegrationSwarm( self->assm, self->integrationSwarm );
-}
-
-void _PressureGradMatrixTerm_Initialise( void* matrixTerm, void* data ) {
- PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Initialise( self, data );
- Stg_Component_Initialise( self->gradField, data, False );
-}
-
-void _PressureGradMatrixTerm_Execute( void* matrixTerm, void* data ) {
- _StiffnessMatrixTerm_Execute( matrixTerm, data );
-}
-
-void _PressureGradMatrixTerm_Destroy( void* matrixTerm, void* data ) {
- PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
- Stg_Component_Destroy( self->gradField, data, False );
- Stg_Component_Destroy( self->stiffMat, data, False );
-
- _StiffnessMatrixTerm_Destroy( matrixTerm, data );
-}
-
-void _PressureGradMatrixTerm_AssembleElement(
- void* matrixTerm,
- StiffnessMatrix* stiffnessMatrix,
- Element_LocalIndex lElement_I,
- SystemLinearEquations* sle,
- FiniteElementContext* context,
- double** elStiffMat )
-{
- PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
-
- assert( self );
-
- self->stiffnessMatrix = stiffnessMatrix;
- self->elStiffMat = elStiffMat;
- Assembler_IntegrateMatrixElement( self->assm, lElement_I );
-}
-
-Bool PressureGradMatrixTerm_RowCB( PressureGradMatrixTerm* self, Assembler* assm ) {
- self->factor = assm->particle->weight * assm->detJac;
- return True;
-}
-
-Bool PressureGradMatrixTerm_ColCB( PressureGradMatrixTerm* self, Assembler* assm ) {
- if( assm->rowDofInd != assm->colDofInd )
- return False;
-
- self->elStiffMat[assm->rowInd][assm->colInd] +=
- assm->shapeFuncs[assm->rowElNodeInd] *
- assm->shapeFuncs[assm->colElNodeInd] *
- self->factor;
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/PressureGradMatrixTerm.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Assembly/src/PressureGradMatrixTerm.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,213 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: PressureGradMatrixTerm.c 822 2007-04-27 06:20:35Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+#include <assert.h>
+#include <string.h>
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include <StgFEM/SLE/SLE.h>
+
+#include "types.h"
+#include "PressureGradMatrixTerm.h"
+
+/* Textual name of this class */
+const Type PressureGradMatrixTerm_Type = "PressureGradMatrixTerm";
+
+PressureGradMatrixTerm* PressureGradMatrixTerm_New(
+ Name name,
+ FiniteElementContext* context,
+ StiffnessMatrix* stiffnessMatrix,
+ Swarm* integrationSwarm,
+ FeVariable* gradField )
+{
+ PressureGradMatrixTerm* self = (PressureGradMatrixTerm*) _PressureGradMatrixTerm_DefaultNew( name );
+
+ self->isConstructed = True;
+ _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
+ _PressureGradMatrixTerm_Init( self, gradField );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+PressureGradMatrixTerm* _PressureGradMatrixTerm_New( PRESSUREGRADMATRIXTERM_DEFARGS )
+{
+ PressureGradMatrixTerm* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(PressureGradMatrixTerm) );
+ self = (PressureGradMatrixTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _PressureGradMatrixTerm_Init( void* matrixTerm, FeVariable* gradField ) {
+ PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
+
+ self->assm = Assembler_New();
+ Assembler_SetCallbacks( self->assm,
+ NULL,
+ NULL,
+ (Assembler_CallbackType*)PressureGradMatrixTerm_RowCB,
+ (Assembler_CallbackType*)PressureGradMatrixTerm_ColCB,
+ (Assembler_CallbackType*)PressureGradMatrixTerm_ColCB,
+ self );
+ self->gradField = gradField;
+ self->stiffnessMatrix = NULL;
+ self->elStiffMat = NULL;
+ self->factor = 0.0;
+}
+
+void _PressureGradMatrixTerm_Delete( void* matrixTerm ) {
+ PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Delete( self );
+}
+
+void _PressureGradMatrixTerm_Print( void* matrixTerm, Stream* stream ) {
+ PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Print( self, stream );
+
+ /* General info */
+ Journal_PrintPointer( stream, self->gradField );
+}
+
+void* _PressureGradMatrixTerm_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(PressureGradMatrixTerm);
+ Type type = PressureGradMatrixTerm_Type;
+ Stg_Class_DeleteFunction* _delete = _PressureGradMatrixTerm_Delete;
+ Stg_Class_PrintFunction* _print = _PressureGradMatrixTerm_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _PressureGradMatrixTerm_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _PressureGradMatrixTerm_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _PressureGradMatrixTerm_Build;
+ Stg_Component_InitialiseFunction* _initialise = _PressureGradMatrixTerm_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _PressureGradMatrixTerm_Execute;
+ Stg_Component_DestroyFunction* _destroy = _PressureGradMatrixTerm_Destroy;
+ StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _PressureGradMatrixTerm_AssembleElement;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_PressureGradMatrixTerm_New( PRESSUREGRADMATRIXTERM_PASSARGS );
+}
+
+void _PressureGradMatrixTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
+ PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
+ FeVariable* gradField;
+
+ /* Construct Parent */
+ _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
+
+ gradField = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"PressureGradField", FeVariable, True, data ) ;
+
+ _PressureGradMatrixTerm_Init( self, gradField );
+}
+
+void _PressureGradMatrixTerm_Build( void* matrixTerm, void* data ) {
+ PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Build( self, data );
+ Stg_Component_Build( self->gradField, data, False );
+ Assembler_SetVariables( self->assm, self->gradField, self->gradField );
+ Assembler_SetIntegrationSwarm( self->assm, self->integrationSwarm );
+}
+
+void _PressureGradMatrixTerm_Initialise( void* matrixTerm, void* data ) {
+ PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Initialise( self, data );
+ Stg_Component_Initialise( self->gradField, data, False );
+}
+
+void _PressureGradMatrixTerm_Execute( void* matrixTerm, void* data ) {
+ _StiffnessMatrixTerm_Execute( matrixTerm, data );
+}
+
+void _PressureGradMatrixTerm_Destroy( void* matrixTerm, void* data ) {
+ PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
+ Stg_Component_Destroy( self->gradField, data, False );
+ Stg_Component_Destroy( self->stiffMat, data, False );
+
+ _StiffnessMatrixTerm_Destroy( matrixTerm, data );
+}
+
+void _PressureGradMatrixTerm_AssembleElement(
+ void* matrixTerm,
+ StiffnessMatrix* stiffnessMatrix,
+ Element_LocalIndex lElement_I,
+ SystemLinearEquations* sle,
+ FiniteElementContext* context,
+ double** elStiffMat )
+{
+ PressureGradMatrixTerm* self = (PressureGradMatrixTerm*)matrixTerm;
+
+ assert( self );
+
+ self->stiffnessMatrix = stiffnessMatrix;
+ self->elStiffMat = elStiffMat;
+ Assembler_IntegrateMatrixElement( self->assm, lElement_I );
+}
+
+Bool PressureGradMatrixTerm_RowCB( PressureGradMatrixTerm* self, Assembler* assm ) {
+ self->factor = assm->particle->weight * assm->detJac;
+ return True;
+}
+
+Bool PressureGradMatrixTerm_ColCB( PressureGradMatrixTerm* self, Assembler* assm ) {
+ if( assm->rowDofInd != assm->colDofInd )
+ return False;
+
+ self->elStiffMat[assm->rowInd][assm->colInd] +=
+ assm->shapeFuncs[assm->rowElNodeInd] *
+ assm->shapeFuncs[assm->colElNodeInd] *
+ self->factor;
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/ThermalBuoyancyForceTerm.c
--- a/Assembly/src/ThermalBuoyancyForceTerm.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,243 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: ThermalBuoyancyForceTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/SLE/SLE.h>
-
-#include "types.h"
-#include "ThermalBuoyancyForceTerm.h"
-
-#include <assert.h>
-#include <string.h>
-
-/* Textual name of this class */
-const Type ThermalBuoyancyForceTerm_Type = "ThermalBuoyancyForceTerm";
-
-ThermalBuoyancyForceTerm* ThermalBuoyancyForceTerm_New(
- Name name,
- FiniteElementContext* context,
- ForceVector* forceVector,
- Swarm* integrationSwarm,
- FeVariable* temperatureField,
- double rayleighNumber )
-{
- ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*) _ThermalBuoyancyForceTerm_DefaultNew( name );
-
- self->isConstructed = True;
- _ForceTerm_Init( self, context, forceVector, integrationSwarm, NULL );
- _ThermalBuoyancyForceTerm_Init( self, temperatureField, rayleighNumber );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-ThermalBuoyancyForceTerm* _ThermalBuoyancyForceTerm_New( THERMALBUOYANCYFORCETERM_DEFARGS )
-{
- ThermalBuoyancyForceTerm* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(ThermalBuoyancyForceTerm) );
- /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
- /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
- and so should be set to ZERO in any children of this class. */
- nameAllocationType = NON_GLOBAL;
-
- self = (ThermalBuoyancyForceTerm*) _ForceTerm_New( FORCETERM_PASSARGS );
-
- /* Virtual info */
-
- return self;
-}
-
-void _ThermalBuoyancyForceTerm_Init( void* forceTerm, FeVariable* temperatureField, double rayleighNumber ) {
- ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
-
- self->temperatureField = temperatureField;
- self->rayleighNumber = rayleighNumber;
-}
-
-void _ThermalBuoyancyForceTerm_Delete( void* forceTerm ) {
- ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
-
- _ForceTerm_Delete( self );
-}
-
-void _ThermalBuoyancyForceTerm_Print( void* forceTerm, Stream* stream ) {
- ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
-
- _ForceTerm_Print( self, stream );
-
- /* General info */
- Journal_PrintPointer( stream, self->temperatureField );
- Journal_PrintDouble( stream, self->rayleighNumber );
-}
-
-void* _ThermalBuoyancyForceTerm_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(ThermalBuoyancyForceTerm);
- Type type = ThermalBuoyancyForceTerm_Type;
- Stg_Class_DeleteFunction* _delete = _ThermalBuoyancyForceTerm_Delete;
- Stg_Class_PrintFunction* _print = _ThermalBuoyancyForceTerm_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _ThermalBuoyancyForceTerm_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _ThermalBuoyancyForceTerm_AssignFromXML;
- Stg_Component_BuildFunction* _build = _ThermalBuoyancyForceTerm_Build;
- Stg_Component_InitialiseFunction* _initialise = _ThermalBuoyancyForceTerm_Initialise;
- Stg_Component_ExecuteFunction* _execute = _ThermalBuoyancyForceTerm_Execute;
- Stg_Component_DestroyFunction* _destroy = _ThermalBuoyancyForceTerm_Destroy;
- ForceTerm_AssembleElementFunction* _assembleElement = _ThermalBuoyancyForceTerm_AssembleElement;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_ThermalBuoyancyForceTerm_New( THERMALBUOYANCYFORCETERM_PASSARGS );
-}
-
-void _ThermalBuoyancyForceTerm_AssignFromXML( void* forceTerm, Stg_ComponentFactory* cf, void* data ) {
- ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
- FeVariable* temperatureField;
- double rayleighNumber;
-
- /* Construct Parent */
- _ForceTerm_AssignFromXML( self, cf, data );
-
- temperatureField = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"TemperatureField", FeVariable, True, data ) ;
- rayleighNumber = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"Ra", 0.0 );
-
- _ThermalBuoyancyForceTerm_Init( self, temperatureField, rayleighNumber );
-}
-
-void _ThermalBuoyancyForceTerm_Build( void* forceTerm, void* data ) {
- ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
-
- Stg_Component_Build( self->temperatureField, data, False );
- _ForceTerm_Build( self, data );
-}
-
-void _ThermalBuoyancyForceTerm_Initialise( void* forceTerm, void* data ) {
- ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
-
- Stg_Component_Initialise( self->temperatureField, data, False );
- _ForceTerm_Initialise( self, data );
-}
-
-void _ThermalBuoyancyForceTerm_Execute( void* forceTerm, void* data ) {
- ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
-
- _ForceTerm_Execute( self, data );
-}
-
-void _ThermalBuoyancyForceTerm_Destroy( void* forceTerm, void* data ) {
- ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
-
- Stg_Component_Destroy( self->temperatureField, data, False );
- _ForceTerm_Destroy( self, data );
-}
-
-
-void _ThermalBuoyancyForceTerm_AssembleElement( void* forceTerm, ForceVector* forceVector, Element_LocalIndex lElement_I, double* elForceVec ) {
- ThermalBuoyancyForceTerm* self = Stg_CheckType( forceTerm, ThermalBuoyancyForceTerm );
- Swarm* swarm = self->integrationSwarm;
- Dimension_Index dim = forceVector->dim;
- IntegrationPoint* particle;
- FeVariable* temperatureField;
- FeMesh* mesh;
- FeMesh* temperatureMesh;
- double* xi;
- Particle_InCellIndex cParticle_I;
- Particle_InCellIndex cellParticleCount;
- Element_NodeIndex elementNodeCount;
- Node_ElementLocalIndex node_I;
- ElementType* elementType;
- Dof_Index dofsPerNode;
- Cell_Index cell_I;
- double detJac;
- double factor;
- /*double Ni[8];*/
- double Ni[27];
- double force;
- double rayleighNumber;
- double temperature;
-
- /* Get context extension */
- rayleighNumber = self->rayleighNumber;
- temperatureField = self->temperatureField;
- temperatureMesh = temperatureField->feMesh;
-
- /* Since we are integrating over the velocity mesh - we want the velocity mesh here and not the temperature mesh */
- mesh = forceVector->feVariable->feMesh;
-
- /* Set the element type */
- elementType = FeMesh_GetElementType( mesh, lElement_I );
- elementNodeCount = elementType->nodeCount;
-
- /* assumes constant number of dofs per element */
- dofsPerNode = dim;
-
- cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
- cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
-
- for ( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
- particle = (IntegrationPoint*) Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
- xi = particle->xi;
-
- /* Calculate Determinant of Jacobian and Shape Functions */
- detJac = ElementType_JacobianDeterminant( elementType, mesh, lElement_I, xi, dim );
- ElementType_EvaluateShapeFunctionsAt( elementType, xi, Ni );
-
- /* Field Get Temperature from Field Variable */
- FeVariable_InterpolateFromMeshLocalCoord( temperatureField, mesh, lElement_I, xi, &temperature );
-
- force = rayleighNumber * temperature;
-
- factor = detJac * particle->weight * force;
- for( node_I = 0 ; node_I < elementNodeCount ; node_I++ )
- elForceVec[node_I * dofsPerNode + J_AXIS ] += factor * Ni[ node_I ] ;
-
- }
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/src/ThermalBuoyancyForceTerm.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Assembly/src/ThermalBuoyancyForceTerm.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,243 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: ThermalBuoyancyForceTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include <StgFEM/SLE/SLE.h>
+
+#include "types.h"
+#include "ThermalBuoyancyForceTerm.h"
+
+#include <assert.h>
+#include <string.h>
+
+/* Textual name of this class */
+const Type ThermalBuoyancyForceTerm_Type = "ThermalBuoyancyForceTerm";
+
+ThermalBuoyancyForceTerm* ThermalBuoyancyForceTerm_New(
+ Name name,
+ FiniteElementContext* context,
+ ForceVector* forceVector,
+ Swarm* integrationSwarm,
+ FeVariable* temperatureField,
+ double rayleighNumber )
+{
+ ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*) _ThermalBuoyancyForceTerm_DefaultNew( name );
+
+ self->isConstructed = True;
+ _ForceTerm_Init( self, context, forceVector, integrationSwarm, NULL );
+ _ThermalBuoyancyForceTerm_Init( self, temperatureField, rayleighNumber );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+ThermalBuoyancyForceTerm* _ThermalBuoyancyForceTerm_New( THERMALBUOYANCYFORCETERM_DEFARGS )
+{
+ ThermalBuoyancyForceTerm* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(ThermalBuoyancyForceTerm) );
+ /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
+ /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
+ and so should be set to ZERO in any children of this class. */
+ nameAllocationType = NON_GLOBAL;
+
+ self = (ThermalBuoyancyForceTerm*) _ForceTerm_New( FORCETERM_PASSARGS );
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _ThermalBuoyancyForceTerm_Init( void* forceTerm, FeVariable* temperatureField, double rayleighNumber ) {
+ ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
+
+ self->temperatureField = temperatureField;
+ self->rayleighNumber = rayleighNumber;
+}
+
+void _ThermalBuoyancyForceTerm_Delete( void* forceTerm ) {
+ ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
+
+ _ForceTerm_Delete( self );
+}
+
+void _ThermalBuoyancyForceTerm_Print( void* forceTerm, Stream* stream ) {
+ ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
+
+ _ForceTerm_Print( self, stream );
+
+ /* General info */
+ Journal_PrintPointer( stream, self->temperatureField );
+ Journal_PrintDouble( stream, self->rayleighNumber );
+}
+
+void* _ThermalBuoyancyForceTerm_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(ThermalBuoyancyForceTerm);
+ Type type = ThermalBuoyancyForceTerm_Type;
+ Stg_Class_DeleteFunction* _delete = _ThermalBuoyancyForceTerm_Delete;
+ Stg_Class_PrintFunction* _print = _ThermalBuoyancyForceTerm_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _ThermalBuoyancyForceTerm_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _ThermalBuoyancyForceTerm_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _ThermalBuoyancyForceTerm_Build;
+ Stg_Component_InitialiseFunction* _initialise = _ThermalBuoyancyForceTerm_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _ThermalBuoyancyForceTerm_Execute;
+ Stg_Component_DestroyFunction* _destroy = _ThermalBuoyancyForceTerm_Destroy;
+ ForceTerm_AssembleElementFunction* _assembleElement = _ThermalBuoyancyForceTerm_AssembleElement;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_ThermalBuoyancyForceTerm_New( THERMALBUOYANCYFORCETERM_PASSARGS );
+}
+
+void _ThermalBuoyancyForceTerm_AssignFromXML( void* forceTerm, Stg_ComponentFactory* cf, void* data ) {
+ ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
+ FeVariable* temperatureField;
+ double rayleighNumber;
+
+ /* Construct Parent */
+ _ForceTerm_AssignFromXML( self, cf, data );
+
+ temperatureField = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"TemperatureField", FeVariable, True, data ) ;
+ rayleighNumber = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"Ra", 0.0 );
+
+ _ThermalBuoyancyForceTerm_Init( self, temperatureField, rayleighNumber );
+}
+
+void _ThermalBuoyancyForceTerm_Build( void* forceTerm, void* data ) {
+ ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
+
+ Stg_Component_Build( self->temperatureField, data, False );
+ _ForceTerm_Build( self, data );
+}
+
+void _ThermalBuoyancyForceTerm_Initialise( void* forceTerm, void* data ) {
+ ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
+
+ Stg_Component_Initialise( self->temperatureField, data, False );
+ _ForceTerm_Initialise( self, data );
+}
+
+void _ThermalBuoyancyForceTerm_Execute( void* forceTerm, void* data ) {
+ ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
+
+ _ForceTerm_Execute( self, data );
+}
+
+void _ThermalBuoyancyForceTerm_Destroy( void* forceTerm, void* data ) {
+ ThermalBuoyancyForceTerm* self = (ThermalBuoyancyForceTerm*)forceTerm;
+
+ Stg_Component_Destroy( self->temperatureField, data, False );
+ _ForceTerm_Destroy( self, data );
+}
+
+
+void _ThermalBuoyancyForceTerm_AssembleElement( void* forceTerm, ForceVector* forceVector, Element_LocalIndex lElement_I, double* elForceVec ) {
+ ThermalBuoyancyForceTerm* self = Stg_CheckType( forceTerm, ThermalBuoyancyForceTerm );
+ Swarm* swarm = self->integrationSwarm;
+ Dimension_Index dim = forceVector->dim;
+ IntegrationPoint* particle;
+ FeVariable* temperatureField;
+ FeMesh* mesh;
+ FeMesh* temperatureMesh;
+ double* xi;
+ Particle_InCellIndex cParticle_I;
+ Particle_InCellIndex cellParticleCount;
+ Element_NodeIndex elementNodeCount;
+ Node_ElementLocalIndex node_I;
+ ElementType* elementType;
+ Dof_Index dofsPerNode;
+ Cell_Index cell_I;
+ double detJac;
+ double factor;
+ /*double Ni[8];*/
+ double Ni[27];
+ double force;
+ double rayleighNumber;
+ double temperature;
+
+ /* Get context extension */
+ rayleighNumber = self->rayleighNumber;
+ temperatureField = self->temperatureField;
+ temperatureMesh = temperatureField->feMesh;
+
+ /* Since we are integrating over the velocity mesh - we want the velocity mesh here and not the temperature mesh */
+ mesh = forceVector->feVariable->feMesh;
+
+ /* Set the element type */
+ elementType = FeMesh_GetElementType( mesh, lElement_I );
+ elementNodeCount = elementType->nodeCount;
+
+ /* assumes constant number of dofs per element */
+ dofsPerNode = dim;
+
+ cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
+ cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
+
+ for ( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
+ particle = (IntegrationPoint*) Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
+ xi = particle->xi;
+
+ /* Calculate Determinant of Jacobian and Shape Functions */
+ detJac = ElementType_JacobianDeterminant( elementType, mesh, lElement_I, xi, dim );
+ ElementType_EvaluateShapeFunctionsAt( elementType, xi, Ni );
+
+ /* Field Get Temperature from Field Variable */
+ FeVariable_InterpolateFromMeshLocalCoord( temperatureField, mesh, lElement_I, xi, &temperature );
+
+ force = rayleighNumber * temperature;
+
+ factor = detJac * particle->weight * force;
+ for( node_I = 0 ; node_I < elementNodeCount ; node_I++ )
+ elForceVec[node_I * dofsPerNode + J_AXIS ] += factor * Ni[ node_I ] ;
+
+ }
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/tests/IsoviscousStiffnessSuite.c
--- a/Assembly/tests/IsoviscousStiffnessSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "pcu/pcu.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-#include <PICellerator/PICellerator.h>
-#include "Underworld/Underworld.h"
-
-/* silly stgermain, I must define this */
-#define CURR_MODULE_NAME "StgFEM.c"
-
-typedef struct {
- FiniteElementContext* context;
-} IsoviscousStiffnessData;
-
-void IsoviscousStiffness_Setup( IsoviscousStiffnessData* data ) {
- Journal_Enable_AllTypedStream( False );
- data->context=NULL;
-}
-
-void IsoviscousStiffness_Teardown( IsoviscousStiffnessData* data ) {
-}
-
-void IsoviscousStiffness2D( IsoviscousStiffnessData* data ) {
- StiffnessMatrix* stiffnessMatrix;
- Dictionary* dictionary;
- FiniteElementContext* context;
- Stg_ComponentFactory* cf;
- PetscViewer expViewer;
- PetscReal matrixNorm, errorNorm, test;
- Mat expected;
- char expected_file[PCU_PATH_MAX];
- char *filename, *matrixName;
- double tolerance;
- char xml_input[PCU_PATH_MAX];
- Stream* infoStream = Journal_Register( Info_Type, (Name)CURR_MODULE_NAME );
- char rFile[PCU_PATH_MAX];
- int err;
-
- pcu_docstring( "This test compares a Stiffness matrix against a previously generated stiffness matrix"
- "The stiffness matrix is generated from a 2D FEM model for an isoviscous fluid flow."
- "See testIsoviscous.xml for the actual xml used" );
-
- /* read in the xml input file */
- pcu_filename_input( "IsoviscousStiffnessMatrix.xml", xml_input );
- cf = stgMainInitFromXML( xml_input, MPI_COMM_WORLD, NULL );
- context = (FiniteElementContext*)LiveComponentRegister_Get( cf->LCRegister, (Name)"context" );
- data->context = context;
- dictionary = context->dictionary;
-
- stgMainBuildAndInitialise( cf );
-
- /* Test is to check the relative error between an
- 1 ) expected stiffness matrix, (made years ago)
- 2) the current stiffness matrix.
-
- both matricies are built using only an Arrhenius rheology
- */
-
- /* get the tolerance */
- tolerance = Dictionary_GetDouble( dictionary, "StiffnessMatrixCompareTolerance" );
-
- /* Get Matrix */
- matrixName = Dictionary_GetString( dictionary, (Dictionary_Entry_Key)"CompareStiffnessMatrix" );
- Journal_Printf( infoStream, "Comparing stiffness matrix '%s'\n", matrixName );
- stiffnessMatrix = (StiffnessMatrix*) LiveComponentRegister_Get( context->CF->LCRegister, (Name)matrixName );
- assert( stiffnessMatrix );
-
- StiffnessMatrix_Assemble( stiffnessMatrix, False, NULL, context );
-
- /* Get Stored Matrix from file */
- filename = Dictionary_GetString( dictionary, (Dictionary_Entry_Key)"StiffnessMatrixCompareFilename" );
- Journal_Printf( infoStream, "Checking with file '%s'\n", filename );
-
- pcu_filename_expected( filename, expected_file );
- PetscViewerBinaryOpen( context->communicator, expected_file, FILE_MODE_READ, &expViewer );
-
- MatLoad( expViewer, MATAIJ, &expected );
-
- MatNorm( expected, NORM_FROBENIUS, &matrixNorm );
- assert( matrixNorm != 0 );
-
- MatAXPY( expected, -1, (stiffnessMatrix->matrix) , DIFFERENT_NONZERO_PATTERN );
- MatNorm( expected, NORM_FROBENIUS, &errorNorm );
- test = errorNorm / matrixNorm;
-
- pcu_check_lt( test, tolerance );
-
- /* Check tolerance */
- /*
- stream = Journal_Register( Info_Type, (Name)"StiffnessMatrixComparison" );
- Stream_RedirectFile_WithPrependedPath( stream, context->outputPath, "StiffnessMatrixCompare.dat" );
- Journal_PrintValue( infoStream, tolerance );
- Journal_Printf( stream, "Comparison between stiffness matrix '%s' %s with tolerance %4g.\n",
- matrixName,
- ( errorNorm/matrixNorm < tolerance ? "passed" : "failed" ),
- tolerance );
- */
-
- /*
- Stream_CloseFile( stream );
- To view the expected and computed matricies uncomment this
- PetscViewerASCIIOpen(context->communicator, "numerical.dat",&currViewer);
- PetscViewerASCIIOpen(context->communicator, "expected.dat",¶llelViewer);
- MatView( stiffnessMatrix->matrix, currViewer ); //PETSC_VIEWER_STDOUT_WORLD );
- MatView( expected, parallelViewer ); //PETSC_VIEWER_STDOUT_WORLD );
- PetscViewerDestroy(currViewer);
- PetscViewerDestroy(parallelViewer);
- */
- if( data->context->rank == 0 ) {
- /* Now clean output path */
- sprintf(rFile, "%s/input.xml", data->context->outputPath );
- err = remove( rFile );
- if( err == -1 ) printf("Error in %s, can't delete the input.xml\n", __func__);
- }
-
- stgMainDestroy( cf );
-}
-
-void IsoviscousStiffnessSuite( pcu_suite_t* suite ) {
- pcu_suite_setData( suite, IsoviscousStiffnessData );
- pcu_suite_setFixtures( suite, IsoviscousStiffness_Setup, IsoviscousStiffness_Teardown );
- pcu_suite_addTest( suite, IsoviscousStiffness2D );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Assembly/tests/IsoviscousStiffnessSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Assembly/tests/IsoviscousStiffnessSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,129 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pcu/pcu.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+#include <PICellerator/PICellerator.h>
+#include "Underworld/Underworld.h"
+
+/* silly stgermain, I must define this */
+#define CURR_MODULE_NAME "StgFEM.c"
+
+typedef struct {
+ FiniteElementContext* context;
+} IsoviscousStiffnessData;
+
+void IsoviscousStiffness_Setup( IsoviscousStiffnessData* data ) {
+ Journal_Enable_AllTypedStream( False );
+ data->context=NULL;
+}
+
+void IsoviscousStiffness_Teardown( IsoviscousStiffnessData* data ) {
+}
+
+void IsoviscousStiffness2D( IsoviscousStiffnessData* data ) {
+ StiffnessMatrix* stiffnessMatrix;
+ Dictionary* dictionary;
+ FiniteElementContext* context;
+ Stg_ComponentFactory* cf;
+ PetscViewer expViewer;
+ PetscReal matrixNorm, errorNorm, test;
+ Mat expected;
+ char expected_file[PCU_PATH_MAX];
+ char *filename, *matrixName;
+ double tolerance;
+ char xml_input[PCU_PATH_MAX];
+ Stream* infoStream = Journal_Register( Info_Type, (Name)CURR_MODULE_NAME );
+ char rFile[PCU_PATH_MAX];
+ int err;
+
+ pcu_docstring( "This test compares a Stiffness matrix against a previously generated stiffness matrix"
+ "The stiffness matrix is generated from a 2D FEM model for an isoviscous fluid flow."
+ "See testIsoviscous.xml for the actual xml used" );
+
+ /* read in the xml input file */
+ pcu_filename_input( "IsoviscousStiffnessMatrix.xml", xml_input );
+ cf = stgMainInitFromXML( xml_input, MPI_COMM_WORLD, NULL );
+ context = (FiniteElementContext*)LiveComponentRegister_Get( cf->LCRegister, (Name)"context" );
+ data->context = context;
+ dictionary = context->dictionary;
+
+ stgMainBuildAndInitialise( cf );
+
+ /* Test is to check the relative error between an
+ 1 ) expected stiffness matrix, (made years ago)
+ 2) the current stiffness matrix.
+
+ both matricies are built using only an Arrhenius rheology
+ */
+
+ /* get the tolerance */
+ tolerance = Dictionary_GetDouble( dictionary, "StiffnessMatrixCompareTolerance" );
+
+ /* Get Matrix */
+ matrixName = Dictionary_GetString( dictionary, (Dictionary_Entry_Key)"CompareStiffnessMatrix" );
+ Journal_Printf( infoStream, "Comparing stiffness matrix '%s'\n", matrixName );
+ stiffnessMatrix = (StiffnessMatrix*) LiveComponentRegister_Get( context->CF->LCRegister, (Name)matrixName );
+ assert( stiffnessMatrix );
+
+ StiffnessMatrix_Assemble( stiffnessMatrix, False, NULL, context );
+
+ /* Get Stored Matrix from file */
+ filename = Dictionary_GetString( dictionary, (Dictionary_Entry_Key)"StiffnessMatrixCompareFilename" );
+ Journal_Printf( infoStream, "Checking with file '%s'\n", filename );
+
+ pcu_filename_expected( filename, expected_file );
+ PetscViewerBinaryOpen( context->communicator, expected_file, FILE_MODE_READ, &expViewer );
+
+ MatLoad( expViewer, MATAIJ, &expected );
+
+ MatNorm( expected, NORM_FROBENIUS, &matrixNorm );
+ assert( matrixNorm != 0 );
+
+ MatAXPY( expected, -1, (stiffnessMatrix->matrix) , DIFFERENT_NONZERO_PATTERN );
+ MatNorm( expected, NORM_FROBENIUS, &errorNorm );
+ test = errorNorm / matrixNorm;
+
+ pcu_check_lt( test, tolerance );
+
+ /* Check tolerance */
+ /*
+ stream = Journal_Register( Info_Type, (Name)"StiffnessMatrixComparison" );
+ Stream_RedirectFile_WithPrependedPath( stream, context->outputPath, "StiffnessMatrixCompare.dat" );
+ Journal_PrintValue( infoStream, tolerance );
+ Journal_Printf( stream, "Comparison between stiffness matrix '%s' %s with tolerance %4g.\n",
+ matrixName,
+ ( errorNorm/matrixNorm < tolerance ? "passed" : "failed" ),
+ tolerance );
+ */
+
+ /*
+ Stream_CloseFile( stream );
+ To view the expected and computed matricies uncomment this
+ PetscViewerASCIIOpen(context->communicator, "numerical.dat",&currViewer);
+ PetscViewerASCIIOpen(context->communicator, "expected.dat",¶llelViewer);
+ MatView( stiffnessMatrix->matrix, currViewer ); //PETSC_VIEWER_STDOUT_WORLD );
+ MatView( expected, parallelViewer ); //PETSC_VIEWER_STDOUT_WORLD );
+ PetscViewerDestroy(currViewer);
+ PetscViewerDestroy(parallelViewer);
+ */
+ if( data->context->rank == 0 ) {
+ /* Now clean output path */
+ sprintf(rFile, "%s/input.xml", data->context->outputPath );
+ err = remove( rFile );
+ if( err == -1 ) printf("Error in %s, can't delete the input.xml\n", __func__);
+ }
+
+ stgMainDestroy( cf );
+}
+
+void IsoviscousStiffnessSuite( pcu_suite_t* suite ) {
+ pcu_suite_setData( suite, IsoviscousStiffnessData );
+ pcu_suite_setFixtures( suite, IsoviscousStiffness_Setup, IsoviscousStiffness_Teardown );
+ pcu_suite_addTest( suite, IsoviscousStiffness2D );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/AnalyticSolution.c
--- a/Discretisation/src/AnalyticSolution.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,636 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: AnalyticSolution.c 1137 2008-05-23 05:57:48Z RobertTurnbull $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "types.h"
-#include "AnalyticSolution.h"
-#include "FeVariable.h"
-#include "OperatorFeVariable.h"
-#include "FeMesh.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-const Type AnalyticSolution_Type = "AnalyticSolution";
-/* Singleton for analytical solution */
-AnalyticSolution* mySingleton = NULL;
-
-void* _AnalyticSolution_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(AnalyticSolution);
- Type type = AnalyticSolution_Type;
- Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
- Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
- Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _AnalyticSolution_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _AnalyticSolution_AssignFromXML;
- Stg_Component_BuildFunction* _build = _AnalyticSolution_Build;
- Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
- Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
-}
-
-AnalyticSolution* _AnalyticSolution_New( ANALYTICSOLUTION_DEFARGS )
-{
- AnalyticSolution* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(AnalyticSolution) );
- /* Construct using parent */
- /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
- /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
- and so should be set to ZERO in any children of this class. */
- nameAllocationType = NON_GLOBAL;
-
- self = (AnalyticSolution*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- /* Assign singleton ptr */
- mySingleton = self;
- return self;
-}
-
-void _AnalyticSolution_Init( AnalyticSolution* self, Swarm* integrationSwarm, LiveComponentRegister* LC_Register, AbstractContext* context, Bool verboseMode ) {
- self->LC_Register = LC_Register;
- self->integrationSwarm = integrationSwarm;
- self->context = (DomainContext*)context;
-
- /* Initialise AnalyticFunctions */
- self->_getAnalyticVelocity = NULL;
- self->_getAnalyticPressure = NULL;
- self->_getAnalyticTotalStress = NULL;
- self->_getAnalyticStrainRate = NULL;
-
- /* Create Lists */
- self->feVariableList = Stg_ObjectList_New();
- self->analyticFeVariableList = Stg_ObjectList_New();
- self->analyticFeVariableFuncList = Stg_ObjectList_New();
- self->errorMagnitudeFieldList = Stg_ObjectList_New();
- self->relativeErrorMagnitudeFieldList = Stg_ObjectList_New();
- self->streamList = Stg_ObjectList_New();
-
- /* Add functions to entry points */
- EntryPoint_AppendClassHook( Context_GetEntryPoint( context, AbstractContext_EP_UpdateClass ),
- self->type, (void*)AnalyticSolution_Update, self->type, self );
- EP_AppendClassHook( Context_GetEntryPoint( context, AbstractContext_EP_DumpClass ),
- AnalyticSolution_TestAll, self );
-
- if ( verboseMode ) {
- Stream* infoStream = Journal_MyStream( Info_Type, self );
- Stream_SetLevel( infoStream, 2 );
- }
-}
-
-void _AnalyticSolution_Delete( void* analyticSolution ) {
- AnalyticSolution* self = (AnalyticSolution*)analyticSolution;
-
- Stg_Class_Delete( self->feVariableList );
- Stg_Class_Delete( self->analyticFeVariableList );
- Stg_Class_Delete( self->analyticFeVariableFuncList );
- Stg_Class_Delete( self->errorMagnitudeFieldList );
- Stg_Class_Delete( self->relativeErrorMagnitudeFieldList );
- Stg_Class_Delete( self->streamList );
-
- if ( self->toleranceList )
- Memory_Free( self->toleranceList );
-
- /* Stg_Class_Delete parent*/
- _Stg_Component_Delete( self );
-}
-
-void _AnalyticSolution_Print( void* analyticSolution, Stream* stream ) {
- AnalyticSolution* self = (AnalyticSolution*)analyticSolution;
-
- /* Print parent */
- _Stg_Component_Print( self, stream );
-
-}
-
-void* _AnalyticSolution_Copy( const void* analyticSolution, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- abort();
- return NULL;
-}
-
-void _AnalyticSolution_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data )
-{
- AnalyticSolution* self = (AnalyticSolution*)analyticSolution;
- AbstractContext* context;
- Swarm* integrationSwarm;
- Bool verboseMode;
-
- context = (AbstractContext*)(Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", DomainContext, False, data ));
- if( !context )
- context = (AbstractContext*)(Stg_ComponentFactory_ConstructByName( cf, (Name)"context", DomainContext, True, data ));
-
- integrationSwarm = Stg_ComponentFactory_ConstructByName( cf, (Name)"gaussSwarm", Swarm, True, data );
- verboseMode = Stg_ComponentFactory_GetRootDictBool( cf, (Dictionary_Entry_Key)"analyticSolutionVerbose", False );
-
- _AnalyticSolution_Init( self, integrationSwarm, cf->LCRegister, context, verboseMode );
-}
-
-void _AnalyticSolution_Build( void* analyticSolution, void* data ) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
- Index analyticFeVariableCount;
- Index analyticFeVariable_I;
-
- Stg_Component_Build( self->integrationSwarm, data, False );
- /* Build all the analytic fields registered to this AnalyticSolution */
- AnalyticSolution_BuildAllAnalyticFields( self, data );
-
- analyticFeVariableCount = Stg_ObjectList_Count( self->analyticFeVariableList );
- assert( analyticFeVariableCount == Stg_ObjectList_Count( self->analyticFeVariableFuncList ) );
-
- for ( analyticFeVariable_I = 0 ; analyticFeVariable_I < analyticFeVariableCount ; analyticFeVariable_I++ ) {
- Stg_Component_Build( Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I ), data, False ) ;
- Stg_Component_Build( Stg_ObjectList_At( self->errorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
- Stg_Component_Build( Stg_ObjectList_At( self->relativeErrorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
- }
-}
-
-void _AnalyticSolution_Initialise( void* analyticSolution, void* data ) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
- Index analyticFeVariableCount = Stg_ObjectList_Count( self->analyticFeVariableList );
- Index analyticFeVariable_I;
-
- Stg_Component_Initialise( self->integrationSwarm, data, False );
- assert( analyticFeVariableCount == Stg_ObjectList_Count( self->analyticFeVariableFuncList ) );
-
- /* Assign values to all analytic fields */
- for ( analyticFeVariable_I = 0 ; analyticFeVariable_I < analyticFeVariableCount ; analyticFeVariable_I++ ) {
- Stg_Component_Initialise( Stg_ObjectList_At( self->feVariableList, analyticFeVariable_I ), data, False ) ;
- Stg_Component_Initialise( Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I ), data, False ) ;
- Stg_Component_Initialise( Stg_ObjectList_At( self->errorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
- Stg_Component_Initialise( Stg_ObjectList_At( self->relativeErrorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
-
- AnalyticSolution_PutAnalyticSolutionOntoNodes( self, analyticFeVariable_I );
- }
-}
-
-/* This function is called when the 'Update' phase happens */
-void AnalyticSolution_Update( void* analyticSolution ) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
-
- self->_initialise( self, NULL );
-}
-
-void _AnalyticSolution_Execute( void* analyticSolution, void* data ) {
-}
-
-void _AnalyticSolution_Destroy( void* analyticSolution, void* data ) {
- AnalyticSolution* self = (AnalyticSolution*)analyticSolution;
- Index analyticFeVariableCount = Stg_ObjectList_Count( self->analyticFeVariableList );
- Index analyticFeVariable_I;
-
- Stg_Component_Destroy( self, data, False );
-
- Stg_Component_Destroy( self->integrationSwarm, data, False );
- assert( analyticFeVariableCount == Stg_ObjectList_Count( self->analyticFeVariableFuncList ) );
-
- /* Destroy all analytic fields */
- for ( analyticFeVariable_I = 0 ; analyticFeVariable_I < analyticFeVariableCount ; analyticFeVariable_I++ ) {
- Stg_Component_Destroy( Stg_ObjectList_At( self->feVariableList, analyticFeVariable_I ), data, False ) ;
- Stg_Component_Destroy( Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I ), data, False ) ;
- Stg_Component_Destroy( Stg_ObjectList_At( self->errorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
- Stg_Component_Destroy( Stg_ObjectList_At( self->relativeErrorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
- }
-
-}
-
-void AnalyticSolution_PutAnalyticSolutionOntoNodes( void* analyticSolution, Index analyticFeVariable_I ) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
- AnalyticSolution_SolutionFunction* solutionFunction;
- FeVariable* analyticFeVariable;
- double* coord;
- Dof_Index dofAtEachNodeCount;
- Node_DomainIndex dNode_I;
- double* value;
- Stream* infoStream = Journal_MyStream( Info_Type, self );
- FeVariable* feVariable;
- FeMesh* mesh;
-
- /* Do some error checking */
- assert( Stg_ObjectList_Count( self->analyticFeVariableList ) >= analyticFeVariable_I );
-
- /* Grab pointers */
- analyticFeVariable =
- Stg_CheckType( Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I ), FeVariable );
- mesh = analyticFeVariable->feMesh;
- solutionFunction = (AnalyticSolution_SolutionFunction*)
- Stg_ObjectList_ObjectAt( self->analyticFeVariableFuncList, analyticFeVariable_I );
- feVariable = AnalyticSolution_GetFeVariableFromAnalyticFeVariable( self, analyticFeVariable );
-
- /* Get number of degrees of freedom at each node (assuming they are the same) */
- dofAtEachNodeCount = analyticFeVariable->fieldComponentCount;
- value = Memory_Alloc_Array( double, dofAtEachNodeCount, "value" );
-
- /* Loop over all the nodes - applying the analytic solution */
- for ( dNode_I = 0 ; dNode_I < Mesh_GetDomainSize( mesh, MT_VERTEX ); dNode_I++ ) {
- coord = Mesh_GetVertex( mesh, dNode_I );
-
- /* Calculate value at node */
- memset( value, 0, dofAtEachNodeCount * sizeof(double) );
- solutionFunction( self, analyticFeVariable, coord, value );
-
- /* Put value on node */
- FeVariable_SetValueAtNode( analyticFeVariable, dNode_I, value );
-
- /* Print verbose information */
- if ( Stream_IsPrintableLevel( infoStream, 2 ) ) {
- Dimension_Index dim = analyticFeVariable->dim;
- Dimension_Index dim_I;
- Dof_Index dof_I;
-
- /* Print Coord */
- Journal_Printf( infoStream, "Node = %u Coord ( ", dNode_I );
- for ( dim_I = 0 ; dim_I < dim - 1 ; dim_I++ ) {
- Journal_Printf( infoStream, "%g, ", coord[ dim_I ] );
- }
- Journal_Printf( infoStream, "%g ) ", coord[ dim_I ] );
-
- /* Print Analytic Values */
- Journal_Printf( infoStream, "%s ( ", analyticFeVariable->name );
- for ( dof_I = 0 ; dof_I < dofAtEachNodeCount - 1 ; dof_I++ ) {
- Journal_Printf( infoStream, "%g, ", value[ dof_I ] );
- }
- Journal_Printf( infoStream, "%g ) ", value[ dof_I ] );
-
- /* Print FeVariable Values */
- memset( value, 0, dofAtEachNodeCount * sizeof(double) );
- FeVariable_GetValueAtNode( feVariable, dNode_I, value );
- Journal_Printf( infoStream, "%s ( ", feVariable->name );
- for ( dof_I = 0 ; dof_I < dofAtEachNodeCount - 1 ; dof_I++ ) {
- Journal_Printf( infoStream, "%g, ", value[ dof_I ] );
- }
- Journal_Printf( infoStream, "%g )\n", value[ dof_I ] );
- }
- }
-
- Memory_Free( value );
-}
-
-void AnalyticSolution_Test( void* analyticSolution, Index analyticFeVariable_I ) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
- FeVariable* errorMagnitudeField;
- double result;
- Stream* stream;
- double tolerance;
- Stream* infoStream = Journal_MyStream( Info_Type, self );
-
- /* Do some error checking */
- assert( Stg_ObjectList_Count( self->analyticFeVariableList ) >= analyticFeVariable_I );
-
- /* Grab pointers */
- errorMagnitudeField =
- Stg_CheckType( Stg_ObjectList_At( self->errorMagnitudeFieldList, analyticFeVariable_I ), FeVariable );
-
- stream = (Stream*) Stg_ObjectList_ObjectAt( self->streamList, analyticFeVariable_I );
- tolerance = self->toleranceList[ analyticFeVariable_I ];
-
- result = FeVariable_Integrate( errorMagnitudeField, self->integrationSwarm );
-
- Journal_Printf( stream, "Timestep %u: Total integrated value of '%s' is %s a tolerance %.5g.\n",
- self->context->timeStep, errorMagnitudeField->name, result <= tolerance ? "within" : "outside", tolerance );
- Stream_Flush( stream );
-
- Journal_Printf( infoStream, "Timestep %u: Total integrated value of '%s' is %g\n",
- self->context->timeStep, errorMagnitudeField->name, result );
-}
-
-
-void AnalyticSolution_TestAll( void* analyticSolution, void* data ) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
- Index analyticFeVariableCount = Stg_ObjectList_Count( self->analyticFeVariableList );
- Index analyticFeVariable_I;
-
- assert( analyticFeVariableCount == Stg_ObjectList_Count( self->analyticFeVariableFuncList ) );
-
- /* Assign values to all analytic fields */
- for ( analyticFeVariable_I = 0 ; analyticFeVariable_I < analyticFeVariableCount ; analyticFeVariable_I++ ) {
- AnalyticSolution_Test( self, analyticFeVariable_I );
- }
-}
-
-void AnalyticSolution_RegisterFeVariableWithAnalyticFunction( void* analyticSolution, FeVariable* feVariable, AnalyticSolution_SolutionFunction* solutionFunction) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
- char* tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"Analytic" );
-
- /* Add feVariable to list */
- Stg_ObjectList_Append( self->feVariableList, feVariable );
- /* Add function to list */
- Stg_ObjectList_GlobalPointerAppend( self->analyticFeVariableFuncList, (void*)solutionFunction, (Name)tmpName );
- Memory_Free( tmpName );
-}
-
-
-FeVariable* AnalyticSolution_RegisterFeVariableFromCF( void* analyticSolution, char* fieldName, AnalyticSolution_SolutionFunction* solutionFunction, Stg_ComponentFactory* cf, Bool isEssential, void* data ) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
- FeVariable* field;
-
- field = Stg_ComponentFactory_ConstructByName( cf, (Name)fieldName, FeVariable, isEssential, data );
- if ( field )
- AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, field, solutionFunction );
-
- return field;
-}
-
-
-void AnalyticSolution_BuildAllAnalyticFields( void* analyticSolution, void* data ) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
- FeVariable* feVariable = NULL;
- Stream* errStream = Journal_Register( Error_Type, (Name)"AnalyticSolution" );
- unsigned feVar_I, feVarCount;
-
- feVarCount = Stg_ObjectList_Count( self->feVariableList );
-
- for( feVar_I = 0 ; feVar_I < feVarCount ; feVar_I++ ) {
- feVariable = (FeVariable*)Stg_ObjectList_At( self->feVariableList, feVar_I );
-
- /* Check to see whether this field has already been added */
-
-
- /* Build the FeVariable here ensuring the analytic "copy" of it has valid values */
- Stg_Component_Build( feVariable, data, False ) ;
-
- if( feVariable->fieldComponentCount == 1 ) {
- if( NULL == AnalyticSolution_CreateAnalyticField( self, feVariable ) ) {
-
- Journal_Firewall( 0 , errStream,
- "Error in function %s: Error in building analyticSolution for the feVariable %s,\n",
- __func__ , feVariable );
- }
- } else {
- if( NULL == AnalyticSolution_CreateAnalyticSymmetricTensorField( self, feVariable ) ) {
-
- Journal_Firewall( 0 , errStream,
- "Error in function %s: Error in building analyticSolution for the feVariable %s,\n",
- __func__ , feVariable );
- }
- }
-
- }
-
-
-}
-
-FeVariable* AnalyticSolution_CreateAnalyticField( void* analyticSolution, FeVariable* feVariable ) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
- char* tmpName;
- FeVariable* analyticFeVariable;
- Variable* dataVariable;
- DofLayout* dofLayout;
- Variable_Register* variable_Register = self->context->variable_Register;
- Dof_Index componentsCount = feVariable->fieldComponentCount;
- char* variableName[9];
- Variable_Index variable_I;
- Node_DomainIndex node_I;
- Bool scalar=(componentsCount==1) ? True : False;
- OperatorFeVariable* analyticMagField;
- OperatorFeVariable* errorField;
- OperatorFeVariable* errorMagnitudeField;
- OperatorFeVariable* relativeErrorMagnitudeField;
- Stream* stream;
- Index count;
-
- Stg_Component_Build( feVariable->feMesh, NULL, False );
-
- /* Create new data Variable */
- tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"Analytic-DataVariable" );
- if ( scalar ) {
- Sync* sync;
-
- sync = Mesh_GetSync( feVariable->feMesh, MT_VERTEX );
- dataVariable = Variable_NewScalar( tmpName, (AbstractContext*)self->context, Variable_DataType_Double, (Index*)(unsigned*)&sync->nDomains, NULL, (void**)NULL, variable_Register );
- }
- else {
- Sync* sync;
- unsigned c_i;
-
- sync = Mesh_GetSync( feVariable->feMesh, MT_VERTEX );
-
- /* Create names of variables */
- assert( componentsCount <= 9 );
- for ( variable_I = 0 ; variable_I < componentsCount ; variable_I++ ) {
- Stg_asprintf( &variableName[ variable_I ], "%s-Analytic-ComponentVariable%d", feVariable->name, variable_I );
- }
- dataVariable = Variable_NewVector(
- tmpName,
- (AbstractContext*)self->context,
- Variable_DataType_Double,
- componentsCount,
- (unsigned*)&sync->nDomains,
- NULL,
- (void**)NULL,
- variable_Register,
- variableName[0],
- variableName[1],
- variableName[2],
- variableName[3],
- variableName[4],
- variableName[5],
- variableName[6],
- variableName[7],
- variableName[8] );
- for( c_i = 0; c_i < dataVariable->dataTypeCounts[0]; c_i++ )
- dataVariable->components[c_i]->allocateSelf = True;
- }
- Memory_Free( tmpName );
- dataVariable->allocateSelf = True;
-
- /* Create new dof layout */
- tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"Analytic-DofLayout" );
- dofLayout = DofLayout_New( tmpName, self->context, variable_Register, Mesh_GetDomainSize( feVariable->feMesh, MT_VERTEX ), NULL );
- if ( scalar ) {
- DofLayout_AddAllFromVariableArray( dofLayout, 1, &dataVariable );
- }
- else {
- for ( variable_I = 0 ; variable_I < componentsCount ; variable_I++ ) {
-
- /* We have to set the array ptr ptr for these guys manually - this should be fixed */
- Variable* variable = Variable_Register_GetByName( variable_Register, variableName[ variable_I ] );
- variable->arrayPtrPtr = &dataVariable->arrayPtr;
-
- /* Assign variable to each node */
- for( node_I = 0; node_I < Mesh_GetDomainSize( feVariable->feMesh, MT_VERTEX ); node_I++ ) {
- DofLayout_AddDof_ByVarName( dofLayout, variableName[variable_I], node_I );
- }
- /* Free Name */
- Memory_Free( variableName[ variable_I ] );
- }
- }
- Memory_Free( tmpName );
-
- /* Create new FeVariable */
- tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"Analytic" );
- analyticFeVariable = FeVariable_New( tmpName, self->context, feVariable->feMesh, feVariable->geometryMesh, dofLayout,
- NULL, NULL, NULL, feVariable->dim, feVariable->isCheckpointedAndReloaded,
- False, False,
- feVariable->fieldVariable_Register );
-
- /* Add new analyticFeVariable to list */
- Stg_ObjectList_Append( self->analyticFeVariableList, analyticFeVariable );
-
- /* Create Magnitude Field */
- tmpName = Stg_Object_AppendSuffix( analyticFeVariable, (Name)"Magnitude" );
- analyticMagField = OperatorFeVariable_NewUnary( tmpName, self->context, analyticFeVariable, "Magnitude" );
- Memory_Free( tmpName );
-
- /* Create Error field - The the calculated field minus the analytic field */
- tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"ErrorField" );
- errorField = OperatorFeVariable_NewBinary( tmpName, self->context, feVariable, analyticFeVariable, "Subtraction" );
- Memory_Free( tmpName );
-
- /* Create Error magnitude field */
- tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"ErrorMagnitudeField" );
- errorMagnitudeField = OperatorFeVariable_NewUnary( tmpName, self->context, errorField, "Magnitude" );
- Memory_Free( tmpName );
- Stg_ObjectList_Append( self->errorMagnitudeFieldList, errorMagnitudeField ); /* Add it to list */
-
- /* Create Relative Error magnitude field - The magnitude of relative error */
- tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"RelativeErrorMagnitudeField" );
- relativeErrorMagnitudeField = OperatorFeVariable_NewBinary( tmpName, self->context, errorMagnitudeField, analyticMagField, "ScalarDivision" );
- Memory_Free( tmpName );
- Stg_ObjectList_Append( self->relativeErrorMagnitudeFieldList, relativeErrorMagnitudeField ); /* Add it to list */
-
- /* Create Stream for field to dump error information to */
- tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"ErrorFile" );
- stream = Journal_Register( Dump_Type, (Name)tmpName );
- Stg_ObjectList_GlobalPointerAppend( self->streamList, stream, (Name)tmpName );
- Stream_Enable( stream, True );
- Stream_RedirectFile_WithPrependedPath( stream, self->context->outputPath, tmpName );
- Memory_Free( tmpName );
-
- /* Get tolerance from dictionary */
- count = Stg_ObjectList_Count( self->analyticFeVariableList );
- self->toleranceList = Memory_Realloc_Array( self->toleranceList, double, count );
- tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"Tolerance" );
- self->toleranceList[ count - 1 ] = Dictionary_GetDouble_WithDefault( self->context->dictionary, (Dictionary_Entry_Key)tmpName, 0.0 );
- Memory_Free( tmpName );
-
- /* Add components to LiveComponentRegister so they will be visible to other components
- * and will be built, initialised and deleted */
- LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) dataVariable );
- LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) dofLayout );
- LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) analyticFeVariable );
- LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) analyticMagField );
- LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) errorField );
- LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) errorMagnitudeField );
- LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) relativeErrorMagnitudeField );
-
- return analyticFeVariable;
-}
-
-FeVariable* AnalyticSolution_CreateAnalyticVectorField( void* analyticSolution, FeVariable* vectorField, AnalyticSolution_SolutionFunction* solutionFunction ) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
- FeVariable* analyticVectorField;
-
- analyticVectorField = AnalyticSolution_CreateAnalyticField( self, vectorField );
-
- return analyticVectorField;
-}
-
-FeVariable* AnalyticSolution_CreateAnalyticSymmetricTensorField( void* analyticSolution, FeVariable* vectorField ) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
- FeVariable* analyticVectorField;
- OperatorFeVariable* analyticVectorInvField;
- char *tmpName, *tmpName2;
- DofLayout* dofLayout;
-
- analyticVectorField = AnalyticSolution_CreateAnalyticField( self, vectorField );
-
- /* Create new dof layout */
- tmpName = Stg_Object_AppendSuffix( analyticVectorField, (Name)"Analytic-DofLayout" );
- dofLayout = DofLayout_New( tmpName, self->context, self->context->variable_Register, Mesh_GetDomainSize( analyticVectorField->feMesh, MT_VERTEX ), NULL );
-
- /* Create Invariant Field */
- tmpName2 = Stg_Object_AppendSuffix( analyticVectorField, (Name)"Invariant" );
- analyticVectorInvField = OperatorFeVariable_NewUnary( tmpName2, self->context, analyticVectorField, "SymmetricTensor_Invariant" );
-
- Memory_Free( tmpName );
- Memory_Free( tmpName2 );
-
- LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) analyticVectorInvField );
-
- return analyticVectorField;
-}
-
-FeVariable* AnalyticSolution_GetFeVariableFromAnalyticFeVariable( void* analyticSolution, FeVariable* analyticFeVariable ) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
- Index analyticFeVariableCount = Stg_ObjectList_Count( self->analyticFeVariableList );
- Index analyticFeVariable_I;
-
- assert( analyticFeVariableCount == Stg_ObjectList_Count( self->feVariableList ) );
-
- for ( analyticFeVariable_I = 0 ; analyticFeVariable_I < analyticFeVariableCount ; analyticFeVariable_I++ ) {
- /* find the index of analytic feVariable and then return the corresponding feVariable */
- if ( analyticFeVariable == (FeVariable*) Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I ) )
- return (FeVariable*) Stg_ObjectList_At( self->feVariableList, analyticFeVariable_I );
- }
-
- return NULL;
-}
-
-InterpolationResult AnalyticSolution_InterpolateValueFromNormalFeVariable( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* value ) {
- AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
- FeVariable* normalFeVariable;
-
- normalFeVariable = AnalyticSolution_GetFeVariableFromAnalyticFeVariable( self, analyticFeVariable );
-
- return FieldVariable_InterpolateValueAt( normalFeVariable, coord, value );
-}
-
-AnalyticSolution* AnalyticSolution_GetAnalyticSolution() {
- Journal_Firewall( mySingleton != NULL , Journal_Register( Error_Type, (Name)"AnalyticSolution" ),
- "Error in function %s: The Singleton Ptr is NULL, meaning the AnalyticSolution has not been created yet\n", __func__ );
-
- return mySingleton;
-}
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/AnalyticSolution.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/AnalyticSolution.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,636 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: AnalyticSolution.c 1137 2008-05-23 05:57:48Z RobertTurnbull $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "types.h"
+#include "AnalyticSolution.h"
+#include "FeVariable.h"
+#include "OperatorFeVariable.h"
+#include "FeMesh.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+const Type AnalyticSolution_Type = "AnalyticSolution";
+/* Singleton for analytical solution */
+AnalyticSolution* mySingleton = NULL;
+
+void* _AnalyticSolution_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(AnalyticSolution);
+ Type type = AnalyticSolution_Type;
+ Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
+ Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
+ Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _AnalyticSolution_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _AnalyticSolution_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _AnalyticSolution_Build;
+ Stg_Component_InitialiseFunction* _initialise = _AnalyticSolution_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
+ Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
+}
+
+AnalyticSolution* _AnalyticSolution_New( ANALYTICSOLUTION_DEFARGS )
+{
+ AnalyticSolution* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(AnalyticSolution) );
+ /* Construct using parent */
+ /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
+ /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
+ and so should be set to ZERO in any children of this class. */
+ nameAllocationType = NON_GLOBAL;
+
+ self = (AnalyticSolution*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ /* Assign singleton ptr */
+ mySingleton = self;
+ return self;
+}
+
+void _AnalyticSolution_Init( AnalyticSolution* self, Swarm* integrationSwarm, LiveComponentRegister* LC_Register, AbstractContext* context, Bool verboseMode ) {
+ self->LC_Register = LC_Register;
+ self->integrationSwarm = integrationSwarm;
+ self->context = (DomainContext*)context;
+
+ /* Initialise AnalyticFunctions */
+ self->_getAnalyticVelocity = NULL;
+ self->_getAnalyticPressure = NULL;
+ self->_getAnalyticTotalStress = NULL;
+ self->_getAnalyticStrainRate = NULL;
+
+ /* Create Lists */
+ self->feVariableList = Stg_ObjectList_New();
+ self->analyticFeVariableList = Stg_ObjectList_New();
+ self->analyticFeVariableFuncList = Stg_ObjectList_New();
+ self->errorMagnitudeFieldList = Stg_ObjectList_New();
+ self->relativeErrorMagnitudeFieldList = Stg_ObjectList_New();
+ self->streamList = Stg_ObjectList_New();
+
+ /* Add functions to entry points */
+ EntryPoint_AppendClassHook( Context_GetEntryPoint( context, AbstractContext_EP_UpdateClass ),
+ self->type, (void*)AnalyticSolution_Update, self->type, self );
+ EP_AppendClassHook( Context_GetEntryPoint( context, AbstractContext_EP_DumpClass ),
+ AnalyticSolution_TestAll, self );
+
+ if ( verboseMode ) {
+ Stream* infoStream = Journal_MyStream( Info_Type, self );
+ Stream_SetLevel( infoStream, 2 );
+ }
+}
+
+void _AnalyticSolution_Delete( void* analyticSolution ) {
+ AnalyticSolution* self = (AnalyticSolution*)analyticSolution;
+
+ Stg_Class_Delete( self->feVariableList );
+ Stg_Class_Delete( self->analyticFeVariableList );
+ Stg_Class_Delete( self->analyticFeVariableFuncList );
+ Stg_Class_Delete( self->errorMagnitudeFieldList );
+ Stg_Class_Delete( self->relativeErrorMagnitudeFieldList );
+ Stg_Class_Delete( self->streamList );
+
+ if ( self->toleranceList )
+ Memory_Free( self->toleranceList );
+
+ /* Stg_Class_Delete parent*/
+ _Stg_Component_Delete( self );
+}
+
+void _AnalyticSolution_Print( void* analyticSolution, Stream* stream ) {
+ AnalyticSolution* self = (AnalyticSolution*)analyticSolution;
+
+ /* Print parent */
+ _Stg_Component_Print( self, stream );
+
+}
+
+void* _AnalyticSolution_Copy( const void* analyticSolution, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ abort();
+ return NULL;
+}
+
+void _AnalyticSolution_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data )
+{
+ AnalyticSolution* self = (AnalyticSolution*)analyticSolution;
+ AbstractContext* context;
+ Swarm* integrationSwarm;
+ Bool verboseMode;
+
+ context = (AbstractContext*)(Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", DomainContext, False, data ));
+ if( !context )
+ context = (AbstractContext*)(Stg_ComponentFactory_ConstructByName( cf, (Name)"context", DomainContext, True, data ));
+
+ integrationSwarm = Stg_ComponentFactory_ConstructByName( cf, (Name)"gaussSwarm", Swarm, True, data );
+ verboseMode = Stg_ComponentFactory_GetRootDictBool( cf, (Dictionary_Entry_Key)"analyticSolutionVerbose", False );
+
+ _AnalyticSolution_Init( self, integrationSwarm, cf->LCRegister, context, verboseMode );
+}
+
+void _AnalyticSolution_Build( void* analyticSolution, void* data ) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+ Index analyticFeVariableCount;
+ Index analyticFeVariable_I;
+
+ Stg_Component_Build( self->integrationSwarm, data, False );
+ /* Build all the analytic fields registered to this AnalyticSolution */
+ AnalyticSolution_BuildAllAnalyticFields( self, data );
+
+ analyticFeVariableCount = Stg_ObjectList_Count( self->analyticFeVariableList );
+ assert( analyticFeVariableCount == Stg_ObjectList_Count( self->analyticFeVariableFuncList ) );
+
+ for ( analyticFeVariable_I = 0 ; analyticFeVariable_I < analyticFeVariableCount ; analyticFeVariable_I++ ) {
+ Stg_Component_Build( Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I ), data, False ) ;
+ Stg_Component_Build( Stg_ObjectList_At( self->errorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
+ Stg_Component_Build( Stg_ObjectList_At( self->relativeErrorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
+ }
+}
+
+void _AnalyticSolution_Initialise( void* analyticSolution, void* data ) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+ Index analyticFeVariableCount = Stg_ObjectList_Count( self->analyticFeVariableList );
+ Index analyticFeVariable_I;
+
+ Stg_Component_Initialise( self->integrationSwarm, data, False );
+ assert( analyticFeVariableCount == Stg_ObjectList_Count( self->analyticFeVariableFuncList ) );
+
+ /* Assign values to all analytic fields */
+ for ( analyticFeVariable_I = 0 ; analyticFeVariable_I < analyticFeVariableCount ; analyticFeVariable_I++ ) {
+ Stg_Component_Initialise( Stg_ObjectList_At( self->feVariableList, analyticFeVariable_I ), data, False ) ;
+ Stg_Component_Initialise( Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I ), data, False ) ;
+ Stg_Component_Initialise( Stg_ObjectList_At( self->errorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
+ Stg_Component_Initialise( Stg_ObjectList_At( self->relativeErrorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
+
+ AnalyticSolution_PutAnalyticSolutionOntoNodes( self, analyticFeVariable_I );
+ }
+}
+
+/* This function is called when the 'Update' phase happens */
+void AnalyticSolution_Update( void* analyticSolution ) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+
+ self->_initialise( self, NULL );
+}
+
+void _AnalyticSolution_Execute( void* analyticSolution, void* data ) {
+}
+
+void _AnalyticSolution_Destroy( void* analyticSolution, void* data ) {
+ AnalyticSolution* self = (AnalyticSolution*)analyticSolution;
+ Index analyticFeVariableCount = Stg_ObjectList_Count( self->analyticFeVariableList );
+ Index analyticFeVariable_I;
+
+ Stg_Component_Destroy( self, data, False );
+
+ Stg_Component_Destroy( self->integrationSwarm, data, False );
+ assert( analyticFeVariableCount == Stg_ObjectList_Count( self->analyticFeVariableFuncList ) );
+
+ /* Destroy all analytic fields */
+ for ( analyticFeVariable_I = 0 ; analyticFeVariable_I < analyticFeVariableCount ; analyticFeVariable_I++ ) {
+ Stg_Component_Destroy( Stg_ObjectList_At( self->feVariableList, analyticFeVariable_I ), data, False ) ;
+ Stg_Component_Destroy( Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I ), data, False ) ;
+ Stg_Component_Destroy( Stg_ObjectList_At( self->errorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
+ Stg_Component_Destroy( Stg_ObjectList_At( self->relativeErrorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
+ }
+
+}
+
+void AnalyticSolution_PutAnalyticSolutionOntoNodes( void* analyticSolution, Index analyticFeVariable_I ) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+ AnalyticSolution_SolutionFunction* solutionFunction;
+ FeVariable* analyticFeVariable;
+ double* coord;
+ Dof_Index dofAtEachNodeCount;
+ Node_DomainIndex dNode_I;
+ double* value;
+ Stream* infoStream = Journal_MyStream( Info_Type, self );
+ FeVariable* feVariable;
+ FeMesh* mesh;
+
+ /* Do some error checking */
+ assert( Stg_ObjectList_Count( self->analyticFeVariableList ) >= analyticFeVariable_I );
+
+ /* Grab pointers */
+ analyticFeVariable =
+ Stg_CheckType( Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I ), FeVariable );
+ mesh = analyticFeVariable->feMesh;
+ solutionFunction = (AnalyticSolution_SolutionFunction*)
+ Stg_ObjectList_ObjectAt( self->analyticFeVariableFuncList, analyticFeVariable_I );
+ feVariable = AnalyticSolution_GetFeVariableFromAnalyticFeVariable( self, analyticFeVariable );
+
+ /* Get number of degrees of freedom at each node (assuming they are the same) */
+ dofAtEachNodeCount = analyticFeVariable->fieldComponentCount;
+ value = Memory_Alloc_Array( double, dofAtEachNodeCount, "value" );
+
+ /* Loop over all the nodes - applying the analytic solution */
+ for ( dNode_I = 0 ; dNode_I < Mesh_GetDomainSize( mesh, MT_VERTEX ); dNode_I++ ) {
+ coord = Mesh_GetVertex( mesh, dNode_I );
+
+ /* Calculate value at node */
+ memset( value, 0, dofAtEachNodeCount * sizeof(double) );
+ solutionFunction( self, analyticFeVariable, coord, value );
+
+ /* Put value on node */
+ FeVariable_SetValueAtNode( analyticFeVariable, dNode_I, value );
+
+ /* Print verbose information */
+ if ( Stream_IsPrintableLevel( infoStream, 2 ) ) {
+ Dimension_Index dim = analyticFeVariable->dim;
+ Dimension_Index dim_I;
+ Dof_Index dof_I;
+
+ /* Print Coord */
+ Journal_Printf( infoStream, "Node = %u Coord ( ", dNode_I );
+ for ( dim_I = 0 ; dim_I < dim - 1 ; dim_I++ ) {
+ Journal_Printf( infoStream, "%g, ", coord[ dim_I ] );
+ }
+ Journal_Printf( infoStream, "%g ) ", coord[ dim_I ] );
+
+ /* Print Analytic Values */
+ Journal_Printf( infoStream, "%s ( ", analyticFeVariable->name );
+ for ( dof_I = 0 ; dof_I < dofAtEachNodeCount - 1 ; dof_I++ ) {
+ Journal_Printf( infoStream, "%g, ", value[ dof_I ] );
+ }
+ Journal_Printf( infoStream, "%g ) ", value[ dof_I ] );
+
+ /* Print FeVariable Values */
+ memset( value, 0, dofAtEachNodeCount * sizeof(double) );
+ FeVariable_GetValueAtNode( feVariable, dNode_I, value );
+ Journal_Printf( infoStream, "%s ( ", feVariable->name );
+ for ( dof_I = 0 ; dof_I < dofAtEachNodeCount - 1 ; dof_I++ ) {
+ Journal_Printf( infoStream, "%g, ", value[ dof_I ] );
+ }
+ Journal_Printf( infoStream, "%g )\n", value[ dof_I ] );
+ }
+ }
+
+ Memory_Free( value );
+}
+
+void AnalyticSolution_Test( void* analyticSolution, Index analyticFeVariable_I ) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+ FeVariable* errorMagnitudeField;
+ double result;
+ Stream* stream;
+ double tolerance;
+ Stream* infoStream = Journal_MyStream( Info_Type, self );
+
+ /* Do some error checking */
+ assert( Stg_ObjectList_Count( self->analyticFeVariableList ) >= analyticFeVariable_I );
+
+ /* Grab pointers */
+ errorMagnitudeField =
+ Stg_CheckType( Stg_ObjectList_At( self->errorMagnitudeFieldList, analyticFeVariable_I ), FeVariable );
+
+ stream = (Stream*) Stg_ObjectList_ObjectAt( self->streamList, analyticFeVariable_I );
+ tolerance = self->toleranceList[ analyticFeVariable_I ];
+
+ result = FeVariable_Integrate( errorMagnitudeField, self->integrationSwarm );
+
+ Journal_Printf( stream, "Timestep %u: Total integrated value of '%s' is %s a tolerance %.5g.\n",
+ self->context->timeStep, errorMagnitudeField->name, result <= tolerance ? "within" : "outside", tolerance );
+ Stream_Flush( stream );
+
+ Journal_Printf( infoStream, "Timestep %u: Total integrated value of '%s' is %g\n",
+ self->context->timeStep, errorMagnitudeField->name, result );
+}
+
+
+void AnalyticSolution_TestAll( void* analyticSolution, void* data ) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+ Index analyticFeVariableCount = Stg_ObjectList_Count( self->analyticFeVariableList );
+ Index analyticFeVariable_I;
+
+ assert( analyticFeVariableCount == Stg_ObjectList_Count( self->analyticFeVariableFuncList ) );
+
+ /* Assign values to all analytic fields */
+ for ( analyticFeVariable_I = 0 ; analyticFeVariable_I < analyticFeVariableCount ; analyticFeVariable_I++ ) {
+ AnalyticSolution_Test( self, analyticFeVariable_I );
+ }
+}
+
+void AnalyticSolution_RegisterFeVariableWithAnalyticFunction( void* analyticSolution, FeVariable* feVariable, AnalyticSolution_SolutionFunction* solutionFunction) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+ char* tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"Analytic" );
+
+ /* Add feVariable to list */
+ Stg_ObjectList_Append( self->feVariableList, feVariable );
+ /* Add function to list */
+ Stg_ObjectList_GlobalPointerAppend( self->analyticFeVariableFuncList, (void*)solutionFunction, (Name)tmpName );
+ Memory_Free( tmpName );
+}
+
+
+FeVariable* AnalyticSolution_RegisterFeVariableFromCF( void* analyticSolution, char* fieldName, AnalyticSolution_SolutionFunction* solutionFunction, Stg_ComponentFactory* cf, Bool isEssential, void* data ) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+ FeVariable* field;
+
+ field = Stg_ComponentFactory_ConstructByName( cf, (Name)fieldName, FeVariable, isEssential, data );
+ if ( field )
+ AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, field, solutionFunction );
+
+ return field;
+}
+
+
+void AnalyticSolution_BuildAllAnalyticFields( void* analyticSolution, void* data ) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+ FeVariable* feVariable = NULL;
+ Stream* errStream = Journal_Register( Error_Type, (Name)"AnalyticSolution" );
+ unsigned feVar_I, feVarCount;
+
+ feVarCount = Stg_ObjectList_Count( self->feVariableList );
+
+ for( feVar_I = 0 ; feVar_I < feVarCount ; feVar_I++ ) {
+ feVariable = (FeVariable*)Stg_ObjectList_At( self->feVariableList, feVar_I );
+
+ /* Check to see whether this field has already been added */
+
+
+ /* Build the FeVariable here ensuring the analytic "copy" of it has valid values */
+ Stg_Component_Build( feVariable, data, False ) ;
+
+ if( feVariable->fieldComponentCount == 1 ) {
+ if( NULL == AnalyticSolution_CreateAnalyticField( self, feVariable ) ) {
+
+ Journal_Firewall( 0 , errStream,
+ "Error in function %s: Error in building analyticSolution for the feVariable %s,\n",
+ __func__ , feVariable );
+ }
+ } else {
+ if( NULL == AnalyticSolution_CreateAnalyticSymmetricTensorField( self, feVariable ) ) {
+
+ Journal_Firewall( 0 , errStream,
+ "Error in function %s: Error in building analyticSolution for the feVariable %s,\n",
+ __func__ , feVariable );
+ }
+ }
+
+ }
+
+
+}
+
+FeVariable* AnalyticSolution_CreateAnalyticField( void* analyticSolution, FeVariable* feVariable ) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+ char* tmpName;
+ FeVariable* analyticFeVariable;
+ Variable* dataVariable;
+ DofLayout* dofLayout;
+ Variable_Register* variable_Register = self->context->variable_Register;
+ Dof_Index componentsCount = feVariable->fieldComponentCount;
+ char* variableName[9];
+ Variable_Index variable_I;
+ Node_DomainIndex node_I;
+ Bool scalar=(componentsCount==1) ? True : False;
+ OperatorFeVariable* analyticMagField;
+ OperatorFeVariable* errorField;
+ OperatorFeVariable* errorMagnitudeField;
+ OperatorFeVariable* relativeErrorMagnitudeField;
+ Stream* stream;
+ Index count;
+
+ Stg_Component_Build( feVariable->feMesh, NULL, False );
+
+ /* Create new data Variable */
+ tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"Analytic-DataVariable" );
+ if ( scalar ) {
+ Sync* sync;
+
+ sync = Mesh_GetSync( feVariable->feMesh, MT_VERTEX );
+ dataVariable = Variable_NewScalar( tmpName, (AbstractContext*)self->context, Variable_DataType_Double, (Index*)(unsigned*)&sync->nDomains, NULL, (void**)NULL, variable_Register );
+ }
+ else {
+ Sync* sync;
+ unsigned c_i;
+
+ sync = Mesh_GetSync( feVariable->feMesh, MT_VERTEX );
+
+ /* Create names of variables */
+ assert( componentsCount <= 9 );
+ for ( variable_I = 0 ; variable_I < componentsCount ; variable_I++ ) {
+ Stg_asprintf( &variableName[ variable_I ], "%s-Analytic-ComponentVariable%d", feVariable->name, variable_I );
+ }
+ dataVariable = Variable_NewVector(
+ tmpName,
+ (AbstractContext*)self->context,
+ Variable_DataType_Double,
+ componentsCount,
+ (unsigned*)&sync->nDomains,
+ NULL,
+ (void**)NULL,
+ variable_Register,
+ variableName[0],
+ variableName[1],
+ variableName[2],
+ variableName[3],
+ variableName[4],
+ variableName[5],
+ variableName[6],
+ variableName[7],
+ variableName[8] );
+ for( c_i = 0; c_i < dataVariable->dataTypeCounts[0]; c_i++ )
+ dataVariable->components[c_i]->allocateSelf = True;
+ }
+ Memory_Free( tmpName );
+ dataVariable->allocateSelf = True;
+
+ /* Create new dof layout */
+ tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"Analytic-DofLayout" );
+ dofLayout = DofLayout_New( tmpName, self->context, variable_Register, Mesh_GetDomainSize( feVariable->feMesh, MT_VERTEX ), NULL );
+ if ( scalar ) {
+ DofLayout_AddAllFromVariableArray( dofLayout, 1, &dataVariable );
+ }
+ else {
+ for ( variable_I = 0 ; variable_I < componentsCount ; variable_I++ ) {
+
+ /* We have to set the array ptr ptr for these guys manually - this should be fixed */
+ Variable* variable = Variable_Register_GetByName( variable_Register, variableName[ variable_I ] );
+ variable->arrayPtrPtr = &dataVariable->arrayPtr;
+
+ /* Assign variable to each node */
+ for( node_I = 0; node_I < Mesh_GetDomainSize( feVariable->feMesh, MT_VERTEX ); node_I++ ) {
+ DofLayout_AddDof_ByVarName( dofLayout, variableName[variable_I], node_I );
+ }
+ /* Free Name */
+ Memory_Free( variableName[ variable_I ] );
+ }
+ }
+ Memory_Free( tmpName );
+
+ /* Create new FeVariable */
+ tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"Analytic" );
+ analyticFeVariable = FeVariable_New( tmpName, self->context, feVariable->feMesh, feVariable->geometryMesh, dofLayout,
+ NULL, NULL, NULL, feVariable->dim, feVariable->isCheckpointedAndReloaded,
+ False, False,
+ feVariable->fieldVariable_Register );
+
+ /* Add new analyticFeVariable to list */
+ Stg_ObjectList_Append( self->analyticFeVariableList, analyticFeVariable );
+
+ /* Create Magnitude Field */
+ tmpName = Stg_Object_AppendSuffix( analyticFeVariable, (Name)"Magnitude" );
+ analyticMagField = OperatorFeVariable_NewUnary( tmpName, self->context, analyticFeVariable, "Magnitude" );
+ Memory_Free( tmpName );
+
+ /* Create Error field - The the calculated field minus the analytic field */
+ tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"ErrorField" );
+ errorField = OperatorFeVariable_NewBinary( tmpName, self->context, feVariable, analyticFeVariable, "Subtraction" );
+ Memory_Free( tmpName );
+
+ /* Create Error magnitude field */
+ tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"ErrorMagnitudeField" );
+ errorMagnitudeField = OperatorFeVariable_NewUnary( tmpName, self->context, errorField, "Magnitude" );
+ Memory_Free( tmpName );
+ Stg_ObjectList_Append( self->errorMagnitudeFieldList, errorMagnitudeField ); /* Add it to list */
+
+ /* Create Relative Error magnitude field - The magnitude of relative error */
+ tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"RelativeErrorMagnitudeField" );
+ relativeErrorMagnitudeField = OperatorFeVariable_NewBinary( tmpName, self->context, errorMagnitudeField, analyticMagField, "ScalarDivision" );
+ Memory_Free( tmpName );
+ Stg_ObjectList_Append( self->relativeErrorMagnitudeFieldList, relativeErrorMagnitudeField ); /* Add it to list */
+
+ /* Create Stream for field to dump error information to */
+ tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"ErrorFile" );
+ stream = Journal_Register( Dump_Type, (Name)tmpName );
+ Stg_ObjectList_GlobalPointerAppend( self->streamList, stream, (Name)tmpName );
+ Stream_Enable( stream, True );
+ Stream_RedirectFile_WithPrependedPath( stream, self->context->outputPath, tmpName );
+ Memory_Free( tmpName );
+
+ /* Get tolerance from dictionary */
+ count = Stg_ObjectList_Count( self->analyticFeVariableList );
+ self->toleranceList = Memory_Realloc_Array( self->toleranceList, double, count );
+ tmpName = Stg_Object_AppendSuffix( feVariable, (Name)"Tolerance" );
+ self->toleranceList[ count - 1 ] = Dictionary_GetDouble_WithDefault( self->context->dictionary, (Dictionary_Entry_Key)tmpName, 0.0 );
+ Memory_Free( tmpName );
+
+ /* Add components to LiveComponentRegister so they will be visible to other components
+ * and will be built, initialised and deleted */
+ LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) dataVariable );
+ LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) dofLayout );
+ LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) analyticFeVariable );
+ LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) analyticMagField );
+ LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) errorField );
+ LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) errorMagnitudeField );
+ LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) relativeErrorMagnitudeField );
+
+ return analyticFeVariable;
+}
+
+FeVariable* AnalyticSolution_CreateAnalyticVectorField( void* analyticSolution, FeVariable* vectorField, AnalyticSolution_SolutionFunction* solutionFunction ) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+ FeVariable* analyticVectorField;
+
+ analyticVectorField = AnalyticSolution_CreateAnalyticField( self, vectorField );
+
+ return analyticVectorField;
+}
+
+FeVariable* AnalyticSolution_CreateAnalyticSymmetricTensorField( void* analyticSolution, FeVariable* vectorField ) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+ FeVariable* analyticVectorField;
+ OperatorFeVariable* analyticVectorInvField;
+ char *tmpName, *tmpName2;
+ DofLayout* dofLayout;
+
+ analyticVectorField = AnalyticSolution_CreateAnalyticField( self, vectorField );
+
+ /* Create new dof layout */
+ tmpName = Stg_Object_AppendSuffix( analyticVectorField, (Name)"Analytic-DofLayout" );
+ dofLayout = DofLayout_New( tmpName, self->context, self->context->variable_Register, Mesh_GetDomainSize( analyticVectorField->feMesh, MT_VERTEX ), NULL );
+
+ /* Create Invariant Field */
+ tmpName2 = Stg_Object_AppendSuffix( analyticVectorField, (Name)"Invariant" );
+ analyticVectorInvField = OperatorFeVariable_NewUnary( tmpName2, self->context, analyticVectorField, "SymmetricTensor_Invariant" );
+
+ Memory_Free( tmpName );
+ Memory_Free( tmpName2 );
+
+ LiveComponentRegister_Add( self->LC_Register, (Stg_Component*) analyticVectorInvField );
+
+ return analyticVectorField;
+}
+
+FeVariable* AnalyticSolution_GetFeVariableFromAnalyticFeVariable( void* analyticSolution, FeVariable* analyticFeVariable ) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+ Index analyticFeVariableCount = Stg_ObjectList_Count( self->analyticFeVariableList );
+ Index analyticFeVariable_I;
+
+ assert( analyticFeVariableCount == Stg_ObjectList_Count( self->feVariableList ) );
+
+ for ( analyticFeVariable_I = 0 ; analyticFeVariable_I < analyticFeVariableCount ; analyticFeVariable_I++ ) {
+ /* find the index of analytic feVariable and then return the corresponding feVariable */
+ if ( analyticFeVariable == (FeVariable*) Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I ) )
+ return (FeVariable*) Stg_ObjectList_At( self->feVariableList, analyticFeVariable_I );
+ }
+
+ return NULL;
+}
+
+InterpolationResult AnalyticSolution_InterpolateValueFromNormalFeVariable( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* value ) {
+ AnalyticSolution* self = (AnalyticSolution*) analyticSolution;
+ FeVariable* normalFeVariable;
+
+ normalFeVariable = AnalyticSolution_GetFeVariableFromAnalyticFeVariable( self, analyticFeVariable );
+
+ return FieldVariable_InterpolateValueAt( normalFeVariable, coord, value );
+}
+
+AnalyticSolution* AnalyticSolution_GetAnalyticSolution() {
+ Journal_Firewall( mySingleton != NULL , Journal_Register( Error_Type, (Name)"AnalyticSolution" ),
+ "Error in function %s: The Singleton Ptr is NULL, meaning the AnalyticSolution has not been created yet\n", __func__ );
+
+ return mySingleton;
+}
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/BilinearElementType.c
--- a/Discretisation/src/BilinearElementType.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,311 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: BilinearElementType.c 1179 2008-07-15 05:28:11Z DavidLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "ElementType.h"
-#include "BilinearElementType.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-#include <math.h>
-
-const Type BilinearElementType_Type = "BilinearElementType";
-
-#define _BilinearElementType_NodeCount 4
-
-BilinearElementType* BilinearElementType_New( Name name ) {
- BilinearElementType* self = (BilinearElementType*)_BilinearElementType_DefaultNew( name );
-
- self->isConstructed = True;
- _ElementType_Init( (ElementType*)self, _BilinearElementType_NodeCount );
- _BilinearElementType_Init( self );
-
- return self;
-}
-
-void* _BilinearElementType_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(BilinearElementType);
- Type type = BilinearElementType_Type;
- Stg_Class_DeleteFunction* _delete = _BilinearElementType_Delete;
- Stg_Class_PrintFunction* _print = _BilinearElementType_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _BilinearElementType_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _BilinearElementType_AssignFromXML;
- Stg_Component_BuildFunction* _build = _BilinearElementType_Build;
- Stg_Component_InitialiseFunction* _initialise = _BilinearElementType_Initialise;
- Stg_Component_ExecuteFunction* _execute = _BilinearElementType_Execute;
- Stg_Component_DestroyFunction* _destroy = _BilinearElementType_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _BilinearElementType_SF_allNodes;
- ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _BilinearElementType_SF_allLocalDerivs_allNodes;
- ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
- ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _BilinearElementType_JacobianDeterminantSurface;
- ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
-
- return _BilinearElementType_New( BILINEARELEMENTTYPE_PASSARGS );
-}
-
-BilinearElementType* _BilinearElementType_New( BILINEARELEMENTTYPE_DEFARGS ) {
- BilinearElementType* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(BilinearElementType) );
- self = (BilinearElementType*)_ElementType_New( ELEMENTTYPE_PASSARGS );
-
- /* General info */
-
- /* Virtual functions */
-
- return self;
-}
-
-void _BilinearElementType_Init( BilinearElementType* self ) {
- Dimension_Index dim, dim_I=0;
- /* General and Virtual info should already be set */
-
- /* set the dimensionality of the element */
- dim = self->dim = 2;
-
- for ( dim_I = 0; dim_I < dim; dim_I++ ) {
- self->minElLocalCoord[dim_I] = -1;
- self->maxElLocalCoord[dim_I] = 1;
- self->elLocalLength[dim_I] = self->maxElLocalCoord[dim_I] - self->minElLocalCoord[dim_I];
- }
-
- self->triInds = Memory_Alloc_2DArray( unsigned, dim, 3, (Name)"BilinearElementType::triInds" );
- self->triInds[0][0] = 0; self->triInds[0][1] = 1; self->triInds[0][2] = 2;
- self->triInds[1][0] = 1; self->triInds[1][1] = 3; self->triInds[1][2] = 2;
-}
-
-void _BilinearElementType_Delete( void* elementType ) {
- BilinearElementType* self = (BilinearElementType*)elementType;
-
- /* Stg_Class_Delete parent */
- _ElementType_Delete( self );
-}
-
-void _BilinearElementType_Print( void* elementType, Stream* stream ) {
- BilinearElementType* self = (BilinearElementType*)elementType;
- Dimension_Index dim_I=0;
-
- /* General info */
- Journal_Printf( stream, "BilinearElementType (ptr): %p\n", self );
-
- /* Print parent */
- _ElementType_Print( self, stream );
-
- /* Virtual info */
-
- /* BilinearElementType info */
- Journal_Printf( stream, "self->minElLocalCoord: (", self );
- for ( dim_I = 0; dim_I < 2; dim_I++ ) {
- Journal_Printf( stream, "%0.5f,", self->minElLocalCoord[dim_I] );
- }
- Journal_Printf( stream, ")\n", self );
- Journal_Printf( stream, "self->maxElLocalCoord: (", self );
- for ( dim_I = 0; dim_I < 2; dim_I++ ) {
- Journal_Printf( stream, "%0.5f,", self->maxElLocalCoord[dim_I] );
- }
- Journal_Printf( stream, ")\n", self );
- Journal_Printf( stream, "self->elLocalLength: (", self );
- for ( dim_I = 0; dim_I < 2; dim_I++ ) {
- Journal_Printf( stream, "%0.5f,", self->elLocalLength[dim_I] );
- }
- Journal_Printf( stream, ")\n", self );
-}
-
-void _BilinearElementType_AssignFromXML( void* elementType, Stg_ComponentFactory *cf, void* data ) {
-}
-
-void _BilinearElementType_Initialise( void* elementType, void *data ){
- BilinearElementType* self = (BilinearElementType*) elementType;
-
- self->faceNodes = Memory_Alloc_2DArray( unsigned, 4, 2, (Name)"node indices for element faces" );
-
- self->faceNodes[0][0] = 0; self->faceNodes[0][1] = 1;
- self->faceNodes[1][0] = 2; self->faceNodes[1][1] = 3;
- self->faceNodes[2][0] = 0; self->faceNodes[2][1] = 2;
- self->faceNodes[3][0] = 1; self->faceNodes[3][1] = 3;
-}
-
-void _BilinearElementType_Execute( void* elementType, void *data ){
-}
-
-void _BilinearElementType_Destroy( void* elementType, void *data ){
- BilinearElementType* self = (BilinearElementType*) elementType;
-
- FreeArray( self->triInds );
-
- Memory_Free( self->faceNodes );
- Memory_Free( self->evaluatedShapeFunc );
- Memory_Free( self->GNi );
-
- _ElementType_Destroy( self, data );
-}
-
-void _BilinearElementType_Build( void* elementType, void *data ) {
- BilinearElementType* self = (BilinearElementType*) elementType;
-
- self->evaluatedShapeFunc = Memory_Alloc_Array( double, self->nodeCount, "evaluatedShapeFuncs" );
- self->GNi = Memory_Alloc_2DArray( double, self->dim, self->nodeCount, (Name)"localShapeFuncDerivitives" );
-}
-
-/*
- - Shape function definitions
- - Local node numbering convention for billinear element (xi, eta)
- - Local coordinate domain spans -1 <= xi,eta <= 1
-
- eta
- |
-3-----2
-| |__|___xi
-| |
-0-----1
-
-*/
-void _BilinearElementType_SF_allNodes( void* elementType, const double localCoord[], double* const evaluatedValues ) {
- double xi, eta;
-
- xi = localCoord[0];
- eta = localCoord[1];
-
- evaluatedValues[0] = 0.25*( 1.0-xi )*( 1.0-eta );
- evaluatedValues[1] = 0.25*( 1.0+xi )*( 1.0-eta );
- evaluatedValues[3] = 0.25*( 1.0+xi )*( 1.0+eta );
- evaluatedValues[2] = 0.25*( 1.0-xi )*( 1.0+eta );
-}
-
-
-void _BilinearElementType_SF_allLocalDerivs_allNodes( void* elementType, const double localCoord[],
- double** const evaluatedDerivatives )
-{
- double xi, eta;
-
- xi = localCoord[0];
- eta = localCoord[1];
-
- /* derivatives wrt xi */
- evaluatedDerivatives[0][0] = - 0.25*( 1.0 - eta );
- evaluatedDerivatives[0][1] = 0.25*( 1.0 - eta );
- evaluatedDerivatives[0][3] = 0.25*( 1.0 + eta );
- evaluatedDerivatives[0][2] = - 0.25*( 1.0 + eta );
-
- /* derivatives wrt eta */
- evaluatedDerivatives[1][0] = - 0.25*( 1.0 - xi );
- evaluatedDerivatives[1][1] = - 0.25*( 1.0 + xi );
- evaluatedDerivatives[1][3] = 0.25*( 1.0 + xi );
- evaluatedDerivatives[1][2] = 0.25*( 1.0 - xi );
-}
-
-
-#if 0
-/*
-** Calculates the barycenter of a triangle with respect to some point.
-*/
-
-void _BilinearElementType_ConvertGlobalCoordToElLocal(
- void* elementType,
- void* _mesh,
- unsigned element,
- const double* globalCoord,
- double* elLocalCoord )
-{
- BilinearElementType* self = (BilinearElementType*)elementType;
- Mesh* mesh = (Mesh*)_mesh;
- unsigned inside;
- double bc[3];
- static double lCrds[4][3] = {{-1.0, -1.0, 0.0}, {1.0, -1.0, 0.0},
- {-1.0, 1.0, 0.0}, {1.0, 1.0, 0.0}};
- unsigned nInc, *inc;
- unsigned bc_i;
-
- Mesh_GetIncidence( mesh, MT_FACE, element, MT_VERTEX, self->inc );
- nInc = IArray_GetSize( self->inc );
- inc = IArray_GetPtr( self->inc );
- assert( nInc == 4 );
-
- insist( Simplex_Search2D( mesh->verts, inc, 2, self->triInds, (double*)globalCoord, bc, &inside ), == True );
-
- elLocalCoord[0] = bc[0] * lCrds[self->triInds[inside][0]][0];
- elLocalCoord[1] = bc[0] * lCrds[self->triInds[inside][0]][1];
- for( bc_i = 1; bc_i < 3; bc_i++ ) {
- elLocalCoord[0] += bc[bc_i] * lCrds[self->triInds[inside][bc_i]][0];
- elLocalCoord[1] += bc[bc_i] * lCrds[self->triInds[inside][bc_i]][1];
- }
-}
-#endif
-
-double _BilinearElementType_JacobianDeterminantSurface(
- void* elementType,
- void* _mesh,
- unsigned element_I,
- const double localCoord[],
- unsigned face_I,
- unsigned norm )
-{
- BilinearElementType* self = (BilinearElementType*) elementType;
- Mesh* mesh = (Mesh*)_mesh;
- unsigned surfaceDim = ( norm + 1 ) % 2;
- double x[2];
- double detJac;
- Index nodes[2];
-
- ElementType_GetFaceNodes( self, mesh, element_I, face_I, 2, nodes );
-
- x[0] = Mesh_GetVertex( mesh, nodes[0] )[surfaceDim];
- x[1] = Mesh_GetVertex( mesh, nodes[1] )[surfaceDim];
-
- detJac = 0.5 * ( x[1] - x[0] );
-
- return fabs( detJac );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/BilinearElementType.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/BilinearElementType.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,311 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: BilinearElementType.c 1179 2008-07-15 05:28:11Z DavidLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "ElementType.h"
+#include "BilinearElementType.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+const Type BilinearElementType_Type = "BilinearElementType";
+
+#define _BilinearElementType_NodeCount 4
+
+BilinearElementType* BilinearElementType_New( Name name ) {
+ BilinearElementType* self = (BilinearElementType*)_BilinearElementType_DefaultNew( name );
+
+ self->isConstructed = True;
+ _ElementType_Init( (ElementType*)self, _BilinearElementType_NodeCount );
+ _BilinearElementType_Init( self );
+
+ return self;
+}
+
+void* _BilinearElementType_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(BilinearElementType);
+ Type type = BilinearElementType_Type;
+ Stg_Class_DeleteFunction* _delete = _BilinearElementType_Delete;
+ Stg_Class_PrintFunction* _print = _BilinearElementType_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _BilinearElementType_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _BilinearElementType_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _BilinearElementType_Build;
+ Stg_Component_InitialiseFunction* _initialise = _BilinearElementType_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _BilinearElementType_Execute;
+ Stg_Component_DestroyFunction* _destroy = _BilinearElementType_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _BilinearElementType_SF_allNodes;
+ ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _BilinearElementType_SF_allLocalDerivs_allNodes;
+ ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
+ ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _BilinearElementType_JacobianDeterminantSurface;
+ ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
+
+ return _BilinearElementType_New( BILINEARELEMENTTYPE_PASSARGS );
+}
+
+BilinearElementType* _BilinearElementType_New( BILINEARELEMENTTYPE_DEFARGS ) {
+ BilinearElementType* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(BilinearElementType) );
+ self = (BilinearElementType*)_ElementType_New( ELEMENTTYPE_PASSARGS );
+
+ /* General info */
+
+ /* Virtual functions */
+
+ return self;
+}
+
+void _BilinearElementType_Init( BilinearElementType* self ) {
+ Dimension_Index dim, dim_I=0;
+ /* General and Virtual info should already be set */
+
+ /* set the dimensionality of the element */
+ dim = self->dim = 2;
+
+ for ( dim_I = 0; dim_I < dim; dim_I++ ) {
+ self->minElLocalCoord[dim_I] = -1;
+ self->maxElLocalCoord[dim_I] = 1;
+ self->elLocalLength[dim_I] = self->maxElLocalCoord[dim_I] - self->minElLocalCoord[dim_I];
+ }
+
+ self->triInds = Memory_Alloc_2DArray( unsigned, dim, 3, (Name)"BilinearElementType::triInds" );
+ self->triInds[0][0] = 0; self->triInds[0][1] = 1; self->triInds[0][2] = 2;
+ self->triInds[1][0] = 1; self->triInds[1][1] = 3; self->triInds[1][2] = 2;
+}
+
+void _BilinearElementType_Delete( void* elementType ) {
+ BilinearElementType* self = (BilinearElementType*)elementType;
+
+ /* Stg_Class_Delete parent */
+ _ElementType_Delete( self );
+}
+
+void _BilinearElementType_Print( void* elementType, Stream* stream ) {
+ BilinearElementType* self = (BilinearElementType*)elementType;
+ Dimension_Index dim_I=0;
+
+ /* General info */
+ Journal_Printf( stream, "BilinearElementType (ptr): %p\n", self );
+
+ /* Print parent */
+ _ElementType_Print( self, stream );
+
+ /* Virtual info */
+
+ /* BilinearElementType info */
+ Journal_Printf( stream, "self->minElLocalCoord: (", self );
+ for ( dim_I = 0; dim_I < 2; dim_I++ ) {
+ Journal_Printf( stream, "%0.5f,", self->minElLocalCoord[dim_I] );
+ }
+ Journal_Printf( stream, ")\n", self );
+ Journal_Printf( stream, "self->maxElLocalCoord: (", self );
+ for ( dim_I = 0; dim_I < 2; dim_I++ ) {
+ Journal_Printf( stream, "%0.5f,", self->maxElLocalCoord[dim_I] );
+ }
+ Journal_Printf( stream, ")\n", self );
+ Journal_Printf( stream, "self->elLocalLength: (", self );
+ for ( dim_I = 0; dim_I < 2; dim_I++ ) {
+ Journal_Printf( stream, "%0.5f,", self->elLocalLength[dim_I] );
+ }
+ Journal_Printf( stream, ")\n", self );
+}
+
+void _BilinearElementType_AssignFromXML( void* elementType, Stg_ComponentFactory *cf, void* data ) {
+}
+
+void _BilinearElementType_Initialise( void* elementType, void *data ){
+ BilinearElementType* self = (BilinearElementType*) elementType;
+
+ self->faceNodes = Memory_Alloc_2DArray( unsigned, 4, 2, (Name)"node indices for element faces" );
+
+ self->faceNodes[0][0] = 0; self->faceNodes[0][1] = 1;
+ self->faceNodes[1][0] = 2; self->faceNodes[1][1] = 3;
+ self->faceNodes[2][0] = 0; self->faceNodes[2][1] = 2;
+ self->faceNodes[3][0] = 1; self->faceNodes[3][1] = 3;
+}
+
+void _BilinearElementType_Execute( void* elementType, void *data ){
+}
+
+void _BilinearElementType_Destroy( void* elementType, void *data ){
+ BilinearElementType* self = (BilinearElementType*) elementType;
+
+ FreeArray( self->triInds );
+
+ Memory_Free( self->faceNodes );
+ Memory_Free( self->evaluatedShapeFunc );
+ Memory_Free( self->GNi );
+
+ _ElementType_Destroy( self, data );
+}
+
+void _BilinearElementType_Build( void* elementType, void *data ) {
+ BilinearElementType* self = (BilinearElementType*) elementType;
+
+ self->evaluatedShapeFunc = Memory_Alloc_Array( double, self->nodeCount, "evaluatedShapeFuncs" );
+ self->GNi = Memory_Alloc_2DArray( double, self->dim, self->nodeCount, (Name)"localShapeFuncDerivitives" );
+}
+
+/*
+ - Shape function definitions
+ - Local node numbering convention for billinear element (xi, eta)
+ - Local coordinate domain spans -1 <= xi,eta <= 1
+
+ eta
+ |
+3-----2
+| |__|___xi
+| |
+0-----1
+
+*/
+void _BilinearElementType_SF_allNodes( void* elementType, const double localCoord[], double* const evaluatedValues ) {
+ double xi, eta;
+
+ xi = localCoord[0];
+ eta = localCoord[1];
+
+ evaluatedValues[0] = 0.25*( 1.0-xi )*( 1.0-eta );
+ evaluatedValues[1] = 0.25*( 1.0+xi )*( 1.0-eta );
+ evaluatedValues[3] = 0.25*( 1.0+xi )*( 1.0+eta );
+ evaluatedValues[2] = 0.25*( 1.0-xi )*( 1.0+eta );
+}
+
+
+void _BilinearElementType_SF_allLocalDerivs_allNodes( void* elementType, const double localCoord[],
+ double** const evaluatedDerivatives )
+{
+ double xi, eta;
+
+ xi = localCoord[0];
+ eta = localCoord[1];
+
+ /* derivatives wrt xi */
+ evaluatedDerivatives[0][0] = - 0.25*( 1.0 - eta );
+ evaluatedDerivatives[0][1] = 0.25*( 1.0 - eta );
+ evaluatedDerivatives[0][3] = 0.25*( 1.0 + eta );
+ evaluatedDerivatives[0][2] = - 0.25*( 1.0 + eta );
+
+ /* derivatives wrt eta */
+ evaluatedDerivatives[1][0] = - 0.25*( 1.0 - xi );
+ evaluatedDerivatives[1][1] = - 0.25*( 1.0 + xi );
+ evaluatedDerivatives[1][3] = 0.25*( 1.0 + xi );
+ evaluatedDerivatives[1][2] = 0.25*( 1.0 - xi );
+}
+
+
+#if 0
+/*
+** Calculates the barycenter of a triangle with respect to some point.
+*/
+
+void _BilinearElementType_ConvertGlobalCoordToElLocal(
+ void* elementType,
+ void* _mesh,
+ unsigned element,
+ const double* globalCoord,
+ double* elLocalCoord )
+{
+ BilinearElementType* self = (BilinearElementType*)elementType;
+ Mesh* mesh = (Mesh*)_mesh;
+ unsigned inside;
+ double bc[3];
+ static double lCrds[4][3] = {{-1.0, -1.0, 0.0}, {1.0, -1.0, 0.0},
+ {-1.0, 1.0, 0.0}, {1.0, 1.0, 0.0}};
+ unsigned nInc, *inc;
+ unsigned bc_i;
+
+ Mesh_GetIncidence( mesh, MT_FACE, element, MT_VERTEX, self->inc );
+ nInc = IArray_GetSize( self->inc );
+ inc = IArray_GetPtr( self->inc );
+ assert( nInc == 4 );
+
+ insist( Simplex_Search2D( mesh->verts, inc, 2, self->triInds, (double*)globalCoord, bc, &inside ), == True );
+
+ elLocalCoord[0] = bc[0] * lCrds[self->triInds[inside][0]][0];
+ elLocalCoord[1] = bc[0] * lCrds[self->triInds[inside][0]][1];
+ for( bc_i = 1; bc_i < 3; bc_i++ ) {
+ elLocalCoord[0] += bc[bc_i] * lCrds[self->triInds[inside][bc_i]][0];
+ elLocalCoord[1] += bc[bc_i] * lCrds[self->triInds[inside][bc_i]][1];
+ }
+}
+#endif
+
+double _BilinearElementType_JacobianDeterminantSurface(
+ void* elementType,
+ void* _mesh,
+ unsigned element_I,
+ const double localCoord[],
+ unsigned face_I,
+ unsigned norm )
+{
+ BilinearElementType* self = (BilinearElementType*) elementType;
+ Mesh* mesh = (Mesh*)_mesh;
+ unsigned surfaceDim = ( norm + 1 ) % 2;
+ double x[2];
+ double detJac;
+ Index nodes[2];
+
+ ElementType_GetFaceNodes( self, mesh, element_I, face_I, 2, nodes );
+
+ x[0] = Mesh_GetVertex( mesh, nodes[0] )[surfaceDim];
+ x[1] = Mesh_GetVertex( mesh, nodes[1] )[surfaceDim];
+
+ detJac = 0.5 * ( x[1] - x[0] );
+
+ return fabs( detJac );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/BilinearInnerElType.c
--- a/Discretisation/src/BilinearInnerElType.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,237 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: BilinearInnerElType.c 832 2007-05-16 01:11:18Z DaveLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "ElementType.h"
-#include "BilinearInnerElType.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-const Type BilinearInnerElType_Type = "BilinearInnerElType";
-
-#define _BilinearInnerElType_NodeCount 3
-
-BilinearInnerElType* BilinearInnerElType_New( Name name ) {
- BilinearInnerElType* self = (BilinearInnerElType*)BilinearInnerElType_DefaultNew( name );
-
- self->isConstructed = True;
- _ElementType_Init( (ElementType*)self, _BilinearInnerElType_NodeCount );
- _BilinearInnerElType_Init( self );
-
- return self;
-}
-
-void* BilinearInnerElType_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(BilinearInnerElType);
- Type type = BilinearInnerElType_Type;
- Stg_Class_DeleteFunction* _delete = _BilinearInnerElType_Delete;
- Stg_Class_PrintFunction* _print = _BilinearInnerElType_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = BilinearInnerElType_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _BilinearInnerElType_AssignFromXML;
- Stg_Component_BuildFunction* _build = _BilinearInnerElType_Build;
- Stg_Component_InitialiseFunction* _initialise = _BilinearInnerElType_Initialise;
- Stg_Component_ExecuteFunction* _execute = _BilinearInnerElType_Execute;
- Stg_Component_DestroyFunction* _destroy = _BilinearInnerElType_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _BilinearInnerElType_SF_allNodes;
- ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _BilinearInnerElType_SF_allLocalDerivs_allNodes;
- ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
- ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _ElementType_JacobianDeterminantSurface;
- ElementType_SurfaceNormalFunction* _surfaceNormal = _BilinearInnerElType_SurfaceNormal;
-
- return _BilinearInnerElType_New( BILINEARINNERELTYPE_PASSARGS );
-}
-
-BilinearInnerElType* _BilinearInnerElType_New( BILINEARINNERELTYPE_DEFARGS ) {
- BilinearInnerElType* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(BilinearInnerElType) );
- self = (BilinearInnerElType*)_ElementType_New( ELEMENTTYPE_PASSARGS );
-
- /* General info */
-
- /* Virtual functions */
-
- return self;
-}
-
-void _BilinearInnerElType_Init( BilinearInnerElType* self ) {
- Dimension_Index dim_I=0;
- /* General and Virtual info should already be set */
-
- /* BilinearInnerElType info */
- self->isConstructed = True;
- for ( dim_I = 0; dim_I < 2; dim_I++ ) {
- self->minElLocalCoord[dim_I] = -1;
- self->maxElLocalCoord[dim_I] = 1;
- self->elLocalLength[dim_I] = self->maxElLocalCoord[dim_I] - self->minElLocalCoord[dim_I];
- }
-
- self->triInds = Memory_Alloc_2DArray( unsigned, 2, 3, (Name)"BilinearInnerElType::triInds" );
- self->triInds[0][0] = 0; self->triInds[0][1] = 1; self->triInds[0][2] = 2;
- self->triInds[1][0] = 1; self->triInds[1][1] = 3; self->triInds[1][2] = 2;
-}
-
-void _BilinearInnerElType_Delete( void* elementType ) {
- BilinearInnerElType* self = (BilinearInnerElType*)elementType;
-
- /* Stg_Class_Delete parent */
- _ElementType_Delete( self );
-}
-
-void _BilinearInnerElType_Print( void* elementType, Stream* stream ) {
- BilinearInnerElType* self = (BilinearInnerElType*)elementType;
- Dimension_Index dim_I=0;
-
- /* General info */
- Journal_Printf( stream, "BilinearInnerElType (ptr): %p\n", self );
-
- /* Print parent */
- _ElementType_Print( self, stream );
-
- /* Virtual info */
-
- /* BilinearInnerElType info */
- Journal_Printf( stream, "self->minElLocalCoord: (", self );
- for ( dim_I = 0; dim_I < 2; dim_I++ ) {
- Journal_Printf( stream, "%0.5f,", self->minElLocalCoord[dim_I] );
- }
- Journal_Printf( stream, ")\n", self );
- Journal_Printf( stream, "self->maxElLocalCoord: (", self );
- for ( dim_I = 0; dim_I < 2; dim_I++ ) {
- Journal_Printf( stream, "%0.5f,", self->maxElLocalCoord[dim_I] );
- }
- Journal_Printf( stream, ")\n", self );
- Journal_Printf( stream, "self->elLocalLength: (", self );
- for ( dim_I = 0; dim_I < 2; dim_I++ ) {
- Journal_Printf( stream, "%0.5f,", self->elLocalLength[dim_I] );
- }
- Journal_Printf( stream, ")\n", self );
-}
-
-void _BilinearInnerElType_AssignFromXML( void* elementType, Stg_ComponentFactory *cf, void* data ){
-}
-
-void _BilinearInnerElType_Initialise( void* elementType, void *data ){
-}
-
-void _BilinearInnerElType_Execute( void* elementType, void *data ){
-}
-
-void _BilinearInnerElType_Destroy( void* elementType, void *data ){
- BilinearInnerElType* self = (BilinearInnerElType*)elementType;
-
- FreeArray( self->triInds );
-
- _ElementType_Destroy( self, data );
-}
-
-void _BilinearInnerElType_Build( void* elementType, void *data ) {
-}
-
-/*
-
- - Shape function definitions
- - Local node numbering convention for billinear element (xi, eta)
- - Local coordinate domain spans -1 <= xi,eta <= 1
-
- eta
- |
-3-----2
-| |__|___xi
-| |
-0-----1
-
-*/
-void _BilinearInnerElType_SF_allNodes( void* elementType, const double localCoord[], double* const evaluatedValues ) {
- double xi, eta;
-
- xi = localCoord[0];
- eta = localCoord[1];
-
- evaluatedValues[0] = - xi - 0.5*eta + 0.25;
- evaluatedValues[1] = xi - 0.5*eta + 0.25;
- evaluatedValues[2] = eta + 0.5;
-}
-
-
-void _BilinearInnerElType_SF_allLocalDerivs_allNodes( void* elementType, const double localCoord[],
- double** const evaluatedDerivatives )
-{
- double xi, eta;
-
- xi = localCoord[0];
- eta = localCoord[1];
-
- evaluatedDerivatives[0][0] = - 1.0;
- evaluatedDerivatives[0][1] = 1.0;
- evaluatedDerivatives[0][2] = 0.0;
-
- evaluatedDerivatives[1][0] = - 0.5;
- evaluatedDerivatives[1][1] = - 0.5;
- evaluatedDerivatives[1][2] = 1.0;
-}
-
-int _BilinearInnerElType_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* norm ) {
- Stream* errStream = Journal_Register( ErrorStream_Type, (Name)ElementType_Type );
-
- Journal_Printf( errStream, "surface normal function not yet implemented for this element type.\n" );
- assert( 0 );
-
- norm = NULL;
-
- return -1;
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/BilinearInnerElType.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/BilinearInnerElType.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,237 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: BilinearInnerElType.c 832 2007-05-16 01:11:18Z DaveLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "ElementType.h"
+#include "BilinearInnerElType.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+const Type BilinearInnerElType_Type = "BilinearInnerElType";
+
+#define _BilinearInnerElType_NodeCount 3
+
+BilinearInnerElType* BilinearInnerElType_New( Name name ) {
+ BilinearInnerElType* self = (BilinearInnerElType*)BilinearInnerElType_DefaultNew( name );
+
+ self->isConstructed = True;
+ _ElementType_Init( (ElementType*)self, _BilinearInnerElType_NodeCount );
+ _BilinearInnerElType_Init( self );
+
+ return self;
+}
+
+void* BilinearInnerElType_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(BilinearInnerElType);
+ Type type = BilinearInnerElType_Type;
+ Stg_Class_DeleteFunction* _delete = _BilinearInnerElType_Delete;
+ Stg_Class_PrintFunction* _print = _BilinearInnerElType_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = BilinearInnerElType_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _BilinearInnerElType_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _BilinearInnerElType_Build;
+ Stg_Component_InitialiseFunction* _initialise = _BilinearInnerElType_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _BilinearInnerElType_Execute;
+ Stg_Component_DestroyFunction* _destroy = _BilinearInnerElType_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _BilinearInnerElType_SF_allNodes;
+ ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _BilinearInnerElType_SF_allLocalDerivs_allNodes;
+ ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
+ ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _ElementType_JacobianDeterminantSurface;
+ ElementType_SurfaceNormalFunction* _surfaceNormal = _BilinearInnerElType_SurfaceNormal;
+
+ return _BilinearInnerElType_New( BILINEARINNERELTYPE_PASSARGS );
+}
+
+BilinearInnerElType* _BilinearInnerElType_New( BILINEARINNERELTYPE_DEFARGS ) {
+ BilinearInnerElType* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(BilinearInnerElType) );
+ self = (BilinearInnerElType*)_ElementType_New( ELEMENTTYPE_PASSARGS );
+
+ /* General info */
+
+ /* Virtual functions */
+
+ return self;
+}
+
+void _BilinearInnerElType_Init( BilinearInnerElType* self ) {
+ Dimension_Index dim_I=0;
+ /* General and Virtual info should already be set */
+
+ /* BilinearInnerElType info */
+ self->isConstructed = True;
+ for ( dim_I = 0; dim_I < 2; dim_I++ ) {
+ self->minElLocalCoord[dim_I] = -1;
+ self->maxElLocalCoord[dim_I] = 1;
+ self->elLocalLength[dim_I] = self->maxElLocalCoord[dim_I] - self->minElLocalCoord[dim_I];
+ }
+
+ self->triInds = Memory_Alloc_2DArray( unsigned, 2, 3, (Name)"BilinearInnerElType::triInds" );
+ self->triInds[0][0] = 0; self->triInds[0][1] = 1; self->triInds[0][2] = 2;
+ self->triInds[1][0] = 1; self->triInds[1][1] = 3; self->triInds[1][2] = 2;
+}
+
+void _BilinearInnerElType_Delete( void* elementType ) {
+ BilinearInnerElType* self = (BilinearInnerElType*)elementType;
+
+ /* Stg_Class_Delete parent */
+ _ElementType_Delete( self );
+}
+
+void _BilinearInnerElType_Print( void* elementType, Stream* stream ) {
+ BilinearInnerElType* self = (BilinearInnerElType*)elementType;
+ Dimension_Index dim_I=0;
+
+ /* General info */
+ Journal_Printf( stream, "BilinearInnerElType (ptr): %p\n", self );
+
+ /* Print parent */
+ _ElementType_Print( self, stream );
+
+ /* Virtual info */
+
+ /* BilinearInnerElType info */
+ Journal_Printf( stream, "self->minElLocalCoord: (", self );
+ for ( dim_I = 0; dim_I < 2; dim_I++ ) {
+ Journal_Printf( stream, "%0.5f,", self->minElLocalCoord[dim_I] );
+ }
+ Journal_Printf( stream, ")\n", self );
+ Journal_Printf( stream, "self->maxElLocalCoord: (", self );
+ for ( dim_I = 0; dim_I < 2; dim_I++ ) {
+ Journal_Printf( stream, "%0.5f,", self->maxElLocalCoord[dim_I] );
+ }
+ Journal_Printf( stream, ")\n", self );
+ Journal_Printf( stream, "self->elLocalLength: (", self );
+ for ( dim_I = 0; dim_I < 2; dim_I++ ) {
+ Journal_Printf( stream, "%0.5f,", self->elLocalLength[dim_I] );
+ }
+ Journal_Printf( stream, ")\n", self );
+}
+
+void _BilinearInnerElType_AssignFromXML( void* elementType, Stg_ComponentFactory *cf, void* data ){
+}
+
+void _BilinearInnerElType_Initialise( void* elementType, void *data ){
+}
+
+void _BilinearInnerElType_Execute( void* elementType, void *data ){
+}
+
+void _BilinearInnerElType_Destroy( void* elementType, void *data ){
+ BilinearInnerElType* self = (BilinearInnerElType*)elementType;
+
+ FreeArray( self->triInds );
+
+ _ElementType_Destroy( self, data );
+}
+
+void _BilinearInnerElType_Build( void* elementType, void *data ) {
+}
+
+/*
+
+ - Shape function definitions
+ - Local node numbering convention for billinear element (xi, eta)
+ - Local coordinate domain spans -1 <= xi,eta <= 1
+
+ eta
+ |
+3-----2
+| |__|___xi
+| |
+0-----1
+
+*/
+void _BilinearInnerElType_SF_allNodes( void* elementType, const double localCoord[], double* const evaluatedValues ) {
+ double xi, eta;
+
+ xi = localCoord[0];
+ eta = localCoord[1];
+
+ evaluatedValues[0] = - xi - 0.5*eta + 0.25;
+ evaluatedValues[1] = xi - 0.5*eta + 0.25;
+ evaluatedValues[2] = eta + 0.5;
+}
+
+
+void _BilinearInnerElType_SF_allLocalDerivs_allNodes( void* elementType, const double localCoord[],
+ double** const evaluatedDerivatives )
+{
+ double xi, eta;
+
+ xi = localCoord[0];
+ eta = localCoord[1];
+
+ evaluatedDerivatives[0][0] = - 1.0;
+ evaluatedDerivatives[0][1] = 1.0;
+ evaluatedDerivatives[0][2] = 0.0;
+
+ evaluatedDerivatives[1][0] = - 0.5;
+ evaluatedDerivatives[1][1] = - 0.5;
+ evaluatedDerivatives[1][2] = 1.0;
+}
+
+int _BilinearInnerElType_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* norm ) {
+ Stream* errStream = Journal_Register( ErrorStream_Type, (Name)ElementType_Type );
+
+ Journal_Printf( errStream, "surface normal function not yet implemented for this element type.\n" );
+ assert( 0 );
+
+ norm = NULL;
+
+ return -1;
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/Biquadratic.c
--- a/Discretisation/src/Biquadratic.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Biquadratic.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <mpi.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "Discretisation.h"
-
-
-/* Textual name of this class */
-const Type Biquadratic_Type = "Biquadratic";
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-#define BIQUADRATICNODECOUNT 9
-
-Biquadratic* Biquadratic_New( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(Biquadratic);
- Type type = Biquadratic_Type;
- Stg_Class_DeleteFunction* _delete = _Biquadratic_Delete;
- Stg_Class_PrintFunction* _print = _Biquadratic_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_Biquadratic_New;
- Stg_Component_ConstructFunction* _construct = _Biquadratic_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Biquadratic_Build;
- Stg_Component_InitialiseFunction* _initialise = _Biquadratic_Initialise;
- Stg_Component_ExecuteFunction* _execute = _Biquadratic_Execute;
- Stg_Component_DestroyFunction* _destroy = _Biquadratic_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = Biquadratic_EvalBasis;
- ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = Biquadratic_EvalLocalDerivs;
- ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
- ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = Biquadratic_JacobianDeterminantSurface;
- ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
-
- return _Biquadratic_New( BIQUADRATIC_PASSARGS );
-}
-
-Biquadratic* _Biquadratic_New( BIQUADRATIC_DEFARGS ) {
- Biquadratic* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(Biquadratic) );
- self = (Biquadratic*)_ElementType_New( ELEMENTTYPE_PASSARGS );
-
- /* Virtual info */
-
- /* Biquadratic info */
- self->isConstructed = True;
- _ElementType_Init( (ElementType*)self, BIQUADRATICNODECOUNT );
- _Biquadratic_Init( self );
-
- return self;
-}
-
-void _Biquadratic_Init( Biquadratic* self ) {
- assert( self && Stg_CheckType( self, Biquadratic ) );
-
- self->dim = 2;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _Biquadratic_Delete( void* elementType ) {
- Biquadratic* self = (Biquadratic*)elementType;
-
- /* Delete the parent. */
- _ElementType_Delete( self );
-}
-
-void _Biquadratic_Print( void* elementType, Stream* stream ) {
- Biquadratic* self = (Biquadratic*)elementType;
-
- /* Set the Journal for printing informations */
- Stream* elementTypeStream;
- elementTypeStream = Journal_Register( InfoStream_Type, (Name)"BiquadraticStream" );
-
- /* Print parent */
- Journal_Printf( stream, "Biquadratic (ptr): (%p)\n", self );
- _ElementType_Print( self, stream );
-}
-
-void _Biquadratic_AssignFromXML( void* elementType, Stg_ComponentFactory* cf, void* data ) {
-}
-
-void _Biquadratic_Build( void* elementType, void* data ) {
-}
-
-void _Biquadratic_Initialise( void* elementType, void* data ) {
- Biquadratic* self = (Biquadratic*)elementType;
-
- self->faceNodes = Memory_Alloc_2DArray( unsigned, 4, 3, (Name)"node indices for element faces" );
-
- self->faceNodes[0][0] = 0; self->faceNodes[0][1] = 1; self->faceNodes[0][2] = 2;
- self->faceNodes[1][0] = 6; self->faceNodes[1][1] = 7; self->faceNodes[1][2] = 8;
- self->faceNodes[2][0] = 0; self->faceNodes[2][1] = 3; self->faceNodes[2][2] = 6;
- self->faceNodes[3][0] = 2; self->faceNodes[3][1] = 5; self->faceNodes[3][2] = 8;
-
- self->evaluatedShapeFunc = Memory_Alloc_Array( double, self->nodeCount, "evaluatedShapeFuncs" );
- self->GNi = Memory_Alloc_2DArray( double, self->dim, self->nodeCount, (Name)"localShapeFuncDerivatives" );
-}
-
-void _Biquadratic_Execute( void* elementType, void* data ) {
-}
-
-void _Biquadratic_Destroy( void* elementType, void* data ) {
- Biquadratic* self = (Biquadratic*)elementType;
-
- Memory_Free( self->faceNodes );
- Memory_Free( self->evaluatedShapeFunc );
- Memory_Free( self->GNi );
-
- _ElementType_Destroy( elementType, data );
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-void Biquadratic_EvalBasis( void* elementType, const double* localCoord, double* basis ) {
- double xi = localCoord[0], eta = localCoord[1];
- double a0 = xi - 1.0, b0 = eta - 1.0;
- double a1 = 1.0 - xi * xi, b1 = 1.0 - eta * eta;
- double a2 = xi + 1.0, b2 = eta + 1.0;
- double m0 = 0.5 * xi;
- double m1 = 0.5 * eta;
- double m2 = 0.25 * xi * eta;
-
- basis[0] = m2 * a0 * b0;
- basis[1] = m1 * a1 * b0;
- basis[2] = m2 * a2 * b0;
-
- basis[3] = m0 * a0 * b1;
- basis[4] = a1 * b1;
- basis[5] = m0 * a2 * b1;
-
- basis[6] = m2 * a0 * b2;
- basis[7] = m1 * a1 * b2;
- basis[8] = m2 * a2 * b2;
-}
-
-void Biquadratic_EvalLocalDerivs( void* elementType, const double* localCoord, double** derivs ) {
- double xi = localCoord[0], eta = localCoord[1];
- double a0 = xi - 1.0, b0 = eta - 1.0;
- double a1 = xi + 1.0, b1 = eta + 1.0;
- double a2 = 2.0 * xi - 1.0, b2 = 2.0 * eta - 1.0;
- double a3 = 2.0 * xi + 1.0, b3 = 2.0 * eta + 1.0;
- double a4 = 1.0 - xi * xi, b4 = 1.0 - eta * eta;
- double m0 = 0.25 * xi;
- double m1 = 0.25 * eta;
- double m2 = -xi * eta;
-
- /* Corner nodes. */
- derivs[0][0] = m1 * a2 * b0;
- derivs[0][2] = m1 * a3 * b0;
- derivs[0][6] = m1 * a2 * b1;
- derivs[0][8] = m1 * a3 * b1;
- derivs[1][0] = m0 * a0 * b2;
- derivs[1][2] = m0 * a1 * b2;
- derivs[1][6] = m0 * a0 * b3;
- derivs[1][8] = m0 * a1 * b3;
-
- /* Side nodes. */
- derivs[0][1] = m2 * b0;
- derivs[0][7] = m2 * b1;
- derivs[0][3] = 0.5 * a2 * b4;
- derivs[0][5] = 0.5 * a3 * b4;
- derivs[1][1] = 0.5 * a4 * b2;
- derivs[1][7] = 0.5 * a4 * b3;
- derivs[1][3] = m2 * a0;
- derivs[1][5] = m2 * a1;
-
- /* Center node. */
- derivs[0][4] = -2.0 * xi * b4;
- derivs[1][4] = -2.0 * eta * a4;
-}
-
-double Biquadratic_JacobianDeterminantSurface(
- void* elementType,
- void* _mesh,
- unsigned element_I,
- const double* localCoord,
- unsigned face_I,
- unsigned norm )
-{
- Biquadratic* self = (Biquadratic*) elementType;
- Mesh* mesh = (Mesh*)_mesh;
- unsigned surfaceDim = ( norm + 1 ) % 2;
- double x[3];
- double detJac;
- unsigned nodes[3];
-
- self = (Biquadratic*) elementType;
-
- ElementType_GetFaceNodes( elementType, mesh, element_I, face_I, 3, nodes );
-
- x[0] = Mesh_GetVertex( mesh, nodes[0] )[surfaceDim];
- x[1] = Mesh_GetVertex( mesh, nodes[1] )[surfaceDim];
- x[2] = Mesh_GetVertex( mesh, nodes[2] )[surfaceDim];
-
- detJac = ( localCoord[surfaceDim] - 0.5 ) * x[0] - 2.0 * localCoord[surfaceDim] * x[1] +
- ( localCoord[surfaceDim] + 0.5 ) * x[2];
-
- return fabs( detJac );
-}
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/Biquadratic.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/Biquadratic.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,251 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Biquadratic.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type Biquadratic_Type = "Biquadratic";
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+#define BIQUADRATICNODECOUNT 9
+
+Biquadratic* Biquadratic_New( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(Biquadratic);
+ Type type = Biquadratic_Type;
+ Stg_Class_DeleteFunction* _delete = _Biquadratic_Delete;
+ Stg_Class_PrintFunction* _print = _Biquadratic_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_Biquadratic_New;
+ Stg_Component_ConstructFunction* _construct = _Biquadratic_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Biquadratic_Build;
+ Stg_Component_InitialiseFunction* _initialise = _Biquadratic_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _Biquadratic_Execute;
+ Stg_Component_DestroyFunction* _destroy = _Biquadratic_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = Biquadratic_EvalBasis;
+ ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = Biquadratic_EvalLocalDerivs;
+ ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
+ ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = Biquadratic_JacobianDeterminantSurface;
+ ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
+
+ return _Biquadratic_New( BIQUADRATIC_PASSARGS );
+}
+
+Biquadratic* _Biquadratic_New( BIQUADRATIC_DEFARGS ) {
+ Biquadratic* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(Biquadratic) );
+ self = (Biquadratic*)_ElementType_New( ELEMENTTYPE_PASSARGS );
+
+ /* Virtual info */
+
+ /* Biquadratic info */
+ self->isConstructed = True;
+ _ElementType_Init( (ElementType*)self, BIQUADRATICNODECOUNT );
+ _Biquadratic_Init( self );
+
+ return self;
+}
+
+void _Biquadratic_Init( Biquadratic* self ) {
+ assert( self && Stg_CheckType( self, Biquadratic ) );
+
+ self->dim = 2;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _Biquadratic_Delete( void* elementType ) {
+ Biquadratic* self = (Biquadratic*)elementType;
+
+ /* Delete the parent. */
+ _ElementType_Delete( self );
+}
+
+void _Biquadratic_Print( void* elementType, Stream* stream ) {
+ Biquadratic* self = (Biquadratic*)elementType;
+
+ /* Set the Journal for printing informations */
+ Stream* elementTypeStream;
+ elementTypeStream = Journal_Register( InfoStream_Type, (Name)"BiquadraticStream" );
+
+ /* Print parent */
+ Journal_Printf( stream, "Biquadratic (ptr): (%p)\n", self );
+ _ElementType_Print( self, stream );
+}
+
+void _Biquadratic_AssignFromXML( void* elementType, Stg_ComponentFactory* cf, void* data ) {
+}
+
+void _Biquadratic_Build( void* elementType, void* data ) {
+}
+
+void _Biquadratic_Initialise( void* elementType, void* data ) {
+ Biquadratic* self = (Biquadratic*)elementType;
+
+ self->faceNodes = Memory_Alloc_2DArray( unsigned, 4, 3, (Name)"node indices for element faces" );
+
+ self->faceNodes[0][0] = 0; self->faceNodes[0][1] = 1; self->faceNodes[0][2] = 2;
+ self->faceNodes[1][0] = 6; self->faceNodes[1][1] = 7; self->faceNodes[1][2] = 8;
+ self->faceNodes[2][0] = 0; self->faceNodes[2][1] = 3; self->faceNodes[2][2] = 6;
+ self->faceNodes[3][0] = 2; self->faceNodes[3][1] = 5; self->faceNodes[3][2] = 8;
+
+ self->evaluatedShapeFunc = Memory_Alloc_Array( double, self->nodeCount, "evaluatedShapeFuncs" );
+ self->GNi = Memory_Alloc_2DArray( double, self->dim, self->nodeCount, (Name)"localShapeFuncDerivatives" );
+}
+
+void _Biquadratic_Execute( void* elementType, void* data ) {
+}
+
+void _Biquadratic_Destroy( void* elementType, void* data ) {
+ Biquadratic* self = (Biquadratic*)elementType;
+
+ Memory_Free( self->faceNodes );
+ Memory_Free( self->evaluatedShapeFunc );
+ Memory_Free( self->GNi );
+
+ _ElementType_Destroy( elementType, data );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+void Biquadratic_EvalBasis( void* elementType, const double* localCoord, double* basis ) {
+ double xi = localCoord[0], eta = localCoord[1];
+ double a0 = xi - 1.0, b0 = eta - 1.0;
+ double a1 = 1.0 - xi * xi, b1 = 1.0 - eta * eta;
+ double a2 = xi + 1.0, b2 = eta + 1.0;
+ double m0 = 0.5 * xi;
+ double m1 = 0.5 * eta;
+ double m2 = 0.25 * xi * eta;
+
+ basis[0] = m2 * a0 * b0;
+ basis[1] = m1 * a1 * b0;
+ basis[2] = m2 * a2 * b0;
+
+ basis[3] = m0 * a0 * b1;
+ basis[4] = a1 * b1;
+ basis[5] = m0 * a2 * b1;
+
+ basis[6] = m2 * a0 * b2;
+ basis[7] = m1 * a1 * b2;
+ basis[8] = m2 * a2 * b2;
+}
+
+void Biquadratic_EvalLocalDerivs( void* elementType, const double* localCoord, double** derivs ) {
+ double xi = localCoord[0], eta = localCoord[1];
+ double a0 = xi - 1.0, b0 = eta - 1.0;
+ double a1 = xi + 1.0, b1 = eta + 1.0;
+ double a2 = 2.0 * xi - 1.0, b2 = 2.0 * eta - 1.0;
+ double a3 = 2.0 * xi + 1.0, b3 = 2.0 * eta + 1.0;
+ double a4 = 1.0 - xi * xi, b4 = 1.0 - eta * eta;
+ double m0 = 0.25 * xi;
+ double m1 = 0.25 * eta;
+ double m2 = -xi * eta;
+
+ /* Corner nodes. */
+ derivs[0][0] = m1 * a2 * b0;
+ derivs[0][2] = m1 * a3 * b0;
+ derivs[0][6] = m1 * a2 * b1;
+ derivs[0][8] = m1 * a3 * b1;
+ derivs[1][0] = m0 * a0 * b2;
+ derivs[1][2] = m0 * a1 * b2;
+ derivs[1][6] = m0 * a0 * b3;
+ derivs[1][8] = m0 * a1 * b3;
+
+ /* Side nodes. */
+ derivs[0][1] = m2 * b0;
+ derivs[0][7] = m2 * b1;
+ derivs[0][3] = 0.5 * a2 * b4;
+ derivs[0][5] = 0.5 * a3 * b4;
+ derivs[1][1] = 0.5 * a4 * b2;
+ derivs[1][7] = 0.5 * a4 * b3;
+ derivs[1][3] = m2 * a0;
+ derivs[1][5] = m2 * a1;
+
+ /* Center node. */
+ derivs[0][4] = -2.0 * xi * b4;
+ derivs[1][4] = -2.0 * eta * a4;
+}
+
+double Biquadratic_JacobianDeterminantSurface(
+ void* elementType,
+ void* _mesh,
+ unsigned element_I,
+ const double* localCoord,
+ unsigned face_I,
+ unsigned norm )
+{
+ Biquadratic* self = (Biquadratic*) elementType;
+ Mesh* mesh = (Mesh*)_mesh;
+ unsigned surfaceDim = ( norm + 1 ) % 2;
+ double x[3];
+ double detJac;
+ unsigned nodes[3];
+
+ self = (Biquadratic*) elementType;
+
+ ElementType_GetFaceNodes( elementType, mesh, element_I, face_I, 3, nodes );
+
+ x[0] = Mesh_GetVertex( mesh, nodes[0] )[surfaceDim];
+ x[1] = Mesh_GetVertex( mesh, nodes[1] )[surfaceDim];
+ x[2] = Mesh_GetVertex( mesh, nodes[2] )[surfaceDim];
+
+ detJac = ( localCoord[surfaceDim] - 0.5 ) * x[0] - 2.0 * localCoord[surfaceDim] * x[1] +
+ ( localCoord[surfaceDim] + 0.5 ) * x[2];
+
+ return fabs( detJac );
+}
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/C0Generator.c
--- a/Discretisation/src/C0Generator.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,272 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: C0Generator.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <mpi.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "Discretisation.h"
-
-
-/* Textual name of this class */
-const Type C0Generator_Type = "C0Generator";
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-C0Generator* C0Generator_New( Name name, AbstractContext* context ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(C0Generator);
- Type type = C0Generator_Type;
- Stg_Class_DeleteFunction* _delete = _C0Generator_Delete;
- Stg_Class_PrintFunction* _print = _C0Generator_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_C0Generator_New;
- Stg_Component_ConstructFunction* _construct = _C0Generator_AssignFromXML;
- Stg_Component_BuildFunction* _build = _C0Generator_Build;
- Stg_Component_InitialiseFunction* _initialise = _C0Generator_Initialise;
- Stg_Component_ExecuteFunction* _execute = _C0Generator_Execute;
- Stg_Component_DestroyFunction* _destroy = NULL;
- AllocationType nameAllocationType = NON_GLOBAL;
- MeshGenerator_SetDimSizeFunc* setDimSizeFunc = _MeshGenerator_SetDimSize;
- MeshGenerator_GenerateFunc* generateFunc = (MeshGenerator_GenerateFunc*)C0Generator_Generate;
-
- C0Generator* self = _C0Generator_New( C0GENERATOR_PASSARGS );
-
- _MeshGenerator_Init( (MeshGenerator*)self, context );
- _C0Generator_Init( self );
-
- return self;
-}
-
-C0Generator* _C0Generator_New( C0GENERATOR_DEFARGS ) {
- C0Generator* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(C0Generator) );
- self = (C0Generator*)_MeshGenerator_New( MESHGENERATOR_PASSARGS );
-
- /* Virtual info */
-
- return self;
-}
-
-void _C0Generator_Init( C0Generator* self ) {
- assert( self && Stg_CheckType( self, C0Generator ) );
-
- self->elMesh = NULL;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _C0Generator_Delete( void* generator ) {
- C0Generator* self = (C0Generator*)generator;
-
- /* Delete the parent. */
- _MeshGenerator_Delete( self );
-}
-
-void _C0Generator_Print( void* generator, Stream* stream ) {
- C0Generator* self = (C0Generator*)generator;
-
- /* Set the Journal for printing informations */
- Stream* generatorStream;
- generatorStream = Journal_Register( InfoStream_Type, (Name)"C0GeneratorStream" );
-
- /* Print parent */
- Journal_Printf( stream, "C0Generator (ptr): (%p)\n", self );
- _MeshGenerator_Print( self, stream );
-}
-
-void _C0Generator_AssignFromXML( void* generator, Stg_ComponentFactory* cf, void* data ) {
- C0Generator* self = (C0Generator*)generator;
- Mesh* elMesh;
-
- assert( self );
- assert( cf );
-
- _MeshGenerator_AssignFromXML( self, cf, data );
-
- elMesh = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"elementMesh", Mesh, True, data );
- C0Generator_SetElementMesh( self, elMesh );
-}
-
-void _C0Generator_Build( void* generator, void* data ) {
- _MeshGenerator_Build( generator, data );
-}
-
-void _C0Generator_Initialise( void* generator, void* data ) {
- _MeshGenerator_Initialise( generator, data );
-}
-
-void _C0Generator_Execute( void* generator, void* data ) {
-}
-
-void _C0Generator_Destroy( void* generator, void* data ) {
-}
-
-void C0Generator_Generate( void* generator, void* _mesh ) {
- C0Generator* self = (C0Generator*)generator;
- FeMesh* mesh = (FeMesh*)_mesh;
- Grid** grid;
- Grid* elGrid;
-
- assert( self && Stg_CheckType( self, C0Generator ) );
- assert( mesh && Stg_CheckType( mesh, FeMesh ) );
-
- C0Generator_BuildTopology( self, mesh );
- C0Generator_BuildGeometry( self, mesh );
- C0Generator_BuildElementTypes( self, mesh );
-
- elGrid = *(Grid**)ExtensionManager_Get( self->elMesh->info, self->elMesh,
- ExtensionManager_GetHandle( self->elMesh->info, (Name)"elementGrid" ) );
- ExtensionManager_Add( mesh->info, (Name)"elementGrid", sizeof(Grid*) );
- grid = (Grid** )ExtensionManager_Get( mesh->info, mesh,
- ExtensionManager_GetHandle( mesh->info, (Name)"elementGrid" ) );
- *grid = Grid_New( );
- Grid_SetNumDims( *grid, elGrid->nDims );
- Grid_SetSizes( *grid, elGrid->sizes );
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-void C0Generator_SetElementMesh( void* generator, void* mesh ) {
- C0Generator* self = (C0Generator*)generator;
-
- assert( self && Stg_CheckType( self, C0Generator ) );
-
- self->elMesh = (Mesh*)mesh;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-void C0Generator_BuildTopology( C0Generator* self, FeMesh* mesh ) {
- Mesh* elMesh;
- MeshTopology *topo, *elTopo;
- Sync* elSync;
- unsigned nDims;
- unsigned *nIncEls, **incEls;
- unsigned nDomainEls;
- unsigned e_i;
-
- assert( self );
- assert( mesh );
-
- elMesh = self->elMesh;
- nDims = Mesh_GetDimSize( elMesh );
- elTopo = Mesh_GetTopology( elMesh );
- elSync = Mesh_GetSync( elMesh, (MeshTopology_Dim)nDims );
-
- topo = Mesh_GetTopology( mesh );
- MeshTopology_SetComm( topo, MeshTopology_GetComm( elTopo ) );
- MeshTopology_SetNumDims( topo, nDims );
- IGraph_SetDomain( topo, nDims, elSync );
- IGraph_SetDomain( topo, MT_VERTEX, elSync );
- topo->shadDepth = elTopo->shadDepth;
-
- nDomainEls = Mesh_GetDomainSize( elMesh, (MeshTopology_Dim)nDims );
- nIncEls = AllocArray( unsigned, nDomainEls );
- incEls = AllocArray2D( unsigned, nDomainEls, 1 );
- for( e_i = 0; e_i < nDomainEls; e_i++ ) {
- nIncEls[e_i] = 1;
- incEls[e_i][0] = e_i;
- IGraph_SetIncidence( topo, nDims, e_i, MT_VERTEX, nIncEls[e_i], (int*)(incEls[e_i]) );
- }
- FreeArray( nIncEls );
- FreeArray( incEls );
-
- IGraph_InvertIncidence( topo, MT_VERTEX, nDims );
-}
-
-void C0Generator_BuildGeometry( C0Generator* self, FeMesh* mesh ) {
- Mesh* elMesh;
- double *centroid, *vert;
- unsigned nDims;
- unsigned nDomainEls;
- Mesh_ElementType* elType;
- unsigned e_i;
-
- assert( self );
- assert( mesh );
-
- elMesh = self->elMesh;
- nDims = Mesh_GetDimSize( elMesh );
- nDomainEls = Mesh_GetDomainSize( elMesh, (MeshTopology_Dim)nDims );
- mesh->verts = AllocArray2D( double, nDomainEls, nDims );
- centroid = AllocArray( double, nDims );
- for( e_i = 0; e_i < nDomainEls; e_i++ ) {
- elType = Mesh_GetElementType( elMesh, e_i );
- Mesh_ElementType_GetCentroid( elType, e_i, centroid );
- vert = Mesh_GetVertex( mesh, e_i );
- memcpy( vert, centroid, nDims * sizeof(double) );
- }
- FreeArray( centroid );
-}
-
-void C0Generator_BuildElementTypes( C0Generator* self, FeMesh* mesh ) {
- unsigned nDomainEls;
- Mesh_Algorithms* algs;
- unsigned e_i;
-
- assert( self );
- assert( mesh );
-
- mesh->nElTypes = 1;
- mesh->elTypes = AllocNamedArray( Mesh_ElementType*, mesh->nElTypes, "Mesh::elTypes" );
- mesh->elTypes[0] = (Mesh_ElementType*)Mesh_CentroidType_New();
- Mesh_ElementType_SetMesh( mesh->elTypes[0], mesh );
- Mesh_CentroidType_SetElementMesh( mesh->elTypes[0], self->elMesh );
- nDomainEls = Mesh_GetDomainSize( mesh, Mesh_GetDimSize( mesh ) );
- mesh->elTypeMap = AllocNamedArray( unsigned, nDomainEls, "Mesh::elTypeMap" );
-
- for( e_i = 0; e_i < nDomainEls; e_i++ )
- mesh->elTypeMap[e_i] = 0;
-
- algs = (Mesh_Algorithms*)Mesh_CentroidAlgorithms_New( "", NULL );
- Mesh_CentroidAlgorithms_SetElementMesh( algs, self->elMesh );
- Mesh_SetAlgorithms( mesh, algs );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/C0Generator.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/C0Generator.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,272 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: C0Generator.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type C0Generator_Type = "C0Generator";
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+C0Generator* C0Generator_New( Name name, AbstractContext* context ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(C0Generator);
+ Type type = C0Generator_Type;
+ Stg_Class_DeleteFunction* _delete = _C0Generator_Delete;
+ Stg_Class_PrintFunction* _print = _C0Generator_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_C0Generator_New;
+ Stg_Component_ConstructFunction* _construct = _C0Generator_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _C0Generator_Build;
+ Stg_Component_InitialiseFunction* _initialise = _C0Generator_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _C0Generator_Execute;
+ Stg_Component_DestroyFunction* _destroy = NULL;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ MeshGenerator_SetDimSizeFunc* setDimSizeFunc = _MeshGenerator_SetDimSize;
+ MeshGenerator_GenerateFunc* generateFunc = (MeshGenerator_GenerateFunc*)C0Generator_Generate;
+
+ C0Generator* self = _C0Generator_New( C0GENERATOR_PASSARGS );
+
+ _MeshGenerator_Init( (MeshGenerator*)self, context );
+ _C0Generator_Init( self );
+
+ return self;
+}
+
+C0Generator* _C0Generator_New( C0GENERATOR_DEFARGS ) {
+ C0Generator* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(C0Generator) );
+ self = (C0Generator*)_MeshGenerator_New( MESHGENERATOR_PASSARGS );
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _C0Generator_Init( C0Generator* self ) {
+ assert( self && Stg_CheckType( self, C0Generator ) );
+
+ self->elMesh = NULL;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _C0Generator_Delete( void* generator ) {
+ C0Generator* self = (C0Generator*)generator;
+
+ /* Delete the parent. */
+ _MeshGenerator_Delete( self );
+}
+
+void _C0Generator_Print( void* generator, Stream* stream ) {
+ C0Generator* self = (C0Generator*)generator;
+
+ /* Set the Journal for printing informations */
+ Stream* generatorStream;
+ generatorStream = Journal_Register( InfoStream_Type, (Name)"C0GeneratorStream" );
+
+ /* Print parent */
+ Journal_Printf( stream, "C0Generator (ptr): (%p)\n", self );
+ _MeshGenerator_Print( self, stream );
+}
+
+void _C0Generator_AssignFromXML( void* generator, Stg_ComponentFactory* cf, void* data ) {
+ C0Generator* self = (C0Generator*)generator;
+ Mesh* elMesh;
+
+ assert( self );
+ assert( cf );
+
+ _MeshGenerator_AssignFromXML( self, cf, data );
+
+ elMesh = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"elementMesh", Mesh, True, data );
+ C0Generator_SetElementMesh( self, elMesh );
+}
+
+void _C0Generator_Build( void* generator, void* data ) {
+ _MeshGenerator_Build( generator, data );
+}
+
+void _C0Generator_Initialise( void* generator, void* data ) {
+ _MeshGenerator_Initialise( generator, data );
+}
+
+void _C0Generator_Execute( void* generator, void* data ) {
+}
+
+void _C0Generator_Destroy( void* generator, void* data ) {
+}
+
+void C0Generator_Generate( void* generator, void* _mesh ) {
+ C0Generator* self = (C0Generator*)generator;
+ FeMesh* mesh = (FeMesh*)_mesh;
+ Grid** grid;
+ Grid* elGrid;
+
+ assert( self && Stg_CheckType( self, C0Generator ) );
+ assert( mesh && Stg_CheckType( mesh, FeMesh ) );
+
+ C0Generator_BuildTopology( self, mesh );
+ C0Generator_BuildGeometry( self, mesh );
+ C0Generator_BuildElementTypes( self, mesh );
+
+ elGrid = *(Grid**)ExtensionManager_Get( self->elMesh->info, self->elMesh,
+ ExtensionManager_GetHandle( self->elMesh->info, (Name)"elementGrid" ) );
+ ExtensionManager_Add( mesh->info, (Name)"elementGrid", sizeof(Grid*) );
+ grid = (Grid** )ExtensionManager_Get( mesh->info, mesh,
+ ExtensionManager_GetHandle( mesh->info, (Name)"elementGrid" ) );
+ *grid = Grid_New( );
+ Grid_SetNumDims( *grid, elGrid->nDims );
+ Grid_SetSizes( *grid, elGrid->sizes );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+void C0Generator_SetElementMesh( void* generator, void* mesh ) {
+ C0Generator* self = (C0Generator*)generator;
+
+ assert( self && Stg_CheckType( self, C0Generator ) );
+
+ self->elMesh = (Mesh*)mesh;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+void C0Generator_BuildTopology( C0Generator* self, FeMesh* mesh ) {
+ Mesh* elMesh;
+ MeshTopology *topo, *elTopo;
+ Sync* elSync;
+ unsigned nDims;
+ unsigned *nIncEls, **incEls;
+ unsigned nDomainEls;
+ unsigned e_i;
+
+ assert( self );
+ assert( mesh );
+
+ elMesh = self->elMesh;
+ nDims = Mesh_GetDimSize( elMesh );
+ elTopo = Mesh_GetTopology( elMesh );
+ elSync = Mesh_GetSync( elMesh, (MeshTopology_Dim)nDims );
+
+ topo = Mesh_GetTopology( mesh );
+ MeshTopology_SetComm( topo, MeshTopology_GetComm( elTopo ) );
+ MeshTopology_SetNumDims( topo, nDims );
+ IGraph_SetDomain( topo, nDims, elSync );
+ IGraph_SetDomain( topo, MT_VERTEX, elSync );
+ topo->shadDepth = elTopo->shadDepth;
+
+ nDomainEls = Mesh_GetDomainSize( elMesh, (MeshTopology_Dim)nDims );
+ nIncEls = AllocArray( unsigned, nDomainEls );
+ incEls = AllocArray2D( unsigned, nDomainEls, 1 );
+ for( e_i = 0; e_i < nDomainEls; e_i++ ) {
+ nIncEls[e_i] = 1;
+ incEls[e_i][0] = e_i;
+ IGraph_SetIncidence( topo, nDims, e_i, MT_VERTEX, nIncEls[e_i], (int*)(incEls[e_i]) );
+ }
+ FreeArray( nIncEls );
+ FreeArray( incEls );
+
+ IGraph_InvertIncidence( topo, MT_VERTEX, nDims );
+}
+
+void C0Generator_BuildGeometry( C0Generator* self, FeMesh* mesh ) {
+ Mesh* elMesh;
+ double *centroid, *vert;
+ unsigned nDims;
+ unsigned nDomainEls;
+ Mesh_ElementType* elType;
+ unsigned e_i;
+
+ assert( self );
+ assert( mesh );
+
+ elMesh = self->elMesh;
+ nDims = Mesh_GetDimSize( elMesh );
+ nDomainEls = Mesh_GetDomainSize( elMesh, (MeshTopology_Dim)nDims );
+ mesh->verts = AllocArray2D( double, nDomainEls, nDims );
+ centroid = AllocArray( double, nDims );
+ for( e_i = 0; e_i < nDomainEls; e_i++ ) {
+ elType = Mesh_GetElementType( elMesh, e_i );
+ Mesh_ElementType_GetCentroid( elType, e_i, centroid );
+ vert = Mesh_GetVertex( mesh, e_i );
+ memcpy( vert, centroid, nDims * sizeof(double) );
+ }
+ FreeArray( centroid );
+}
+
+void C0Generator_BuildElementTypes( C0Generator* self, FeMesh* mesh ) {
+ unsigned nDomainEls;
+ Mesh_Algorithms* algs;
+ unsigned e_i;
+
+ assert( self );
+ assert( mesh );
+
+ mesh->nElTypes = 1;
+ mesh->elTypes = AllocNamedArray( Mesh_ElementType*, mesh->nElTypes, "Mesh::elTypes" );
+ mesh->elTypes[0] = (Mesh_ElementType*)Mesh_CentroidType_New();
+ Mesh_ElementType_SetMesh( mesh->elTypes[0], mesh );
+ Mesh_CentroidType_SetElementMesh( mesh->elTypes[0], self->elMesh );
+ nDomainEls = Mesh_GetDomainSize( mesh, Mesh_GetDimSize( mesh ) );
+ mesh->elTypeMap = AllocNamedArray( unsigned, nDomainEls, "Mesh::elTypeMap" );
+
+ for( e_i = 0; e_i < nDomainEls; e_i++ )
+ mesh->elTypeMap[e_i] = 0;
+
+ algs = (Mesh_Algorithms*)Mesh_CentroidAlgorithms_New( "", NULL );
+ Mesh_CentroidAlgorithms_SetElementMesh( algs, self->elMesh );
+ Mesh_SetAlgorithms( mesh, algs );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/C2Generator.c
--- a/Discretisation/src/C2Generator.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,508 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: C2Generator.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <mpi.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "Discretisation.h"
-
-
-/* Textual name of this class */
-const Type C2Generator_Type = "C2Generator";
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-C2Generator* C2Generator_New( Name name, AbstractContext* context ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(C2Generator);
- Type type = C2Generator_Type;
- Stg_Class_DeleteFunction* _delete = _C2Generator_Delete;
- Stg_Class_PrintFunction* _print = _C2Generator_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_C2Generator_New;
- Stg_Component_ConstructFunction* _construct = _C2Generator_AssignFromXML;
- Stg_Component_BuildFunction* _build = _C2Generator_Build;
- Stg_Component_InitialiseFunction* _initialise = _C2Generator_Initialise;
- Stg_Component_ExecuteFunction* _execute = _C2Generator_Execute;
- Stg_Component_DestroyFunction* _destroy = NULL;
- AllocationType nameAllocationType = NON_GLOBAL;
- MeshGenerator_SetDimSizeFunc* setDimSizeFunc = CartesianGenerator_SetDimSize;
- MeshGenerator_GenerateFunc* generateFunc = CartesianGenerator_Generate;
- CartesianGenerator_SetTopologyParamsFunc* setTopologyParamsFunc = C2Generator_SetTopologyParams;
- CartesianGenerator_GenElementsFunc* genElementsFunc = _CartesianGenerator_GenElements;
- CartesianGenerator_GenFacesFunc* genFacesFunc = _CartesianGenerator_GenFaces;
- CartesianGenerator_GenEdgesFunc* genEdgesFunc = _CartesianGenerator_GenEdges;
- CartesianGenerator_GenVerticesFunc* genVerticesFunc = _CartesianGenerator_GenVertices;
- CartesianGenerator_GenElementVertexIncFunc* genElementVertexIncFunc = C2Generator_GenElementVertexInc;
- CartesianGenerator_GenVolumeEdgeIncFunc* genVolumeEdgeIncFunc = _CartesianGenerator_GenVolumeEdgeInc;
- CartesianGenerator_GenVolumeFaceIncFunc* genVolumeFaceIncFunc = _CartesianGenerator_GenVolumeFaceInc;
- CartesianGenerator_GenFaceVertexIncFunc* genFaceVertexIncFunc = C2Generator_GenFaceVertexInc;
- CartesianGenerator_GenFaceEdgeIncFunc* genFaceEdgeIncFunc = _CartesianGenerator_GenFaceEdgeInc;
- CartesianGenerator_GenEdgeVertexIncFunc* genEdgeVertexIncFunc = C2Generator_GenEdgeVertexInc;
- CartesianGenerator_GenElementTypesFunc* genElementTypesFunc = C2Generator_GenElementTypes;
-
- C2Generator* self = _C2Generator_New( C2GENERATOR_PASSARGS );
-
- _MeshGenerator_Init( (MeshGenerator*)self, context );
- _CartesianGenerator_Init( (CartesianGenerator*)self );
- _C2Generator_Init( self );
- return self;
-}
-
-C2Generator* _C2Generator_New( C2GENERATOR_DEFARGS ) {
- C2Generator* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(C2Generator) );
- self = (C2Generator*)_CartesianGenerator_New( CARTESIANGENERATOR_PASSARGS );
-
-
-
- return self;
-}
-
-void _C2Generator_Init( C2Generator* self ) {
- assert( self );
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _C2Generator_Delete( void* meshGenerator ) {
- C2Generator* self = (C2Generator*)meshGenerator;
-
- /* Delete the parent. */
- _CartesianGenerator_Delete( self );
-}
-
-void _C2Generator_Print( void* meshGenerator, Stream* stream ) {
- C2Generator* self = (C2Generator*)meshGenerator;
-
- /* Set the Journal for printing informations */
- Stream* meshGeneratorStream;
- meshGeneratorStream = Journal_Register( InfoStream_Type, (Name)"C2GeneratorStream" );
-
- assert( self );
-
- /* Print parent */
- Journal_Printf( stream, "C2Generator (ptr): (%p)\n", self );
- _CartesianGenerator_Print( self, stream );
-}
-
-void _C2Generator_AssignFromXML( void* meshGenerator, Stg_ComponentFactory* cf, void* data ) {
- _CartesianGenerator_AssignFromXML( meshGenerator, cf, data );
-}
-
-void _C2Generator_Build( void* meshGenerator, void* data ) {
- _CartesianGenerator_Build( meshGenerator, data );
-}
-
-void _C2Generator_Initialise( void* meshGenerator, void* data ) {
-}
-
-void _C2Generator_Execute( void* meshGenerator, void* data ) {
-}
-
-void _C2Generator_Destroy( void* meshGenerator, void* data ) {
-}
-
-void C2Generator_SetTopologyParams( void* meshGenerator, unsigned* sizes,
- unsigned maxDecompDims, unsigned* minDecomp, unsigned* maxDecomp )
-{
- C2Generator* self = (C2Generator*)meshGenerator;
- unsigned* vertSizes;
- unsigned d_i;
-
- assert( self );
-
- _CartesianGenerator_SetTopologyParams( self, sizes,
- maxDecompDims, minDecomp, maxDecomp );
- vertSizes = AllocArray( unsigned, self->vertGrid->nDims );
- for( d_i = 0; d_i < self->vertGrid->nDims; d_i++ ) {
- vertSizes[d_i] = self->vertGrid->sizes[d_i] * 2 - 1;
- self->vertOrigin[d_i] *= 2;
- self->vertRange[d_i] = self->vertRange[d_i] * 2 - 1;
- }
- Grid_SetSizes( self->vertGrid, vertSizes );
- FreeArray( vertSizes );
-}
-
-void C2Generator_GenElementVertexInc( void* meshGenerator, IGraph* topo, Grid*** grids ) {
- C2Generator* self = (C2Generator*)meshGenerator;
- Stream* stream = Journal_Register( Info_Type, (Name)self->type );
- unsigned* incEls;
- unsigned* dimInds;
- unsigned vertsPerEl;
- unsigned nDims;
- unsigned e_i, d_i;
- int nDomainEls;
-
- assert( self );
- assert( topo );
- assert( grids );
-
- Journal_Printf( stream, "Generating element-vertex incidence...\n" );
- Stream_Indent( stream );
-
- vertsPerEl = (topo->nDims == 1) ? 3 : (topo->nDims == 2) ? 9 : 27;
-
- nDims = topo->nDims;
- nDomainEls = Sync_GetNumDomains( IGraph_GetDomain( topo, nDims ) );
- incEls = Memory_Alloc_Array_Unnamed( unsigned, vertsPerEl );
- dimInds = Memory_Alloc_Array_Unnamed( unsigned, topo->nDims );
- for( e_i = 0; e_i < (unsigned)nDomainEls; e_i++ ) {
- unsigned gInd = Sync_DomainToGlobal( IGraph_GetDomain( topo, nDims ), e_i );
- unsigned curNode = 0;
-
- Grid_Lift( grids[topo->nDims][0], gInd, dimInds );
- for( d_i = 0; d_i < nDims; d_i++ )
- dimInds[d_i] *= 2;
-
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2;
-
- if( topo->nDims >= 2 ) {
- dimInds[1]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2;
- dimInds[1]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2;
- dimInds[1] -= 2;
-
- if( topo->nDims >= 3 ) {
- dimInds[2]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2;
- dimInds[1]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2;
- dimInds[1]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2;
- dimInds[1] -= 2;
- dimInds[2]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2;
- dimInds[1]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2;
- dimInds[1]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2;
- dimInds[1] -= 2;
- dimInds[2] -= 2;
- }
- }
- CartesianGenerator_MapToDomain( (CartesianGenerator*)self, IGraph_GetDomain( topo, 0), vertsPerEl, incEls );
- IGraph_SetIncidence( topo, topo->nDims, e_i, MT_VERTEX, vertsPerEl, (int*)incEls );
- }
-
- FreeArray( incEls );
- FreeArray( dimInds );
-
- MPI_Barrier( self->mpiComm );
- Journal_Printf( stream, "... done.\n" );
- Stream_UnIndent( stream );
-}
-
-void C2Generator_GenFaceVertexInc( void* meshGenerator, IGraph* topo, Grid*** grids ) {
- C2Generator* self = (C2Generator*)meshGenerator;
- Stream* stream;
- unsigned face_i;
- unsigned gFace;
- unsigned verts[9];
- unsigned* dimInds = Memory_Alloc_Array( unsigned, topo->nDims, "edgeDimensionIndices" );
-
- stream = Journal_Register( Info_Type, (Name)self->type );
- Journal_Printf( stream, "Generating face-vertex types...\n" );
- Stream_Indent( stream );
-
- for( face_i = 0; face_i < (unsigned)(topo->remotes[MT_FACE]->nDomains); face_i++ ) {
- gFace = Sync_DomainToGlobal( topo->remotes[MT_FACE], face_i );
-
- if( gFace < grids[2][0]->nPoints ) {
- Grid_Lift( grids[2][0], gFace, dimInds );
-
- dimInds[0] *= 2;
- dimInds[1] *= 2;
- if( topo->nDims == 3 )
- dimInds[2] *= 2;
-
- verts[0] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[1] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[2] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2; dimInds[1]++;
- verts[3] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[4] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[5] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2; dimInds[1]++;
- verts[6] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[7] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[8] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2; dimInds[1] -= 2;
- }
- else if( topo->nDims == 3 && gFace < grids[2][0]->nPoints + grids[2][1]->nPoints ) {
- Grid_Lift( grids[2][1], gFace - grids[2][0]->nPoints, dimInds );
-
- dimInds[0] *= 2;
- dimInds[1] *= 2;
- if( topo->nDims == 3 )
- dimInds[2] *= 2;
-
- verts[0] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[1] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[2] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2; dimInds[2]++;
- verts[3] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[4] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[5] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2; dimInds[2]++;
- verts[6] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[7] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[8] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2; dimInds[2] -= 2;
- }
- else if( topo->nDims == 3 && gFace < grids[2][0]->nPoints + grids[2][1]->nPoints + grids[2][2]->nPoints ) {
- Grid_Lift( grids[2][2], gFace - grids[2][0]->nPoints - grids[2][1]->nPoints, dimInds );
-
- dimInds[0] *= 2;
- dimInds[1] *= 2;
- if( topo->nDims == 3 )
- dimInds[2] *= 2;
-
- verts[0] = Grid_Project( grids[0][0], dimInds );
- dimInds[1]++;
- verts[1] = Grid_Project( grids[0][0], dimInds );
- dimInds[1]++;
- verts[2] = Grid_Project( grids[0][0], dimInds );
- dimInds[1] -= 2; dimInds[2]++;
- verts[3] = Grid_Project( grids[0][0], dimInds );
- dimInds[1]++;
- verts[4] = Grid_Project( grids[0][0], dimInds );
- dimInds[1]++;
- verts[5] = Grid_Project( grids[0][0], dimInds );
- dimInds[1] -= 2; dimInds[2]++;
- verts[6] = Grid_Project( grids[0][0], dimInds );
- dimInds[1]++;
- verts[7] = Grid_Project( grids[0][0], dimInds );
- dimInds[1]++;
- verts[8] = Grid_Project( grids[0][0], dimInds );
- dimInds[1] -= 2; dimInds[2] -= 2;
- }
-
- CartesianGenerator_MapToDomain( (CartesianGenerator*)self, (Sync*)IGraph_GetDomain( topo, MT_VERTEX ), 9, verts );
- IGraph_SetIncidence( topo, MT_FACE, face_i, MT_VERTEX, 9, (int*)verts );
- }
-
- Memory_Free( dimInds );
-
- MPI_Barrier( self->mpiComm );
-
- Journal_Printf( stream, "... done.\n" );
- Stream_UnIndent( stream );
-}
-
-void C2Generator_GenEdgeVertexInc( void* meshGenerator, IGraph* topo, Grid*** grids ) {
- C2Generator* self = (C2Generator*)meshGenerator;
- const Sync* sync = IGraph_GetDomain( topo, MT_EDGE );
- Stream* stream;
- unsigned edge_i;
- unsigned gEdge;
- unsigned verts[3];
- unsigned* dimInds = Memory_Alloc_Array( unsigned, topo->nDims, "edgeDimensionIndices" );
-
- stream = Journal_Register( Info_Type, (Name)self->type );
- Journal_Printf( stream, "Generating edge-vertex incidence...\n" );
- Stream_Indent( stream );
-
- for( edge_i = 0; edge_i < (unsigned)Sync_GetNumDomains( sync ); edge_i++ ) {
- gEdge = Sync_DomainToGlobal( sync, edge_i );
-
- if( gEdge < grids[1][0]->nPoints ) {
- Grid_Lift( grids[1][0], gEdge, dimInds );
-
- dimInds[0] *= 2;
- dimInds[1] *= 2;
- if( topo->nDims == 3 )
- dimInds[2] *= 2;
-
- verts[0] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[1] = Grid_Project( grids[0][0], dimInds );
- dimInds[0]++;
- verts[2] = Grid_Project( grids[0][0], dimInds );
- dimInds[0] -= 2;
- }
- else if( gEdge < grids[1][0]->nPoints + grids[1][1]->nPoints ) {
- Grid_Lift( grids[1][1], gEdge - grids[1][0]->nPoints, dimInds );
-
- dimInds[0] *= 2;
- dimInds[1] *= 2;
- if( topo->nDims == 3 )
- dimInds[2] *= 2;
-
- verts[0] = Grid_Project( grids[0][0], dimInds );
- dimInds[1]++;
- verts[1] = Grid_Project( grids[0][0], dimInds );
- dimInds[1]++;
- verts[2] = Grid_Project( grids[0][0], dimInds );
- dimInds[1] -= 2;
- }
- else if( topo->nDims == 3 && gEdge < grids[1][0]->nPoints + grids[1][1]->nPoints + grids[1][2]->nPoints ) {
- Grid_Lift( grids[1][2], gEdge - grids[1][0]->nPoints - grids[1][1]->nPoints, dimInds );
-
- dimInds[0] *= 2;
- dimInds[1] *= 2;
- if( topo->nDims == 3 )
- dimInds[2] *= 2;
-
- verts[0] = Grid_Project( grids[0][0], dimInds );
- dimInds[2]++;
- verts[1] = Grid_Project( grids[0][0], dimInds );
- dimInds[2]++;
- verts[2] = Grid_Project( grids[0][0], dimInds );
- dimInds[2] -= 2;
- }
-
- CartesianGenerator_MapToDomain( (CartesianGenerator*)self, (Sync*)IGraph_GetDomain( topo, MT_VERTEX ), 3, verts );
- IGraph_SetIncidence( topo, MT_EDGE, edge_i, MT_VERTEX, 3, (int*)verts );
- }
-
- Memory_Free( dimInds );
-
- MPI_Barrier( self->mpiComm );
-
- Journal_Printf( stream, "... done.\n" );
- Stream_UnIndent( stream );
-}
-
-void C2Generator_GenElementTypes( void* meshGenerator, Mesh* mesh ) {
- C2Generator* self = (C2Generator*)meshGenerator;
- Stream* stream;
- unsigned nDomainEls;
- unsigned vertMap[8] = {0, 2, 6, 8, 18, 20, 24, 26};
- unsigned e_i;
-
- assert( self );
-
- stream = Journal_Register( Info_Type, (Name)self->type );
- Journal_Printf( stream, "Generating element types...\n" );
- Stream_Indent( stream );
-
- mesh->nElTypes = 1;
- mesh->elTypes = AllocArray( Mesh_ElementType*, mesh->nElTypes );
- mesh->elTypes[0] = (Mesh_ElementType*)Mesh_HexType_New();
- Mesh_ElementType_SetMesh( mesh->elTypes[0], mesh );
- Mesh_HexType_SetVertexMap( mesh->elTypes[0], vertMap );
- nDomainEls = Mesh_GetDomainSize( mesh, Mesh_GetDimSize( mesh ) );
- mesh->elTypeMap = AllocArray( unsigned, nDomainEls );
- for( e_i = 0; e_i < nDomainEls; e_i++ )
- mesh->elTypeMap[e_i] = 0;
-
- if( self->regular )
- Mesh_SetAlgorithms( mesh, Mesh_RegularAlgorithms_New( "", NULL ) );
-
- MPI_Barrier( self->mpiComm );
- Journal_Printf( stream, "... element types are '%s',\n", mesh->elTypes[0]->type );
- Journal_Printf( stream, "... mesh algorithm type is '%s',\n", mesh->algorithms->type );
- Journal_Printf( stream, "... done.\n" );
- Stream_UnIndent( stream );
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/C2Generator.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/C2Generator.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,508 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: C2Generator.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type C2Generator_Type = "C2Generator";
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+C2Generator* C2Generator_New( Name name, AbstractContext* context ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(C2Generator);
+ Type type = C2Generator_Type;
+ Stg_Class_DeleteFunction* _delete = _C2Generator_Delete;
+ Stg_Class_PrintFunction* _print = _C2Generator_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_C2Generator_New;
+ Stg_Component_ConstructFunction* _construct = _C2Generator_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _C2Generator_Build;
+ Stg_Component_InitialiseFunction* _initialise = _C2Generator_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _C2Generator_Execute;
+ Stg_Component_DestroyFunction* _destroy = NULL;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ MeshGenerator_SetDimSizeFunc* setDimSizeFunc = CartesianGenerator_SetDimSize;
+ MeshGenerator_GenerateFunc* generateFunc = CartesianGenerator_Generate;
+ CartesianGenerator_SetTopologyParamsFunc* setTopologyParamsFunc = C2Generator_SetTopologyParams;
+ CartesianGenerator_GenElementsFunc* genElementsFunc = _CartesianGenerator_GenElements;
+ CartesianGenerator_GenFacesFunc* genFacesFunc = _CartesianGenerator_GenFaces;
+ CartesianGenerator_GenEdgesFunc* genEdgesFunc = _CartesianGenerator_GenEdges;
+ CartesianGenerator_GenVerticesFunc* genVerticesFunc = _CartesianGenerator_GenVertices;
+ CartesianGenerator_GenElementVertexIncFunc* genElementVertexIncFunc = C2Generator_GenElementVertexInc;
+ CartesianGenerator_GenVolumeEdgeIncFunc* genVolumeEdgeIncFunc = _CartesianGenerator_GenVolumeEdgeInc;
+ CartesianGenerator_GenVolumeFaceIncFunc* genVolumeFaceIncFunc = _CartesianGenerator_GenVolumeFaceInc;
+ CartesianGenerator_GenFaceVertexIncFunc* genFaceVertexIncFunc = C2Generator_GenFaceVertexInc;
+ CartesianGenerator_GenFaceEdgeIncFunc* genFaceEdgeIncFunc = _CartesianGenerator_GenFaceEdgeInc;
+ CartesianGenerator_GenEdgeVertexIncFunc* genEdgeVertexIncFunc = C2Generator_GenEdgeVertexInc;
+ CartesianGenerator_GenElementTypesFunc* genElementTypesFunc = C2Generator_GenElementTypes;
+
+ C2Generator* self = _C2Generator_New( C2GENERATOR_PASSARGS );
+
+ _MeshGenerator_Init( (MeshGenerator*)self, context );
+ _CartesianGenerator_Init( (CartesianGenerator*)self );
+ _C2Generator_Init( self );
+ return self;
+}
+
+C2Generator* _C2Generator_New( C2GENERATOR_DEFARGS ) {
+ C2Generator* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(C2Generator) );
+ self = (C2Generator*)_CartesianGenerator_New( CARTESIANGENERATOR_PASSARGS );
+
+
+
+ return self;
+}
+
+void _C2Generator_Init( C2Generator* self ) {
+ assert( self );
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _C2Generator_Delete( void* meshGenerator ) {
+ C2Generator* self = (C2Generator*)meshGenerator;
+
+ /* Delete the parent. */
+ _CartesianGenerator_Delete( self );
+}
+
+void _C2Generator_Print( void* meshGenerator, Stream* stream ) {
+ C2Generator* self = (C2Generator*)meshGenerator;
+
+ /* Set the Journal for printing informations */
+ Stream* meshGeneratorStream;
+ meshGeneratorStream = Journal_Register( InfoStream_Type, (Name)"C2GeneratorStream" );
+
+ assert( self );
+
+ /* Print parent */
+ Journal_Printf( stream, "C2Generator (ptr): (%p)\n", self );
+ _CartesianGenerator_Print( self, stream );
+}
+
+void _C2Generator_AssignFromXML( void* meshGenerator, Stg_ComponentFactory* cf, void* data ) {
+ _CartesianGenerator_AssignFromXML( meshGenerator, cf, data );
+}
+
+void _C2Generator_Build( void* meshGenerator, void* data ) {
+ _CartesianGenerator_Build( meshGenerator, data );
+}
+
+void _C2Generator_Initialise( void* meshGenerator, void* data ) {
+}
+
+void _C2Generator_Execute( void* meshGenerator, void* data ) {
+}
+
+void _C2Generator_Destroy( void* meshGenerator, void* data ) {
+}
+
+void C2Generator_SetTopologyParams( void* meshGenerator, unsigned* sizes,
+ unsigned maxDecompDims, unsigned* minDecomp, unsigned* maxDecomp )
+{
+ C2Generator* self = (C2Generator*)meshGenerator;
+ unsigned* vertSizes;
+ unsigned d_i;
+
+ assert( self );
+
+ _CartesianGenerator_SetTopologyParams( self, sizes,
+ maxDecompDims, minDecomp, maxDecomp );
+ vertSizes = AllocArray( unsigned, self->vertGrid->nDims );
+ for( d_i = 0; d_i < self->vertGrid->nDims; d_i++ ) {
+ vertSizes[d_i] = self->vertGrid->sizes[d_i] * 2 - 1;
+ self->vertOrigin[d_i] *= 2;
+ self->vertRange[d_i] = self->vertRange[d_i] * 2 - 1;
+ }
+ Grid_SetSizes( self->vertGrid, vertSizes );
+ FreeArray( vertSizes );
+}
+
+void C2Generator_GenElementVertexInc( void* meshGenerator, IGraph* topo, Grid*** grids ) {
+ C2Generator* self = (C2Generator*)meshGenerator;
+ Stream* stream = Journal_Register( Info_Type, (Name)self->type );
+ unsigned* incEls;
+ unsigned* dimInds;
+ unsigned vertsPerEl;
+ unsigned nDims;
+ unsigned e_i, d_i;
+ int nDomainEls;
+
+ assert( self );
+ assert( topo );
+ assert( grids );
+
+ Journal_Printf( stream, "Generating element-vertex incidence...\n" );
+ Stream_Indent( stream );
+
+ vertsPerEl = (topo->nDims == 1) ? 3 : (topo->nDims == 2) ? 9 : 27;
+
+ nDims = topo->nDims;
+ nDomainEls = Sync_GetNumDomains( IGraph_GetDomain( topo, nDims ) );
+ incEls = Memory_Alloc_Array_Unnamed( unsigned, vertsPerEl );
+ dimInds = Memory_Alloc_Array_Unnamed( unsigned, topo->nDims );
+ for( e_i = 0; e_i < (unsigned)nDomainEls; e_i++ ) {
+ unsigned gInd = Sync_DomainToGlobal( IGraph_GetDomain( topo, nDims ), e_i );
+ unsigned curNode = 0;
+
+ Grid_Lift( grids[topo->nDims][0], gInd, dimInds );
+ for( d_i = 0; d_i < nDims; d_i++ )
+ dimInds[d_i] *= 2;
+
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2;
+
+ if( topo->nDims >= 2 ) {
+ dimInds[1]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2;
+ dimInds[1]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2;
+ dimInds[1] -= 2;
+
+ if( topo->nDims >= 3 ) {
+ dimInds[2]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2;
+ dimInds[1]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2;
+ dimInds[1]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2;
+ dimInds[1] -= 2;
+ dimInds[2]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2;
+ dimInds[1]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2;
+ dimInds[1]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ incEls[curNode++] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2;
+ dimInds[1] -= 2;
+ dimInds[2] -= 2;
+ }
+ }
+ CartesianGenerator_MapToDomain( (CartesianGenerator*)self, IGraph_GetDomain( topo, 0), vertsPerEl, incEls );
+ IGraph_SetIncidence( topo, topo->nDims, e_i, MT_VERTEX, vertsPerEl, (int*)incEls );
+ }
+
+ FreeArray( incEls );
+ FreeArray( dimInds );
+
+ MPI_Barrier( self->mpiComm );
+ Journal_Printf( stream, "... done.\n" );
+ Stream_UnIndent( stream );
+}
+
+void C2Generator_GenFaceVertexInc( void* meshGenerator, IGraph* topo, Grid*** grids ) {
+ C2Generator* self = (C2Generator*)meshGenerator;
+ Stream* stream;
+ unsigned face_i;
+ unsigned gFace;
+ unsigned verts[9];
+ unsigned* dimInds = Memory_Alloc_Array( unsigned, topo->nDims, "edgeDimensionIndices" );
+
+ stream = Journal_Register( Info_Type, (Name)self->type );
+ Journal_Printf( stream, "Generating face-vertex types...\n" );
+ Stream_Indent( stream );
+
+ for( face_i = 0; face_i < (unsigned)(topo->remotes[MT_FACE]->nDomains); face_i++ ) {
+ gFace = Sync_DomainToGlobal( topo->remotes[MT_FACE], face_i );
+
+ if( gFace < grids[2][0]->nPoints ) {
+ Grid_Lift( grids[2][0], gFace, dimInds );
+
+ dimInds[0] *= 2;
+ dimInds[1] *= 2;
+ if( topo->nDims == 3 )
+ dimInds[2] *= 2;
+
+ verts[0] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[1] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[2] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2; dimInds[1]++;
+ verts[3] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[4] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[5] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2; dimInds[1]++;
+ verts[6] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[7] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[8] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2; dimInds[1] -= 2;
+ }
+ else if( topo->nDims == 3 && gFace < grids[2][0]->nPoints + grids[2][1]->nPoints ) {
+ Grid_Lift( grids[2][1], gFace - grids[2][0]->nPoints, dimInds );
+
+ dimInds[0] *= 2;
+ dimInds[1] *= 2;
+ if( topo->nDims == 3 )
+ dimInds[2] *= 2;
+
+ verts[0] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[1] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[2] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2; dimInds[2]++;
+ verts[3] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[4] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[5] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2; dimInds[2]++;
+ verts[6] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[7] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[8] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2; dimInds[2] -= 2;
+ }
+ else if( topo->nDims == 3 && gFace < grids[2][0]->nPoints + grids[2][1]->nPoints + grids[2][2]->nPoints ) {
+ Grid_Lift( grids[2][2], gFace - grids[2][0]->nPoints - grids[2][1]->nPoints, dimInds );
+
+ dimInds[0] *= 2;
+ dimInds[1] *= 2;
+ if( topo->nDims == 3 )
+ dimInds[2] *= 2;
+
+ verts[0] = Grid_Project( grids[0][0], dimInds );
+ dimInds[1]++;
+ verts[1] = Grid_Project( grids[0][0], dimInds );
+ dimInds[1]++;
+ verts[2] = Grid_Project( grids[0][0], dimInds );
+ dimInds[1] -= 2; dimInds[2]++;
+ verts[3] = Grid_Project( grids[0][0], dimInds );
+ dimInds[1]++;
+ verts[4] = Grid_Project( grids[0][0], dimInds );
+ dimInds[1]++;
+ verts[5] = Grid_Project( grids[0][0], dimInds );
+ dimInds[1] -= 2; dimInds[2]++;
+ verts[6] = Grid_Project( grids[0][0], dimInds );
+ dimInds[1]++;
+ verts[7] = Grid_Project( grids[0][0], dimInds );
+ dimInds[1]++;
+ verts[8] = Grid_Project( grids[0][0], dimInds );
+ dimInds[1] -= 2; dimInds[2] -= 2;
+ }
+
+ CartesianGenerator_MapToDomain( (CartesianGenerator*)self, (Sync*)IGraph_GetDomain( topo, MT_VERTEX ), 9, verts );
+ IGraph_SetIncidence( topo, MT_FACE, face_i, MT_VERTEX, 9, (int*)verts );
+ }
+
+ Memory_Free( dimInds );
+
+ MPI_Barrier( self->mpiComm );
+
+ Journal_Printf( stream, "... done.\n" );
+ Stream_UnIndent( stream );
+}
+
+void C2Generator_GenEdgeVertexInc( void* meshGenerator, IGraph* topo, Grid*** grids ) {
+ C2Generator* self = (C2Generator*)meshGenerator;
+ const Sync* sync = IGraph_GetDomain( topo, MT_EDGE );
+ Stream* stream;
+ unsigned edge_i;
+ unsigned gEdge;
+ unsigned verts[3];
+ unsigned* dimInds = Memory_Alloc_Array( unsigned, topo->nDims, "edgeDimensionIndices" );
+
+ stream = Journal_Register( Info_Type, (Name)self->type );
+ Journal_Printf( stream, "Generating edge-vertex incidence...\n" );
+ Stream_Indent( stream );
+
+ for( edge_i = 0; edge_i < (unsigned)Sync_GetNumDomains( sync ); edge_i++ ) {
+ gEdge = Sync_DomainToGlobal( sync, edge_i );
+
+ if( gEdge < grids[1][0]->nPoints ) {
+ Grid_Lift( grids[1][0], gEdge, dimInds );
+
+ dimInds[0] *= 2;
+ dimInds[1] *= 2;
+ if( topo->nDims == 3 )
+ dimInds[2] *= 2;
+
+ verts[0] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[1] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0]++;
+ verts[2] = Grid_Project( grids[0][0], dimInds );
+ dimInds[0] -= 2;
+ }
+ else if( gEdge < grids[1][0]->nPoints + grids[1][1]->nPoints ) {
+ Grid_Lift( grids[1][1], gEdge - grids[1][0]->nPoints, dimInds );
+
+ dimInds[0] *= 2;
+ dimInds[1] *= 2;
+ if( topo->nDims == 3 )
+ dimInds[2] *= 2;
+
+ verts[0] = Grid_Project( grids[0][0], dimInds );
+ dimInds[1]++;
+ verts[1] = Grid_Project( grids[0][0], dimInds );
+ dimInds[1]++;
+ verts[2] = Grid_Project( grids[0][0], dimInds );
+ dimInds[1] -= 2;
+ }
+ else if( topo->nDims == 3 && gEdge < grids[1][0]->nPoints + grids[1][1]->nPoints + grids[1][2]->nPoints ) {
+ Grid_Lift( grids[1][2], gEdge - grids[1][0]->nPoints - grids[1][1]->nPoints, dimInds );
+
+ dimInds[0] *= 2;
+ dimInds[1] *= 2;
+ if( topo->nDims == 3 )
+ dimInds[2] *= 2;
+
+ verts[0] = Grid_Project( grids[0][0], dimInds );
+ dimInds[2]++;
+ verts[1] = Grid_Project( grids[0][0], dimInds );
+ dimInds[2]++;
+ verts[2] = Grid_Project( grids[0][0], dimInds );
+ dimInds[2] -= 2;
+ }
+
+ CartesianGenerator_MapToDomain( (CartesianGenerator*)self, (Sync*)IGraph_GetDomain( topo, MT_VERTEX ), 3, verts );
+ IGraph_SetIncidence( topo, MT_EDGE, edge_i, MT_VERTEX, 3, (int*)verts );
+ }
+
+ Memory_Free( dimInds );
+
+ MPI_Barrier( self->mpiComm );
+
+ Journal_Printf( stream, "... done.\n" );
+ Stream_UnIndent( stream );
+}
+
+void C2Generator_GenElementTypes( void* meshGenerator, Mesh* mesh ) {
+ C2Generator* self = (C2Generator*)meshGenerator;
+ Stream* stream;
+ unsigned nDomainEls;
+ unsigned vertMap[8] = {0, 2, 6, 8, 18, 20, 24, 26};
+ unsigned e_i;
+
+ assert( self );
+
+ stream = Journal_Register( Info_Type, (Name)self->type );
+ Journal_Printf( stream, "Generating element types...\n" );
+ Stream_Indent( stream );
+
+ mesh->nElTypes = 1;
+ mesh->elTypes = AllocArray( Mesh_ElementType*, mesh->nElTypes );
+ mesh->elTypes[0] = (Mesh_ElementType*)Mesh_HexType_New();
+ Mesh_ElementType_SetMesh( mesh->elTypes[0], mesh );
+ Mesh_HexType_SetVertexMap( mesh->elTypes[0], vertMap );
+ nDomainEls = Mesh_GetDomainSize( mesh, Mesh_GetDimSize( mesh ) );
+ mesh->elTypeMap = AllocArray( unsigned, nDomainEls );
+ for( e_i = 0; e_i < nDomainEls; e_i++ )
+ mesh->elTypeMap[e_i] = 0;
+
+ if( self->regular )
+ Mesh_SetAlgorithms( mesh, Mesh_RegularAlgorithms_New( "", NULL ) );
+
+ MPI_Barrier( self->mpiComm );
+ Journal_Printf( stream, "... element types are '%s',\n", mesh->elTypes[0]->type );
+ Journal_Printf( stream, "... mesh algorithm type is '%s',\n", mesh->algorithms->type );
+ Journal_Printf( stream, "... done.\n" );
+ Stream_UnIndent( stream );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/ConstantElementType.c
--- a/Discretisation/src/ConstantElementType.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: ConstantElementType.c 1177 2008-07-15 01:29:58Z DavidLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "ElementType.h"
-#include "ConstantElementType.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-
-const Type ConstantElementType_Type = "ConstantElementType";
-#define _ConstantElementType_NodeCount 1
-
-ConstantElementType* ConstantElementType_New( Name name ) {
- ConstantElementType* self = (ConstantElementType*)ConstantElementType_DefaultNew( name );
-
- self->isConstructed = True;
- _ElementType_Init( (ElementType*)self, _ConstantElementType_NodeCount );
- _ConstantElementType_Init( self );
-
- return self;
-}
-
-void* ConstantElementType_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(ConstantElementType);
- Type type = ConstantElementType_Type;
- Stg_Class_DeleteFunction* _delete = _ConstantElementType_Delete;
- Stg_Class_PrintFunction* _print = _ConstantElementType_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = ConstantElementType_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _ConstantElementType_AssignFromXML;
- Stg_Component_BuildFunction* _build = _ConstantElementType_Build;
- Stg_Component_InitialiseFunction* _initialise = _ConstantElementType_Initialise;
- Stg_Component_ExecuteFunction* _execute = _ConstantElementType_Execute;
- Stg_Component_DestroyFunction* _destroy = _ConstantElementType_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _ConstantElementType_SF_allNodes;
- ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _ConstantElementType_SF_allLocalDerivs_allNodes;
- ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ConstantElementType_ConvertGlobalCoordToElLocal;
- ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _ElementType_JacobianDeterminantSurface;
- ElementType_SurfaceNormalFunction* _surfaceNormal = _ConstantElementType_SurfaceNormal;
-
- return _ConstantElementType_New( CONSTANTELEMENTTYPE_PASSARGS );
-}
-
-ConstantElementType* _ConstantElementType_New( CONSTANTELEMENTTYPE_DEFARGS ) {
- ConstantElementType* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(ConstantElementType) );
- self = (ConstantElementType*)_ElementType_New( ELEMENTTYPE_PASSARGS );
-
- /* General info */
-
- /* Virtual functions */
-
- /* ConstantElementType info */
-
- return self;
-}
-
-void _ConstantElementType_Init( ConstantElementType* self ) {
- self->dim = 0;
-}
-
-void _ConstantElementType_Delete( void* elementType ) {
- ConstantElementType* self = (ConstantElementType*)elementType;
-
- /* Stg_Class_Delete parent*/
- _ElementType_Delete( self );
-}
-
-void _ConstantElementType_Print( void* elementType, Stream* stream ) {
- ConstantElementType* self = (ConstantElementType*)elementType;
-
- /* Set the Journal for printing informations */
- Stream* constantElementTypeStream = stream;
-
- /* General info */
- Journal_Printf( constantElementTypeStream, "ConstantElementType (ptr): %p\n", self );
-
- /* Print parent */
- _ElementType_Print( self, constantElementTypeStream );
-
- /* Virtual info */
-
- /* ConstantElementType info */
-}
-
-void _ConstantElementType_AssignFromXML( void* elementType, Stg_ComponentFactory *cf, void* data ){
- ConstantElementType* self = (ConstantElementType*)elementType;
-
- _ConstantElementType_Init( self );
-}
-
-void _ConstantElementType_Initialise( void* elementType, void *data ){
-}
-
-void _ConstantElementType_Execute( void* elementType, void *data ){
-}
-
-void _ConstantElementType_Destroy( void* elementType, void *data ){
- ConstantElementType* self = (ConstantElementType*)elementType;
-
- _ElementType_Destroy( self, data );
-}
-
-void _ConstantElementType_Build( void* elementType, void *data ) {
-
-}
-
-/*
-
- - Shape function definition
- - Constant shape function in 2d/3d has only one node at centroid of element.
- - Node id is 0 in both cases.
- - Local coordinate domain spans -1 <= xi,eta <= 1 in 2d
- - Local coordinate domain spans -1 <= xi,eta,zeta <= 1 in 3d
-
-*/
-void _ConstantElementType_SF_allNodes( void* elementType, const double localCoord[], double* const evaluatedValues ) {
- evaluatedValues[0] = 1.0;
-}
-
-
-/*
-Since we use only have one constant shape func for 2d and 3d quads, then
-if we want to return the zero derivatives we need to pass in "dim" so we know
-whether to fill in GNi[0][0] = GNi[1][0] = 0.0 + GNi[2][0] = 0.0 if dim == 3
-Should just return error if we try to take deriv of constant. No one would want
-to do this!
-*/
-void _ConstantElementType_SF_allLocalDerivs_allNodes( void* elementType, const double localCoord[],
- double** const evaluatedDerivatives )
-{
- Stream* error = Journal_Register( ErrorStream_Type, (Name)ConstantElementType_Type );
- /* all derivatives are zero*/
- Journal_Printf( error, "Error: Trying take derivative of a constant shape function \n" );
- assert( 0 );
-}
-
-
-void _ConstantElementType_ConvertGlobalCoordToElLocal(
- void* elementType,
- void* mesh,
- unsigned element,
- const double* globalCoord,
- double* elLocalCoord )
-{
- /* See header file function introduction for explanation... */
- elLocalCoord[0] = elLocalCoord[1] = elLocalCoord[2] = 0;
-}
-
-int _ConstantElementType_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* normal ) {
- Stream* errStream = Journal_Register( ErrorStream_Type, (Name)ElementType_Type );
-
- Journal_Printf( errStream, "surface normal not defined for this element type.\n" );
- assert( 0 );
-
- normal = NULL;
-
- return -1;
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/ConstantElementType.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/ConstantElementType.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,210 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: ConstantElementType.c 1177 2008-07-15 01:29:58Z DavidLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "ElementType.h"
+#include "ConstantElementType.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+const Type ConstantElementType_Type = "ConstantElementType";
+#define _ConstantElementType_NodeCount 1
+
+ConstantElementType* ConstantElementType_New( Name name ) {
+ ConstantElementType* self = (ConstantElementType*)ConstantElementType_DefaultNew( name );
+
+ self->isConstructed = True;
+ _ElementType_Init( (ElementType*)self, _ConstantElementType_NodeCount );
+ _ConstantElementType_Init( self );
+
+ return self;
+}
+
+void* ConstantElementType_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(ConstantElementType);
+ Type type = ConstantElementType_Type;
+ Stg_Class_DeleteFunction* _delete = _ConstantElementType_Delete;
+ Stg_Class_PrintFunction* _print = _ConstantElementType_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = ConstantElementType_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _ConstantElementType_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _ConstantElementType_Build;
+ Stg_Component_InitialiseFunction* _initialise = _ConstantElementType_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _ConstantElementType_Execute;
+ Stg_Component_DestroyFunction* _destroy = _ConstantElementType_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _ConstantElementType_SF_allNodes;
+ ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _ConstantElementType_SF_allLocalDerivs_allNodes;
+ ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ConstantElementType_ConvertGlobalCoordToElLocal;
+ ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _ElementType_JacobianDeterminantSurface;
+ ElementType_SurfaceNormalFunction* _surfaceNormal = _ConstantElementType_SurfaceNormal;
+
+ return _ConstantElementType_New( CONSTANTELEMENTTYPE_PASSARGS );
+}
+
+ConstantElementType* _ConstantElementType_New( CONSTANTELEMENTTYPE_DEFARGS ) {
+ ConstantElementType* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(ConstantElementType) );
+ self = (ConstantElementType*)_ElementType_New( ELEMENTTYPE_PASSARGS );
+
+ /* General info */
+
+ /* Virtual functions */
+
+ /* ConstantElementType info */
+
+ return self;
+}
+
+void _ConstantElementType_Init( ConstantElementType* self ) {
+ self->dim = 0;
+}
+
+void _ConstantElementType_Delete( void* elementType ) {
+ ConstantElementType* self = (ConstantElementType*)elementType;
+
+ /* Stg_Class_Delete parent*/
+ _ElementType_Delete( self );
+}
+
+void _ConstantElementType_Print( void* elementType, Stream* stream ) {
+ ConstantElementType* self = (ConstantElementType*)elementType;
+
+ /* Set the Journal for printing informations */
+ Stream* constantElementTypeStream = stream;
+
+ /* General info */
+ Journal_Printf( constantElementTypeStream, "ConstantElementType (ptr): %p\n", self );
+
+ /* Print parent */
+ _ElementType_Print( self, constantElementTypeStream );
+
+ /* Virtual info */
+
+ /* ConstantElementType info */
+}
+
+void _ConstantElementType_AssignFromXML( void* elementType, Stg_ComponentFactory *cf, void* data ){
+ ConstantElementType* self = (ConstantElementType*)elementType;
+
+ _ConstantElementType_Init( self );
+}
+
+void _ConstantElementType_Initialise( void* elementType, void *data ){
+}
+
+void _ConstantElementType_Execute( void* elementType, void *data ){
+}
+
+void _ConstantElementType_Destroy( void* elementType, void *data ){
+ ConstantElementType* self = (ConstantElementType*)elementType;
+
+ _ElementType_Destroy( self, data );
+}
+
+void _ConstantElementType_Build( void* elementType, void *data ) {
+
+}
+
+/*
+
+ - Shape function definition
+ - Constant shape function in 2d/3d has only one node at centroid of element.
+ - Node id is 0 in both cases.
+ - Local coordinate domain spans -1 <= xi,eta <= 1 in 2d
+ - Local coordinate domain spans -1 <= xi,eta,zeta <= 1 in 3d
+
+*/
+void _ConstantElementType_SF_allNodes( void* elementType, const double localCoord[], double* const evaluatedValues ) {
+ evaluatedValues[0] = 1.0;
+}
+
+
+/*
+Since we use only have one constant shape func for 2d and 3d quads, then
+if we want to return the zero derivatives we need to pass in "dim" so we know
+whether to fill in GNi[0][0] = GNi[1][0] = 0.0 + GNi[2][0] = 0.0 if dim == 3
+Should just return error if we try to take deriv of constant. No one would want
+to do this!
+*/
+void _ConstantElementType_SF_allLocalDerivs_allNodes( void* elementType, const double localCoord[],
+ double** const evaluatedDerivatives )
+{
+ Stream* error = Journal_Register( ErrorStream_Type, (Name)ConstantElementType_Type );
+ /* all derivatives are zero*/
+ Journal_Printf( error, "Error: Trying take derivative of a constant shape function \n" );
+ assert( 0 );
+}
+
+
+void _ConstantElementType_ConvertGlobalCoordToElLocal(
+ void* elementType,
+ void* mesh,
+ unsigned element,
+ const double* globalCoord,
+ double* elLocalCoord )
+{
+ /* See header file function introduction for explanation... */
+ elLocalCoord[0] = elLocalCoord[1] = elLocalCoord[2] = 0;
+}
+
+int _ConstantElementType_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* normal ) {
+ Stream* errStream = Journal_Register( ErrorStream_Type, (Name)ElementType_Type );
+
+ Journal_Printf( errStream, "surface normal not defined for this element type.\n" );
+ assert( 0 );
+
+ normal = NULL;
+
+ return -1;
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/Element.c
--- a/Discretisation/src/Element.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Element.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "Element.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-void FiniteElement_Element_Print( void* element, Stream* stream ) {
- FiniteElement_Element* self = (FiniteElement_Element*)element;
-
- Journal_Printf( stream, "FiniteElement_Element (ptr): %p\n", self );
- Journal_Printf( stream, "\telementType_I: %u", self->elementType_I );
- Journal_Printf( stream, "\tcell_I: %u", self->cell_I );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/Element.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/Element.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,62 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Element.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "Element.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+void FiniteElement_Element_Print( void* element, Stream* stream ) {
+ FiniteElement_Element* self = (FiniteElement_Element*)element;
+
+ Journal_Printf( stream, "FiniteElement_Element (ptr): %p\n", self );
+ Journal_Printf( stream, "\telementType_I: %u", self->elementType_I );
+ Journal_Printf( stream, "\tcell_I: %u", self->cell_I );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/ElementType.c
--- a/Discretisation/src/ElementType.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,633 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: ElementType.c 1179 2008-07-15 05:28:11Z DavidLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "FeMesh.h"
-#include "ElementType.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-
-const Type ElementType_Type = "ElementType";
-
-ElementType* _ElementType_New( ELEMENTTYPE_DEFARGS ) {
- ElementType* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(ElementType) );
- self = (ElementType*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- /* General info */
-
- /* Virtual functions */
- self->_build = _build;
- self->_evaluateShapeFunctionsAt = _evaluateShapeFunctionsAt;
- self->_evaluateShapeFunctionLocalDerivsAt = _evaluateShapeFunctionLocalDerivsAt;
- self->_convertGlobalCoordToElLocal = _convertGlobalCoordToElLocal;
- self->_jacobianDeterminantSurface = _jacobianDeterminantSurface;
- self->_surfaceNormal = _surfaceNormal;
-
- /* ElementType info */
-
- return self;
-}
-
-void _ElementType_Init( ElementType* self, Index nodeCount ) {
- /* General and Virtual info should already be set */
- self->dim = 0;
- /* ElementType info */
- self->nodeCount = nodeCount;
- self->debug = Stream_RegisterChild( StgFEM_Discretisation_Debug, ElementType_Type );
- self->inc = IArray_New();
-}
-
-
-void _ElementType_Destroy( void* elementType, void* data ){
- ElementType* self = (ElementType*)elementType;
-
- NewClass_Delete( self->inc );
-
- Stg_Component_Destroy( self, data, False );
-}
-
-void _ElementType_Delete( void* elementType ) {
- ElementType* self = (ElementType*)elementType;
-
- /* Stg_Class_Delete parent*/
- _Stg_Component_Delete( self );
-}
-
-void _ElementType_Print( void* elementType, Stream* stream ) {
- ElementType* self = (ElementType*)elementType;
-
- /* Set the Journal for printing informations */
- Stream* elementTypeStream = stream;
-
- /* General info */
- Journal_Printf( elementTypeStream, "ElementType (ptr): %p\n", self );
-
- /* Print parent */
- _Stg_Class_Print( self, elementTypeStream );
-
- /* Virtual info */
- Journal_Printf( elementTypeStream, "\t_build (func ptr): %p\n", self->_build );
- Journal_Printf( elementTypeStream, "\t_evaluateShapeFunctionsAt (func ptr): %p\n", self->_evaluateShapeFunctionsAt );
- Journal_Printf( elementTypeStream, "\t_evaluateShapeFunctionLocalDerivsAt (func ptr): %p\n", self->_evaluateShapeFunctionLocalDerivsAt );
-
- /* ElementType info */
- Journal_Printf( elementTypeStream, "\tnodeCount: %u\n", self->nodeCount );
-}
-
-/* +++ Virtual Function Interfaces +++ */
-
-void ElementType_Build( void* elementType, void *data ) {
- ElementType* self = (ElementType*)elementType;
-
- /* ElementType's are implemented NOT in the standard parent child
- * manner as the rest of StGermain. Here the parents calls the child's
- * build function */
- self->_build( self, data);
-}
-
-void ElementType_EvaluateShapeFunctionsAt( void* elementType, const double localCoord[], double* const evaluatedValues ) {
- ElementType* self = (ElementType*)elementType;
-
- self->_evaluateShapeFunctionsAt( self, localCoord, evaluatedValues );
-}
-
-void ElementType_EvaluateShapeFunctionLocalDerivsAt( void* elementType, const double localCoord[], double** const evaluatedDerivatives ) {
- ElementType* self = (ElementType*)elementType;
-
- self->_evaluateShapeFunctionLocalDerivsAt( self, localCoord, evaluatedDerivatives );
-}
-
-double _ElementType_JacobianDeterminantSurface( void* elementType, void* mesh, unsigned element_I, const double localCoord[],
- unsigned face_I, unsigned norm )
-{
- ElementType* self;
- Stream* error = Journal_Register( ErrorStream_Type, (Name)ElementType_Type );
-
- self = (ElementType* ) elementType;
-
- Journal_Printf( error, "Error: the jacobian for this element type cannot be evaluated on the element surface" );
- Journal_Printf( error, "(perhaps because the nodes are defined internally for the element).\n" );
- assert( 0 );
-
- return -1;
-}
-
-double ElementType_JacobianDeterminantSurface( void* elementType, void* mesh, unsigned element_I,
- const double localCoord[], unsigned face_I, unsigned norm ) {
- ElementType* self = (ElementType*)elementType;
-
- return self->_jacobianDeterminantSurface( self, mesh, element_I, localCoord, face_I, norm );
-}
-
-#define EPS 1.0E-6
-
-int _ElementType_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* normal ) {
- ElementType* self;
-
- self = (ElementType*)elementType;
-
- memset( normal, 0, sizeof(double) * dim );
-
- if( xi[J_AXIS] < -1.0 + EPS ) {
- normal[J_AXIS] = -1.0;
- return 0;
- }
- else if( xi[J_AXIS] > +1.0 - EPS ) {
- normal[J_AXIS] = +1.0;
- return 1;
- }
- else if( xi[I_AXIS] < -1.0 + EPS ) {
- normal[I_AXIS] = -1.0;
- return 2;
- }
- else if( xi[I_AXIS] > +1.0 - EPS ) {
- normal[I_AXIS] = +1.0;
- return 3;
- }
- else if( xi[K_AXIS] < -1.0 + EPS ) {
- normal[K_AXIS] = -1.0;
- return 4;
- }
- else if( xi[K_AXIS] > +1.0 - EPS ) {
- normal[K_AXIS] = +1.0;
- return 5;
- }
- return 0;
-}
-
-int ElementType_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* normal ) {
- ElementType* self = (ElementType*)elementType;
-
- return self->_surfaceNormal( self, element_I, dim, xi, normal );
-}
-
-void ElementType_ConvertGlobalCoordToElLocal(
- void* elementType,
- void* mesh,
- unsigned element,
- const double* globalCoord,
- double* elLocalCoord )
-{
- ElementType* self = (ElementType*)elementType;
-
- self->_convertGlobalCoordToElLocal( self, mesh, element, globalCoord, elLocalCoord );
-}
-
-
-/* +++ Virtual Function Implementations +++ */
-
-void _ElementType_ConvertGlobalCoordToElLocal(
- void* elementType,
- void* _mesh,
- unsigned element,
- const double* globalCoord,
- double* elLocalCoord )
-{
- ElementType* self = (ElementType*)elementType;
- Mesh* mesh = (Mesh*)_mesh;
- TensorArray jacobiMatrix;
- double tolerance = 0.0001; /* TODO put on class */
- double maxResidual;
- Iteration_Index maxIterations = 100; /* TODO put on class */
- Iteration_Index iteration_I;
- Node_Index node_I;
- Node_Index nodeCount = self->nodeCount;
- double* evaluatedShapeFuncs = self->evaluatedShapeFunc;
- XYZ rightHandSide;
- XYZ xiIncrement;
- double shapeFunc;
- double* nodeCoord;
- double** GNi = self->GNi;
- unsigned nInc, *inc;
- Dimension_Index dim = Mesh_GetDimSize( mesh );
-
- /* This function uses a Newton-Raphson iterative method to find the local coordinate from the global coordinate
- * the equations are ( see FEM/BEM nodes p. 9 )
- *
- * x = \Sum_n( Ni( \xi, \eta, \zeta ) x_n )
- * y = \Sum_n( Ni( \xi, \eta, \zeta ) y_n )
- * z = \Sum_n( Ni( \xi, \eta, \zeta ) z_n )
- *
- * which are non-linear.
- *
- * This can be formulated into a system of linear equations of the form
- *
- * [ ][ \xi_{i + 1} - \xi_i ] [ x - \Sum_n( Ni( \xi_i, \eta_i, \zeta_i ) x_n ]
- * [ Jacobian ][ \eta_{i + 1} - \eta_i ] = [ y - \Sum_n( Ni( \xi_i, \eta_i, \zeta_i ) y_n ]
- * [ ][ \zeta_{i + 1} - \zeta_I ] [ z - \Sum_n( Ni( \xi_i, \eta_i, \zeta_i ) z_n ]
- *
- * see http://en.wikipedia.org/wiki/Newton-Raphson_method
- *
- * */
-
- Mesh_GetIncidence( mesh, Mesh_GetDimSize( mesh ), element, MT_VERTEX, self->inc );
- nInc = IArray_GetSize( self->inc );
- inc = (unsigned*)IArray_GetPtr( (self->inc) );
-
- /* Initial guess for element local coordinate is in the centre of the element - ( 0.0, 0.0, 0.0 ) */
- memset( elLocalCoord, 0, dim*sizeof(double) );
-
- /* Do Newton-Raphson Iteration */
- for ( iteration_I = 0 ; iteration_I < maxIterations ; iteration_I++ ) {
- /* Initialise Values */
- TensorArray_Zero( jacobiMatrix );
- memset( rightHandSide, 0, sizeof( XYZ ) );
-
- /* Evaluate shape functions for rhs */
- ElementType_EvaluateShapeFunctionsAt( self, elLocalCoord, evaluatedShapeFuncs );
- self->_evaluateShapeFunctionLocalDerivsAt( self, elLocalCoord, GNi );
-
-
- for ( node_I = 0 ; node_I < nodeCount ; node_I++ ) {
- shapeFunc = evaluatedShapeFuncs[node_I];
- nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
-
- /* Form jacobi matrix */
- jacobiMatrix[ MAP_TENSOR( 0, 0, dim ) ] += GNi[0][node_I] * nodeCoord[ I_AXIS ];
- jacobiMatrix[ MAP_TENSOR( 0, 1, dim ) ] += GNi[1][node_I] * nodeCoord[ I_AXIS ];
-
- jacobiMatrix[ MAP_TENSOR( 1, 0, dim ) ] += GNi[0][node_I] * nodeCoord[ J_AXIS ];
- jacobiMatrix[ MAP_TENSOR( 1, 1, dim ) ] += GNi[1][node_I] * nodeCoord[ J_AXIS ];
-
-
- /* Form right hand side */
- rightHandSide[ I_AXIS ] -= shapeFunc * nodeCoord[ I_AXIS ];
- rightHandSide[ J_AXIS ] -= shapeFunc * nodeCoord[ J_AXIS ];
-
- if ( dim == 3 ) {
- jacobiMatrix[ MAP_3D_TENSOR( 0, 2 ) ] += GNi[2][node_I] * nodeCoord[ I_AXIS ];
- jacobiMatrix[ MAP_3D_TENSOR( 1, 2 ) ] += GNi[2][node_I] * nodeCoord[ J_AXIS ];
-
- jacobiMatrix[ MAP_3D_TENSOR( 2, 0 ) ] += GNi[0][node_I] * nodeCoord[ K_AXIS ];
- jacobiMatrix[ MAP_3D_TENSOR( 2, 1 ) ] += GNi[1][node_I] * nodeCoord[ K_AXIS ];
- jacobiMatrix[ MAP_3D_TENSOR( 2, 2 ) ] += GNi[2][node_I] * nodeCoord[ K_AXIS ];
-
- rightHandSide[ K_AXIS ] -= shapeFunc * nodeCoord[ K_AXIS ];
- }
- }
-
- /* Finish building right hand side */
- rightHandSide[ I_AXIS ] += globalCoord[ I_AXIS ];
- rightHandSide[ J_AXIS ] += globalCoord[ J_AXIS ];
- if ( dim == 3 )
- rightHandSide[ K_AXIS ] += globalCoord[ K_AXIS ];
-
- /* Solve for xi increment */
- TensorArray_SolveSystem( jacobiMatrix, xiIncrement, rightHandSide, dim );
-
- /* Update xi */
- elLocalCoord[ I_AXIS ] += xiIncrement[ I_AXIS ];
- elLocalCoord[ J_AXIS ] += xiIncrement[ J_AXIS ];
- if ( dim == 3 )
- elLocalCoord[ K_AXIS ] += xiIncrement[ K_AXIS ];
-
- /* Check for convergence */
- maxResidual = fabs( xiIncrement[ I_AXIS ] );
- if ( maxResidual < fabs( xiIncrement[ J_AXIS ] ) )
- maxResidual = fabs( xiIncrement[ J_AXIS ] );
- if ( dim == 3 && maxResidual < fabs( xiIncrement[ K_AXIS ] ) )
- maxResidual = fabs( xiIncrement[ K_AXIS ] );
-
- if ( maxResidual < tolerance )
- break;
- }
-}
-
-
-/* +++ Public Functions +++ */
-void ElementType_ShapeFunctionsGlobalDerivs(
- void* elementType,
- void* _mesh,
- Element_DomainIndex elId,
- double* xi,
- int dim,
- double* detJac,
- double** GNx )
-{
- ElementType* self = (ElementType*)elementType;
- Mesh* mesh = (Mesh*)_mesh;
- double *nodeCoord;
-
- double jac[3][3];
- int rows; /* max dimensions */
- int cols; /* max nodes per el */
- double** GNi;
- int n, i, j;
- double globalSF_DerivVal;
- int dx, dxi;
- double tmp, D = 0.0;
- double cof[3][3]; /* cofactors */
- unsigned nInc, *inc;
- Index nodesPerEl;
-
- rows=Mesh_GetDimSize( mesh );
- cols=self->nodeCount;
-
- GNi = self->GNi;
-
- nodesPerEl = self->nodeCount;
-
- Mesh_GetIncidence( mesh, Mesh_GetDimSize( mesh ), elId, MT_VERTEX, self->inc );
- nInc = IArray_GetSize( self->inc );
- inc = (unsigned*)IArray_GetPtr((self->inc) );
-
- /*
- If constant shape function gets passed in here, getLocalDeriv will
- indicate the error and exit code.
- */
-
- self->_evaluateShapeFunctionLocalDerivsAt( self, xi, GNi );
-
-
- /* build the jacobian matrix */
- /*
- jac = \sum_i d/d\xi( N_i ) x_i \sum_i d/d\xi( N_i ) y_i
- \sum_i d/d\eta( N_i ) x_i \sum_i d/d\eta( N_i ) y_i
- */
- /* unroll this bugger cause we do it all the time */
- if( dim == 2 ) {
- jac[0][0] = jac[0][1] = jac[1][0] = jac[1][1] = 0.0;
- for( n=0; n<(int)nodesPerEl; n++){
- nodeCoord = Mesh_GetVertex( mesh, inc[n] );
- jac[0][0] = jac[0][0] + GNi[0][n] * nodeCoord[0];
- jac[0][1] = jac[0][1] + GNi[0][n] * nodeCoord[1];
-
- jac[1][0] = jac[1][0] + GNi[1][n] * nodeCoord[0];
- jac[1][1] = jac[1][1] + GNi[1][n] * nodeCoord[1];
- }
- }
-
- if( dim == 3 ) {
- jac[0][0] = jac[0][1] = jac[0][2] = 0.0;
- jac[1][0] = jac[1][1] = jac[1][2] = 0.0;
- jac[2][0] = jac[2][1] = jac[2][2] = 0.0;
- for( n=0; n<(int)nodesPerEl; n++){
- nodeCoord = Mesh_GetVertex( mesh, inc[n] );
- jac[0][0] = jac[0][0] + GNi[0][n] * nodeCoord[0];
- jac[0][1] = jac[0][1] + GNi[0][n] * nodeCoord[1];
- jac[0][2] = jac[0][2] + GNi[0][n] * nodeCoord[2];
-
- jac[1][0] = jac[1][0] + GNi[1][n] * nodeCoord[0];
- jac[1][1] = jac[1][1] + GNi[1][n] * nodeCoord[1];
- jac[1][2] = jac[1][2] + GNi[1][n] * nodeCoord[2];
-
- jac[2][0] = jac[2][0] + GNi[2][n] * nodeCoord[0];
- jac[2][1] = jac[2][1] + GNi[2][n] * nodeCoord[1];
- jac[2][2] = jac[2][2] + GNi[2][n] * nodeCoord[2];
- }
- }
-
- /* get determinant of the jacobian matrix */
- if( dim == 2 ) {
- D = jac[0][0]*jac[1][1] - jac[0][1]*jac[1][0];
- }
- if( dim == 3 ) {
- D = jac[0][0]*( jac[1][1]*jac[2][2] - jac[1][2]*jac[2][1] )
- - jac[0][1]*( jac[1][0]*jac[2][2] - jac[1][2]*jac[2][0] )
- + jac[0][2]*( jac[1][0]*jac[2][1] - jac[1][1]*jac[2][0] );
- }
- (*detJac) = D;
-
-
- /* invert the jacobian matrix A^-1 = adj(A)/det(A) */
- if( dim == 2 ) {
- tmp = jac[0][0];
- jac[0][0] = jac[1][1]/D;
- jac[1][1] = tmp/D;
- jac[0][1] = -jac[0][1]/D;
- jac[1][0] = -jac[1][0]/D;
- }
- if( dim == 3 ) {
- /*
- 00 01 02
- 10 11 12
- 20 21 22
- */
- cof[0][0] = jac[1][1]*jac[2][2] - jac[1][2]*jac[2][1];
- cof[1][0] = -(jac[1][0]*jac[2][2] - jac[1][2]*jac[2][0]);
- cof[2][0] = jac[1][0]*jac[2][1] - jac[1][1]*jac[2][0];
-
- cof[0][1] = -(jac[0][1]*jac[2][2] - jac[0][2]*jac[2][1]);
- cof[1][1] = jac[0][0]*jac[2][2] - jac[0][2]*jac[2][0];
- cof[2][1] = -(jac[0][0]*jac[2][1] - jac[0][1]*jac[2][0]);
-
- cof[0][2] = jac[0][1]*jac[1][2] - jac[0][2]*jac[1][1];
- cof[1][2] = -(jac[0][0]*jac[1][2] - jac[0][2]*jac[1][0]);
- cof[2][2] = jac[0][0]*jac[1][1] - jac[0][1]*jac[1][0];
-
- for( i=0; i<dim; i++ ) {
- for( j=0; j<dim; j++ ) {
- jac[i][j] = cof[i][j]/D;
- }
- }
-
-
- }
-
- /* get global derivs Ni_x, Ni_y and Ni_z if dim == 3 */
- for( dx=0; dx<dim; dx++ ) {
- for( n=0; n<(int)nodesPerEl; n++ ) {
-
- globalSF_DerivVal = 0.0;
- for(dxi=0; dxi<dim; dxi++) {
- globalSF_DerivVal = globalSF_DerivVal + GNi[dxi][n] * jac[dx][dxi];
- }
-
- GNx[dx][n] = globalSF_DerivVal;
- }
- }
-}
-
-void ElementType_Jacobian_AxisIndependent(
- void* elementType,
- void* _mesh,
- Element_DomainIndex elId,
- double* xi,
- Dimension_Index dim,
- double** jacobian,
- double** _GNi,
- Coord_Index A_axis,
- Coord_Index B_axis,
- Coord_Index C_axis )
-{
- ElementType* self = (ElementType*) elementType;
- Mesh* mesh = (Mesh*)_mesh;
- double* nodeCoord;
- double** GNi;
- Node_Index nodesPerEl = self->nodeCount;
- Node_Index node_I;
- unsigned nInc, *inc;
-
- Mesh_GetIncidence( mesh, Mesh_GetDimSize( mesh ), elId, MT_VERTEX, self->inc );
- nInc = IArray_GetSize( self->inc );
- inc = (unsigned*)IArray_GetPtr((self->inc) );
-
- /* If GNi isn't passed in - then evaluate them for you */
- if (_GNi == NULL) {
- /* Using 3 here instead of dim so that you can pass in dim = 2 and use axes 0 and 2 for your jacobian */
- GNi = Memory_Alloc_2DArray( double, 3, nodesPerEl, (Name)"Temporary GNi" );
- self->_evaluateShapeFunctionLocalDerivsAt( self, xi, GNi );
- }
- else GNi = _GNi;
-
- /* build the jacobian matrix */
- /*
- jacobian = \sum_i d/d\xi( N_i ) x_i \sum_i d/d\xi( N_i ) y_i
- \sum_i d/d\eta( N_i ) x_i \sum_i d/d\eta( N_i ) y_i
- */
- switch (dim) {
- case 1:
- jacobian[A_axis][A_axis] = 0.0;
- for( node_I = 0 ; node_I < nodesPerEl; node_I++){
- nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
- jacobian[A_axis][A_axis] += GNi[A_axis][node_I] * nodeCoord[A_axis];
- }
- break;
- case 2:
- jacobian[A_axis][A_axis] = jacobian[A_axis][B_axis] = jacobian[B_axis][A_axis] = jacobian[B_axis][B_axis] = 0.0;
- for( node_I = 0 ; node_I < nodesPerEl; node_I++){
- nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
- jacobian[A_axis][A_axis] += GNi[A_axis][node_I] * nodeCoord[A_axis];
- jacobian[A_axis][B_axis] += GNi[A_axis][node_I] * nodeCoord[B_axis];
-
- jacobian[B_axis][A_axis] += GNi[B_axis][node_I] * nodeCoord[A_axis];
- jacobian[B_axis][B_axis] += GNi[B_axis][node_I] * nodeCoord[B_axis];
- }
- break;
- case 3:
- jacobian[A_axis][A_axis] = jacobian[A_axis][B_axis] = jacobian[A_axis][C_axis] = 0.0;
- jacobian[B_axis][A_axis] = jacobian[B_axis][B_axis] = jacobian[B_axis][C_axis] = 0.0;
- jacobian[C_axis][A_axis] = jacobian[C_axis][B_axis] = jacobian[C_axis][C_axis] = 0.0;
- for( node_I = 0 ; node_I < nodesPerEl; node_I++){
- nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
-
- jacobian[A_axis][A_axis] += GNi[A_axis][node_I] * nodeCoord[A_axis];
- jacobian[A_axis][B_axis] += GNi[A_axis][node_I] * nodeCoord[B_axis];
- jacobian[A_axis][C_axis] += GNi[A_axis][node_I] * nodeCoord[C_axis];
-
- jacobian[B_axis][A_axis] += GNi[B_axis][node_I] * nodeCoord[A_axis];
- jacobian[B_axis][B_axis] += GNi[B_axis][node_I] * nodeCoord[B_axis];
- jacobian[B_axis][C_axis] += GNi[B_axis][node_I] * nodeCoord[C_axis];
-
- jacobian[C_axis][A_axis] += GNi[C_axis][node_I] * nodeCoord[A_axis];
- jacobian[C_axis][B_axis] += GNi[C_axis][node_I] * nodeCoord[B_axis];
- jacobian[C_axis][C_axis] += GNi[C_axis][node_I] * nodeCoord[C_axis];
- }
- break;
- /* Mainly here to check unrolled loops above */
- default: {
- Coord_Index row_I, column_I;
-
- for ( row_I = 0 ; row_I < dim ; row_I++ ) {
- for ( column_I = 0 ; column_I < dim ; column_I++ ) {
- /* Initialise */
- jacobian[row_I][column_I] = 0.0;
-
- /* Calculate */
- for( node_I = 0 ; node_I < nodesPerEl; node_I++){
- nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
-
- jacobian[row_I][column_I] += GNi[row_I][node_I] * nodeCoord[column_I];
- }
- }
- }
- }
- }
-
- /* Clean up */
- if (_GNi == NULL)
- Memory_Free(GNi);
-}
-
-double ElementType_JacobianDeterminant_AxisIndependent(
- void* elementType,
- void* _mesh,
- Element_DomainIndex elId,
- double* xi,
- Dimension_Index dim,
- Coord_Index A_axis,
- Coord_Index B_axis,
- Coord_Index C_axis )
-{
- double** jacobian;
- double detJac;
-
- /* Using 3 here instead of dim so that you can pass in dim = 2 and use axes 0 and 2 for your jacobian */
- jacobian = Memory_Alloc_2DArray( double, 3, 3, (Name)"Temporary Jacobian" );
-
- ElementType_Jacobian_AxisIndependent( elementType, _mesh, elId, xi, dim, jacobian, NULL, A_axis, B_axis, C_axis );
- detJac = StGermain_MatrixDeterminant_AxisIndependent( jacobian, dim, A_axis, B_axis, C_axis );
-
- /* Cleaning up */
- Memory_Free( jacobian );
-
- return detJac;
-}
-
-void ElementType_GetFaceNodes( void* elementType, Mesh* mesh, unsigned element_I, unsigned face_I,
- unsigned nNodes, unsigned* nodes ) {
- ElementType* self = (ElementType*) elementType;
- Index node_i;
- unsigned* inc;
-
- assert( mesh && Stg_CheckType( mesh, FeMesh ) );
-
- FeMesh_GetElementNodes( mesh, element_I, self->inc );
- inc = (unsigned*)IArray_GetPtr((self->inc) );
-
- for( node_i = 0; node_i < nNodes; node_i++ )
- nodes[node_i] = inc[self->faceNodes[face_I][node_i]];
-}
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/ElementType.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/ElementType.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,633 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: ElementType.c 1179 2008-07-15 05:28:11Z DavidLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "FeMesh.h"
+#include "ElementType.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+
+const Type ElementType_Type = "ElementType";
+
+ElementType* _ElementType_New( ELEMENTTYPE_DEFARGS ) {
+ ElementType* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(ElementType) );
+ self = (ElementType*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ /* General info */
+
+ /* Virtual functions */
+ self->_build = _build;
+ self->_evaluateShapeFunctionsAt = _evaluateShapeFunctionsAt;
+ self->_evaluateShapeFunctionLocalDerivsAt = _evaluateShapeFunctionLocalDerivsAt;
+ self->_convertGlobalCoordToElLocal = _convertGlobalCoordToElLocal;
+ self->_jacobianDeterminantSurface = _jacobianDeterminantSurface;
+ self->_surfaceNormal = _surfaceNormal;
+
+ /* ElementType info */
+
+ return self;
+}
+
+void _ElementType_Init( ElementType* self, Index nodeCount ) {
+ /* General and Virtual info should already be set */
+ self->dim = 0;
+ /* ElementType info */
+ self->nodeCount = nodeCount;
+ self->debug = Stream_RegisterChild( StgFEM_Discretisation_Debug, ElementType_Type );
+ self->inc = IArray_New();
+}
+
+
+void _ElementType_Destroy( void* elementType, void* data ){
+ ElementType* self = (ElementType*)elementType;
+
+ NewClass_Delete( self->inc );
+
+ Stg_Component_Destroy( self, data, False );
+}
+
+void _ElementType_Delete( void* elementType ) {
+ ElementType* self = (ElementType*)elementType;
+
+ /* Stg_Class_Delete parent*/
+ _Stg_Component_Delete( self );
+}
+
+void _ElementType_Print( void* elementType, Stream* stream ) {
+ ElementType* self = (ElementType*)elementType;
+
+ /* Set the Journal for printing informations */
+ Stream* elementTypeStream = stream;
+
+ /* General info */
+ Journal_Printf( elementTypeStream, "ElementType (ptr): %p\n", self );
+
+ /* Print parent */
+ _Stg_Class_Print( self, elementTypeStream );
+
+ /* Virtual info */
+ Journal_Printf( elementTypeStream, "\t_build (func ptr): %p\n", self->_build );
+ Journal_Printf( elementTypeStream, "\t_evaluateShapeFunctionsAt (func ptr): %p\n", self->_evaluateShapeFunctionsAt );
+ Journal_Printf( elementTypeStream, "\t_evaluateShapeFunctionLocalDerivsAt (func ptr): %p\n", self->_evaluateShapeFunctionLocalDerivsAt );
+
+ /* ElementType info */
+ Journal_Printf( elementTypeStream, "\tnodeCount: %u\n", self->nodeCount );
+}
+
+/* +++ Virtual Function Interfaces +++ */
+
+void ElementType_Build( void* elementType, void *data ) {
+ ElementType* self = (ElementType*)elementType;
+
+ /* ElementType's are implemented NOT in the standard parent child
+ * manner as the rest of StGermain. Here the parents calls the child's
+ * build function */
+ self->_build( self, data);
+}
+
+void ElementType_EvaluateShapeFunctionsAt( void* elementType, const double localCoord[], double* const evaluatedValues ) {
+ ElementType* self = (ElementType*)elementType;
+
+ self->_evaluateShapeFunctionsAt( self, localCoord, evaluatedValues );
+}
+
+void ElementType_EvaluateShapeFunctionLocalDerivsAt( void* elementType, const double localCoord[], double** const evaluatedDerivatives ) {
+ ElementType* self = (ElementType*)elementType;
+
+ self->_evaluateShapeFunctionLocalDerivsAt( self, localCoord, evaluatedDerivatives );
+}
+
+double _ElementType_JacobianDeterminantSurface( void* elementType, void* mesh, unsigned element_I, const double localCoord[],
+ unsigned face_I, unsigned norm )
+{
+ ElementType* self;
+ Stream* error = Journal_Register( ErrorStream_Type, (Name)ElementType_Type );
+
+ self = (ElementType* ) elementType;
+
+ Journal_Printf( error, "Error: the jacobian for this element type cannot be evaluated on the element surface" );
+ Journal_Printf( error, "(perhaps because the nodes are defined internally for the element).\n" );
+ assert( 0 );
+
+ return -1;
+}
+
+double ElementType_JacobianDeterminantSurface( void* elementType, void* mesh, unsigned element_I,
+ const double localCoord[], unsigned face_I, unsigned norm ) {
+ ElementType* self = (ElementType*)elementType;
+
+ return self->_jacobianDeterminantSurface( self, mesh, element_I, localCoord, face_I, norm );
+}
+
+#define EPS 1.0E-6
+
+int _ElementType_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* normal ) {
+ ElementType* self;
+
+ self = (ElementType*)elementType;
+
+ memset( normal, 0, sizeof(double) * dim );
+
+ if( xi[J_AXIS] < -1.0 + EPS ) {
+ normal[J_AXIS] = -1.0;
+ return 0;
+ }
+ else if( xi[J_AXIS] > +1.0 - EPS ) {
+ normal[J_AXIS] = +1.0;
+ return 1;
+ }
+ else if( xi[I_AXIS] < -1.0 + EPS ) {
+ normal[I_AXIS] = -1.0;
+ return 2;
+ }
+ else if( xi[I_AXIS] > +1.0 - EPS ) {
+ normal[I_AXIS] = +1.0;
+ return 3;
+ }
+ else if( xi[K_AXIS] < -1.0 + EPS ) {
+ normal[K_AXIS] = -1.0;
+ return 4;
+ }
+ else if( xi[K_AXIS] > +1.0 - EPS ) {
+ normal[K_AXIS] = +1.0;
+ return 5;
+ }
+ return 0;
+}
+
+int ElementType_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* normal ) {
+ ElementType* self = (ElementType*)elementType;
+
+ return self->_surfaceNormal( self, element_I, dim, xi, normal );
+}
+
+void ElementType_ConvertGlobalCoordToElLocal(
+ void* elementType,
+ void* mesh,
+ unsigned element,
+ const double* globalCoord,
+ double* elLocalCoord )
+{
+ ElementType* self = (ElementType*)elementType;
+
+ self->_convertGlobalCoordToElLocal( self, mesh, element, globalCoord, elLocalCoord );
+}
+
+
+/* +++ Virtual Function Implementations +++ */
+
+void _ElementType_ConvertGlobalCoordToElLocal(
+ void* elementType,
+ void* _mesh,
+ unsigned element,
+ const double* globalCoord,
+ double* elLocalCoord )
+{
+ ElementType* self = (ElementType*)elementType;
+ Mesh* mesh = (Mesh*)_mesh;
+ TensorArray jacobiMatrix;
+ double tolerance = 0.0001; /* TODO put on class */
+ double maxResidual;
+ Iteration_Index maxIterations = 100; /* TODO put on class */
+ Iteration_Index iteration_I;
+ Node_Index node_I;
+ Node_Index nodeCount = self->nodeCount;
+ double* evaluatedShapeFuncs = self->evaluatedShapeFunc;
+ XYZ rightHandSide;
+ XYZ xiIncrement;
+ double shapeFunc;
+ double* nodeCoord;
+ double** GNi = self->GNi;
+ unsigned nInc, *inc;
+ Dimension_Index dim = Mesh_GetDimSize( mesh );
+
+ /* This function uses a Newton-Raphson iterative method to find the local coordinate from the global coordinate
+ * the equations are ( see FEM/BEM nodes p. 9 )
+ *
+ * x = \Sum_n( Ni( \xi, \eta, \zeta ) x_n )
+ * y = \Sum_n( Ni( \xi, \eta, \zeta ) y_n )
+ * z = \Sum_n( Ni( \xi, \eta, \zeta ) z_n )
+ *
+ * which are non-linear.
+ *
+ * This can be formulated into a system of linear equations of the form
+ *
+ * [ ][ \xi_{i + 1} - \xi_i ] [ x - \Sum_n( Ni( \xi_i, \eta_i, \zeta_i ) x_n ]
+ * [ Jacobian ][ \eta_{i + 1} - \eta_i ] = [ y - \Sum_n( Ni( \xi_i, \eta_i, \zeta_i ) y_n ]
+ * [ ][ \zeta_{i + 1} - \zeta_I ] [ z - \Sum_n( Ni( \xi_i, \eta_i, \zeta_i ) z_n ]
+ *
+ * see http://en.wikipedia.org/wiki/Newton-Raphson_method
+ *
+ * */
+
+ Mesh_GetIncidence( mesh, Mesh_GetDimSize( mesh ), element, MT_VERTEX, self->inc );
+ nInc = IArray_GetSize( self->inc );
+ inc = (unsigned*)IArray_GetPtr( (self->inc) );
+
+ /* Initial guess for element local coordinate is in the centre of the element - ( 0.0, 0.0, 0.0 ) */
+ memset( elLocalCoord, 0, dim*sizeof(double) );
+
+ /* Do Newton-Raphson Iteration */
+ for ( iteration_I = 0 ; iteration_I < maxIterations ; iteration_I++ ) {
+ /* Initialise Values */
+ TensorArray_Zero( jacobiMatrix );
+ memset( rightHandSide, 0, sizeof( XYZ ) );
+
+ /* Evaluate shape functions for rhs */
+ ElementType_EvaluateShapeFunctionsAt( self, elLocalCoord, evaluatedShapeFuncs );
+ self->_evaluateShapeFunctionLocalDerivsAt( self, elLocalCoord, GNi );
+
+
+ for ( node_I = 0 ; node_I < nodeCount ; node_I++ ) {
+ shapeFunc = evaluatedShapeFuncs[node_I];
+ nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
+
+ /* Form jacobi matrix */
+ jacobiMatrix[ MAP_TENSOR( 0, 0, dim ) ] += GNi[0][node_I] * nodeCoord[ I_AXIS ];
+ jacobiMatrix[ MAP_TENSOR( 0, 1, dim ) ] += GNi[1][node_I] * nodeCoord[ I_AXIS ];
+
+ jacobiMatrix[ MAP_TENSOR( 1, 0, dim ) ] += GNi[0][node_I] * nodeCoord[ J_AXIS ];
+ jacobiMatrix[ MAP_TENSOR( 1, 1, dim ) ] += GNi[1][node_I] * nodeCoord[ J_AXIS ];
+
+
+ /* Form right hand side */
+ rightHandSide[ I_AXIS ] -= shapeFunc * nodeCoord[ I_AXIS ];
+ rightHandSide[ J_AXIS ] -= shapeFunc * nodeCoord[ J_AXIS ];
+
+ if ( dim == 3 ) {
+ jacobiMatrix[ MAP_3D_TENSOR( 0, 2 ) ] += GNi[2][node_I] * nodeCoord[ I_AXIS ];
+ jacobiMatrix[ MAP_3D_TENSOR( 1, 2 ) ] += GNi[2][node_I] * nodeCoord[ J_AXIS ];
+
+ jacobiMatrix[ MAP_3D_TENSOR( 2, 0 ) ] += GNi[0][node_I] * nodeCoord[ K_AXIS ];
+ jacobiMatrix[ MAP_3D_TENSOR( 2, 1 ) ] += GNi[1][node_I] * nodeCoord[ K_AXIS ];
+ jacobiMatrix[ MAP_3D_TENSOR( 2, 2 ) ] += GNi[2][node_I] * nodeCoord[ K_AXIS ];
+
+ rightHandSide[ K_AXIS ] -= shapeFunc * nodeCoord[ K_AXIS ];
+ }
+ }
+
+ /* Finish building right hand side */
+ rightHandSide[ I_AXIS ] += globalCoord[ I_AXIS ];
+ rightHandSide[ J_AXIS ] += globalCoord[ J_AXIS ];
+ if ( dim == 3 )
+ rightHandSide[ K_AXIS ] += globalCoord[ K_AXIS ];
+
+ /* Solve for xi increment */
+ TensorArray_SolveSystem( jacobiMatrix, xiIncrement, rightHandSide, dim );
+
+ /* Update xi */
+ elLocalCoord[ I_AXIS ] += xiIncrement[ I_AXIS ];
+ elLocalCoord[ J_AXIS ] += xiIncrement[ J_AXIS ];
+ if ( dim == 3 )
+ elLocalCoord[ K_AXIS ] += xiIncrement[ K_AXIS ];
+
+ /* Check for convergence */
+ maxResidual = fabs( xiIncrement[ I_AXIS ] );
+ if ( maxResidual < fabs( xiIncrement[ J_AXIS ] ) )
+ maxResidual = fabs( xiIncrement[ J_AXIS ] );
+ if ( dim == 3 && maxResidual < fabs( xiIncrement[ K_AXIS ] ) )
+ maxResidual = fabs( xiIncrement[ K_AXIS ] );
+
+ if ( maxResidual < tolerance )
+ break;
+ }
+}
+
+
+/* +++ Public Functions +++ */
+void ElementType_ShapeFunctionsGlobalDerivs(
+ void* elementType,
+ void* _mesh,
+ Element_DomainIndex elId,
+ double* xi,
+ int dim,
+ double* detJac,
+ double** GNx )
+{
+ ElementType* self = (ElementType*)elementType;
+ Mesh* mesh = (Mesh*)_mesh;
+ double *nodeCoord;
+
+ double jac[3][3];
+ int rows; /* max dimensions */
+ int cols; /* max nodes per el */
+ double** GNi;
+ int n, i, j;
+ double globalSF_DerivVal;
+ int dx, dxi;
+ double tmp, D = 0.0;
+ double cof[3][3]; /* cofactors */
+ unsigned nInc, *inc;
+ Index nodesPerEl;
+
+ rows=Mesh_GetDimSize( mesh );
+ cols=self->nodeCount;
+
+ GNi = self->GNi;
+
+ nodesPerEl = self->nodeCount;
+
+ Mesh_GetIncidence( mesh, Mesh_GetDimSize( mesh ), elId, MT_VERTEX, self->inc );
+ nInc = IArray_GetSize( self->inc );
+ inc = (unsigned*)IArray_GetPtr((self->inc) );
+
+ /*
+ If constant shape function gets passed in here, getLocalDeriv will
+ indicate the error and exit code.
+ */
+
+ self->_evaluateShapeFunctionLocalDerivsAt( self, xi, GNi );
+
+
+ /* build the jacobian matrix */
+ /*
+ jac = \sum_i d/d\xi( N_i ) x_i \sum_i d/d\xi( N_i ) y_i
+ \sum_i d/d\eta( N_i ) x_i \sum_i d/d\eta( N_i ) y_i
+ */
+ /* unroll this bugger cause we do it all the time */
+ if( dim == 2 ) {
+ jac[0][0] = jac[0][1] = jac[1][0] = jac[1][1] = 0.0;
+ for( n=0; n<(int)nodesPerEl; n++){
+ nodeCoord = Mesh_GetVertex( mesh, inc[n] );
+ jac[0][0] = jac[0][0] + GNi[0][n] * nodeCoord[0];
+ jac[0][1] = jac[0][1] + GNi[0][n] * nodeCoord[1];
+
+ jac[1][0] = jac[1][0] + GNi[1][n] * nodeCoord[0];
+ jac[1][1] = jac[1][1] + GNi[1][n] * nodeCoord[1];
+ }
+ }
+
+ if( dim == 3 ) {
+ jac[0][0] = jac[0][1] = jac[0][2] = 0.0;
+ jac[1][0] = jac[1][1] = jac[1][2] = 0.0;
+ jac[2][0] = jac[2][1] = jac[2][2] = 0.0;
+ for( n=0; n<(int)nodesPerEl; n++){
+ nodeCoord = Mesh_GetVertex( mesh, inc[n] );
+ jac[0][0] = jac[0][0] + GNi[0][n] * nodeCoord[0];
+ jac[0][1] = jac[0][1] + GNi[0][n] * nodeCoord[1];
+ jac[0][2] = jac[0][2] + GNi[0][n] * nodeCoord[2];
+
+ jac[1][0] = jac[1][0] + GNi[1][n] * nodeCoord[0];
+ jac[1][1] = jac[1][1] + GNi[1][n] * nodeCoord[1];
+ jac[1][2] = jac[1][2] + GNi[1][n] * nodeCoord[2];
+
+ jac[2][0] = jac[2][0] + GNi[2][n] * nodeCoord[0];
+ jac[2][1] = jac[2][1] + GNi[2][n] * nodeCoord[1];
+ jac[2][2] = jac[2][2] + GNi[2][n] * nodeCoord[2];
+ }
+ }
+
+ /* get determinant of the jacobian matrix */
+ if( dim == 2 ) {
+ D = jac[0][0]*jac[1][1] - jac[0][1]*jac[1][0];
+ }
+ if( dim == 3 ) {
+ D = jac[0][0]*( jac[1][1]*jac[2][2] - jac[1][2]*jac[2][1] )
+ - jac[0][1]*( jac[1][0]*jac[2][2] - jac[1][2]*jac[2][0] )
+ + jac[0][2]*( jac[1][0]*jac[2][1] - jac[1][1]*jac[2][0] );
+ }
+ (*detJac) = D;
+
+
+ /* invert the jacobian matrix A^-1 = adj(A)/det(A) */
+ if( dim == 2 ) {
+ tmp = jac[0][0];
+ jac[0][0] = jac[1][1]/D;
+ jac[1][1] = tmp/D;
+ jac[0][1] = -jac[0][1]/D;
+ jac[1][0] = -jac[1][0]/D;
+ }
+ if( dim == 3 ) {
+ /*
+ 00 01 02
+ 10 11 12
+ 20 21 22
+ */
+ cof[0][0] = jac[1][1]*jac[2][2] - jac[1][2]*jac[2][1];
+ cof[1][0] = -(jac[1][0]*jac[2][2] - jac[1][2]*jac[2][0]);
+ cof[2][0] = jac[1][0]*jac[2][1] - jac[1][1]*jac[2][0];
+
+ cof[0][1] = -(jac[0][1]*jac[2][2] - jac[0][2]*jac[2][1]);
+ cof[1][1] = jac[0][0]*jac[2][2] - jac[0][2]*jac[2][0];
+ cof[2][1] = -(jac[0][0]*jac[2][1] - jac[0][1]*jac[2][0]);
+
+ cof[0][2] = jac[0][1]*jac[1][2] - jac[0][2]*jac[1][1];
+ cof[1][2] = -(jac[0][0]*jac[1][2] - jac[0][2]*jac[1][0]);
+ cof[2][2] = jac[0][0]*jac[1][1] - jac[0][1]*jac[1][0];
+
+ for( i=0; i<dim; i++ ) {
+ for( j=0; j<dim; j++ ) {
+ jac[i][j] = cof[i][j]/D;
+ }
+ }
+
+
+ }
+
+ /* get global derivs Ni_x, Ni_y and Ni_z if dim == 3 */
+ for( dx=0; dx<dim; dx++ ) {
+ for( n=0; n<(int)nodesPerEl; n++ ) {
+
+ globalSF_DerivVal = 0.0;
+ for(dxi=0; dxi<dim; dxi++) {
+ globalSF_DerivVal = globalSF_DerivVal + GNi[dxi][n] * jac[dx][dxi];
+ }
+
+ GNx[dx][n] = globalSF_DerivVal;
+ }
+ }
+}
+
+void ElementType_Jacobian_AxisIndependent(
+ void* elementType,
+ void* _mesh,
+ Element_DomainIndex elId,
+ double* xi,
+ Dimension_Index dim,
+ double** jacobian,
+ double** _GNi,
+ Coord_Index A_axis,
+ Coord_Index B_axis,
+ Coord_Index C_axis )
+{
+ ElementType* self = (ElementType*) elementType;
+ Mesh* mesh = (Mesh*)_mesh;
+ double* nodeCoord;
+ double** GNi;
+ Node_Index nodesPerEl = self->nodeCount;
+ Node_Index node_I;
+ unsigned nInc, *inc;
+
+ Mesh_GetIncidence( mesh, Mesh_GetDimSize( mesh ), elId, MT_VERTEX, self->inc );
+ nInc = IArray_GetSize( self->inc );
+ inc = (unsigned*)IArray_GetPtr((self->inc) );
+
+ /* If GNi isn't passed in - then evaluate them for you */
+ if (_GNi == NULL) {
+ /* Using 3 here instead of dim so that you can pass in dim = 2 and use axes 0 and 2 for your jacobian */
+ GNi = Memory_Alloc_2DArray( double, 3, nodesPerEl, (Name)"Temporary GNi" );
+ self->_evaluateShapeFunctionLocalDerivsAt( self, xi, GNi );
+ }
+ else GNi = _GNi;
+
+ /* build the jacobian matrix */
+ /*
+ jacobian = \sum_i d/d\xi( N_i ) x_i \sum_i d/d\xi( N_i ) y_i
+ \sum_i d/d\eta( N_i ) x_i \sum_i d/d\eta( N_i ) y_i
+ */
+ switch (dim) {
+ case 1:
+ jacobian[A_axis][A_axis] = 0.0;
+ for( node_I = 0 ; node_I < nodesPerEl; node_I++){
+ nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
+ jacobian[A_axis][A_axis] += GNi[A_axis][node_I] * nodeCoord[A_axis];
+ }
+ break;
+ case 2:
+ jacobian[A_axis][A_axis] = jacobian[A_axis][B_axis] = jacobian[B_axis][A_axis] = jacobian[B_axis][B_axis] = 0.0;
+ for( node_I = 0 ; node_I < nodesPerEl; node_I++){
+ nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
+ jacobian[A_axis][A_axis] += GNi[A_axis][node_I] * nodeCoord[A_axis];
+ jacobian[A_axis][B_axis] += GNi[A_axis][node_I] * nodeCoord[B_axis];
+
+ jacobian[B_axis][A_axis] += GNi[B_axis][node_I] * nodeCoord[A_axis];
+ jacobian[B_axis][B_axis] += GNi[B_axis][node_I] * nodeCoord[B_axis];
+ }
+ break;
+ case 3:
+ jacobian[A_axis][A_axis] = jacobian[A_axis][B_axis] = jacobian[A_axis][C_axis] = 0.0;
+ jacobian[B_axis][A_axis] = jacobian[B_axis][B_axis] = jacobian[B_axis][C_axis] = 0.0;
+ jacobian[C_axis][A_axis] = jacobian[C_axis][B_axis] = jacobian[C_axis][C_axis] = 0.0;
+ for( node_I = 0 ; node_I < nodesPerEl; node_I++){
+ nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
+
+ jacobian[A_axis][A_axis] += GNi[A_axis][node_I] * nodeCoord[A_axis];
+ jacobian[A_axis][B_axis] += GNi[A_axis][node_I] * nodeCoord[B_axis];
+ jacobian[A_axis][C_axis] += GNi[A_axis][node_I] * nodeCoord[C_axis];
+
+ jacobian[B_axis][A_axis] += GNi[B_axis][node_I] * nodeCoord[A_axis];
+ jacobian[B_axis][B_axis] += GNi[B_axis][node_I] * nodeCoord[B_axis];
+ jacobian[B_axis][C_axis] += GNi[B_axis][node_I] * nodeCoord[C_axis];
+
+ jacobian[C_axis][A_axis] += GNi[C_axis][node_I] * nodeCoord[A_axis];
+ jacobian[C_axis][B_axis] += GNi[C_axis][node_I] * nodeCoord[B_axis];
+ jacobian[C_axis][C_axis] += GNi[C_axis][node_I] * nodeCoord[C_axis];
+ }
+ break;
+ /* Mainly here to check unrolled loops above */
+ default: {
+ Coord_Index row_I, column_I;
+
+ for ( row_I = 0 ; row_I < dim ; row_I++ ) {
+ for ( column_I = 0 ; column_I < dim ; column_I++ ) {
+ /* Initialise */
+ jacobian[row_I][column_I] = 0.0;
+
+ /* Calculate */
+ for( node_I = 0 ; node_I < nodesPerEl; node_I++){
+ nodeCoord = Mesh_GetVertex( mesh, inc[node_I] );
+
+ jacobian[row_I][column_I] += GNi[row_I][node_I] * nodeCoord[column_I];
+ }
+ }
+ }
+ }
+ }
+
+ /* Clean up */
+ if (_GNi == NULL)
+ Memory_Free(GNi);
+}
+
+double ElementType_JacobianDeterminant_AxisIndependent(
+ void* elementType,
+ void* _mesh,
+ Element_DomainIndex elId,
+ double* xi,
+ Dimension_Index dim,
+ Coord_Index A_axis,
+ Coord_Index B_axis,
+ Coord_Index C_axis )
+{
+ double** jacobian;
+ double detJac;
+
+ /* Using 3 here instead of dim so that you can pass in dim = 2 and use axes 0 and 2 for your jacobian */
+ jacobian = Memory_Alloc_2DArray( double, 3, 3, (Name)"Temporary Jacobian" );
+
+ ElementType_Jacobian_AxisIndependent( elementType, _mesh, elId, xi, dim, jacobian, NULL, A_axis, B_axis, C_axis );
+ detJac = StGermain_MatrixDeterminant_AxisIndependent( jacobian, dim, A_axis, B_axis, C_axis );
+
+ /* Cleaning up */
+ Memory_Free( jacobian );
+
+ return detJac;
+}
+
+void ElementType_GetFaceNodes( void* elementType, Mesh* mesh, unsigned element_I, unsigned face_I,
+ unsigned nNodes, unsigned* nodes ) {
+ ElementType* self = (ElementType*) elementType;
+ Index node_i;
+ unsigned* inc;
+
+ assert( mesh && Stg_CheckType( mesh, FeMesh ) );
+
+ FeMesh_GetElementNodes( mesh, element_I, self->inc );
+ inc = (unsigned*)IArray_GetPtr((self->inc) );
+
+ for( node_i = 0; node_i < nNodes; node_i++ )
+ nodes[node_i] = inc[self->faceNodes[face_I][node_i]];
+}
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/ElementType_Register.c
--- a/Discretisation/src/ElementType_Register.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,232 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: ElementType_Register.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "ElementType.h"
-#include "ElementType_Register.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-/* Textual name of this class */
-const Type ElementType_Register_Type = "ElementType_Register";
-
-ElementType_Register* elementType_Register = 0;
-
-ElementType_Register* ElementType_Register_New( Name name ) {
- ElementType_Register* self = (ElementType_Register*)ElementType_Register_DefaultNew( name );
-
- self->isConstructed = True;
- _ElementType_Register_Init( self );
-
- return self;
-}
-
-void* ElementType_Register_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(ElementType_Register);
- Type type = ElementType_Register_Type;
- Stg_Class_DeleteFunction* _delete = _ElementType_Register_Delete;
- Stg_Class_PrintFunction* _print = _ElementType_Register_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = ElementType_Register_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _ElementType_Register_AssignFromXML;
- Stg_Component_BuildFunction* _build = _ElementType_Register_Build;
- Stg_Component_InitialiseFunction* _initialise = _ElementType_Register_Initialise;
- Stg_Component_ExecuteFunction* _execute = _ElementType_Register_Execute;
- Stg_Component_DestroyFunction* _destroy = _ElementType_Register_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
-
- return (void*) _ElementType_Register_New( ELEMENTTYPE_REGISTER_PASSARGS );
-}
-
-ElementType_Register* _ElementType_Register_New( ELEMENTTYPE_REGISTER_DEFARGS ) {
- ElementType_Register* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(ElementType_Register) );
- self = (ElementType_Register*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- /* General info */
-
- /* Virtual info */
-
- return self;
-}
-
-void _ElementType_Register_Init( void* elementType_Register ) {
- ElementType_Register* self = (ElementType_Register*)elementType_Register;
-
- /* General and Virtual info should already be set */
-
- /* ElementType_Register info */
- self->count = 0;
- self->_size = 8;
- self->_delta = 8;
- self->elementType = Memory_Alloc_Array( ElementType*, self->_size, "ElementType_Register->elementType" );
- memset( self->elementType, 0, sizeof(ElementType*) * self->_size );
- self->debug = Stream_RegisterChild( StgFEM_Discretisation_Debug, ElementType_Register_Type );
-}
-
-void _ElementType_Register_Delete( void* elementType_Register ) {
- ElementType_Register* self = (ElementType_Register*)elementType_Register;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- _Stg_Component_Delete( self );
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-void _ElementType_Register_Print( void* elementType_Register, Stream* stream ) {
- ElementType_Register* self = (ElementType_Register*)elementType_Register;
- ElementType_Index elementType_I;
-
- /* Set the Journal for printing informations */
- Stream* elementType_RegisterStream = stream;
-
- /* General info */
- Journal_Printf( stream, "ElementType_Register (ptr): %p\n", self );
-
- /* Print parent */
- _Stg_Class_Print( self, elementType_RegisterStream );
-
- /* Virtual info */
-
- /* ElementType_Register info */
- Journal_Printf( stream, "\tcount: %u\n", self->count );
- Journal_Printf( stream, "\t_size: %lu\n", self->_size );
- Journal_Printf( stream, "\t_delta: %lu\n", self->_delta );
-
- Journal_Printf( stream, "\telementType (ptr): %p\n", self->elementType );
- Journal_Printf( stream, "\telementType[0-%u]:\n", self->count );
-
- for( elementType_I = 0; elementType_I < self->count; elementType_I++ ) {
- Journal_Printf( stream, "elementType[%u]: ", elementType_I );
- Stg_Class_Print( self->elementType[elementType_I], elementType_RegisterStream );
- }
- Journal_Printf( stream, "\t]\n" );
-}
-
-void _ElementType_Register_AssignFromXML( void* elementType_Register, Stg_ComponentFactory *cf, void* data ){
- ElementType_Register* self = (ElementType_Register*)elementType_Register;
-
- self->context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", DomainContext, False, data );
- if( !self->context )
- self->context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", DomainContext, True, data );
-}
-
-void _ElementType_Register_Build( void* elementType_Register, void *data ){
-
-}
-
-void _ElementType_Register_Initialise( void* elementType_Register, void *data ){
-
-}
-
-void _ElementType_Register_Execute( void* elementType_Register, void *data ){
-
-}
-
-void _ElementType_Register_Destroy( void* elementType_Register, void *data ){
- ElementType_Register* self = (ElementType_Register*)elementType_Register;
-
- /* Assumes ownerships of the element types */
- if( self->elementType ) {
- ElementType_Index elementType_I;
-
- for( elementType_I = 0; elementType_I < self->count; elementType_I++ ) {
- _Stg_Component_Delete( self->elementType[elementType_I] );
- }
- }
- Memory_Free( self->elementType );
-}
-
-ElementType_Index ElementType_Register_Add( void* elementType_Register, void* elementType ) {
- ElementType_Register* self = (ElementType_Register*)elementType_Register;
- ElementType_Index handle;
-
- if( self->count >= self->_size ) {
- ElementType** newElementType;
-
- self->_size += self->_delta;
- newElementType = Memory_Alloc_Array( ElementType*, self->_size, "ElementType_Register->elementType" );
- memcpy( newElementType, self->elementType, sizeof(ElementType*) * self->count );
- Memory_Free( self->elementType );
- self->elementType = newElementType;
- Memory_Free( newElementType );
- }
-
- handle = self->count;
- self->elementType[handle] = (ElementType*)elementType;
- self->count++;
-
- /* Build the elementType... i.e assume it hasn't been built already */
- ElementType_Build( self->elementType[handle], NULL );
-
- return handle;
-}
-
-ElementType_Index ElementType_Register_GetIndex( void* elementType_Register, Type type ) {
- ElementType_Register* self = (ElementType_Register*)elementType_Register;
- ElementType_Index elementType_I;
-
- for( elementType_I = 0; elementType_I < self->count; elementType_I++ ) {
- if( self->elementType[elementType_I]->type == type ) {
- return elementType_I;
- }
- }
- return (unsigned)-1;
-}
-
-ElementType* _ElementType_Register_At( void* elementType_Register, ElementType_Index handle ) {
- ElementType_Register* self = (ElementType_Register*)elementType_Register;
-
- return ElementType_Register_At( self, handle );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/ElementType_Register.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/ElementType_Register.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,232 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: ElementType_Register.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "ElementType.h"
+#include "ElementType_Register.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+/* Textual name of this class */
+const Type ElementType_Register_Type = "ElementType_Register";
+
+ElementType_Register* elementType_Register = 0;
+
+ElementType_Register* ElementType_Register_New( Name name ) {
+ ElementType_Register* self = (ElementType_Register*)ElementType_Register_DefaultNew( name );
+
+ self->isConstructed = True;
+ _ElementType_Register_Init( self );
+
+ return self;
+}
+
+void* ElementType_Register_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(ElementType_Register);
+ Type type = ElementType_Register_Type;
+ Stg_Class_DeleteFunction* _delete = _ElementType_Register_Delete;
+ Stg_Class_PrintFunction* _print = _ElementType_Register_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = ElementType_Register_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _ElementType_Register_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _ElementType_Register_Build;
+ Stg_Component_InitialiseFunction* _initialise = _ElementType_Register_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _ElementType_Register_Execute;
+ Stg_Component_DestroyFunction* _destroy = _ElementType_Register_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+
+ return (void*) _ElementType_Register_New( ELEMENTTYPE_REGISTER_PASSARGS );
+}
+
+ElementType_Register* _ElementType_Register_New( ELEMENTTYPE_REGISTER_DEFARGS ) {
+ ElementType_Register* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(ElementType_Register) );
+ self = (ElementType_Register*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ /* General info */
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _ElementType_Register_Init( void* elementType_Register ) {
+ ElementType_Register* self = (ElementType_Register*)elementType_Register;
+
+ /* General and Virtual info should already be set */
+
+ /* ElementType_Register info */
+ self->count = 0;
+ self->_size = 8;
+ self->_delta = 8;
+ self->elementType = Memory_Alloc_Array( ElementType*, self->_size, "ElementType_Register->elementType" );
+ memset( self->elementType, 0, sizeof(ElementType*) * self->_size );
+ self->debug = Stream_RegisterChild( StgFEM_Discretisation_Debug, ElementType_Register_Type );
+}
+
+void _ElementType_Register_Delete( void* elementType_Register ) {
+ ElementType_Register* self = (ElementType_Register*)elementType_Register;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ _Stg_Component_Delete( self );
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+void _ElementType_Register_Print( void* elementType_Register, Stream* stream ) {
+ ElementType_Register* self = (ElementType_Register*)elementType_Register;
+ ElementType_Index elementType_I;
+
+ /* Set the Journal for printing informations */
+ Stream* elementType_RegisterStream = stream;
+
+ /* General info */
+ Journal_Printf( stream, "ElementType_Register (ptr): %p\n", self );
+
+ /* Print parent */
+ _Stg_Class_Print( self, elementType_RegisterStream );
+
+ /* Virtual info */
+
+ /* ElementType_Register info */
+ Journal_Printf( stream, "\tcount: %u\n", self->count );
+ Journal_Printf( stream, "\t_size: %lu\n", self->_size );
+ Journal_Printf( stream, "\t_delta: %lu\n", self->_delta );
+
+ Journal_Printf( stream, "\telementType (ptr): %p\n", self->elementType );
+ Journal_Printf( stream, "\telementType[0-%u]:\n", self->count );
+
+ for( elementType_I = 0; elementType_I < self->count; elementType_I++ ) {
+ Journal_Printf( stream, "elementType[%u]: ", elementType_I );
+ Stg_Class_Print( self->elementType[elementType_I], elementType_RegisterStream );
+ }
+ Journal_Printf( stream, "\t]\n" );
+}
+
+void _ElementType_Register_AssignFromXML( void* elementType_Register, Stg_ComponentFactory *cf, void* data ){
+ ElementType_Register* self = (ElementType_Register*)elementType_Register;
+
+ self->context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", DomainContext, False, data );
+ if( !self->context )
+ self->context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", DomainContext, True, data );
+}
+
+void _ElementType_Register_Build( void* elementType_Register, void *data ){
+
+}
+
+void _ElementType_Register_Initialise( void* elementType_Register, void *data ){
+
+}
+
+void _ElementType_Register_Execute( void* elementType_Register, void *data ){
+
+}
+
+void _ElementType_Register_Destroy( void* elementType_Register, void *data ){
+ ElementType_Register* self = (ElementType_Register*)elementType_Register;
+
+ /* Assumes ownerships of the element types */
+ if( self->elementType ) {
+ ElementType_Index elementType_I;
+
+ for( elementType_I = 0; elementType_I < self->count; elementType_I++ ) {
+ _Stg_Component_Delete( self->elementType[elementType_I] );
+ }
+ }
+ Memory_Free( self->elementType );
+}
+
+ElementType_Index ElementType_Register_Add( void* elementType_Register, void* elementType ) {
+ ElementType_Register* self = (ElementType_Register*)elementType_Register;
+ ElementType_Index handle;
+
+ if( self->count >= self->_size ) {
+ ElementType** newElementType;
+
+ self->_size += self->_delta;
+ newElementType = Memory_Alloc_Array( ElementType*, self->_size, "ElementType_Register->elementType" );
+ memcpy( newElementType, self->elementType, sizeof(ElementType*) * self->count );
+ Memory_Free( self->elementType );
+ self->elementType = newElementType;
+ Memory_Free( newElementType );
+ }
+
+ handle = self->count;
+ self->elementType[handle] = (ElementType*)elementType;
+ self->count++;
+
+ /* Build the elementType... i.e assume it hasn't been built already */
+ ElementType_Build( self->elementType[handle], NULL );
+
+ return handle;
+}
+
+ElementType_Index ElementType_Register_GetIndex( void* elementType_Register, Type type ) {
+ ElementType_Register* self = (ElementType_Register*)elementType_Register;
+ ElementType_Index elementType_I;
+
+ for( elementType_I = 0; elementType_I < self->count; elementType_I++ ) {
+ if( self->elementType[elementType_I]->type == type ) {
+ return elementType_I;
+ }
+ }
+ return (unsigned)-1;
+}
+
+ElementType* _ElementType_Register_At( void* elementType_Register, ElementType_Index handle ) {
+ ElementType_Register* self = (ElementType_Register*)elementType_Register;
+
+ return ElementType_Register_At( self, handle );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FeEquationNumber.c
--- a/Discretisation/src/FeEquationNumber.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3367 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: FeEquationNumber.c 1191 2008-07-25 03:06:19Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "ElementType.h"
-#include "ElementType_Register.h"
-#include "Element.h"
-#include "FeMesh.h"
-#include "FeEquationNumber.h"
-#include "LinkedDofInfo.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <mpi.h>
-#include <petsc.h>
-#include <petscvec.h>
-
-int stgCmpInt( const void *l, const void *r ) {
- return *(int*)l - *(int*)r;
-}
-
-/*###### Typedefs and Structs ######*/
-
-/** Textual name of this class */
-const Type FeEquationNumber_Type = "FeEquationNumber";
-
-/** struct to store sub-totals: what is the equation number up to at a given
- node? These can then be exchanged between processors */
-typedef struct CritPointInfo {
- Node_GlobalIndex index;
- Dof_EquationNumber eqNum;
-} CritPointInfo;
-
-
-/** An element of linked list of critical point info. Several of the functions
- use this to keep track of key points */
-typedef struct AddListEntry {
- CritPointInfo* critPointInfo;
- struct AddListEntry* next;
-} AddListEntry;
-
-/** Enum to say whetehr values at crit. nodes should be printed */
-typedef enum PrintValuesFlag {
- DONT_PRINT_VALUES,
- PRINT_VALUES
-} PrintValuesFlag;
-
-/** MPI datatype handle for efficiently exchanging CritPointInfo structures.
- see FeEquationNumber_Create_CritPointInfo_MPI_Datatype() for where this
- handle is defined. */
-MPI_Datatype MPI_critPointInfoType;
-
-/*###### Private Function Declarations ######*/
-
-#if 0
-static void _FeEquationNumber_BuildRemappedNodeInfoTable( void* feEquationNumber );
-
-static void _FeEquationNumber_CalculateDomainKnownCriticalPoints(
- FeEquationNumber* self,
- Node_DomainIndex nodeDomainCount,
- CritPointInfo* mySetEnds,
- Index* const mySetEndsTotal,
- Node_GlobalIndex* myWantedCriticalPoints,
- Index* const myWantedCriticalPointsTotal );
-
-static void _FeEquationNumber_HandleNode(
- FeEquationNumber* self,
- const Node_DomainIndex dNode_I,
- Dof_EquationNumber* const currEqNum );
-
-static void _FeEquationNumber_PostProcessLinkedDofs( FeEquationNumber* self );
-
-static void _FeEquationNumber_CalculateCritPointsIHave(
- FeEquationNumber* self,
- Node_GlobalIndex** const myWantedCriticalPointsPtr,
- Node_GlobalIndex myWantedCriticalPointsTotal,
- CritPointInfo** const critPointsIHave,
- Index* const critPointsIHaveTotal,
- CritPointInfo* const critPointsToSend,
- Index* const critPointsToSendTotal );
-
-static void _FeEquationNumber_ShareCriticalPoints(
- FeEquationNumber* self,
- Node_GlobalIndex** const myCriticalPoints,
- Node_GlobalIndex myCriticalPointsTotal,
- Node_GlobalIndex** allCriticalPoints,
- Index** procCritPointsTotals,
- Node_GlobalIndex* const maxCritPointsPerProc );
-
-static void _FeEquationNumber_ShareCritPointInfo(
- FeEquationNumber* self,
- CritPointInfo** const myCritPointInfo,
- Index myCritPointInfoTotal,
- CritPointInfo** allCritPointInfo,
- Index** procCritPointInfoTotals,
- Index* const maxCritPointInfoPerProc,
- PrintValuesFlag printValuesFlag );
-
-static void _FeEquationNumber_DoPartialTotals(
- FeEquationNumber* self,
- CritPointInfo* const critPointsIHave,
- Index critPointsIHaveTotal,
- CritPointInfo* const critPointsToSend,
- Index critPointsToSendTotal );
-
-static void _FeEquationNumber_AddAllPartialTotals(
- FeEquationNumber* self,
- CritPointInfo* mySubTotals,
- Index myCritPointInfoTotal,
- CritPointInfo* allSubTotals,
- Index* procCritPointInfoTotals,
- Index maxSubTotalsPerProc );
-
-Node_RemappedGlobalIndex _FeEquationNumber_RemapNode(
- Mesh* mesh,
- Index newDimOrder[3],
- Node_GlobalIndex gNode_I );
-
-int GenerateEquationNumbering(
- int NX, int NY, int NZ,
- int nlocal, int g_node_id[],
- int dof, int nglobal,
- PetscTruth periodic_x, PetscTruth periodic_y, PetscTruth periodic_z,
- int npx, int npy, int npz,
- int periodic_x_gnode_id[], int periodic_y_gnode_id[], int periodic_z_gnode_id[],
- int eqnums[], int *neqnums );
-
-/** Tests if the critical point from another processor is held by ours.
- Is complicated by the possibility of remapping. */
-static Bool _FeEquationNumber_IHaveCritPoint(
- FeEquationNumber* self,
- Node_RemappedGlobalIndex critPoint );
-#endif
-
-/*###### Function Definitions ######*/
-
-/** Public constructor */
-
-FeEquationNumber* FeEquationNumber_New(
- Name name,
- DomainContext* context,
- void* mesh,
- DofLayout* dofLayout,
- VariableCondition* bcs,
- LinkedDofInfo* linkedDofInfo )
-{
- FeEquationNumber* self = (FeEquationNumber*)FeEquationNumber_DefaultNew( name );
-
- self->isConstructed = True;
- _FeEquationNumber_Init( self, context, mesh, dofLayout, bcs, linkedDofInfo );
-
- return self;
-}
-
-void* FeEquationNumber_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(FeEquationNumber);
- Type type = FeEquationNumber_Type;
- Stg_Class_DeleteFunction* _delete = _FeEquationNumber_Delete;
- Stg_Class_PrintFunction* _print = _FeEquationNumber_Print;
- Stg_Class_CopyFunction* _copy = _FeEquationNumber_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (Stg_Component_DefaultConstructorFunction*)FeEquationNumber_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _FeEquationNumber_AssignFromXML;
- Stg_Component_BuildFunction* _build = _FeEquationNumber_Build;
- Stg_Component_InitialiseFunction* _initialise = _FeEquationNumber_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FeEquationNumber_Execute;
- Stg_Component_DestroyFunction* _destroy = _FeEquationNumber_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
-
- return _FeEquationNumber_New( FEEQUATIONNUMBER_PASSARGS );
-}
-/** Constructor implementation. */
-FeEquationNumber* _FeEquationNumber_New( FEEQUATIONNUMBER_DEFARGS ){
- FeEquationNumber* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(FeEquationNumber) );
- self = (FeEquationNumber*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- /* General info */
-
- /* Virtual info */
- self->_build = _build;
- self->_initialise = _initialise;
-
- /* Mesh info */
-
- return self;
-}
-
-
-/** Constructor variables initialisation. Doesn't allocate any
- memory, just saves arguments and sets counters to 0. */
-void _FeEquationNumber_Init(
- FeEquationNumber* self,
- DomainContext* context,
- void* feMesh,
- DofLayout* dofLayout,
- VariableCondition* bcs,
- LinkedDofInfo* linkedDofInfo )
-{
- /* General and Virtual info should already be set */
-
- /* FinteElementMesh info */
- self->context = context;
- self->feMesh = (FeMesh*)feMesh;
- self->globalSumUnconstrainedDofs = 0;
- self->isBuilt = False;
- self->locationMatrixBuilt = False;
- self->_lowestLocalEqNum = -1;
- self->_lowestGlobalEqNums = NULL;
- self->_highestLocalEqNum = -1;
- self->dofLayout = dofLayout;
- self->bcs = bcs;
- self->linkedDofInfo = linkedDofInfo;
- self->remappingActivated = False;
- /* register streams */
- self->debug = Stream_RegisterChild( StgFEM_Discretisation_Debug, FeEquationNumber_Type );
- self->debugLM = Stream_RegisterChild( self->debug, "LM" );
- self->warning = Stream_RegisterChild( StgFEM_Warning, FeEquationNumber_Type );
- self->removeBCs = True;
- self->bcEqNums = STree_New();
- STree_SetIntCallbacks( self->bcEqNums );
- STree_SetItemSize( self->bcEqNums, sizeof(int) );
- self->ownedMap = STreeMap_New();
- STreeMap_SetItemSize( self->ownedMap, sizeof(int), sizeof(int) );
- STree_SetIntCallbacks( self->ownedMap );
-
- Stream_SetPrintingRank( self->debug, 0 );
-}
-
-void _FeEquationNumber_AssignFromXML( void* feEquationNumber, Stg_ComponentFactory *cf, void* data ) {
-}
-
-void _FeEquationNumber_Execute( void* feEquationNumber, void *data ){
-
-}
-
-void _FeEquationNumber_Destroy( void* feEquationNumber, void *data ){
- FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
- Index ii;
-
- Stg_Component_Destroy( self->feMesh , data, False );
- Stg_Component_Destroy( self->dofLayout, data, False );
- if ( self->linkedDofInfo ) Stg_Component_Destroy( self->dofLayout, data, False );
- if ( self->bcs ) Stg_Component_Destroy( self->bcs , data, False );
-
- FreeArray( self->remappedNodeInfos );
- /* free destination array memory */
- Journal_DPrintfL( self->debug, 2, "Freeing I.D. Array\n" );
- FreeArray( self->destinationArray );
-
- if (self->locationMatrix) {
- Journal_DPrintfL( self->debug, 2, "Freeing Full L.M. Array\n" );
- for( ii = 0; ii < self->nDomainEls; ii++ )
- FreeArray( self->locationMatrix[ii] );
-
- FreeArray( self->locationMatrix );
- }
-
- if( self->bcEqNums )
- NewClass_Delete( self->bcEqNums );
-
- if( self->ownedMap )
- NewClass_Delete( self->ownedMap );
-}
-
-/* Copy */
-
-/** Stg_Class_Delete implementation. */
-void _FeEquationNumber_Delete( void* feEquationNumber ) {
- FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
-
- Journal_DPrintfL( self->debug, 1, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- /* Stg_Class_Delete parent */
- _Stg_Class_Delete( self );
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-/** Print implementation */
-void _FeEquationNumber_Print( void* mesh, Stream* stream ) {
- FeEquationNumber* self = (FeEquationNumber*)mesh;
-
- /* General info */
- Journal_Printf( stream, "FeEquationNumber (ptr): %p\n", self );
-
- /* Print parent */
- _Stg_Class_Print( self, stream );
-
- /* Virtual info */
- Journal_Printf( stream, "\t_build (func ptr): %p\n", self->_build );
- Journal_Printf( stream, "\t_intialise (func ptr): %p\n", self->_initialise );
-
- /* FeEquationNumber info */
- /* Don't print dofs or bcs as these will be printed by FeVariable */
-
- if ( self->destinationArray ) {
- FeEquationNumber_PrintDestinationArray( self, stream );
- FeEquationNumber_PrintLocationMatrix( self, stream );
- }
- else {
- Journal_Printf( stream, "\tdestinationArray: (null)... not built yet\n" );
- Journal_Printf( stream, "\tlocationMatrix: (null)... not built yet\n" );
- }
-}
-
-
-void* _FeEquationNumber_Copy( const void* feEquationNumber, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
-#if 0
- FeEquationNumber* self = (FeEquationNumber*)feEquationNumber;
- Mesh* mesh;
- FeEquationNumber* newFeEquationNumber;
- PtrMap* map = ptrMap;
- Bool ownMap = False;
-
- mesh = (Mesh*)self->feMesh;
-
- if( !map ) {
- map = PtrMap_New( 10 );
- ownMap = True;
- }
-
- newFeEquationNumber = _Stg_Class_Copy( self, dest, deep, nameExt, map );
-
- /* Virtual methods */
- newFeEquationNumber->_build = self->_build;
- newFeEquationNumber->_initialise = self->_initialise;
-
- newFeEquationNumber->_highestLocalEqNum = self->_highestLocalEqNum;
- newFeEquationNumber->_lowestLocalEqNum = self->_lowestLocalEqNum;
- newFeEquationNumber->_eqNumsPerProcDivisor = self->_eqNumsPerProcDivisor;
- newFeEquationNumber->_eqNumsRemainder = self->_eqNumsRemainder;
- newFeEquationNumber->_remNotAddedChangeover = self->_remNotAddedChangeover;
- newFeEquationNumber->firstOwnedEqNum = self->firstOwnedEqNum;
- newFeEquationNumber->lastOwnedEqNum = self->lastOwnedEqNum;
- newFeEquationNumber->localEqNumsOwnedCount = self->localEqNumsOwnedCount;
- newFeEquationNumber->globalSumUnconstrainedDofs = self->globalSumUnconstrainedDofs;
- newFeEquationNumber->locationMatrixBuilt = self->locationMatrixBuilt;
- newFeEquationNumber->remappingActivated = self->remappingActivated;
-
- if( deep ) {
- newFeEquationNumber->debug = (Stream*)Stg_Class_Copy( self->debug, NULL, deep, nameExt, map );
- newFeEquationNumber->debugLM = (Stream*)Stg_Class_Copy( self->debugLM, NULL, deep, nameExt, map );
- newFeEquationNumber->warning = (Stream*)Stg_Class_Copy( self->warning, NULL, deep, nameExt, map );
- newFeEquationNumber->feMesh = (FeMesh*)Stg_Class_Copy( self->feMesh, NULL, deep, nameExt, map );
- newFeEquationNumber->dofLayout = (DofLayout*)Stg_Class_Copy( self->dofLayout, NULL, deep, nameExt, map );
- newFeEquationNumber->bcs = (VariableCondition*)Stg_Class_Copy( self->bcs, NULL, deep, nameExt, map );
- newFeEquationNumber->linkedDofInfo = (LinkedDofInfo*)Stg_Class_Copy( self->linkedDofInfo, NULL, deep, nameExt, map );
-
- if( (newFeEquationNumber->remappedNodeInfos = PtrMap_Find( map, self->remappedNodeInfos )) == NULL && self->remappedNodeInfos ) {
- Node_DomainIndex nodeDomainCount;
-
- nodeDomainCount = Mesh_GetDomainSize( mesh, MT_VERTEX );
-
- newFeEquationNumber->remappedNodeInfos = Memory_Alloc_Array( RemappedNodeInfo, nodeDomainCount, "FeEquationNumber->remappedNodeInfos" );
- memcpy( newFeEquationNumber->remappedNodeInfos, self->remappedNodeInfos, sizeof(RemappedNodeInfo) * nodeDomainCount );
- PtrMap_Append( map, self->remappedNodeInfos, newFeEquationNumber->remappedNodeInfos );
- }
-
- if( (newFeEquationNumber->destinationArray = PtrMap_Find( map, self->destinationArray )) == NULL && self->destinationArray ) {
- Node_DomainIndex nodeDomainCount;
- Node_DomainIndex node_dI;
-
- nodeDomainCount = Mesh_GetDomainSize( mesh, MT_VERTEX );
-
- newFeEquationNumber->destinationArray = Memory_Alloc_2DComplex( Dof_EquationNumber, nodeDomainCount, self->dofLayout->dofCounts, "FeEquationNumber->destinationArray" );
- for( node_dI = 0; node_dI < nodeDomainCount; node_dI++ ) {
- memcpy( newFeEquationNumber->destinationArray[node_dI], self->destinationArray[node_dI], sizeof(Dof_EquationNumber) * self->dofLayout->dofCounts[node_dI] );
- }
- PtrMap_Append( map, self->destinationArray, newFeEquationNumber->destinationArray );
- }
-
- if( (newFeEquationNumber->_lowestGlobalEqNums = PtrMap_Find( map, self->_lowestGlobalEqNums )) == NULL && self->_lowestGlobalEqNums ) {
- Partition_Index nProc;
-
- nProc = Mesh_GetCommTopology( mesh, MT_VERTEX )->nProcs;
-
- newFeEquationNumber->_lowestGlobalEqNums = Memory_Alloc_Array( Dof_EquationNumber, nProc, "FeEquationNumber->_lowestGlobalEqNums" );
- memcpy( newFeEquationNumber->_lowestGlobalEqNums, self->_lowestGlobalEqNums, sizeof(Dof_EquationNumber) * nProc );
- PtrMap_Append( map, self->_lowestGlobalEqNums, newFeEquationNumber->_lowestGlobalEqNums );
- }
-
- if( (newFeEquationNumber->locationMatrix = PtrMap_Find( map, self->locationMatrix )) == NULL && self->locationMatrix ) {
- FeMesh* mesh = self->feMesh;
- Element_LocalIndex lElement_I;
- Node_LocalIndex numNodesThisElement;
- Node_LocalIndex elLocalNode_I;
- Dof_Index numDofsThisNode;
- Element_LocalIndex elementLocalCount = mesh->elementLocalCount;
- Dof_Index** dofCountsAtElementNodesArray;
-
- dofCountsAtElementNodesArray = Memory_Alloc_3DSetup( elementLocalCount, mesh->elementNodeCountTbl );
- for ( lElement_I = 0; lElement_I < elementLocalCount; lElement_I++ ) {
- numNodesThisElement = mesh->elementNodeCountTbl[lElement_I];
-
- for( elLocalNode_I = 0; elLocalNode_I < numNodesThisElement; elLocalNode_I++) {
- Node_LocalIndex dNode_I = mesh->elementNodeTbl[lElement_I][elLocalNode_I];
-
- numDofsThisNode = self->dofLayout->dofCounts[dNode_I];
- dofCountsAtElementNodesArray[lElement_I][elLocalNode_I] = numDofsThisNode;
- }
- }
-
- newFeEquationNumber->locationMatrix = Memory_Alloc_3DComplex( Dof_EquationNumber, elementLocalCount, mesh->elementNodeCountTbl, dofCountsAtElementNodesArray, "FeEquationNumber->locationMatrix" );
- for( lElement_I = 0; lElement_I < elementLocalCount; lElement_I++ ) {
- for( elLocalNode_I = 0; elLocalNode_I < mesh->elementNodeCountTbl[lElement_I]; elLocalNode_I++ ) {
- memcpy( newFeEquationNumber->locationMatrix[lElement_I][elLocalNode_I], self->locationMatrix[lElement_I][elLocalNode_I], sizeof(Dof_EquationNumber) * dofCountsAtElementNodesArray[lElement_I][elLocalNode_I] );
- }
- }
-
- Memory_Free( dofCountsAtElementNodesArray );
- PtrMap_Append( map, self->locationMatrix, newFeEquationNumber->locationMatrix );
- }
- }
- else {
- newFeEquationNumber->debug = self->debug;
- newFeEquationNumber->debugLM = self->debugLM;
- newFeEquationNumber->warning = self->warning;
- newFeEquationNumber->feMesh = self->feMesh;
- newFeEquationNumber->dofLayout = self->dofLayout;
- newFeEquationNumber->bcs = self->bcs;
- newFeEquationNumber->linkedDofInfo = self->linkedDofInfo;
- newFeEquationNumber->remappedNodeInfos = self->remappedNodeInfos;
- newFeEquationNumber->destinationArray = self->destinationArray;
- newFeEquationNumber->_lowestGlobalEqNums = self->_lowestGlobalEqNums;
- newFeEquationNumber->locationMatrix = self->locationMatrix;
- }
-
- if( ownMap ) {
- Stg_Class_Delete( map );
- }
-
- return (void*)newFeEquationNumber;
-#endif
- abort();
-}
-
-void _FeEquationNumber_Build( void* feEquationNumber, void* data ) {
- FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
-
- assert(self);
-
- Journal_DPrintf( self->debug, "In %s:\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- Stg_Component_Build( self->feMesh , data, False );
- Stg_Component_Build( self->dofLayout, data, False );
- if ( self->linkedDofInfo ) Stg_Component_Build( self->dofLayout, data, False );
- if ( self->bcs ) Stg_Component_Build( self->bcs , data, False );
- /* If we have new mesh topology information, do this differently. */
- /* if( self->feMesh->topo->domains && self->feMesh->topo->domains[MT_VERTEX] ) { */
-
- if( Mesh_HasExtension( self->feMesh, "vertexGrid" ) )
- FeEquationNumber_BuildWithDave( self );
- else
- FeEquationNumber_BuildWithTopology( self );
-
- /* If not removing BCs, construct a table of which equation numbers are actually BCs. */
- if( !self->removeBCs ) {
- FeMesh* mesh = self->feMesh;
- DofLayout* dofLayout = self->dofLayout;
- VariableCondition* bcs = self->bcs;
- int nDofs, varInd;
- unsigned ii;
- int jj;
-
- for( ii = 0; ii < FeMesh_GetNodeLocalSize( mesh ); ii++ ) {
- nDofs = dofLayout->dofCounts[ii];
- for( jj = 0; jj < nDofs; jj++ ) {
- varInd = dofLayout->varIndices[ii][jj];
- if( bcs && VariableCondition_IsCondition( bcs, ii, varInd ) ) {
- if( !STree_Has( self->bcEqNums, self->destinationArray[ii] + jj ) )
- STree_Insert( self->bcEqNums, self->destinationArray[ii] + jj );
- }
- }
- }
- }
-
- /*}
- else {
- _FeEquationNumber_BuildRemappedNodeInfoTable( self );
- _FeEquationNumber_BuildDestinationArray( self );
- _FeEquationNumber_CalculateGlobalUnconstrainedDofTotal( self );
- _FeEquationNumber_CalculateEqNumsDecomposition( self );
- }*/
-
- if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
- FeEquationNumber_PrintDestinationArray( self, self->debug );
- }
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-/** Initialise implementation. Currently does nothing. */
-void _FeEquationNumber_Initialise( void* feEquationNumber, void* data ) {
- FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
-
- Stg_Component_Initialise( self->feMesh , data, False );
- Stg_Component_Initialise( self->dofLayout, data, False );
- if ( self->linkedDofInfo ) Stg_Component_Initialise( self->dofLayout, data, False );
- if ( self->bcs ) Stg_Component_Initialise( self->bcs , data, False );
-}
-
-
-#if 0
-Node_RemappedGlobalIndex _FeEquationNumber_RemapNode(
- HexaMD* hexaMD,
- Index newDimOrder[3],
- Node_GlobalIndex gNode_I )
-{
- Node_RemappedGlobalIndex remappedGlobalIndex = 0;
- Index dim_I = 0;
- Index currNewDim = 0;
- IJK defaultIJK;
- IJK newOrderIJK;
- IJK newOrderNodeCounts;
-
- Dimension_1DTo3D( gNode_I, hexaMD->nodeGlobal3DCounts, defaultIJK );
-
- for ( dim_I = I_AXIS; dim_I < 3; dim_I++ ) {
- currNewDim = newDimOrder[dim_I];
- newOrderIJK[dim_I] = defaultIJK[currNewDim];
- newOrderNodeCounts[dim_I] = hexaMD->nodeGlobal3DCounts[currNewDim];
- }
-
- Dimension_3DTo1D( newOrderIJK, newOrderNodeCounts, &remappedGlobalIndex );
-
- return remappedGlobalIndex;
-}
-
-
-static void _FeEquationNumber_BuildRemappedNodeInfoTable( void* feEquationNumber ) {
- FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
- FeMesh* mesh = self->feMesh;
- Node_DomainIndex nodeDomainCount = Mesh_GetDomainSize( mesh, MT_VERTEX );
- CommTopology* commTopo = Mesh_GetCommTopology( mesh, MT_VERTEX );
- Node_GlobalIndex gNode_I = 0;
- Node_DomainIndex dNode_I = 0;
-/*#if DEBUG*/
- RemappedNodeInfo_Index rNodeInfo_I;
-/*#endif*/
-
- Journal_DPrintfL( self->debug, 1, "In %s:\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- self->remappedNodeInfos = Memory_Alloc_Array( RemappedNodeInfo, nodeDomainCount,
- "FeEquationNumber->remappedNodeInfos" );
-
- if ( 1 == commTopo->nProcs ) {
- Journal_DPrintfL( self->debug, 1, "Serial code: No remapping required...filling remapping table with normal values.\n" );
- for (dNode_I = 0; dNode_I < nodeDomainCount; dNode_I++ ) {
- gNode_I = mesh->nodeD2G[dNode_I];
- self->remappedNodeInfos[dNode_I].remappedGlobal = gNode_I;
- self->remappedNodeInfos[dNode_I].domain = dNode_I;
- }
- }
- else if ( meshDecomp->type != HexaMD_Type ) {
- Node_GlobalIndex prevGNode_I = (unsigned int)-1;
- RemappedNodeInfo_Index insertIndex;
-
- Journal_DPrintfL( self->debug, 1, "Parallel, but non-hexa decomp: building the remapping table by "
- "insertion-sorting based on global node number order.\n" );
- for (dNode_I = 0; dNode_I < nodeDomainCount; dNode_I++ ) {
- gNode_I = mesh->nodeD2G[dNode_I];
-
- if ( gNode_I > prevGNode_I ) {
- self->remappedNodeInfos[dNode_I].remappedGlobal = gNode_I;
- self->remappedNodeInfos[dNode_I].domain = dNode_I;
- prevGNode_I = gNode_I;
- continue;
- }
- else {
- insertIndex = 0;
- while ( gNode_I > self->remappedNodeInfos[insertIndex].remappedGlobal ) insertIndex++;
- memmove( &self->remappedNodeInfos[insertIndex+1], &self->remappedNodeInfos[insertIndex],
- sizeof(RemappedNodeInfo) * (dNode_I - insertIndex + 1) );
- self->remappedNodeInfos[insertIndex].remappedGlobal = gNode_I;
- self->remappedNodeInfos[insertIndex].domain = dNode_I;
- }
- }
- }
- else if ( ((HexaMD*)meshDecomp)->numPartitionedDims > 1 )
- {
- Node_GlobalIndex nextShadowGlobalMap;
- Node_LocalIndex lNode_I;
- Node_ShadowIndex sNode_I = mesh->nodeLocalCount;
- RemappedNodeInfo_Index insertIndex = 0;
-
- Journal_DPrintfL( self->debug, 1, "Parallel, hexa decomp but multiple partition dims:\n"
- "filling remapping table with insertion sort\n"
- "of local & shadow elements.\n" );
-
- if ( meshDecomp->shadowDepth > 0 ) {
- nextShadowGlobalMap = mesh->nodeD2G[sNode_I];
- }
- else {
- nextShadowGlobalMap = mesh->nodeGlobalCount;
- }
-
- insertIndex = 0;
- for (lNode_I = 0; lNode_I < mesh->nodeLocalCount; lNode_I++ ) {
- gNode_I = mesh->nodeL2G[lNode_I];
-
- while ( nextShadowGlobalMap < gNode_I ) {
- self->remappedNodeInfos[insertIndex].remappedGlobal = nextShadowGlobalMap;
- self->remappedNodeInfos[insertIndex++].domain = sNode_I++;
- if ( sNode_I < mesh->nodeDomainCount ) {
- nextShadowGlobalMap = mesh->nodeD2G[sNode_I];
- }
- else {
- nextShadowGlobalMap = mesh->nodeGlobalCount;
- }
- }
- self->remappedNodeInfos[insertIndex].remappedGlobal = gNode_I;
- self->remappedNodeInfos[insertIndex++].domain = lNode_I;
- }
-
- /* now know all local elements inserted, so ensure all shadow elements have also been inserted */
- for ( ; sNode_I < mesh->nodeDomainCount; sNode_I++ ) {
- gNode_I = mesh->nodeD2G[sNode_I];
- self->remappedNodeInfos[insertIndex].remappedGlobal = gNode_I;
- self->remappedNodeInfos[insertIndex++].domain = sNode_I;
- }
- Journal_Firewall( (insertIndex == mesh->nodeDomainCount), self->debug,
- "Stuffup: should have inserted exactly the right number of values by here.\n" );
- }
- else {
- /* Otherwise, we remap each of the global node values, so the eqNums
- will cause minimal communication during mesh assembly */
- Node_RemappedGlobalIndex currRemappedGNode_I = 0;
- Node_RemappedGlobalIndex firstRemappedGNode_I = 0;
- Index newDimOrder[3] = {0,0,0};
- Index newOrder_I = 0;
- Index partitionedAxis = I_AXIS;
- Index dim_I;
- RemappedNodeInfo_Index insertIndex;
- Bool lowestIsShadow = False;
-
- self->remappingActivated = True;
-
- Journal_DPrintfL( self->debug, 1, "Parallel, hexa decomp with 1 partition dim:\n"
- "remapping eqNum traversal order to be aligned with mesh decomposition:\n" );
-
- /* Work out the new dimension order for the EqNums. The partitioned index
- goes last */
- for ( dim_I = I_AXIS; dim_I < 3; dim_I++ ) {
- if (True == ((HexaMD*)meshDecomp)->partitionedAxis[dim_I]) {
- partitionedAxis = dim_I;
- newDimOrder[2] = partitionedAxis;
- } else {
- newDimOrder[newOrder_I++] = dim_I;
- }
- }
- Journal_DPrintfL( self->debug, 1, "Given partition axis is %c, calc. remapping dimension order as %c,%c,%c\n",
- IJKTopology_DimNumToDimLetter[partitionedAxis],
- IJKTopology_DimNumToDimLetter[newDimOrder[0]],
- IJKTopology_DimNumToDimLetter[newDimOrder[1]],
- IJKTopology_DimNumToDimLetter[newDimOrder[2]] );
-
- Journal_DPrintfL( self->debug, 4, "Calculating over %d domain nodes, %d local, %d shadow.\n",
- mesh->nodeDomainCount, mesh->nodeLocalCount, mesh->nodeShadowCount );
-
- /* Work out the lowest remapped global index (so we know where to insert into the table) */
- gNode_I = mesh->nodeD2G[0];
- firstRemappedGNode_I = _FeEquationNumber_RemapNode( (HexaMD*)meshDecomp, newDimOrder, gNode_I );
- /* if shadow elements are enabled, check if the first shadow element has lower
- global index than first local element */
- if ( meshDecomp->shadowDepth > 0 ) {
- Node_RemappedGlobalIndex firstRemappedShadowGNode_I;
-
- gNode_I = mesh->nodeD2G[mesh->nodeLocalCount];
- firstRemappedShadowGNode_I = _FeEquationNumber_RemapNode( (HexaMD*)meshDecomp,
- newDimOrder, gNode_I );
-
- if ( firstRemappedShadowGNode_I < firstRemappedGNode_I ) {
- firstRemappedGNode_I = firstRemappedShadowGNode_I;
- lowestIsShadow = True;
- }
- }
- Journal_DPrintfL( self->debug, 4, "Calculated lowest remapped global index is %d",
- firstRemappedGNode_I );
- if ( lowestIsShadow ) {
- Journal_DPrintfL( self->debug, 4, " (a shadow node.)\n" );
- }
- else {
- Journal_DPrintfL( self->debug, 4, " (a local node.)\n" );
- }
-
- Stream_IndentBranch( StgFEM_Debug );
- /* Now add the rest, relative to the first */
- for (dNode_I = 0; dNode_I < nodeDomainCount; dNode_I++ ) {
- gNode_I = mesh->nodeD2G[dNode_I];
- currRemappedGNode_I = _FeEquationNumber_RemapNode( (HexaMD*)meshDecomp, newDimOrder, gNode_I );
- insertIndex = currRemappedGNode_I - firstRemappedGNode_I;
- self->remappedNodeInfos[insertIndex].remappedGlobal = currRemappedGNode_I;
- self->remappedNodeInfos[insertIndex].domain = dNode_I;
- Journal_DPrintfL( self->debug, 4, "Processing domain node %d: original global = %d, remaps to %d.\n",
- dNode_I, gNode_I, currRemappedGNode_I );
- }
- Stream_UnIndentBranch( StgFEM_Debug );
- }
-
-/*#if DEBUG*/
- if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
- Journal_DPrintf( self->debug, "Calculated remapped node info table as:\n{\n" );
- for (rNodeInfo_I = 0; rNodeInfo_I < nodeDomainCount; rNodeInfo_I++ ) {
- Journal_DPrintf( self->debug, " %d:(remap=%d,domain=%d),\n", rNodeInfo_I,
- self->remappedNodeInfos[rNodeInfo_I].remappedGlobal,
- self->remappedNodeInfos[rNodeInfo_I].domain );
- }
- Journal_DPrintf( self->debug, "}\n");
- }
-/*#endif*/
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-/* Build the processor's ID (destination) array */
-void _FeEquationNumber_BuildDestinationArray( FeEquationNumber* self ) {
- MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
- Node_DomainIndex nodeDomainCount = meshDecomp->nodeDomainCount;
- CritPointInfo* critPointsIHave = NULL;
- Index critPointsIHaveTotal = 0;
- CritPointInfo* critPointsToSend = NULL;
- Index critPointsToSendTotal = 0;
- Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
-
- Journal_DPrintfL( self->debug, 1, "In %s:\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- Journal_Firewall( ( nodeDomainCount == self->dofLayout->_numItemsInLayout ),
- errorStream, "Error: In %s: DofLayout's size is %d, which isn't equal to "
- "Node domain count of %d. Did you create the dofLayout of size node local count? "
- "It should be aset up to size node domain count.\n",
- __func__, self->dofLayout->_numItemsInLayout, nodeDomainCount );
-
-
- self->destinationArray = Memory_Alloc_2DComplex( Dof_EquationNumber, nodeDomainCount,
- self->dofLayout->dofCounts, "FeEquationNumber->destinationArray" );
-
-
- if (meshDecomp->procsInUse == 1)
- {
- /* for serial jobs, don't worry about the critical points, just calculate
- the totals normally */
- critPointsIHave = Memory_Alloc( CritPointInfo, "critPointsIHave (BuildDestinationArray)" );
- critPointsToSend = Memory_Alloc( CritPointInfo, "critPointsToSend (BuildDestinationArray)" );
- critPointsIHave[0].index = meshDecomp->nodeGlobalCount;
- critPointsToSend[0].index = meshDecomp->nodeGlobalCount;
- _FeEquationNumber_DoPartialTotals( self, critPointsIHave, 0, critPointsToSend, 0 );
- self->_lowestLocalEqNum = 0;
- }
- else {
- Node_GlobalIndex* myWantedCriticalPoints = NULL;
- Index myWantedCriticalPointsTotal = 0;
- CritPointInfo* allSendCriticalPoints = NULL;
- Index* procSendCritPointsTotals = NULL;
- Index maxSendCritPointsPerProc = 0;
-
- critPointsIHave = Memory_Alloc_Array( CritPointInfo, nodeDomainCount,
- "critPointsIHave (BuildDestinationArray)" );
- critPointsToSend = Memory_Alloc_Array( CritPointInfo, nodeDomainCount,
- "critPointsToSend (BuildDestinationArray)" );
- myWantedCriticalPoints = Memory_Alloc_Array( Node_GlobalIndex, nodeDomainCount,
- "myWantedCritialPoints (BuildDestinationArray)" );
-
- /* Go through all domain nodes, work out end of runs, and interfaces needed */
- _FeEquationNumber_CalculateDomainKnownCriticalPoints( self, nodeDomainCount, critPointsIHave, &critPointsIHaveTotal,
- myWantedCriticalPoints, &myWantedCriticalPointsTotal );
-
- /* initialise the below to the set end critical nodes I already worked out I have */
- critPointsToSend = (CritPointInfo*) memcpy( critPointsToSend, critPointsIHave, (critPointsIHaveTotal * sizeof(CritPointInfo)) );
- critPointsToSendTotal = critPointsIHaveTotal;
-
- /* work out critical points (inc. those needed by others) I hold, and those to send.
- The list I have could be greater than my end of runs, in an irregular mesh case */
- _FeEquationNumber_CalculateCritPointsIHave( self,
- &myWantedCriticalPoints, myWantedCriticalPointsTotal, &critPointsIHave, &critPointsIHaveTotal,
- critPointsToSend, &critPointsToSendTotal );
-
- Memory_Free( myWantedCriticalPoints );
-
- /* OK: We now know all the critical points on this processor, so go ahead and work out the partial ID number
- at all of them. */
-
- Journal_DPrintfL( self->debug, 2, "Looping through nodes again, calculating eq nums (re-setting to 0 at critical points)\n,"
- "and storing subtotal of each each critical node:\n" );
- _FeEquationNumber_DoPartialTotals( self, critPointsIHave, critPointsIHaveTotal,
- critPointsToSend, critPointsToSendTotal );
-
- Journal_DPrintfL( self->debug, 2, "Now sub-totals have been calculated, share all of my critical point sub-totals "
- "and get any that I need:\n" );
- _FeEquationNumber_ShareCritPointInfo( self, &critPointsToSend, critPointsToSendTotal,
- &allSendCriticalPoints, &procSendCritPointsTotals, &maxSendCritPointsPerProc, PRINT_VALUES );
-
- Journal_DPrintfL( self->debug, 2, "Final loop: add the sub-totals at all the critical points to the existing values:\n" );
- _FeEquationNumber_AddAllPartialTotals( self, critPointsIHave, critPointsIHaveTotal,
- allSendCriticalPoints, procSendCritPointsTotals, maxSendCritPointsPerProc );
-
- /* Post process the linked dofs */
- if ( self->linkedDofInfo ) {
- _FeEquationNumber_PostProcessLinkedDofs( self );
- }
-
- Memory_Free( allSendCriticalPoints );
- Memory_Free( procSendCritPointsTotals );
- }
-
- /* If not removing BCs, construct a table of which equation numbers are actually BCs. */
- if( !self->removeBCs ) {
- FeMesh* feMesh = self->feMesh;
- DofLayout* dofLayout = self->dofLayout;
- VariableCondition* bcs = self->bcs;
- unsigned lNode_i;
-
- /* New index set. */
- self->bcEqNums = IndexSet_New( self->_highestLocalEqNum - self->_lowestLocalEqNum );
-
- /* Fill it up. */
- for( lNode_i = 0; lNode_i < feMesh->nodeLocalCount; lNode_i++ ) {
- unsigned nDofs = dofLayout->dofCounts[lNode_i];
- unsigned dof_i;
-
- for( dof_i = 0; dof_i < nDofs; dof_i++ ) {
- unsigned varInd = dofLayout->varIndices[lNode_i][dof_i];
-
- if( bcs && VariableCondition_IsCondition( bcs, lNode_i, varInd ) ) {
- IndexSet_Add( self->bcEqNums, self->destinationArray[lNode_i][dof_i] );
- }
- }
- }
- }
-
- Memory_Free( critPointsIHave );
- Memory_Free( critPointsToSend );
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-
-
-/** Works out 'critical nodes' I know from domain information (those I want are the start
- of my runs -1, those I know others want are the end of my runs. */
-static void _FeEquationNumber_CalculateDomainKnownCriticalPoints(
- FeEquationNumber* self,
- Node_DomainIndex nodeDomainCount,
- CritPointInfo* mySetEnds,
- Index* const mySetEndsTotal,
- Node_GlobalIndex* myWantedCriticalPoints,
- Index* const myWantedCriticalPointsTotal )
-{
- RemappedNodeInfo_Index rNodeInfo_I = 0;
- Node_RemappedGlobalIndex remappedGlobal_I = 0;
- MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- if ( self->remappingActivated ) {
- /* if remapping has been done, the only possible crit points are the first and last
- points */
- remappedGlobal_I = self->remappedNodeInfos[0].remappedGlobal;
- if (remappedGlobal_I != 0) {
- Journal_DPrintfL( self->debug, 3, "Adding interface c.p. to myWantedCriticalPoints[%d] = %d\n",
- (*myWantedCriticalPointsTotal), remappedGlobal_I-1 );
- myWantedCriticalPoints[(*myWantedCriticalPointsTotal)++] = remappedGlobal_I-1;
- }
-
- remappedGlobal_I = self->remappedNodeInfos[nodeDomainCount-1].remappedGlobal;
- if ( remappedGlobal_I != (meshDecomp->nodeGlobalCount-1) ) {
- Journal_DPrintfL( self->debug, 3, "Adding set end c.p. mySetEnds[%d] = %d\n",
- (*mySetEndsTotal), remappedGlobal_I );
- mySetEnds[(*mySetEndsTotal)++].index = remappedGlobal_I;
- }
- Stream_UnIndentBranch( StgFEM_Debug );
- return;
- }
-
- while ( rNodeInfo_I < nodeDomainCount ) {
- /* save start of set */
- remappedGlobal_I = self->remappedNodeInfos[rNodeInfo_I].remappedGlobal;
-
- if (remappedGlobal_I != 0) {
- Journal_DPrintfL( self->debug, 3, "Adding interface c.p. to myWantedCriticalPoints[%d] = %d\n",
- (*myWantedCriticalPointsTotal), remappedGlobal_I-1 );
- myWantedCriticalPoints[(*myWantedCriticalPointsTotal)++] = remappedGlobal_I-1;
- }
- rNodeInfo_I++;
-
- /* skip to end of contiguous set */
- while ( (rNodeInfo_I < nodeDomainCount)
- && (self->remappedNodeInfos[rNodeInfo_I].remappedGlobal ==
- (self->remappedNodeInfos[rNodeInfo_I-1].remappedGlobal + 1) ) )
- {
- Journal_DPrintfL( self->debug, 4, "skipping remapped gNode[%d] domain = %d\n",
- self->remappedNodeInfos[rNodeInfo_I].remappedGlobal,
- self->remappedNodeInfos[rNodeInfo_I].domain );
- rNodeInfo_I++;
- }
-
- /* and add the critical point, if not the last node */
- remappedGlobal_I = self->remappedNodeInfos[rNodeInfo_I-1].remappedGlobal;
- if ( remappedGlobal_I != (meshDecomp->nodeGlobalCount-1) ) {
- Journal_DPrintfL( self->debug, 3, "Adding set end c.p. mySetEnds[%d] = %d\n",
- (*mySetEndsTotal), remappedGlobal_I );
- mySetEnds[(*mySetEndsTotal)++].index = remappedGlobal_I;
- }
- }
-
-/*#if DEBUG*/
- if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
- Index cPoint_I;
-
- Journal_DPrintf( self->debug, "My set end Crit Points:[0-%d][ ", (*mySetEndsTotal) );
- for (cPoint_I = 0 ; cPoint_I < (*mySetEndsTotal) ; cPoint_I++) {
- Journal_DPrintf( self->debug, "%2d, ", mySetEnds[cPoint_I].index );
- }
- Journal_DPrintf( self->debug, "]\n" );
-
- Journal_DPrintf( self->debug, "interface Crit Points I want:[0-%d][ ", (*myWantedCriticalPointsTotal) );
- for (cPoint_I = 0 ; cPoint_I < (*myWantedCriticalPointsTotal) ; cPoint_I++) {
- Journal_DPrintf( self->debug, "%2d, ", myWantedCriticalPoints[cPoint_I] );
- }
- Journal_DPrintf( self->debug, "]\n" );
- }
-/*#endif*/
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-/* work out critical points (inc. those needed by others) I hold, and those to send.
- The list I have could be greater than my end of runs, in an irregular mesh case */
-static void _FeEquationNumber_CalculateCritPointsIHave( FeEquationNumber* self,
- Node_GlobalIndex** const myWantedCriticalPointsPtr, Node_GlobalIndex myWantedCriticalPointsTotal,
- CritPointInfo** const critPointsIHavePtr, Index* const critPointsIHaveTotal,
- CritPointInfo* const critPointsToSend, Index* const critPointsToSendTotal )
-{
- MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
- Partition_Index proc_I;
- Node_GlobalIndex* allWantedCriticalPoints = NULL;
- CritPointInfo* allHaveCriticalPoints = NULL;
- Node_GlobalIndex* procWantedCritPointsTotals = NULL;
- Index* procHaveCritPointsTotals = NULL;
- Node_GlobalIndex maxWantedCritPointsPerProc = 0;
- Node_GlobalIndex maxHaveCritPointsPerProc = 0;
- Index myCritPoint_I = 0;
- PartitionIndex myRank = meshDecomp->rank;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- Journal_DPrintfL( self->debug, 2, "Globally sharing locally known wanted C.N. lists:\n", __func__ );
- _FeEquationNumber_ShareCriticalPoints( self, myWantedCriticalPointsPtr, myWantedCriticalPointsTotal,
- &allWantedCriticalPoints, &procWantedCritPointsTotals, &maxWantedCritPointsPerProc );
-
- Journal_DPrintfL( self->debug, 2, "Globally sharing locally known 'have' C.N. lists:\n", __func__ );
- _FeEquationNumber_ShareCritPointInfo( self, critPointsIHavePtr, (*critPointsIHaveTotal),
- &allHaveCriticalPoints, &procHaveCritPointsTotals, &maxHaveCritPointsPerProc, DONT_PRINT_VALUES );
-
- /* now we build our lists of crit points on my processor, and crit points on my processor to send to others */
- for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
- Index otherCritPoint_I = proc_I * maxWantedCritPointsPerProc;
- Index otherCritPoint_End_I = (proc_I * maxWantedCritPointsPerProc) + procWantedCritPointsTotals[proc_I];
- myCritPoint_I = 0;
-
- /* don't try and add my own */
- if ( myRank == proc_I ) continue;
-
- /* for each crit point they want, if I have it add it to my have and send lists */
- for (; otherCritPoint_I < otherCritPoint_End_I; otherCritPoint_I++) {
- Node_GlobalIndex otherCritPoint = allWantedCriticalPoints[otherCritPoint_I];
-
- if ( _FeEquationNumber_IHaveCritPoint( self, otherCritPoint ) ) {
-
- while ( (myCritPoint_I < (*critPointsIHaveTotal) ) &&
- (otherCritPoint > (*critPointsIHavePtr)[myCritPoint_I].index) ) {
- /* skip ahead to right spot */
- myCritPoint_I++;
- }
- if ( myCritPoint_I == (*critPointsIHaveTotal) ) {
- (*critPointsIHavePtr)[(*critPointsIHaveTotal)++].index = otherCritPoint;
- critPointsToSend[(*critPointsToSendTotal)++].index = otherCritPoint;
- }
- else if ( otherCritPoint != (*critPointsIHavePtr)[myCritPoint_I].index ) {
- memmove( &((*critPointsIHavePtr)[myCritPoint_I+1]),
- &((*critPointsIHavePtr)[myCritPoint_I]),
- ((*critPointsIHaveTotal) - myCritPoint_I) * sizeof(CritPointInfo) );
- (*critPointsIHavePtr)[myCritPoint_I].index = otherCritPoint;
- (*critPointsIHaveTotal)++;
- memmove( &critPointsToSend[myCritPoint_I+1], &critPointsToSend[myCritPoint_I],
- ((*critPointsToSendTotal) - myCritPoint_I) * sizeof(CritPointInfo) );
- critPointsToSend[myCritPoint_I].index = otherCritPoint;
- (*critPointsToSendTotal)++;
- }
- /* move to the next point in any case */
- myCritPoint_I++;
- }
- }
- }
-
- /* For each crit point the others have, if I have it add it to my have list */
- for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
- Index otherCritPointInfo_I = proc_I * maxHaveCritPointsPerProc;
- Index otherCritPointInfo_End_I = (proc_I * maxHaveCritPointsPerProc) + procHaveCritPointsTotals[proc_I];
- myCritPoint_I = 0;
-
- /* don't try and add my own */
- if ( myRank == proc_I ) continue;
-
- for (; otherCritPointInfo_I < otherCritPointInfo_End_I; otherCritPointInfo_I++) {
- Node_GlobalIndex otherCritPoint = allHaveCriticalPoints[otherCritPointInfo_I].index;
-
- if ( _FeEquationNumber_IHaveCritPoint( self, otherCritPoint ) ) {
-
- while ( (myCritPoint_I < (*critPointsIHaveTotal) ) &&
- (otherCritPoint > (*critPointsIHavePtr)[myCritPoint_I].index) ) {
- myCritPoint_I++;
- /* skip ahead to right spot */
- }
- if ( myCritPoint_I == (*critPointsIHaveTotal) ) {
- (*critPointsIHavePtr)[(*critPointsIHaveTotal)++].index = otherCritPoint;
- }
- else if ( otherCritPoint != (*critPointsIHavePtr)[myCritPoint_I].index ) {
- memmove( &((*critPointsIHavePtr)[myCritPoint_I+1]),
- &((*critPointsIHavePtr)[myCritPoint_I]),
- ((*critPointsIHaveTotal) - myCritPoint_I) * sizeof(CritPointInfo) );
- (*critPointsIHavePtr)[myCritPoint_I].index = otherCritPoint;
- (*critPointsIHaveTotal)++;
- }
- /* move to the next point in any case */
- myCritPoint_I++;
- }
- }
- }
-/*#if DEBUG*/
- if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
- Journal_DPrintf( self->debug, "Calculated crit points I Have:\n[" );
- for ( myCritPoint_I = 0; myCritPoint_I < (*critPointsIHaveTotal); myCritPoint_I++ ) {
- Journal_DPrintf( self->debug, "%3d, ", (*critPointsIHavePtr)[myCritPoint_I].index );
- }
- Journal_DPrintf( self->debug, "]\nCalculated crit points To Send:\n[" );
- for ( myCritPoint_I = 0; myCritPoint_I < (*critPointsToSendTotal); myCritPoint_I++ ) {
- Journal_DPrintf( self->debug, "%3d, ", critPointsToSend[myCritPoint_I].index );
- }
- Journal_DPrintf( self->debug, "]\n");
- }
-/*#endif*/
-
- Memory_Free( allWantedCriticalPoints );
- Memory_Free( procWantedCritPointsTotals );
- Memory_Free( allHaveCriticalPoints );
- Memory_Free( procHaveCritPointsTotals );
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-static Bool _FeEquationNumber_IHaveCritPoint(
- FeEquationNumber* self,
- Node_RemappedGlobalIndex critPoint )
-{
- MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
- Node_DomainIndex nodeDomainCount = meshDecomp->nodeDomainCount;
- PartitionIndex myRank = meshDecomp->rank;
-
- /* Case 1: for remapped hexa mesh, just check if its between max and min numbers */
- if ( self->remappingActivated ) {
- if ( ( self->remappedNodeInfos[0].remappedGlobal <= critPoint ) &&
- ( critPoint <= self->remappedNodeInfos[nodeDomainCount-1].remappedGlobal ) )
- {
- return True;
- }
- else {
- return False;
- }
- }
- /* Case 2: 2D+ hexa decomps or other decomp strategy, use local (and shadow if enabled) node IndexSet */
- else {
- if ( IndexSet_IsMember( meshDecomp->localNodeSets[myRank], critPoint ) ) {
- return True;
- }
- else if ( (meshDecomp->shadowDepth > 0)
- && IndexSet_IsMember( meshDecomp->shadowNodeSets[myRank], critPoint ) ) {
- return True;
- }
- else {
- return False;
- }
- }
-}
-
-
-/** Performs an AllGather on a set of critical points: Each processer will afterwards have all the critical points
- of all the processors, in one large array. The user must then index into the array by processor carefully. */
-static void _FeEquationNumber_ShareCriticalPoints(
- FeEquationNumber* self,
- Node_GlobalIndex** const myCriticalPoints,
- Node_GlobalIndex myCriticalPointsTotal,
- Node_GlobalIndex** allCriticalPoints,
- Index** procCritPointsTotals,
- Node_GlobalIndex* const maxCritPointsPerProc)
-{
- MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
- Partition_Index proc_I;
-/*#if DEBUG*/
- Index point_I = 0;
-/*#endif*/
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- (*maxCritPointsPerProc) = 0;
-
-/*#if DEBUG*/
- if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
- Journal_DPrintf( self->debug, "myCriticalPointsTotal=%u\n", myCriticalPointsTotal);
- Journal_DPrintf( self->debug, "myCritPoints:(" );
- for ( point_I = 0; point_I < myCriticalPointsTotal; point_I++)
- {
- Journal_DPrintf( self->debug, "%u, ", (*myCriticalPoints)[point_I]);
- }
- Journal_DPrintf( self->debug, ")\n");
- }
-/*#endif*/
-
- /* First, we allocate and calculate how many critical points are on each node (this way, we don't have to guess
- how much memory to allocate in the main array.) */
- (*procCritPointsTotals) = Memory_Alloc_Array( Node_GlobalIndex, meshDecomp->nproc,
- "*procCritPointsTotals (ShareCriticalPoints)" );
-
- MPI_Allgather( &myCriticalPointsTotal, 1, MPI_UNSIGNED,
- (*procCritPointsTotals), 1, MPI_UNSIGNED,
- meshDecomp->communicator );
-
- for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
- if ( (*procCritPointsTotals)[proc_I] > (*maxCritPointsPerProc) )
- (*maxCritPointsPerProc) = (*procCritPointsTotals)[proc_I];
- }
-
-/*#if DEBUG*/
- Journal_DPrintfL( self->debug, 2, "procCritPoints totals:(");
- for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
- Journal_DPrintfL( self->debug, 2, "%d, ", (*procCritPointsTotals)[proc_I]);
- }
- Journal_DPrintfL( self->debug, 2, ")\n");
- Journal_DPrintfL( self->debug, 2, "MaxCritPointsPerProc = %d\n", (*maxCritPointsPerProc));
-/*#endif*/
-
- /* Now share the actual point values */
- (*myCriticalPoints) = Memory_Realloc_Array( (*myCriticalPoints), Node_GlobalIndex, *maxCritPointsPerProc );
- (*allCriticalPoints) = Memory_Alloc_Array( Node_GlobalIndex, meshDecomp->nproc * (*maxCritPointsPerProc),
- "*allCriticalPoints (ShareCriticalPoints)" );
-
- MPI_Allgather( (*myCriticalPoints), (*maxCritPointsPerProc), MPI_UNSIGNED,
- (*allCriticalPoints), (*maxCritPointsPerProc), MPI_UNSIGNED,
- meshDecomp->communicator );
-
-/*#if DEBUG*/
- Journal_DPrintfL( self->debug, 2, "procCritPoints:(" );
- for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
- for ( point_I = 0; point_I < (*procCritPointsTotals)[proc_I]; point_I++)
- {
- Journal_DPrintfL( self->debug, 2, "%u, ",
- (*allCriticalPoints)[(*maxCritPointsPerProc)*proc_I + point_I]);
- }
- }
- Journal_DPrintfL( self->debug, 2, ")\n");
-/*#endif*/
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-
-/** Performs an AllGather on a set of CritPointInfo structs: Each processer will afterwards have all the CritPointInfo
- structs of all the processors, in one large array. The user must then index into the array by processor
- carefully. */
-static void _FeEquationNumber_ShareCritPointInfo(
- FeEquationNumber* self,
- CritPointInfo** const myCritPointInfo,
- Index myCritPointInfoTotal,
- CritPointInfo** allCritPointInfo,
- Index** procCritPointInfoTotals,
- Index* const maxCritPointInfoPerProc,
- PrintValuesFlag printValuesFlag )
-{
- MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
- Partition_Index proc_I;
-/*#if DEBUG*/
- Index point_I = 0;
-/*#endif*/
-
- Journal_DPrintfL( self->debug, 1, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
- (*maxCritPointInfoPerProc) = 0;
-
- /* allgather the totals (to save allocating unnecessary memory) */
- (*procCritPointInfoTotals) = Memory_Alloc_Array( Node_GlobalIndex, meshDecomp->nproc, "*procCritPointInfoTotals" );
-
- MPI_Allgather( &myCritPointInfoTotal, 1, MPI_INT, (*procCritPointInfoTotals), 1, MPI_INT,
- meshDecomp->communicator );
-
- for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
- if ( (*procCritPointInfoTotals)[proc_I] > (*maxCritPointInfoPerProc) )
- (*maxCritPointInfoPerProc) = (*procCritPointInfoTotals)[proc_I];
- }
-
-/*#if DEBUG*/
- if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
- Journal_DPrintf( self->debug, "procCritPointInfo totals:(" );
- for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
- Journal_DPrintf( self->debug, "%d, ", (*procCritPointInfoTotals)[proc_I]);
- }
- Journal_DPrintf( self->debug, ")\n");
- Journal_DPrintf( self->debug, "MaxCritPointInfoPerProc = %d\n", (*maxCritPointInfoPerProc));
- }
-/*#endif*/
-
- /* Now share the actual critPointInfo arrays */
- (*allCritPointInfo) = Memory_Alloc_Array( CritPointInfo, meshDecomp->nproc * (*maxCritPointInfoPerProc),
- "allCritPointInfo (ShareCritPointInfo)" );
-
- /* below changed by PatrickSunter 27/1/2004 to work on grendel */
- MPI_Allgather( (*myCritPointInfo), (*maxCritPointInfoPerProc), MPI_critPointInfoType,
- (*allCritPointInfo), (*maxCritPointInfoPerProc), MPI_critPointInfoType,
- meshDecomp->communicator );
-
-/*#if DEBUG*/
- if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
- Journal_DPrintf( self->debug, "procCritPointInfos" );
- if ( DONT_PRINT_VALUES == printValuesFlag ) {
- Journal_DPrintf( self->debug, "(indices only)" );
- }
- Journal_DPrintf( self->debug, ": (" );
- for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
- for ( point_I = 0; point_I < (*procCritPointInfoTotals)[proc_I]; point_I++)
- {
- Index current = (*maxCritPointInfoPerProc)*proc_I + point_I;
- Journal_DPrintf( self->debug, "%u", (*allCritPointInfo)[current].index );
- if ( PRINT_VALUES == printValuesFlag ) {
- Journal_DPrintf( self->debug, "= %d", (*allCritPointInfo)[current].eqNum );
- }
- Journal_DPrintf( self->debug, ", " );
- }
- }
- Journal_DPrintf( self->debug, ")\n");
- }
-/*#endif*/
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-/** For each domain node, calculate the Equation number, restarting at 0 whenever a critical node is reached and
- saving the value I was up to. */
-static void _FeEquationNumber_DoPartialTotals( FeEquationNumber* self,
- CritPointInfo* const critPointsIHave, Index critPointsIHaveTotal,
- CritPointInfo* const critPointsToSend, Index critPointsToSendTotal )
-{
- MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
- Node_DomainIndex nodeDomainCount = meshDecomp->nodeDomainCount;
- RemappedNodeInfo_Index rNodeInfo_I = 0;
- Node_RemappedGlobalIndex remappedGlobal_I = 0;
- Node_DomainIndex dNode_I = 0;
- Index haveCritPoint_I = 0;
- Index sendCritPoint_I = 0;
- Dof_EquationNumber currSubTotalEqNum = 0;
-
- Journal_DPrintf( self->debug, "In %s:\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- while ( (rNodeInfo_I < nodeDomainCount) ) {
- remappedGlobal_I = self->remappedNodeInfos[rNodeInfo_I].remappedGlobal;
- dNode_I = self->remappedNodeInfos[rNodeInfo_I].domain;
-
- _FeEquationNumber_HandleNode( self, dNode_I, &currSubTotalEqNum );
-
- /* if the node is next critical point */
- if ( ( haveCritPoint_I < critPointsIHaveTotal )
- && ( remappedGlobal_I == critPointsIHave[haveCritPoint_I].index ) )
- {
- Journal_DPrintfL( self->debug, 3, "storing c.p. subtotal at remapped global index %u = %d\n",
- remappedGlobal_I, currSubTotalEqNum );
- /* store current value */
- critPointsIHave[haveCritPoint_I++].eqNum = currSubTotalEqNum;
-
- /* check if its also a to send point */
- if ( ( sendCritPoint_I < critPointsToSendTotal )
- && ( remappedGlobal_I == critPointsToSend[sendCritPoint_I].index ) )
- {
- /* store current value */
- critPointsToSend[sendCritPoint_I++].eqNum = currSubTotalEqNum;
- }
- /* reset counter and move to next point */
- currSubTotalEqNum = 0;
- }
- rNodeInfo_I++;
- }
-
-/*#if DEBUG*/
- if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
- Journal_DPrintf( self->debug, "Totals I have:[ " );
- haveCritPoint_I = 0;
- for ( haveCritPoint_I = 0; haveCritPoint_I < critPointsIHaveTotal; haveCritPoint_I++ )
- {
- Journal_DPrintf( self->debug, "%2u=%d, ", critPointsIHave[haveCritPoint_I].index, critPointsIHave[haveCritPoint_I].eqNum );
- }
- Journal_DPrintf( self->debug, "]\n" );
- Journal_DPrintf( self->debug, "Totals to send:[ " );
- sendCritPoint_I = 0;
- for ( sendCritPoint_I = 0; sendCritPoint_I < critPointsToSendTotal; sendCritPoint_I++ )
- {
- Journal_DPrintf( self->debug, "%2u=%d, ", critPointsToSend[sendCritPoint_I].index, critPointsToSend[sendCritPoint_I].eqNum );
- }
- Journal_Printf( self->debug, "]\n" );
- }
-/*#endif*/
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-/** Called right at the end of calculating ID array, to add the locally calculated partial totals with the final
- global information, and arrive at the complete figures. */
-static void _FeEquationNumber_AddAllPartialTotals( FeEquationNumber* self, CritPointInfo* mySubTotals,
- Index myCritPointInfoTotal, CritPointInfo* allSubTotals, Index* procCritPointInfoTotals,
- Index maxSubTotalsPerProc )
-{
- Partition_Index proc_I;
- FeMesh* mesh = self->feMesh;
- MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
- Index myRank = meshDecomp->rank;
- Node_GlobalIndex nodeDomainCount = meshDecomp->nodeDomainCount;
- RemappedNodeInfo_Index rNodeInfo_I = 0;
- Node_RemappedGlobalIndex remappedGlobal_I = 0;
- Node_DomainIndex dNode_I = 0;
- Node_GlobalIndex gNode_I = 0;
- Index myCritPointInfo_I = 0;
- Index* procCritPointInfo_Is = NULL;
- Dof_EquationNumber adjustSum = 0;
- Dof_EquationNumber currEqNum;
- Dof_Index currNodeNumDofs;
- Dof_Index nodeLocalDof_I;
- AddListEntry* addListStart;
- AddListEntry* addListPtr;
- AddListEntry* addListPrev;
- Bool firstOfSet;
- Bool* haveUpdatedLinkedDofSetTbl = NULL;
- Index linkedDof_I;
- Index linkedDofSet;
-#define NEXT_PROCESSOR_SECTION_START ( maxSubTotalsPerProc * (proc_I) + procCritPointInfoTotals[proc_I] )
-
- Journal_DPrintfL( self->debug, 1, "In %s:\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- gNode_I += 0;
-
- self->_lowestLocalEqNum = -1;
- self->_highestLocalEqNum = -1;
- procCritPointInfo_Is = Memory_Alloc_Array( Index, meshDecomp->nproc, "procCritPointInfo_Is (AddAllPartialTotals)" );
-
- /* set iterators into processors */
- for ( proc_I = 0; proc_I < meshDecomp->nproc; proc_I++ ) {
- procCritPointInfo_Is[proc_I] = maxSubTotalsPerProc * proc_I;
- }
-
- if ( self->linkedDofInfo ) {
- haveUpdatedLinkedDofSetTbl = Memory_Alloc_Array( Bool, self->linkedDofInfo->linkedDofSetsCount,
- "haveUpdatedLinkedDofSetTbl" );
- for ( linkedDof_I=0; linkedDof_I < self->linkedDofInfo->linkedDofSetsCount; linkedDof_I++ ) {
- haveUpdatedLinkedDofSetTbl[linkedDof_I] = False;
- }
- }
-
-
- Journal_DPrintfL( self->debug, 3, "beginning sequential run through nodes...\n" );
-
- while (rNodeInfo_I < nodeDomainCount) {
- Node_GlobalIndex newCritInfoIndex;
- /* reset the add list information */
- addListPtr = addListStart = NULL;
- remappedGlobal_I = self->remappedNodeInfos[rNodeInfo_I].remappedGlobal;
- dNode_I = self->remappedNodeInfos[rNodeInfo_I].domain;
-
- Journal_DPrintfL( self->debug, 3, "At remapped gNode[%d]: ", remappedGlobal_I );
- Journal_DPrintfL( self->debug, 3, "...adding critical node totals from the block we just skipped...\n" );
-
- /* Ok, now add critical node totals from other processors in the block we just skipped. */
- for ( proc_I = 0; proc_I < meshDecomp->nproc; proc_I++ ) {
- if ( proc_I == myRank ) continue;
-
- /* reset the add list back to start */
- addListPtr = addListStart;
- addListPrev = NULL;
-
-
- /* Only add critical node totals from other processors lower than current index */
- while (( procCritPointInfo_Is[proc_I] < NEXT_PROCESSOR_SECTION_START ) &&
- (newCritInfoIndex = allSubTotals[(procCritPointInfo_Is[proc_I])].index) < remappedGlobal_I )
- {
- /* See if we are scheduled to add this critical point yet, and if not where it should go */
- while ( addListPtr && ( newCritInfoIndex > addListPtr->critPointInfo->index ) ) {
- addListPrev = addListPtr;
- addListPtr = addListPtr->next;
- }
- /* Note: The 2nd condition guards against trying to add a duplicate. In that case we
- * just progress on. */
- if ( (addListPtr == NULL) || ( addListPtr->critPointInfo->index != newCritInfoIndex )) {
- /*
- if inside this condition we are either:
- 1. Adding the first crit node to be added
- 2. Have found a non-duplicate crit node to be added, either at the end or
- partway through.
- So go ahead and add to the addList, reconnecting both the prev and next.
- */
- AddListEntry* newAddListEntry = Memory_Alloc( AddListEntry,
- "newAddListEntry (AddAllPartialTotals)" );
- adjustSum += allSubTotals[procCritPointInfo_Is[proc_I]].eqNum;
- Journal_DPrintfL( self->debug, 3, "at other c.p. (%d):incrementing adjustSum by %d to = %d\n",
- allSubTotals[procCritPointInfo_Is[proc_I]].index,
- allSubTotals[procCritPointInfo_Is[proc_I]].eqNum,
- adjustSum );
- newAddListEntry->critPointInfo = &allSubTotals[procCritPointInfo_Is[proc_I]];
- newAddListEntry->next = addListPtr;
- if ( addListPrev ) {
- addListPrev->next = newAddListEntry;
- }
- else {
- addListStart = newAddListEntry;
- }
- addListPtr = newAddListEntry;
- }
- /* Move to the next potential crit node from that processor, regardless of whether we
- * added the last one or not. */
- (procCritPointInfo_Is[proc_I])++;
- }
- }
-
- /* free the add list */
- while ( addListStart ) {
- addListPrev = addListStart;
- addListStart = addListStart->next;
- Memory_Free( addListPrev );
- }
-
- /* Now go through a run of nodes this processor owns, and add subtotals locally calculated */
- firstOfSet = True;
-
- while ( (firstOfSet) ||
- ( (rNodeInfo_I < nodeDomainCount)
- && (self->remappedNodeInfos[rNodeInfo_I].remappedGlobal ==
- (self->remappedNodeInfos[rNodeInfo_I-1].remappedGlobal + 1) ) ) )
- {
- remappedGlobal_I = self->remappedNodeInfos[rNodeInfo_I].remappedGlobal;
- dNode_I = self->remappedNodeInfos[rNodeInfo_I].domain;
- gNode_I = mesh->nodeD2G[dNode_I];
- firstOfSet = False;
-
- Journal_DPrintfL( self->debug, 3, "At remapped gNode[%d]: I own it, so adjusting EqNums\n",
- remappedGlobal_I );
-
- /* increment the value at each non-bc dof by adjustSum */
- currNodeNumDofs = self->dofLayout->dofCounts[ dNode_I ];
-
- for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
- if( !self->bcs || !VariableCondition_IsCondition( self->bcs, dNode_I,
- self->dofLayout->varIndices[dNode_I][nodeLocalDof_I] ) )
- {
- if ( (NULL == self->linkedDofInfo) || /* TAG: bcs */
- ( self->linkedDofInfo->linkedDofTbl[dNode_I][nodeLocalDof_I] == -1 ) )
- {
- /* A normal point, so increment */
- self->destinationArray[dNode_I][nodeLocalDof_I] += adjustSum;
- }
- else {
- /* Handling of linked dofs: the first time we encounter one of a set,
- add the adjust sum. Afterwards, just set to the updated value. */
- linkedDofSet = self->linkedDofInfo->linkedDofTbl[dNode_I][nodeLocalDof_I];
- if ( False == haveUpdatedLinkedDofSetTbl[linkedDofSet] ) {
- self->destinationArray[dNode_I][nodeLocalDof_I] += adjustSum;
- self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet] += adjustSum;
- haveUpdatedLinkedDofSetTbl[linkedDofSet] = True;
- }
- else {
- self->destinationArray[dNode_I][nodeLocalDof_I] =
- self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet];
- }
- }
-
- currEqNum = self->destinationArray[dNode_I][nodeLocalDof_I];
- /* If current node not a shadow, then check totals */
- if ( dNode_I < mesh->nodeLocalCount ) {
- if ( currEqNum != -1 ) { /* TAG: bcs */
- if ( self->_lowestLocalEqNum == -1 ) {
- /* We need this if statement to initialise this */
- self->_lowestLocalEqNum = currEqNum;
- }
- else if ( currEqNum < self->_lowestLocalEqNum ) {
- self->_lowestLocalEqNum = currEqNum;
- }
-
- if ( currEqNum > self->_highestLocalEqNum ) {
- self->_highestLocalEqNum = currEqNum;
- }
- }
- }
- }
- }
-
- /* if the node is my next critical point, add the sub-total */
- if ( ( myCritPointInfo_I < myCritPointInfoTotal ) &&
- ( remappedGlobal_I == mySubTotals[myCritPointInfo_I].index) )
- {
- adjustSum += mySubTotals[myCritPointInfo_I].eqNum;
- Journal_DPrintfL( self->debug, 3, "at my c.p. %d(%d):incrementing adjustSum by %d to = %d\n",
- myCritPointInfo_I, remappedGlobal_I, mySubTotals[myCritPointInfo_I].eqNum, adjustSum );
- myCritPointInfo_I++;
- }
-
- rNodeInfo_I++;
- }
-
- /* If any of the other processors had sub-totals I've just added, jump past them */
- if (rNodeInfo_I < nodeDomainCount) {
- for ( proc_I = 0; proc_I < meshDecomp->nproc; proc_I++ ) {
-
- while (( procCritPointInfo_Is[proc_I] < NEXT_PROCESSOR_SECTION_START ) &&
- allSubTotals[(procCritPointInfo_Is[proc_I])].index <= remappedGlobal_I )
- {
- (procCritPointInfo_Is[proc_I])++;
- }
-
- }
- }
- }
-
- if ( self->linkedDofInfo ) {
- Memory_Free( haveUpdatedLinkedDofSetTbl );
- }
- Memory_Free( procCritPointInfo_Is );
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-/** Updates the currEqNum argument for the number of dofs at the current node, and increments the ID Eq. Num for each
- dof where appropriate (setting it to -1 if its a B.C.) */
-static void _FeEquationNumber_HandleNode( FeEquationNumber* self, const Node_DomainIndex dNode_I,
- Dof_EquationNumber* const currEqNum )
-{
- Dof_Index currNodeNumDofs;
- Dof_Index nodeLocalDof_I;
-/*#if DEBUG*/
- Stream* error;
-/*#endif*/
-
- Journal_DPrintfL( self->debug, 3, "In %s:", __func__ );
-/*#if DEBUG*/
- error = Journal_Register( Error_Type, (Name)self->type );
- Journal_Firewall( (dNode_I < self->feMesh->nodeDomainCount ), error, "Stuffup: %s() asked to operate on node %d, bigger "
- "than domain count %d. Exiting.\n", __func__, dNode_I, self->feMesh->nodeDomainCount );
-/*#endif*/
-
- /* get the number of dofs */
- currNodeNumDofs = self->dofLayout->dofCounts[ dNode_I ];
- Journal_DPrintfL( self->debug, 3, " domain node %d, has %d dofs.\n", dNode_I, currNodeNumDofs );
- /* process each dof, at the same time updating the updatePtr for the next node. */
- for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
- Journal_DPrintfL( self->debug, 3, "dof %d: ", nodeLocalDof_I );
-
- /* if dof is a boundary condition, set eq num=-1. Otherwise increment counter. */
- /* Also, only set to -1 if we want the BCs removed from the matrix. - Luke */
- if( self->removeBCs &&
- self->bcs && VariableCondition_IsCondition( self->bcs, dNode_I, self->dofLayout->varIndices[dNode_I][nodeLocalDof_I] ) )
- {
- Journal_DPrintfL( self->debug, 3, "is a BC, setting ID[%d][%d] = -1.\n", dNode_I, nodeLocalDof_I );
- self->destinationArray[dNode_I][nodeLocalDof_I] = -1;
- }
- /* Check if node,dof is a linked dof */
- else if ( self->linkedDofInfo && ( self->linkedDofInfo->linkedDofTbl[dNode_I][nodeLocalDof_I] != -1 ) ) {
- Index linkedDofSet = self->linkedDofInfo->linkedDofTbl[dNode_I][nodeLocalDof_I];
-
- if ( self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet] != -1 ) {
- Journal_DPrintfL( self->debug, 3, "is a linked Dof, so setting ID[%d][%d] to the "
- "previous value = %d.\n", dNode_I, nodeLocalDof_I,
- self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet] );
- /* value is same as the first part of the linked node set */
- self->destinationArray[dNode_I][nodeLocalDof_I] =
- self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet];
- }
- else /* This is the first time we've hit this linked eq num, so treat as normal */
- {
- Journal_DPrintfL( self->debug, 3, "is a linked Dof hit the first time, so setting "
- "ID[%d][%d] = %d.\n", dNode_I, nodeLocalDof_I, *currEqNum );
-
- self->destinationArray[dNode_I][nodeLocalDof_I] = (*currEqNum)++;
- if ( dNode_I < self->feMesh->nodeLocalCount ) {
- self->_highestLocalEqNum = self->destinationArray[dNode_I][nodeLocalDof_I];
- }
- /* And save the value at the linked eq num for later */
- self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet] =
- self->destinationArray[dNode_I][nodeLocalDof_I];
- }
- }
- else {
- Journal_DPrintfL( self->debug, 3, "is a normal node, setting ID[%d][%d] = %d.\n", dNode_I, nodeLocalDof_I, *currEqNum );
- self->destinationArray[dNode_I][nodeLocalDof_I] = (*currEqNum)++;
- if ( dNode_I < self->feMesh->nodeLocalCount ) {
- self->_highestLocalEqNum = self->destinationArray[dNode_I][nodeLocalDof_I];
- }
- }
- }
-}
-
-
-void _FeEquationNumber_PostProcessLinkedDofs( FeEquationNumber* self ) {
- Index linkedDof_I;
- int valueToReduce;
- int minimumValue;
- Node_Index rNodeInfo_I;
- Node_DomainIndex dNode_I;
- MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
- Dof_Index nodeLocalDof_I;
- Dof_Index currNodeNumDofs;
- Index linkedDofSet;
- Bool* adjustDueToNonLocalLinkedDofsTbl = NULL;
- unsigned int subtractionAdjustmentTotal;
- Dof_EquationNumber currEqNum;
-
- Journal_DPrintfL( self->debug, 1, "In Func %s():\n", __func__ );
- adjustDueToNonLocalLinkedDofsTbl = Memory_Alloc_Array( Bool, self->linkedDofInfo->linkedDofSetsCount,
- "adjustDueToNonLocalLinkedDofsTbl" );
-
- /* We need to re-calculate these, since the post processing may alter both the lowest and higest eqNum values */
- self->_lowestLocalEqNum = -1;
- self->_highestLocalEqNum = -1;
-
- Journal_DPrintfL( self->debug, 2, "Note: in reductions to follow, value of %d, the node global count, "
- "denotes that this processor doesn't hold any of that linked dof.\n", self->feMesh->nodeGlobalCount );
-
- Stream_Indent( self->debug );
- for ( linkedDof_I=0; linkedDof_I < self->linkedDofInfo->linkedDofSetsCount; linkedDof_I++ ) {
- if ( -1 != self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDof_I] ) {
- valueToReduce = self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDof_I];
- }
- else {
- valueToReduce = self->feMesh->nodeGlobalCount;
- }
-
- Journal_DPrintfL( self->debug, 2, "Reducing linked Dof %d: this proc has value %d\n", linkedDof_I, valueToReduce );
- MPI_Allreduce( &valueToReduce, &minimumValue, 1, MPI_INT, MPI_MIN, meshDecomp->communicator );
-
- Journal_DPrintfL( self->debug, 2, "\tMinimum val = %d\n", minimumValue );
- self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDof_I] = minimumValue;
-
- if ( valueToReduce != minimumValue ) {
- adjustDueToNonLocalLinkedDofsTbl[linkedDof_I] = True;
- }
- else {
- adjustDueToNonLocalLinkedDofsTbl[linkedDof_I] = False;
- }
- }
- Stream_UnIndent( self->debug );
-
- Journal_DPrintfL( self->debug, 2, "Post-processing totals to correct based on non-local linked dofs\n" );
- subtractionAdjustmentTotal = 0;
-
- Stream_Indent( self->debug );
- for ( rNodeInfo_I = 0; rNodeInfo_I < self->feMesh->nodeDomainCount; rNodeInfo_I++ ) {
- dNode_I = self->remappedNodeInfos[rNodeInfo_I].domain;
- Journal_DPrintfL( self->debug, 3, "At remapped node %d (dNode %d):\n", rNodeInfo_I, dNode_I );
- currNodeNumDofs = self->dofLayout->dofCounts[ dNode_I ];
-
- for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
-
- Stream_Indent( self->debug );
- Journal_DPrintfL( self->debug, 3, "At dof %d: ", nodeLocalDof_I );
-
- if( self->bcs && VariableCondition_IsCondition( self->bcs, dNode_I,
- self->dofLayout->varIndices[dNode_I][nodeLocalDof_I] ) )
- {
- Journal_DPrintfL( self->debug, 3, "is a BC: ignoring.\n" );
- }
- else if ( self->linkedDofInfo->linkedDofTbl[dNode_I][nodeLocalDof_I] != -1 ) {
- linkedDofSet = self->linkedDofInfo->linkedDofTbl[dNode_I][nodeLocalDof_I];
-
- Journal_DPrintfL( self->debug, 3, "is a linked Dof, so setting value to %d\n",
- self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet] );
-
- self->destinationArray[dNode_I][nodeLocalDof_I] -= subtractionAdjustmentTotal;
-
- if ( True == adjustDueToNonLocalLinkedDofsTbl[linkedDofSet] ) {
- /* We now need to test, after the subtraction adjustment has been made, if the
- value of this linked dof now matches the minimum. If so, don't subtract further. */
- if ( self->destinationArray[dNode_I][nodeLocalDof_I] !=
- self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet] )
- {
- subtractionAdjustmentTotal++;
- Journal_DPrintfL( self->debug, 3, "And since first was non-local, increasing "
- "subtraction adj. to %d\n", subtractionAdjustmentTotal );
- }
-
- /* Make sure we only adjust once */
- adjustDueToNonLocalLinkedDofsTbl[linkedDofSet] = False;
- }
-
- self->destinationArray[dNode_I][nodeLocalDof_I] =
- self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet];
-
- }
- else {
- Journal_DPrintfL( self->debug, 3, "subtracting %d\n", subtractionAdjustmentTotal );
- self->destinationArray[dNode_I][nodeLocalDof_I] -= subtractionAdjustmentTotal;
- }
-
- currEqNum = self->destinationArray[dNode_I][nodeLocalDof_I];
- if ( dNode_I < self->feMesh->nodeLocalCount ) {
- if ( currEqNum != -1 ) { /* TAG: bcs */
- if ( self->_lowestLocalEqNum == -1 ) {
- /* We need this if statement to initialise this */
- self->_lowestLocalEqNum = currEqNum;
- }
- else if ( currEqNum < self->_lowestLocalEqNum ) {
- self->_lowestLocalEqNum = currEqNum;
- }
-
- if ( currEqNum > self->_highestLocalEqNum ) {
- self->_highestLocalEqNum = currEqNum;
- }
- }
- }
- Stream_UnIndent( self->debug );
- }
- }
- Stream_UnIndent( self->debug );
-
- Memory_Free( adjustDueToNonLocalLinkedDofsTbl );
-}
-#endif
-
-
-Index FeEquationNumber_CalculateActiveEqCountAtNode(
- void* feEquationNumber,
- Node_DomainIndex dNode_I,
- Dof_EquationNumber* lowestActiveEqNumAtNodePtr )
-{
- FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
- Dof_Index nodalDof_I = 0;
- Index activeEqsAtCurrRowNode = 0;
- Dof_EquationNumber currEqNum;
- Bool foundLowest = False;
-
- for ( nodalDof_I = 0; nodalDof_I < self->dofLayout->dofCounts[dNode_I]; nodalDof_I++ ) {
- currEqNum = self->destinationArray[dNode_I][nodalDof_I];
- if ( currEqNum != -1 ) {
- activeEqsAtCurrRowNode++;
- if ( False == foundLowest ) {
- (*lowestActiveEqNumAtNodePtr) = currEqNum;
- foundLowest = True;
- }
- }
- }
-
- return activeEqsAtCurrRowNode;
-}
-
-
-void FeEquationNumber_BuildLocationMatrix( void* feEquationNumber ) {
- FeEquationNumber* self = (FeEquationNumber*)feEquationNumber;
- FeMesh* feMesh;
- unsigned nDims;
- unsigned nDomainEls;
- unsigned nLocalNodes;
- unsigned* nNodalDofs;
- unsigned nElNodes;
- unsigned* elNodes;
- int** dstArray;
- int*** locMat;
- IArray* inc;
- unsigned e_i, n_i, dof_i;
-
- assert( self );
-
- /* Don't build if already done. */
- if( self->locationMatrixBuilt ) {
- Journal_DPrintf( self->debugLM, "In %s: LM already built, so just returning.\n", __func__ );
- Stream_UnIndentBranch( StgFEM_Debug );
- return;
- }
-
- inc = IArray_New();
-
- /* Shortcuts. */
- feMesh = self->feMesh;
- nDims = Mesh_GetDimSize( feMesh );
- nDomainEls = FeMesh_GetElementDomainSize( feMesh );
- nLocalNodes = FeMesh_GetNodeLocalSize( feMesh );
- nNodalDofs = self->dofLayout->dofCounts;
- dstArray = self->destinationArray;
-
- /* Allocate for the location matrix. */
- locMat = AllocArray( int**, nDomainEls );
- for( e_i = 0; e_i < nDomainEls; e_i++ ) {
- FeMesh_GetElementNodes( feMesh, e_i, inc );
- nElNodes = IArray_GetSize( inc );
- elNodes = (unsigned*)IArray_GetPtr( inc );
- locMat[e_i] = AllocArray( int*, nElNodes );
- for( n_i = 0; n_i < nElNodes; n_i++ )
- locMat[e_i][n_i] = AllocArray( int, nNodalDofs[elNodes[n_i]] );
- }
-
- /* Build location matrix. */
- for( e_i = 0; e_i < nDomainEls; e_i++ ) {
- FeMesh_GetElementNodes( feMesh, e_i, inc );
- nElNodes = IArray_GetSize( inc );
- elNodes = (unsigned*)IArray_GetPtr( inc );
- for( n_i = 0; n_i < nElNodes; n_i++ ) {
- for( dof_i = 0; dof_i < nNodalDofs[elNodes[n_i]]; dof_i++ )
- locMat[e_i][n_i][dof_i] = dstArray[elNodes[n_i]][dof_i];
- }
- }
-
- NewClass_Delete( inc );
-
- /* Store result. */
- self->locationMatrix = locMat;
-}
-
-
-#if 0
-/** build the element location matrix mapping elements, element node, dof -> eq num */
-void FeEquationNumber_BuildLocationMatrix( FeEquationNumber* self ) {
- FeMesh* mesh = self->feMesh;
- Element_LocalIndex lElement_I;
- Node_LocalIndex numNodesThisElement = 0;
- Node_LocalIndex elLocalNode_I = 0;
- Dof_Index numDofsThisNode = 0;
- Dof_Index** dofCountsAtElementNodesArray = NULL;
- Element_LocalIndex elementLocalCount = Mesh_GetLocalSize( mesh, Mesh_GetDimSize( mesh ) );
-
- Journal_DPrintf( self->debug, "In %s():\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- if (self->locationMatrixBuilt) {
- Journal_DPrintf( self->debugLM, "In %s: LM already built, so just returning.\n", __func__ );
- Stream_UnIndentBranch( StgFEM_Debug );
- return;
- }
-
- Journal_DPrintf( self->debugLM, "In %s: building over %d elements.\n", __func__, elementLocalCount );
-
- /* Allocate the LM 3D array using the Memory module, in 2 stage process */
- dofCountsAtElementNodesArray = Memory_Alloc_3DSetup( elementLocalCount,
- mesh->topo->nIncEls[nDims][MT_VERTEX] );
-
- for ( lElement_I = 0; lElement_I < elementLocalCount; lElement_I++ ) {
- numNodesThisElement = mesh->elementNodeCountTbl[lElement_I];
-
- for( elLocalNode_I = 0; elLocalNode_I < numNodesThisElement; elLocalNode_I++) {
- Node_LocalIndex dNode_I = mesh->elementNodeTbl[lElement_I][elLocalNode_I];
- numDofsThisNode = self->dofLayout->dofCounts[dNode_I];
- dofCountsAtElementNodesArray[lElement_I][elLocalNode_I] = numDofsThisNode;
- }
- }
-
- self->locationMatrix = Memory_Alloc_3DComplex( Dof_EquationNumber, elementLocalCount, mesh->elementNodeCountTbl,
- dofCountsAtElementNodesArray, "FeEquationNumber->locationMatrix" );
- /* Free the dof counts array:- we have to look up domain node numbers anyway later, might as
- well just use the dof counts array then. */
- Memory_Free( dofCountsAtElementNodesArray );
-
- for ( lElement_I = 0; lElement_I < elementLocalCount; lElement_I++ ) {
- FeEquationNumber_BuildOneElementLocationMatrix( self, lElement_I );
- }
-
- self->locationMatrixBuilt = True;
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-#endif
-
-
-/** Build an element's local location matrix */
-Dof_EquationNumber** FeEquationNumber_BuildOneElementLocationMatrix( void* feEquationNumber, Element_LocalIndex lElement_I ) {
- FeEquationNumber* self = (FeEquationNumber*)feEquationNumber;
- /* Node_DomainIndex elLocalNode_I; */
- Node_DomainIndex numNodesThisElement, *elInc;
- Dof_EquationNumber** localLocationMatrix = NULL;
- FeMesh* feMesh = self->feMesh;
- /* Dof_Index numDofsThisNode = 0; */
- IArray* inc;
-
- inc = IArray_New();
- FeMesh_GetElementNodes( feMesh, lElement_I, inc );
- numNodesThisElement = IArray_GetSize( inc );
- elInc = (Node_DomainIndex*)IArray_GetPtr( inc );
-
- /* HACK: Make sure global element location matrix is built. */
- if( !self->locationMatrixBuilt )
- abort();
-
- /* if ( big LM allocated ) set pointer into it correctly */
- if ( self->locationMatrix ) {
- /* set ptr to correct set of local nodes ptrs */
- localLocationMatrix = self->locationMatrix[lElement_I];
- Journal_DPrintfL( self->debugLM, 3, "set localLocationMatrix to pt. to big LM[%d] = %p\n", lElement_I, self->locationMatrix[lElement_I] ) ;
- }
-
-#if 0
- else {
- Dof_Index* numDofsEachNode = NULL;
-
- /* allocate memory for local LM to return */
- numDofsEachNode = Memory_Alloc_Array_Unnamed( Dof_Index, numNodesThisElement );
-
- for( elLocalNode_I = 0; elLocalNode_I < numNodesThisElement; elLocalNode_I++) {
- Node_LocalIndex localNode = mesh->elementNodeTbl[lElement_I][elLocalNode_I];
- numDofsEachNode[elLocalNode_I] = self->dofLayout->dofCounts[localNode];
- }
-
- localLocationMatrix = Memory_Alloc_2DComplex( Dof_EquationNumber, numNodesThisElement, numDofsEachNode,
- "localLocationMatrix (set of ptrs to dof lists, indexed by element-local node)" );
- Memory_Free( numDofsEachNode );
- }
-#endif
-
-#if 0
- /* If we haven't yet built full LM, copy ID values across */
- if ( False == self->locationMatrixBuilt ) {
- /* for (each el-local node) */
- for ( elLocalNode_I = 0; elLocalNode_I < numNodesThisElement; elLocalNode_I++ ) {
- /* look up processor local node number. */
- Node_LocalIndex procDomainNode = mesh->elementNodeTbl[lElement_I][elLocalNode_I];
- numDofsThisNode = self->dofLayout->dofCounts[procDomainNode];
-
- /* copy pointers to dof eq nums from ID array relevant to that node */
- Journal_DPrintfL( self->debugLM, 3, "copying %d dof eq. numbers from ID[%d] to LM[%d][%d]\n",
- numDofsThisNode, procDomainNode, lElement_I, elLocalNode_I );
- memcpy( localLocationMatrix[elLocalNode_I],
- self->destinationArray[procDomainNode], numDofsThisNode * sizeof(Dof_EquationNumber) );
- }
- }
-#endif
-
- NewClass_Delete( inc );
-
- return localLocationMatrix;
-}
-
-
-void FeEquationNumber_PrintDestinationArray( void* feFeEquationNumber, Stream* stream ) {
- FeEquationNumber* self = (FeEquationNumber*) feFeEquationNumber;
- FeMesh* feMesh = self->feMesh;
- MPI_Comm comm = Comm_GetMPIComm( Mesh_GetCommTopology( feMesh, MT_VERTEX ) );
- unsigned rank;
- Node_GlobalIndex gNode_I;
- Node_GlobalIndex nodeGlobalCount = FeMesh_GetNodeGlobalSize( feMesh );
-
- MPI_Comm_rank( comm, (int*)&rank );
- Journal_Printf( stream, "%d: *** Printing destination array ***\n", rank );
-
- for (gNode_I =0; gNode_I < nodeGlobalCount; gNode_I++) {
- Node_DomainIndex dNode_I;
-
- if ( !Mesh_GlobalToDomain( feMesh, MT_VERTEX, gNode_I, &dNode_I ) ) {
- Journal_Printf( stream, "\tdestinationArray[(gnode)%2d]: on another proc\n", gNode_I);
- }
- else {
- Dof_Index currNodeNumDofs = self->dofLayout->dofCounts[ dNode_I ];
- Dof_Index nodeLocalDof_I;
-
- Journal_Printf( stream, "\tdestinationArray[(gnode)%2d][(dof)0-%d]:",gNode_I, currNodeNumDofs );
- for( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
- Journal_Printf( stream, "%3d, ", self->destinationArray[dNode_I][nodeLocalDof_I] );
- }
- Journal_Printf( stream, "\n" );
- }
- }
-}
-
-void FeEquationNumber_PrintDestinationArrayBox( void* feFeEquationNumber, Stream* stream ) {
- FeEquationNumber* self = (FeEquationNumber*) feFeEquationNumber;
- FeMesh* feMesh = self->feMesh;
- MPI_Comm comm = Comm_GetMPIComm( Mesh_GetCommTopology( feMesh, MT_VERTEX ) );
- unsigned rank;
- Grid* vGrid;
- unsigned ijk[3];
- Element_LocalIndex lNode_I;
- Node_GlobalIndex gNode_I;
- Node_Index sizeI, sizeJ, sizeK;
- Dof_Index nDofs;
- Dof_Index dof_I;
-
- MPI_Comm_rank( comm, (int*)&rank );
- Journal_Printf( stream, "%d: *** Printing destination array ***\n", rank );
-
- vGrid = *Mesh_GetExtension( feMesh, Grid**, "vertexGrid" );
- nDofs = self->dofLayout->dofCounts[0];
- sizeI = vGrid->sizes[ I_AXIS ];
- sizeJ = vGrid->sizes[ J_AXIS ];
- sizeK = vGrid->sizes[ K_AXIS ] ? vGrid->sizes[ K_AXIS ] : 1;
-
- for ( ijk[2] = 0 ; ijk[2] < sizeK ; ijk[2]++ ) {
- if ( sizeK != 1 )
- Journal_Printf( stream, "\nk = %d\n", ijk[2] );
- for ( ijk[1] = sizeJ - 1 ; ijk[1] >= 0 ; ijk[1]-- ) {
- Journal_Printf( stream, "%2d - ", ijk[1] );
- for ( ijk[0] = 0 ; ijk[0] < sizeI ; ijk[0]++ ) {
- gNode_I = Grid_Project( vGrid, ijk );
- Journal_Printf( stream, "{ " );
- if ( Mesh_GlobalToDomain( feMesh, MT_VERTEX, gNode_I, &lNode_I ) ) {
- for ( dof_I = 0 ; dof_I < nDofs ; dof_I++ )
- Journal_Printf( stream, "%3d ", self->destinationArray[lNode_I][dof_I] );
- }
- else {
- for ( dof_I = 0 ; dof_I < nDofs ; dof_I++ )
- Journal_Printf( stream, " XX " );
- }
- Journal_Printf( stream, "}" );
- }
- Journal_Printf( stream, "\n" );
- }
- /* Bottom row */
- Journal_Printf( stream, " " );
- for ( ijk[0] = 0 ; ijk[0] < sizeI ; ijk[0]++ ) {
- Journal_Printf( stream, " %3d ", ijk[0] );
- if ( nDofs == 3 )
- Journal_Printf( stream, " " );
- }
- Journal_Printf( stream, "\n" );
- }
-}
-
-void FeEquationNumber_PrintLocationMatrix( void* feFeEquationNumber, Stream* stream ) {
- FeEquationNumber* self = (FeEquationNumber*) feFeEquationNumber;
- FeMesh* feMesh = self->feMesh;
- MPI_Comm comm = Comm_GetMPIComm( Mesh_GetCommTopology( feMesh, MT_VERTEX ) );
- unsigned rank;
- Element_GlobalIndex gEl_I;
- unsigned nDims = Mesh_GetDimSize( feMesh );
- Element_GlobalIndex elementGlobalCount = FeMesh_GetElementGlobalSize( feMesh );
- unsigned nLocalEls = FeMesh_GetElementLocalSize( feMesh );
-
- Journal_Printf( stream, "%d: *** Printing location matrix ***\n", rank );
-
- MPI_Comm_rank( comm, (int*)&rank );
-
- for (gEl_I =0; gEl_I < elementGlobalCount; gEl_I++ ) {
- Element_LocalIndex lEl_I;
-
- if ( !Mesh_GlobalToDomain( feMesh, (MeshTopology_Dim)nDims, gEl_I, &lEl_I ) || lEl_I >= nLocalEls ) {
- Journal_Printf( stream, "\tLM[(g/l el)%2d/XXX]: on another proc\n", gEl_I);
- }
- else {
- Node_LocalIndex numNodesAtElement;
- Node_LocalIndex elLocalNode_I;
- unsigned* incNodes;
- IArray* inc;
-
- inc = IArray_New();
- FeMesh_GetElementNodes( self->feMesh, lEl_I, inc );
- numNodesAtElement = IArray_GetSize( inc );
- incNodes = (unsigned*)IArray_GetPtr( inc );
-
- Journal_Printf( stream, "\tLM[(g/l el)%2d/%2d][(enodes)0-%d]", gEl_I, lEl_I, numNodesAtElement);
- /* print the nodes and dofs */
- for ( elLocalNode_I = 0; elLocalNode_I < numNodesAtElement; elLocalNode_I++ ) {
- /* look up processor local node number. */
- Element_LocalIndex currNode = incNodes[elLocalNode_I == 2 ? 3 :
- elLocalNode_I == 3 ? 2 :
- elLocalNode_I == 6 ? 7 :
- elLocalNode_I == 7 ? 6 :
- elLocalNode_I];
- /* get the number of dofs at current node */
- Dof_Index currNodeNumDofs = self->dofLayout->dofCounts[ currNode ];
- Dof_Index nodeLocalDof_I;
-
- Journal_Printf( stream, "({%2d}", currNode );
- for( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
- Journal_Printf( stream, "%3d,", self->destinationArray[currNode][nodeLocalDof_I] );
- }
- Journal_Printf( stream, "), " );
- }
-
- Journal_Printf( stream, "\n" );
-
- NewClass_Delete( inc );
- }
-
- }
-}
-
-
-#if 0
-void FeEquationNumber_PrintElementLocationMatrix(
- void* feEquationNumber,
- Dof_EquationNumber** elementLM,
- Element_LocalIndex element_lI,
- Stream* stream )
-{
- FeEquationNumber* self = (FeEquationNumber*)feEquationNumber;
- Dof_Index dof_elLocalI;
- Node_ElementLocalIndex nodeCountThisEl = self->feMesh->elementNodeCountTbl[element_lI];
- Node_LocalIndex node_lI = self->feMesh->elementNodeTbl[element_lI][nodeCountThisEl-1];
- Dof_Index dofCountLastNode = self->dofLayout->dofCounts[node_lI];
- Dof_Index totalDofsThisElement = 0;
-
- totalDofsThisElement = &elementLM[nodeCountThisEl-1][dofCountLastNode-1] - &elementLM[0][0] + 1;
-
- Journal_DPrintf( stream, "LM[ el %d ], dofs[0-%d] = {", element_lI, totalDofsThisElement );
-
- for( dof_elLocalI=0; dof_elLocalI < totalDofsThisElement; dof_elLocalI++ ) {
- Journal_DPrintf( stream, "%d, ", elementLM[0][dof_elLocalI] );
- }
- Journal_DPrintf( stream, "}\n" );
-}
-
-
-/* Calculates global sum unconstrained dofs */
-void _FeEquationNumber_CalculateGlobalUnconstrainedDofTotal( FeEquationNumber* self ) {
- int globalSumUnconstrainedDofs;
- MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
-
- Journal_DPrintfL( self->debug, 1, "In %s:\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
- MPI_Allreduce( &self->_highestLocalEqNum, &globalSumUnconstrainedDofs, 1, MPI_INT, MPI_MAX, meshDecomp->communicator );
- self->globalSumUnconstrainedDofs = (unsigned)(globalSumUnconstrainedDofs+1);
-
- Journal_DPrintf( self->debug, "Calculated total (across all processors) unconstrained dofs as:%d\n", self->globalSumUnconstrainedDofs );
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-/* calculate the minimum and maximum parts that my processor is responsible for holding */
-void _FeEquationNumber_CalculateEqNumsDecomposition( FeEquationNumber* self ) {
- MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
- Partition_Index myRank = meshDecomp->rank;
- Partition_Index nProc = meshDecomp->nproc;
-
- Journal_DPrintfL( self->debug, 1, "In %s:\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- if ( (self->remappingActivated) && ( (self->linkedDofInfo == NULL) || (self->linkedDofInfo->linkedDofSetsCount == 0 ) ) ) {
- /* If the remapping is activated, and things aren't complicated by periodic BCs,
- then each processor should hold the Matrix/Vector
- component corresponding to the lowest local eqNum, to the lowest eqNum of the next
- processor. This means that _only shared boundary nodes_ will need to be communicated,
- and the last processor will have no communication. */
- Journal_DPrintfL( self->debug, 2, "Remapping active and no periodic bcs: using lowest local eqNums as boundaries.\n");
-
- self->_lowestGlobalEqNums = Memory_Alloc_Array( Dof_EquationNumber, nProc,
- "FeEquationNumber->_lowestGlobalEqNums" );
- MPI_Allgather(
- &self->_lowestLocalEqNum, 1, MPI_INT,
- self->_lowestGlobalEqNums, 1, MPI_INT,
- meshDecomp->communicator );
-
- self->firstOwnedEqNum = self->_lowestLocalEqNum;
- if (myRank == nProc-1) {
- self->lastOwnedEqNum = self->_highestLocalEqNum;
- }
- else {
- Node_LocalIndex nextProcLowestEqNum = self->_lowestGlobalEqNums[myRank+1] - 1;
- if ( (unsigned int)-1 == nextProcLowestEqNum ) {
- /* Pathological case of next proc having all B.C.s */
- self->lastOwnedEqNum = self->_highestLocalEqNum;
- }
- else {
- self->lastOwnedEqNum = nextProcLowestEqNum;
- }
- }
-
- self->localEqNumsOwnedCount = self->lastOwnedEqNum - self->firstOwnedEqNum + 1;
- }
- else {
- /* If the remapping isn't activated and the eqNum ordering isn't aligned with the mesh
- decomposition, or there are periodic BCs, we can't get a clear idea of where the processor boundaries are:
- therefore just split up the EqNums equally between processors: still should be
- fairly good alignment. */
- Journal_DPrintfL( self->debug, 2, "Remapping inactive and/or periodic bcs used: just dividing eqNums as evenly as possible.\n");
-
- self->_eqNumsPerProcDivisor = self->globalSumUnconstrainedDofs / nProc;
- self->_eqNumsRemainder = self->globalSumUnconstrainedDofs % nProc;
- Journal_DPrintfL( self->debug, 2, "Calculated %d eqNums per proc, with %d remainder\n",
- self->_eqNumsPerProcDivisor, self->_eqNumsRemainder );
- self->_remNotAddedChangeover = (self->_eqNumsPerProcDivisor+1) * self->_eqNumsRemainder;
-
- self->localEqNumsOwnedCount = self->_eqNumsPerProcDivisor;
- if ( myRank < self->_eqNumsRemainder ) {
- self->localEqNumsOwnedCount++;
- }
-
- if ( myRank < self->_eqNumsRemainder ) {
- self->firstOwnedEqNum = myRank * (self->_eqNumsPerProcDivisor+1);
- }
- else {
- self->firstOwnedEqNum = self->_remNotAddedChangeover
- + (myRank - self->_eqNumsRemainder) * self->_eqNumsPerProcDivisor;
- }
- self->lastOwnedEqNum = self->firstOwnedEqNum + self->localEqNumsOwnedCount - 1;
- }
-
- Journal_DPrintfL( self->debug, 1, "Calculated I own %d eqNums, between indices %d to %d\n",
- self->localEqNumsOwnedCount, self->firstOwnedEqNum, self->lastOwnedEqNum );
- Journal_DPrintfL( self->debug, 1, "(Range of eqNums on local mesh segment is %d to %d)\n",
- self->_lowestLocalEqNum, self->_highestLocalEqNum );
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-#endif
-
-
-Partition_Index FeEquationNumber_CalculateOwningProcessorOfEqNum( void* feEquationNumber, Dof_EquationNumber eqNum ) {
- FeEquationNumber* self = (FeEquationNumber*)feEquationNumber;
- /* Partition_Index ownerProc = (unsigned int)-1; */
- Comm* comm = Mesh_GetCommTopology( self->feMesh, MT_VERTEX );
- MPI_Comm mpiComm = Comm_GetMPIComm( comm );
- unsigned nProcs;
- unsigned p_i;
-
- MPI_Comm_size( mpiComm, (int*)&nProcs );
- for( p_i = 1; p_i < nProcs; p_i++ ) {
- if( eqNum < self->_lowestGlobalEqNums[p_i] )
- break;
- }
-
- return p_i - 1;
-
-#if 0
- if ( (self->remappingActivated) && ( (self->linkedDofInfo == NULL) || (self->linkedDofInfo->linkedDofSetsCount == 0 ) ) ) {
- MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
- Partition_Index myRank = meshDecomp->rank;
- Partition_Index nProc = meshDecomp->nproc;
-
- /* Expect it to be on the next processor, so try there first */
- if ( eqNum > self->lastOwnedEqNum ) {
- ownerProc = myRank + 1;
- while ( (ownerProc+1) < nProc ) {
- if ( eqNum >= self->_lowestGlobalEqNums[ownerProc+1] ) {
- ownerProc++;
- }
- else {
- break;
- }
- }
- }
- /* otherwise count back from current */
- else {
- ownerProc = myRank;
- while ( ownerProc > 0 ) {
- if ( eqNum < self->_lowestGlobalEqNums[ownerProc] ) {
- ownerProc--;
- }
- else {
- break;
- }
- }
- }
- }
- else {
- if ( eqNum < self->_remNotAddedChangeover ) {
- ownerProc = eqNum / (self->_eqNumsPerProcDivisor+1);
- }
- else {
- ownerProc = self->_eqNumsRemainder + (eqNum - self->_remNotAddedChangeover) / self->_eqNumsPerProcDivisor;
- }
- }
-}
-
-return ownerProc;
-#endif
-}
-
-
-#if 0
-void FeEquationNumber_Create_CritPointInfo_MPI_Datatype( void ) {
-#define CRIT_POINT_INFO_NBLOCKS 2
- MPI_Aint indexExtent = 0;
- MPI_Datatype critPointInfoTypes[CRIT_POINT_INFO_NBLOCKS] = {MPI_UNSIGNED, MPI_INT };
- MPI_Aint critPointInfoBlockDisplacements[CRIT_POINT_INFO_NBLOCKS];
- int critPointInfoBlockLengths[CRIT_POINT_INFO_NBLOCKS] = { 1, 1 };
-
- MPI_Type_extent(MPI_UNSIGNED, &indexExtent);
- critPointInfoBlockDisplacements[0] = 0;
- critPointInfoBlockDisplacements[1] = indexExtent;
-
- MPI_Type_struct( CRIT_POINT_INFO_NBLOCKS, critPointInfoBlockLengths, critPointInfoBlockDisplacements,
- critPointInfoTypes, &MPI_critPointInfoType );
-
- MPI_Type_commit( &MPI_critPointInfoType );
-}
-#endif
-
-
-void FeEquationNumber_BuildWithTopology( FeEquationNumber* self ) {
- Stream* stream;
- double startTime, endTime, time, tmin, tmax;
- FeMesh* feMesh;
- Sync* sync;
- Comm* comm;
- MPI_Comm mpiComm;
- unsigned rank, nProcs;
- unsigned nDims;
- unsigned nDomainNodes;
- unsigned nLocalNodes;
- unsigned* nNodalDofs;
- unsigned nElNodes, *elNodes;
- int** dstArray;
- int *nLocMatDofs, ***locMat;
- unsigned varInd;
- unsigned curEqNum;
- unsigned base;
- unsigned subTotal;
- MPI_Status status;
- unsigned maxDofs;
- unsigned* tuples;
- LinkedDofInfo* links;
- unsigned highest;
- IArray* inc;
- unsigned e_i, n_i, dof_i, s_i;
- int ii;
-
- assert( self );
-
- inc = IArray_New();
-
- stream = Journal_Register( Info_Type, (Name)self->type );
- Stream_SetPrintingRank( stream, 0 );
-
- Journal_RPrintf( stream, "FeEquationNumber: '%s'\n", self->name );
- Stream_Indent( stream );
- Journal_RPrintf( stream, "Generating equation numbers...\n" );
- Stream_Indent( stream );
- if( self->removeBCs )
- Journal_RPrintf( stream, "BCs set to be removed.\n" );
- else
- Journal_RPrintf( stream, "BCs will not be removed.\n" );
-
- startTime = MPI_Wtime();
-
- /* Shortcuts. */
- feMesh = self->feMesh;
- comm = Mesh_GetCommTopology( feMesh, MT_VERTEX );
- mpiComm = Comm_GetMPIComm( comm );
- MPI_Comm_size( mpiComm, (int*)&nProcs );
- MPI_Comm_rank( mpiComm, (int*)&rank );
- nDims = Mesh_GetDimSize( feMesh );
- nDomainNodes = FeMesh_GetNodeDomainSize( feMesh );
- self->nDomainEls = FeMesh_GetElementDomainSize( feMesh );
- nLocalNodes = FeMesh_GetNodeLocalSize( feMesh );
- nNodalDofs = self->dofLayout->dofCounts;
- links = self->linkedDofInfo;
-
- /* Allocate for destination array. */
- dstArray = Memory_Alloc_2DComplex( int, nDomainNodes, nNodalDofs,
- "FeEquationNumber::destinationArray" );
-
- /* If needed, allocate for linked equation numbers. */
- if( links ) {
- unsigned s_i;
-
- links->eqNumsOfLinkedDofs = ReallocArray( links->eqNumsOfLinkedDofs, int, links->linkedDofSetsCount );
- for( s_i = 0; s_i < links->linkedDofSetsCount; s_i++ )
- links->eqNumsOfLinkedDofs[s_i] = -1;
- }
-
- /* Allocate for the location matrix. */
- nLocMatDofs = NULL;
- locMat = AllocArray( int**, self->nDomainEls );
- for( e_i = 0; e_i < self->nDomainEls; e_i++ ) {
- FeMesh_GetElementNodes( feMesh, e_i, inc );
- nElNodes = IArray_GetSize( inc );
- elNodes = (unsigned*)IArray_GetPtr( inc );
- nLocMatDofs = ReallocArray( nLocMatDofs, int, nElNodes );
- for( n_i = 0; n_i < nElNodes; n_i++ )
- nLocMatDofs[n_i] = nNodalDofs[elNodes[n_i]];
- locMat[e_i] = AllocComplex2D( int, nElNodes, (Index*)nLocMatDofs );
- }
- FreeArray( nLocMatDofs );
-
- /* Build initial destination array and store max dofs. */
- curEqNum = 0;
- maxDofs = 0;
- for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
- if( nNodalDofs[n_i] > maxDofs )
- maxDofs = nNodalDofs[n_i];
-
- for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
- varInd = self->dofLayout->varIndices[n_i][dof_i];
- if( !self->bcs || !VariableCondition_IsCondition( self->bcs, n_i, varInd ) ||
- !self->removeBCs )
- {
- if( links && links->linkedDofTbl[n_i][dof_i] != -1 ) {
- if( rank > 0 ) {
- dstArray[n_i][dof_i] = -2;
- continue;
- }
- if( links->eqNumsOfLinkedDofs[links->linkedDofTbl[n_i][dof_i]] == -1 )
- links->eqNumsOfLinkedDofs[links->linkedDofTbl[n_i][dof_i]] = curEqNum++;
- dstArray[n_i][dof_i] = links->eqNumsOfLinkedDofs[links->linkedDofTbl[n_i][dof_i]];
- }
- else
- dstArray[n_i][dof_i] = curEqNum++;
- }
- else
- dstArray[n_i][dof_i] = -1;
- }
- }
-
- /* Order the equation numbers based on processor rank; cascade counts forward. */
- base = 0;
- if( rank > 0 )
- MPI_Recv( &base, 1, MPI_UNSIGNED, rank - 1, 6669, mpiComm, &status );
- subTotal = base + curEqNum;
- if( rank < nProcs - 1 )
- MPI_Send( &subTotal, 1, MPI_UNSIGNED, rank + 1, 6669, mpiComm );
-
- if( links ) {
- /* Reduce to find lowest linked DOFs. */
- for( s_i = 0; s_i < links->linkedDofSetsCount; s_i++ ) {
- if( links->eqNumsOfLinkedDofs[s_i] != -1 )
- links->eqNumsOfLinkedDofs[s_i] += base;
-/*
- MPI_Allreduce( links->eqNumsOfLinkedDofs + s_i, &lowest, 1, MPI_UNSIGNED, MPI_MAX, mpiComm );
-*/
- MPI_Allreduce( links->eqNumsOfLinkedDofs + s_i, &highest, 1, MPI_INT, MPI_MAX, mpiComm );
-/*
- assert( (lowest == (unsigned)-1) ? lowest == highest : 1 );
-*/
- links->eqNumsOfLinkedDofs[s_i] = highest;
- }
- }
-
- /* Modify existing destination array and dump to a tuple array. */
- tuples = AllocArray( unsigned, nDomainNodes * maxDofs );
- for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
- for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
- varInd = self->dofLayout->varIndices[n_i][dof_i];
- if( !self->bcs || !VariableCondition_IsCondition( self->bcs, n_i, varInd ) ||
- !self->removeBCs )
- {
- if( links && links->linkedDofTbl[n_i][dof_i] != -1 ) {
- highest = links->eqNumsOfLinkedDofs[links->linkedDofTbl[n_i][dof_i]];
- dstArray[n_i][dof_i] = highest;
- }
- else
- dstArray[n_i][dof_i] += base;
- }
- tuples[n_i * maxDofs + dof_i] = dstArray[n_i][dof_i];
- }
- }
-
- /* Update all other procs. */
- sync = Mesh_GetSync( feMesh, MT_VERTEX );
- Sync_SyncArray( sync, tuples, maxDofs * sizeof(unsigned),
- tuples + nLocalNodes * maxDofs, maxDofs * sizeof(unsigned),
- maxDofs * sizeof(unsigned) );
-
- /* Update destination array's domain indices. */
- for( n_i = nLocalNodes; n_i < nDomainNodes; n_i++ ) {
- for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
- varInd = self->dofLayout->varIndices[n_i][dof_i];
- if( !self->bcs || !VariableCondition_IsCondition( self->bcs, n_i, varInd ) ||
- !self->removeBCs )
- {
- dstArray[n_i][dof_i] = tuples[n_i * maxDofs + dof_i];
- }
- else
- dstArray[n_i][dof_i] = -1;
- }
- }
-
- /* Destroy tuple array. */
- FreeArray( tuples );
-
- /* Build location matrix. */
- for( e_i = 0; e_i < self->nDomainEls; e_i++ ) {
- FeMesh_GetElementNodes( feMesh, e_i, inc );
- nElNodes = IArray_GetSize( inc );
- elNodes = (unsigned*)IArray_GetPtr( inc );
- for( n_i = 0; n_i < nElNodes; n_i++ ) {
- for( dof_i = 0; dof_i < nNodalDofs[elNodes[n_i]]; dof_i++ )
- locMat[e_i][n_i][dof_i] = dstArray[elNodes[n_i]][dof_i];
- }
- }
-
- /* Store stuff on class. */
- self->destinationArray = dstArray;
- self->locationMatrix = locMat;
- self->locationMatrixBuilt = True;
- self->remappingActivated = False;
- self->localEqNumsOwnedCount = curEqNum;
- self->firstOwnedEqNum = base;
- self->lastOwnedEqNum = subTotal - 1;
- self->_lowestLocalEqNum = self->firstOwnedEqNum;
-
- /* Setup owned mapping. */
- STree_Clear( self->ownedMap );
- for( ii = self->firstOwnedEqNum; ii <= self->lastOwnedEqNum; ii++ ) {
- int val = ii - self->firstOwnedEqNum;
- STreeMap_Insert( self->ownedMap, &ii, &val );
- }
-
- /* Bcast global sum from highest rank. */
- if( rank == nProcs - 1 )
- self->globalSumUnconstrainedDofs = self->lastOwnedEqNum + 1;
- MPI_Bcast( &self->globalSumUnconstrainedDofs, 1, MPI_UNSIGNED, nProcs - 1, mpiComm );
-
- /* Construct lowest global equation number list. */
- self->_lowestGlobalEqNums = AllocArray( int, nProcs );
- MPI_Allgather( &self->firstOwnedEqNum, 1, MPI_UNSIGNED, self->_lowestGlobalEqNums, 1, MPI_UNSIGNED, mpiComm );
-
- endTime = MPI_Wtime();
-
- Journal_RPrintf( stream, "Assigned %d global equation numbers.\n", self->globalSumUnconstrainedDofs );
- Journal_Printf( stream, "[%u] Assigned %d local equation numbers, within range %d to %d.\n",
- rank, self->lastOwnedEqNum - self->firstOwnedEqNum + 1, self->firstOwnedEqNum, self->lastOwnedEqNum + 1 );
- Stream_UnIndent( stream );
-
- time = endTime - startTime;
- MPI_Reduce( &time, &tmin, 1, MPI_DOUBLE, MPI_MIN, 0, mpiComm );
- MPI_Reduce( &time, &tmax, 1, MPI_DOUBLE, MPI_MAX, 0, mpiComm );
- Journal_RPrintf( stream, "... Completed in %g [min] / %g [max] seconds.\n", tmin, tmax );
- Stream_UnIndent( stream );
-
- NewClass_Delete( inc );
-}
-
-#if 0
-void FeEquationNumber_BuildVariableIndices( FeEquationNumber* self, int* nInds, int** inds, int* maxDofs ) {
- int maxDofs;
- ISet indSetObj, *indSet = &indSetObj;
-
- *maxDofs = 0;
- for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
- if( nNodalDofs[n_i] > *maxDofs )
- *maxDofs = nNodalDofs[n_i];
- }
-
- ISet_Construct( indSet );
- ISet_SetMaxSize( indSet, *maxDofs );
- for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
- for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
- varInd = self->dofLayout->varIndices[n_i][dof_i];
- ISet_TryInsert( indSet, varInd );
- }
- }
-
- *nInds = ISet_GetSize( indSet );
- *inds = MemArray( int, *nInds, FeEquationNumber_Type );
- ISet_GetArray( indSet, NULL, inds );
- ISet_Destruct( indSet );
-}
-#endif
-
-
-#if 0
-void FeEquationNumber_Invert( void* feEqNum, int equation, unsigned* node, unsigned* dof ) {
- FeEquationNumber* self = (FeEquationNumber*)feEqNum;
-
- assert( self && Stg_CheckType( self, FeEquationNumber ) );
- assert( equation - self->firstOwnedEqNum < self->localEqNumsOwnedCount );
- assert( node );
- assert( dof );
-
- eq = equation - self->firstOwnedEqNum;
- *node = self->eqToNode[eq];
- *dof = self->eqToDof[eq];
-}
-
-Bool FeEquationNumber_IsKnown( void* feEqNum, int equation ) {
- FeEquationNumber* self = (FeEquationNumber*)feEqNum;
- unsigned node, dof;
- unsigned varInd;
-
- assert( self && Stg_CheckType( self, FeEquationNumber ) );
-
- if( !self->bcs ) return False;
- FeEquationNumber_Invert( self, equation, &node, &dof );
-
- assert( self->dofLayout );
- assert( self->dofLayout->varIndices );
- assert( self->dofLayout->varIndices[node] );
- varInd = self->dofLayout->varIndices[node][dof];
- return VariableCondition_IsCondition( self->bcs, n_i, varInd );
-}
-#endif
-
-
-int GenerateEquationNumbering(
- int NX, int NY, int NZ,
- int nlocal, int g_node_id[],
- int dof, int nglobal,
- PetscTruth periodic_x, PetscTruth periodic_y, PetscTruth periodic_z,
- int npx, int npy, int npz,
- int periodic_x_gnode_id[], int periodic_y_gnode_id[], int periodic_z_gnode_id[],
- int eqnums[], int *neqnums );
-
-void FeEquationNumber_BuildWithDave( FeEquationNumber* self ) {
- int nLocals, *locals;
- Grid *vGrid;
- int varInd;
- int nEqNums, **dstArray;
- IArray *inc;
- int nDofs;
- int *periodic;
- int ***locMat;
- int nDims;
- int *elNodes;
- Comm *comm;
- MPI_Comm mpiComm;
- int nRanks, rank;
- Sync *sync;
- Bool isCond;
- int nPeriodicInds[3];
- int *periodicInds[3];
- int inds[3];
- Bool usePeriodic;
- int *tmpArray, nLocalEqNums;
- int lastOwnedEqNum, ind;
- STree *doneSet;
- int ii, jj, kk;
-
- comm = Mesh_GetCommTopology( self->feMesh, (MeshTopology_Dim)0 );
- mpiComm = Comm_GetMPIComm( comm );
- MPI_Comm_size( mpiComm, &nRanks );
- MPI_Comm_rank( mpiComm, &rank );
-
- /* Setup an array containing global indices of all locally owned nodes. */
- nLocals = Mesh_GetLocalSize( self->feMesh, (MeshTopology_Dim)0 );
- locals = AllocArray( int, nLocals );
- for( ii = 0; ii < nLocals; ii++ )
- locals[ii] = Mesh_DomainToGlobal( self->feMesh, (MeshTopology_Dim)0, ii );
-
- /* Allocate for destination array. */
- nDofs = self->dofLayout->dofCounts[0];
- dstArray = AllocArray2D( int, Mesh_GetDomainSize( self->feMesh, (MeshTopology_Dim)0 ), nDofs );
-
- /* Get the vertex grid extension and any periodicity. */
- nDims = Mesh_GetDimSize( self->feMesh );
- vGrid = *Mesh_GetExtension( self->feMesh, Grid**, "vertexGrid" );
- periodic = Mesh_GetExtension( self->feMesh, int*, "periodic" );
-
- /* Fill destination array with initial values, setting dirichlet BCs as we go. */
- for( ii = 0; ii < nLocals; ii++ ) {
- Grid_Lift( vGrid, locals[ii], (unsigned*)inds );
- usePeriodic = False;
- for( jj = 0; jj < nDims; jj++ ) {
- if( periodic[jj] && (inds[jj] == 0 || inds[jj] == (int)(vGrid->sizes[jj] - 1)) ) {
- usePeriodic = True;
- break;
- }
- }
- for( jj = 0; jj < nDofs; jj++ ) {
- varInd = self->dofLayout->varIndices[ii][jj];
- if( self->bcs )
- isCond = VariableCondition_IsCondition( self->bcs, ii, varInd );
- else
- isCond = False;
- if( isCond && self->removeBCs )
- dstArray[ii][jj] = -1;
- else
- dstArray[ii][jj] = 0;
- }
- }
-
- /* Generate opposing indices for periodicity. */
- for( ii = 0; ii < nDims; ii++ ) {
- nPeriodicInds[ii] = 0;
- periodicInds[ii] = NULL;
- if( periodic[ii] ) {
- periodicInds[ii] = AllocArray( int, nLocals );
- for( jj = 0; jj < nLocals; jj++ ) {
- Grid_Lift( vGrid, locals[jj], (unsigned*)inds );
- if( inds[ii] != (int)(vGrid->sizes[ii] - 1) ) continue;
-/*
- for( kk = 0; kk < nDofs; kk++ )
- if( dstArray[jj][kk] == -1 ) break;
- if( kk < nDofs ) continue;
-*/
- periodicInds[ii][nPeriodicInds[ii]++] = locals[jj];
- }
- }
- }
-
- /* Call Dave's equation number generation routine. */
- if( nDims == 2 ) {
- GenerateEquationNumbering( vGrid->sizes[0], vGrid->sizes[1], 1,
- nLocals, locals,
- nDofs, Mesh_GetGlobalSize( self->feMesh, (MeshTopology_Dim)0 ),
- (PetscTruth)periodic[0], (PetscTruth)periodic[1], (PetscTruth)False,
- nPeriodicInds[0], nPeriodicInds[1], 0,
- periodicInds[0], periodicInds[1], NULL,
- dstArray[0], &nEqNums );
- }
- else {
- GenerateEquationNumbering( vGrid->sizes[0], vGrid->sizes[1], vGrid->sizes[2],
- nLocals, locals,
- nDofs, Mesh_GetGlobalSize( self->feMesh, (MeshTopology_Dim)0 ),
- (PetscTruth)periodic[0], (PetscTruth)periodic[1], (PetscTruth)periodic[2],
- nPeriodicInds[0], nPeriodicInds[1], nPeriodicInds[2],
- periodicInds[0], periodicInds[1], periodicInds[2],
- dstArray[0], &nEqNums );
- }
-
- /* Free periodic arrays. */
- for( ii = 0; ii < nDims; ii++ ) {
- if( periodicInds[ii] )
- FreeArray( periodicInds[ii] );
- }
-
- /* Setup owned mapping part 1. */
- STree_Clear( self->ownedMap );
- for( ii = 0; ii < nLocals; ii++ ) {
- Grid_Lift( vGrid, locals[ii], (unsigned*)inds );
- for( jj = 0; jj < nDims; jj++ ) {
- if( periodic[jj] && inds[jj] == (int)(vGrid->sizes[jj] - 1) ) {
- inds[jj] = 0;
- ind = Grid_Project( vGrid, (unsigned*)inds );
- if( !FeMesh_NodeGlobalToDomain( self->feMesh, ind, (unsigned*)(&ind) ) )
- break;
- }
- }
- if( jj < nDims ) continue;
- for( jj = 0; jj < nDofs; jj++ ) {
- if( dstArray[ii][jj] == -1 || STreeMap_HasKey( self->ownedMap, dstArray[ii] + jj ) )
- continue;
- STreeMap_Insert( self->ownedMap, dstArray[ii] + jj, &ii );
- }
- }
-
- /* Setup owned mapping. */
- tmpArray = AllocArray( int, nLocals * nDofs );
- memcpy( tmpArray, dstArray[0], nLocals * nDofs * sizeof(int) );
- qsort( tmpArray, nLocals * nDofs, sizeof(int), stgCmpInt );
- doneSet = STree_New();
- STree_SetItemSize( doneSet, sizeof(int) );
- STree_SetIntCallbacks( doneSet );
- for( nLocalEqNums = 0, ii = 0; ii < nLocals * nDofs; ii++ ) {
- if( tmpArray[ii] != -1 &&
- STreeMap_HasKey( self->ownedMap, tmpArray + ii ) &&
- !STree_Has( doneSet, tmpArray + ii ) )
- {
- if( !nLocalEqNums )
- self->_lowestLocalEqNum = tmpArray[ii];
- *(int*)STreeMap_Map( self->ownedMap, tmpArray + ii ) = nLocalEqNums;
- STree_Insert( doneSet, tmpArray + ii );
- nLocalEqNums++;
- }
- }
- lastOwnedEqNum = -1; /* Don't need this anymore. */
- FreeArray( tmpArray );
- NewClass_Delete( doneSet );
-
- /* Transfer remote equation numbers. */
- sync = Mesh_GetSync( self->feMesh, (MeshTopology_Dim)0 );
- Sync_SyncArray( sync, dstArray[0], nDofs * sizeof(int),
- dstArray[0] + nLocals * nDofs, nDofs * sizeof(int),
- nDofs * sizeof(int) );
-
- /* Allocate for location matrix. */
- /* first store nDomainEls for usage during destroy */
- self->nDomainEls = Mesh_GetDomainSize( self->feMesh, (MeshTopology_Dim)nDims );
- locMat = AllocArray( int**, self->nDomainEls );
- for( ii = 0; ii < (int)(self->nDomainEls); ii++ )
- locMat[ii] = AllocArray2D( int, FeMesh_GetElementNodeSize( self->feMesh, 0 ), nDofs );
-
- /* Fill in location matrix. */
- inc = IArray_New();
- for( ii = 0; ii < (int)Mesh_GetDomainSize( self->feMesh, (MeshTopology_Dim)nDims ); ii++ ) {
- FeMesh_GetElementNodes( self->feMesh, ii, inc );
- elNodes = IArray_GetPtr( inc );
- for( jj = 0; jj < (int)FeMesh_GetElementNodeSize( self->feMesh, 0 ); jj++ ) {
- for( kk = 0; kk < nDofs; kk++ )
- locMat[ii][jj][kk] = dstArray[elNodes[jj]][kk];
- }
- }
- NewClass_Delete( inc );
-
- /* Fill in our other weird values. */
- self->destinationArray = dstArray;
- self->locationMatrix = locMat;
- self->locationMatrixBuilt = True;
- self->remappingActivated = False;
- self->localEqNumsOwnedCount = nLocalEqNums;
-
- /* Bcast global sum from highest rank. */
- self->globalSumUnconstrainedDofs = nEqNums;
-
- /* Construct lowest global equation number list. */
- self->_lowestGlobalEqNums = AllocArray( int, nRanks );
- MPI_Allgather( &self->_lowestLocalEqNum, 1, MPI_UNSIGNED,
- self->_lowestGlobalEqNums, 1, MPI_UNSIGNED,
- mpiComm );
-
- FreeArray( locals );
-
- /*
- printf( "%d: localEqNumsOwned = %d\n", rank, self->localEqNumsOwnedCount );
- printf( "%d: globalSumUnconstrainedDofs = %d\n", rank, self->globalSumUnconstrainedDofs );
- */
-}
-
-
-
-
-/*
-
-Input:
- nlocal - number of locally ownded nodes
- g_node_id - global indices of nodes owned locally. Size nlocal
- dof - degrees of freedom per node
- nglobal - number of global nodes
- npx - number of consider to be periodic in x (local to this proc)
- npy - number of consider to be periodic in y (local to this proc)
- periodic_x_gnode_id - global indices of nodes (on this proc) which are on right hand side boundary
- periodic_y_gnode_id - global indices of nodes (on this proc) which are on top boundary
- eqnums - contains any dirichlet boundary conditions. Size nlocal*dof
-
-Output;
- eqnums - contains full list of eqnums
-
-Assumptions:
-- Ordering eqnums[] = { (node_0,[dof_0,dof_1,..,dof_x]), (node_1,[dof_0,dof_1,..,dof_x]), ... }
-- Any dirichlet set along a boundary deemed to be periodic will be clobbered.
-- Processors may have duplicate nodes in the g_node_id[] list.
-- A number in the corner is considered part of both boundaries (horiz and vert)
-- If npx is not 0, then periodicity is assumed in x
-- If npy is not 0, then periodicity is assumed in y
-- Dofs constrained to be dirichlet must be marked with a negative number.
-- Dofs are NOT split across processors.
-- We can define a logical i,j,k ordering to uniquely identify nodes.
-
-*/
-
-PetscErrorCode _VecScatterBeginEnd( VecScatter vscat, Vec FROM, Vec TO, InsertMode addv,ScatterMode mode )
-{
-#if( (PETSC_VERSION_MAJOR==2) && (PETSC_VERSION_MINOR==3) && (PETSC_VERSION_SUBMINOR==2) )
- // 2.3.2 ordering of args
- VecScatterBegin( FROM, TO, addv, mode, vscat );
- VecScatterEnd( FROM, TO, addv, mode, vscat );
-#else
- // 2.3.3 or 3.0.0
- VecScatterBegin( vscat, FROM, TO, addv, mode );
- VecScatterEnd( vscat, FROM, TO, addv, mode );
-#endif
-
- PetscFunctionReturn(0);
-}
-
-int GenerateEquationNumbering(
- int NX, int NY, int NZ,
- int nlocal, int g_node_id[],
- int dof, int nglobal,
- PetscTruth periodic_x, PetscTruth periodic_y, PetscTruth periodic_z,
- int npx, int npy, int npz,
- int periodic_x_gnode_id[], int periodic_y_gnode_id[], int periodic_z_gnode_id[],
- int eqnums[], int *neqnums )
-{
- PetscErrorCode ierr;
- PetscInt periodic_mask;
- Vec global_eqnum, g_ownership;
- PetscInt i;
- PetscMPIInt rank; /* processor rank */
- PetscMPIInt size; /* size of communicator */
- Vec local_ownership, local_eqnum;
- PetscInt *_g_node_id;
- IS is_gnode, is_eqnum;
- VecScatter vscat_ownership, vscat_eqnum;
- PetscScalar *_local_ownership, *_local_eqnum;
- PetscInt local_eqnum_count,global_eqnum_count;
- PetscScalar val[10];
- PetscInt d,idx[10];
- PetscInt *to_fetch,cnt,number_to_fetch;
- PetscInt eq_cnt;
- Vec offset_list;
- VecScatter vscat_offset;
- Vec seq_offset_list;
- PetscInt offset, inc;
-
- PetscInt spanx,spany,spanz,total;
- PetscInt loc;
- PetscReal max;
- PetscInt n_inserts;
-
-
- ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
- ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
-
- if( dof>=10 ) {
- SETERRQ(PETSC_ERR_SUP, "Max allowable degrees of freedom per node = 10. Change static size" );
- }
-
-
- /*
- Claim locally owned nodes. Duplicate nodes on the interior will be resolved by the processor
- which inserts last.
- */
- VecCreate( PETSC_COMM_WORLD, &g_ownership );
- VecSetSizes( g_ownership, PETSC_DECIDE, nglobal );
- VecSetFromOptions( g_ownership );
-
- for( i=0; i<nlocal; i++ ) {
- VecSetValue( g_ownership, g_node_id[i], rank, INSERT_VALUES );
- }
- VecAssemblyBegin(g_ownership);
- VecAssemblyEnd(g_ownership);
-
-
- /* Mask out the periodic boundaries. */
- periodic_mask = -6699.0;
- if (periodic_x_gnode_id!=NULL) {
- for( i=0; i<npx; i++ ) {
- VecSetValue( g_ownership, periodic_x_gnode_id[i], periodic_mask, INSERT_VALUES );
- }
- }
- if (periodic_y_gnode_id!=NULL) {
- for( i=0; i<npy; i++ ) {
- VecSetValue( g_ownership, periodic_y_gnode_id[i], periodic_mask, INSERT_VALUES );
- }
- }
- if (periodic_z_gnode_id!=NULL) {
- for( i=0; i<npz; i++ ) {
- VecSetValue( g_ownership, periodic_z_gnode_id[i], periodic_mask, INSERT_VALUES );
- }
- }
- VecAssemblyBegin(g_ownership);
- VecAssemblyEnd(g_ownership);
-
- /*
- PetscPrintf(PETSC_COMM_WORLD, "g_ownership \n");
- VecView( g_ownership, PETSC_VIEWER_STDOUT_WORLD );
- */
-
- /* Get all locally owned nodes */
- VecCreate( PETSC_COMM_SELF, &local_ownership );
- VecSetSizes( local_ownership, PETSC_DECIDE, nlocal );
- VecSetFromOptions( local_ownership );
-
- PetscMalloc( sizeof(PetscInt)*nlocal, &_g_node_id);
- for( i=0; i<nlocal; i++ ) {
- _g_node_id[i] = g_node_id[i];
- }
- ISCreateGeneralWithArray( PETSC_COMM_WORLD, nlocal, _g_node_id, &is_gnode );
- VecScatterCreate( g_ownership, is_gnode, local_ownership, PETSC_NULL, &vscat_ownership );
-
-
- /* assign unique equation numbers */
- VecSet( local_ownership, -6699 );
- _VecScatterBeginEnd( vscat_ownership, g_ownership, local_ownership, INSERT_VALUES, SCATTER_FORWARD );
-
-
- /* Count instances of rank in the local_ownership vector */
- VecGetArray( local_ownership, &_local_ownership );
- local_eqnum_count = 0;
- for( i=0; i<nlocal; i++ ) {
- if( ((PetscInt)_local_ownership[i]) == rank ) {
- local_eqnum_count++;
- }
- }
-
- MPI_Allreduce( &local_eqnum_count, &global_eqnum_count, 1, MPI_INT, MPI_SUM, PETSC_COMM_WORLD );
- /* PetscPrintf( PETSC_COMM_SELF,
- "[%d] number of local,global equations (without dofs) %d,%d \n", rank, local_eqnum_count, global_eqnum_count ); */
- /* check */
- spanx = NX;
- spany = NY;
- spanz = NZ;
- if( periodic_x==PETSC_TRUE ) {
- spanx--;
- }
- if( periodic_y==PETSC_TRUE ) {
- spany--;
- }
- if( periodic_z==PETSC_TRUE ) {
- spanz--;
- }
- total = spanx*spany*spanz;
- if( total!=global_eqnum_count ) {
- SETERRQ(PETSC_ERR_SUP, "Something stinks. Computed global size for nodes does not match expected" );
- }
-
-
-
- VecCreate( PETSC_COMM_WORLD, &global_eqnum );
- VecSetSizes( global_eqnum, PETSC_DECIDE, nglobal*dof );
- VecSetFromOptions( global_eqnum );
- VecSet( global_eqnum, 0.0 );
-
- /* Load existing eqnums in */
- for( i=0; i<nlocal; i++ ) {
- n_inserts = 0;
- for( d=0; d<dof; d++ ) {
-/*
- idx[d] = -(g_node_id[i]*dof + d);
- val[d] = 0.0;
-*/
- if( eqnums[ i*dof + d ] < 0.0 ) {
- idx[n_inserts] = g_node_id[i]*dof + d;
- val[n_inserts] = eqnums[ i*dof + d ];
- n_inserts++;
- }
- }
- /* only insert dirichlet bc's */
- VecSetValues( global_eqnum, n_inserts, idx, val, INSERT_VALUES );
- }
- VecAssemblyBegin(global_eqnum);
- VecAssemblyEnd(global_eqnum);
-
-
-
-
-
- /* Generate list of eqnums to get */
- PetscMalloc( sizeof(PetscInt)*nlocal*dof, &to_fetch );
- cnt = 0;
- for( i=0; i<nlocal; i++ ) {
- if( _local_ownership[i]==rank ) {
- for( d=0; d<dof; d++ ) {
- to_fetch[cnt] = g_node_id[i]*dof + d;
- cnt++;
- }
- }
- }
- number_to_fetch = cnt;
-
-
- VecCreate( PETSC_COMM_SELF, &local_eqnum );
- VecSetSizes( local_eqnum, PETSC_DECIDE, number_to_fetch);
- VecSetFromOptions( local_eqnum );
-
- ISCreateGeneralWithArray( PETSC_COMM_SELF, number_to_fetch, to_fetch, &is_eqnum );
- VecScatterCreate( global_eqnum, is_eqnum, local_eqnum, PETSC_NULL, &vscat_eqnum );
-
- VecSet( local_eqnum, -6699 );
- _VecScatterBeginEnd( vscat_eqnum, global_eqnum, local_eqnum, INSERT_VALUES, SCATTER_FORWARD );
-
-
- /* compute offset */
- /* count how many entries there are */
- VecGetArray( local_eqnum, &_local_eqnum );
- eq_cnt = 0;
- for( i=0; i<number_to_fetch; i++ ) {
- if( (PetscInt)_local_eqnum[i]==0 ) {
- eq_cnt++;
- }
- }
- VecRestoreArray( local_eqnum, &_local_eqnum );
-
- VecCreate( PETSC_COMM_WORLD, &offset_list );
- VecSetSizes( offset_list, PETSC_DECIDE, (size+1) );
- VecSetFromOptions( offset_list );
- for( i=rank; i<size; i++ ) {
- VecSetValue( offset_list, i+1, eq_cnt, ADD_VALUES );
- }
- VecAssemblyBegin(offset_list);
- VecAssemblyEnd(offset_list);
- /*
- PetscPrintf(PETSC_COMM_WORLD, "offset_list \n");
- VecView( offset_list, PETSC_VIEWER_STDOUT_WORLD );
- */
-
- VecScatterCreateToAll(offset_list,&vscat_offset,&seq_offset_list);
- _VecScatterBeginEnd( vscat_offset, offset_list, seq_offset_list, INSERT_VALUES, SCATTER_FORWARD );
-
- {
- PetscScalar *_seq_offset_list;
-
- VecGetArray( seq_offset_list, &_seq_offset_list );
- offset = _seq_offset_list[ rank ];
- VecRestoreArray( seq_offset_list, &_seq_offset_list );
- }
- VecScatterDestroy(vscat_offset);
- VecDestroy(offset_list);
- VecDestroy(seq_offset_list);
-
- /* PetscPrintf( PETSC_COMM_SELF, "[%d]: offset = %d \n", rank, offset ); */
-
-
- VecGetArray( local_eqnum, &_local_eqnum );
- inc = 0;
- for( i=0; i<number_to_fetch; i++ ) {
- if( (PetscInt)_local_eqnum[i]==0 ) {
- _local_eqnum[i] = offset+inc;
- inc++;
- }
- }
- VecRestoreArray( local_eqnum, &_local_eqnum );
-
- _VecScatterBeginEnd( vscat_eqnum, local_eqnum, global_eqnum, INSERT_VALUES, SCATTER_REVERSE );
- /*
- PetscPrintf(PETSC_COMM_WORLD, "global_eqnum \n");
- VecView( global_eqnum, PETSC_VIEWER_STDOUT_WORLD );
- */
-
- /* For each periodic boundary, get the mapped nodes */
-
- if( periodic_x==PETSC_TRUE ) {
- VecScatter vscat_p;
- IS is_from;
- PetscInt *from, *to;
- Vec mapped;
- PetscScalar *_mapped;
- PetscInt c;
-
- PetscMalloc( sizeof(PetscInt)*npx*dof, &from );
- PetscMalloc( sizeof(PetscInt)*npx*dof, &to );
-
- c = 0;
- for( i=0; i<npx; i++ ) {
- PetscInt I,J,K,gid,from_gid;
-
- gid = periodic_x_gnode_id[i];
- K = gid/(NX*NY);
- J = (gid - K*(NX*NY))/NX;
- I = gid - K*(NX*NY) - J*NX;
- from_gid = (I-(NX-1)) + J*NX + K*(NX*NY);
-
- for( d=0; d<dof; d++ ) {
- to[c] = gid * dof + d;
- from[c] = from_gid * dof + d;
- c++;
- }
- }
-
-
- VecCreate( PETSC_COMM_SELF, &mapped );
- VecSetSizes( mapped, PETSC_DECIDE, npx*dof );
- VecSetFromOptions( mapped );
-
- ISCreateGeneralWithArray( PETSC_COMM_SELF, npx*dof, from, &is_from );
- VecScatterCreate( global_eqnum, is_from, mapped, PETSC_NULL, &vscat_p );
-
- _VecScatterBeginEnd( vscat_p, global_eqnum, mapped, INSERT_VALUES, SCATTER_FORWARD );
- if( npx>0 ) {
- VecGetArray( mapped, &_mapped );
- VecSetValues( global_eqnum, npx*dof, to, _mapped, INSERT_VALUES );
- VecRestoreArray( mapped, &_mapped );
- }
-
- VecAssemblyBegin(global_eqnum);
- VecAssemblyEnd(global_eqnum);
-
- VecScatterDestroy( vscat_p );
- ISDestroy( is_from );
- VecDestroy( mapped );
- PetscFree( from );
- PetscFree( to );
- }
-
-
- if( periodic_y==PETSC_TRUE ) {
- VecScatter vscat_p;
- IS is_from;
- PetscInt *from, *to;
- Vec mapped;
- PetscScalar *_mapped;
- PetscInt c;
-
- PetscMalloc( sizeof(PetscInt)*npy*dof, &from );
- PetscMalloc( sizeof(PetscInt)*npy*dof, &to );
-
- c = 0;
- for( i=0; i<npy; i++ ) {
- PetscInt I,J,K,gid,from_gid;
-
- gid = periodic_y_gnode_id[i];
- K = gid/(NX*NY);
- J = (gid - K*(NX*NY))/NX;
- I = gid - K*(NX*NY) - J*NX;
- from_gid = I + (J - (NY - 1))*NX + K*(NX*NY);
-
- for( d=0; d<dof; d++ ) {
- to[c] = gid * dof + d;
- from[c] = from_gid * dof + d;
- c++;
- }
- }
-
-
- VecCreate( PETSC_COMM_SELF, &mapped );
- VecSetSizes( mapped, PETSC_DECIDE, npy*dof );
- VecSetFromOptions( mapped );
-
- ISCreateGeneralWithArray( PETSC_COMM_SELF, npy*dof, from, &is_from );
- VecScatterCreate( global_eqnum, is_from, mapped, PETSC_NULL, &vscat_p );
-
- _VecScatterBeginEnd( vscat_p, global_eqnum, mapped, INSERT_VALUES, SCATTER_FORWARD );
- if( npy>0 ) {
- VecGetArray( mapped, &_mapped );
- VecSetValues( global_eqnum, npy*dof, to, _mapped, INSERT_VALUES );
- VecRestoreArray( mapped, &_mapped );
- }
-
- VecAssemblyBegin(global_eqnum);
- VecAssemblyEnd(global_eqnum);
-
- VecScatterDestroy( vscat_p );
- ISDestroy( is_from );
- VecDestroy( mapped );
- PetscFree( from );
- PetscFree( to );
- }
-
- if( periodic_z==PETSC_TRUE ) {
- VecScatter vscat_p;
- IS is_from;
- PetscInt *from, *to;
- Vec mapped;
- PetscScalar *_mapped;
- PetscInt c;
-
- PetscMalloc( sizeof(PetscInt)*npz*dof, &from );
- PetscMalloc( sizeof(PetscInt)*npz*dof, &to );
-
- c = 0;
- for( i=0; i<npz; i++ ) {
- PetscInt I,J,K,gid,from_gid;
-
- gid = periodic_z_gnode_id[i];
- K = gid/(NX*NY);
- J = (gid - K*(NX*NY))/NX;
- I = gid - K*(NX*NY) - J*NX;
- from_gid = I + J*NX + (K - (NZ-1))*(NX*NY);
-
- for( d=0; d<dof; d++ ) {
- to[c] = gid * dof + d;
- from[c] = from_gid * dof + d;
- c++;
- }
- }
-
-
- VecCreate( PETSC_COMM_SELF, &mapped );
- VecSetSizes( mapped, PETSC_DECIDE, npz*dof );
- VecSetFromOptions( mapped );
-
- ISCreateGeneralWithArray( PETSC_COMM_SELF, npz*dof, from, &is_from );
- VecScatterCreate( global_eqnum, is_from, mapped, PETSC_NULL, &vscat_p );
-
- _VecScatterBeginEnd( vscat_p, global_eqnum, mapped, INSERT_VALUES, SCATTER_FORWARD );
- if( npz>0 ) {
- VecGetArray( mapped, &_mapped );
- VecSetValues( global_eqnum, npz*dof, to, _mapped, INSERT_VALUES );
- VecRestoreArray( mapped, &_mapped );
- }
-
- VecAssemblyBegin(global_eqnum);
- VecAssemblyEnd(global_eqnum);
-
- VecScatterDestroy( vscat_p );
- ISDestroy( is_from );
- VecDestroy( mapped );
- PetscFree( from );
- PetscFree( to );
- }
-
-
- /*
- PetscPrintf(PETSC_COMM_WORLD, "global_eqnum following periodic \n");
- VecView( global_eqnum, PETSC_VIEWER_STDOUT_WORLD );
- */
-
-
- /* Finally, scatter stuff from global_eqnums into MY array */
- {
- IS is_all_my_eqnums;
- PetscInt *all_my_eqnum_index;
- PetscInt _I,_D,CNT;
- Vec all_my_eqnums;
- PetscScalar *_all_my_eqnums;
- VecScatter vscat_p;
-
- PetscMalloc( sizeof(PetscInt)*dof*nlocal, &all_my_eqnum_index );
-
- CNT = 0;
- for( _I=0; _I<nlocal; _I++ ) {
- for( _D=0; _D<dof; _D++ ) {
- all_my_eqnum_index[CNT] = g_node_id[_I]*dof + _D;
- CNT++;
- }
- }
-
- ISCreateGeneralWithArray( PETSC_COMM_SELF, nlocal*dof, all_my_eqnum_index, &is_all_my_eqnums );
- VecCreate( PETSC_COMM_SELF, &all_my_eqnums );
- VecSetSizes( all_my_eqnums, PETSC_DECIDE, nlocal*dof );
- VecSetFromOptions( all_my_eqnums );
- VecScatterCreate( global_eqnum, is_all_my_eqnums, all_my_eqnums, PETSC_NULL, &vscat_p );
- _VecScatterBeginEnd( vscat_p, global_eqnum, all_my_eqnums, INSERT_VALUES, SCATTER_FORWARD );
- VecGetArray( all_my_eqnums, &_all_my_eqnums );
-
- for( i=0; i<nlocal*dof; i++ ) {
- eqnums[i] = (int)_all_my_eqnums[i];
- }
- VecRestoreArray( all_my_eqnums, &_all_my_eqnums );
-
- VecScatterDestroy( vscat_p );
- VecDestroy( all_my_eqnums );
- ISDestroy( is_all_my_eqnums );
- PetscFree( all_my_eqnum_index );
- }
-
- VecMax( global_eqnum, &loc, &max );
- *neqnums = (int)max;
- (*neqnums)++;
-
- /* tidy up */
- VecRestoreArray( local_ownership, &_local_ownership );
-
-
- VecDestroy( g_ownership );
- VecDestroy( local_ownership );
- PetscFree( _g_node_id );
- ISDestroy( is_gnode );
- VecScatterDestroy( vscat_ownership );
-
- VecDestroy( global_eqnum );
- VecDestroy( local_eqnum );
- PetscFree( to_fetch );
- ISDestroy( is_eqnum );
- VecScatterDestroy( vscat_eqnum );
-
- return 0;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FeEquationNumber.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/FeEquationNumber.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,3367 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: FeEquationNumber.c 1191 2008-07-25 03:06:19Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "ElementType.h"
+#include "ElementType_Register.h"
+#include "Element.h"
+#include "FeMesh.h"
+#include "FeEquationNumber.h"
+#include "LinkedDofInfo.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+#include <petsc.h>
+#include <petscvec.h>
+
+int stgCmpInt( const void *l, const void *r ) {
+ return *(int*)l - *(int*)r;
+}
+
+/*###### Typedefs and Structs ######*/
+
+/** Textual name of this class */
+const Type FeEquationNumber_Type = "FeEquationNumber";
+
+/** struct to store sub-totals: what is the equation number up to at a given
+ node? These can then be exchanged between processors */
+typedef struct CritPointInfo {
+ Node_GlobalIndex index;
+ Dof_EquationNumber eqNum;
+} CritPointInfo;
+
+
+/** An element of linked list of critical point info. Several of the functions
+ use this to keep track of key points */
+typedef struct AddListEntry {
+ CritPointInfo* critPointInfo;
+ struct AddListEntry* next;
+} AddListEntry;
+
+/** Enum to say whetehr values at crit. nodes should be printed */
+typedef enum PrintValuesFlag {
+ DONT_PRINT_VALUES,
+ PRINT_VALUES
+} PrintValuesFlag;
+
+/** MPI datatype handle for efficiently exchanging CritPointInfo structures.
+ see FeEquationNumber_Create_CritPointInfo_MPI_Datatype() for where this
+ handle is defined. */
+MPI_Datatype MPI_critPointInfoType;
+
+/*###### Private Function Declarations ######*/
+
+#if 0
+static void _FeEquationNumber_BuildRemappedNodeInfoTable( void* feEquationNumber );
+
+static void _FeEquationNumber_CalculateDomainKnownCriticalPoints(
+ FeEquationNumber* self,
+ Node_DomainIndex nodeDomainCount,
+ CritPointInfo* mySetEnds,
+ Index* const mySetEndsTotal,
+ Node_GlobalIndex* myWantedCriticalPoints,
+ Index* const myWantedCriticalPointsTotal );
+
+static void _FeEquationNumber_HandleNode(
+ FeEquationNumber* self,
+ const Node_DomainIndex dNode_I,
+ Dof_EquationNumber* const currEqNum );
+
+static void _FeEquationNumber_PostProcessLinkedDofs( FeEquationNumber* self );
+
+static void _FeEquationNumber_CalculateCritPointsIHave(
+ FeEquationNumber* self,
+ Node_GlobalIndex** const myWantedCriticalPointsPtr,
+ Node_GlobalIndex myWantedCriticalPointsTotal,
+ CritPointInfo** const critPointsIHave,
+ Index* const critPointsIHaveTotal,
+ CritPointInfo* const critPointsToSend,
+ Index* const critPointsToSendTotal );
+
+static void _FeEquationNumber_ShareCriticalPoints(
+ FeEquationNumber* self,
+ Node_GlobalIndex** const myCriticalPoints,
+ Node_GlobalIndex myCriticalPointsTotal,
+ Node_GlobalIndex** allCriticalPoints,
+ Index** procCritPointsTotals,
+ Node_GlobalIndex* const maxCritPointsPerProc );
+
+static void _FeEquationNumber_ShareCritPointInfo(
+ FeEquationNumber* self,
+ CritPointInfo** const myCritPointInfo,
+ Index myCritPointInfoTotal,
+ CritPointInfo** allCritPointInfo,
+ Index** procCritPointInfoTotals,
+ Index* const maxCritPointInfoPerProc,
+ PrintValuesFlag printValuesFlag );
+
+static void _FeEquationNumber_DoPartialTotals(
+ FeEquationNumber* self,
+ CritPointInfo* const critPointsIHave,
+ Index critPointsIHaveTotal,
+ CritPointInfo* const critPointsToSend,
+ Index critPointsToSendTotal );
+
+static void _FeEquationNumber_AddAllPartialTotals(
+ FeEquationNumber* self,
+ CritPointInfo* mySubTotals,
+ Index myCritPointInfoTotal,
+ CritPointInfo* allSubTotals,
+ Index* procCritPointInfoTotals,
+ Index maxSubTotalsPerProc );
+
+Node_RemappedGlobalIndex _FeEquationNumber_RemapNode(
+ Mesh* mesh,
+ Index newDimOrder[3],
+ Node_GlobalIndex gNode_I );
+
+int GenerateEquationNumbering(
+ int NX, int NY, int NZ,
+ int nlocal, int g_node_id[],
+ int dof, int nglobal,
+ PetscTruth periodic_x, PetscTruth periodic_y, PetscTruth periodic_z,
+ int npx, int npy, int npz,
+ int periodic_x_gnode_id[], int periodic_y_gnode_id[], int periodic_z_gnode_id[],
+ int eqnums[], int *neqnums );
+
+/** Tests if the critical point from another processor is held by ours.
+ Is complicated by the possibility of remapping. */
+static Bool _FeEquationNumber_IHaveCritPoint(
+ FeEquationNumber* self,
+ Node_RemappedGlobalIndex critPoint );
+#endif
+
+/*###### Function Definitions ######*/
+
+/** Public constructor */
+
+FeEquationNumber* FeEquationNumber_New(
+ Name name,
+ DomainContext* context,
+ void* mesh,
+ DofLayout* dofLayout,
+ VariableCondition* bcs,
+ LinkedDofInfo* linkedDofInfo )
+{
+ FeEquationNumber* self = (FeEquationNumber*)FeEquationNumber_DefaultNew( name );
+
+ self->isConstructed = True;
+ _FeEquationNumber_Init( self, context, mesh, dofLayout, bcs, linkedDofInfo );
+
+ return self;
+}
+
+void* FeEquationNumber_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(FeEquationNumber);
+ Type type = FeEquationNumber_Type;
+ Stg_Class_DeleteFunction* _delete = _FeEquationNumber_Delete;
+ Stg_Class_PrintFunction* _print = _FeEquationNumber_Print;
+ Stg_Class_CopyFunction* _copy = _FeEquationNumber_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (Stg_Component_DefaultConstructorFunction*)FeEquationNumber_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _FeEquationNumber_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _FeEquationNumber_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FeEquationNumber_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FeEquationNumber_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FeEquationNumber_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+
+ return _FeEquationNumber_New( FEEQUATIONNUMBER_PASSARGS );
+}
+/** Constructor implementation. */
+FeEquationNumber* _FeEquationNumber_New( FEEQUATIONNUMBER_DEFARGS ){
+ FeEquationNumber* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(FeEquationNumber) );
+ self = (FeEquationNumber*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ /* General info */
+
+ /* Virtual info */
+ self->_build = _build;
+ self->_initialise = _initialise;
+
+ /* Mesh info */
+
+ return self;
+}
+
+
+/** Constructor variables initialisation. Doesn't allocate any
+ memory, just saves arguments and sets counters to 0. */
+void _FeEquationNumber_Init(
+ FeEquationNumber* self,
+ DomainContext* context,
+ void* feMesh,
+ DofLayout* dofLayout,
+ VariableCondition* bcs,
+ LinkedDofInfo* linkedDofInfo )
+{
+ /* General and Virtual info should already be set */
+
+ /* FinteElementMesh info */
+ self->context = context;
+ self->feMesh = (FeMesh*)feMesh;
+ self->globalSumUnconstrainedDofs = 0;
+ self->isBuilt = False;
+ self->locationMatrixBuilt = False;
+ self->_lowestLocalEqNum = -1;
+ self->_lowestGlobalEqNums = NULL;
+ self->_highestLocalEqNum = -1;
+ self->dofLayout = dofLayout;
+ self->bcs = bcs;
+ self->linkedDofInfo = linkedDofInfo;
+ self->remappingActivated = False;
+ /* register streams */
+ self->debug = Stream_RegisterChild( StgFEM_Discretisation_Debug, FeEquationNumber_Type );
+ self->debugLM = Stream_RegisterChild( self->debug, "LM" );
+ self->warning = Stream_RegisterChild( StgFEM_Warning, FeEquationNumber_Type );
+ self->removeBCs = True;
+ self->bcEqNums = STree_New();
+ STree_SetIntCallbacks( self->bcEqNums );
+ STree_SetItemSize( self->bcEqNums, sizeof(int) );
+ self->ownedMap = STreeMap_New();
+ STreeMap_SetItemSize( self->ownedMap, sizeof(int), sizeof(int) );
+ STree_SetIntCallbacks( self->ownedMap );
+
+ Stream_SetPrintingRank( self->debug, 0 );
+}
+
+void _FeEquationNumber_AssignFromXML( void* feEquationNumber, Stg_ComponentFactory *cf, void* data ) {
+}
+
+void _FeEquationNumber_Execute( void* feEquationNumber, void *data ){
+
+}
+
+void _FeEquationNumber_Destroy( void* feEquationNumber, void *data ){
+ FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
+ Index ii;
+
+ Stg_Component_Destroy( self->feMesh , data, False );
+ Stg_Component_Destroy( self->dofLayout, data, False );
+ if ( self->linkedDofInfo ) Stg_Component_Destroy( self->dofLayout, data, False );
+ if ( self->bcs ) Stg_Component_Destroy( self->bcs , data, False );
+
+ FreeArray( self->remappedNodeInfos );
+ /* free destination array memory */
+ Journal_DPrintfL( self->debug, 2, "Freeing I.D. Array\n" );
+ FreeArray( self->destinationArray );
+
+ if (self->locationMatrix) {
+ Journal_DPrintfL( self->debug, 2, "Freeing Full L.M. Array\n" );
+ for( ii = 0; ii < self->nDomainEls; ii++ )
+ FreeArray( self->locationMatrix[ii] );
+
+ FreeArray( self->locationMatrix );
+ }
+
+ if( self->bcEqNums )
+ NewClass_Delete( self->bcEqNums );
+
+ if( self->ownedMap )
+ NewClass_Delete( self->ownedMap );
+}
+
+/* Copy */
+
+/** Stg_Class_Delete implementation. */
+void _FeEquationNumber_Delete( void* feEquationNumber ) {
+ FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
+
+ Journal_DPrintfL( self->debug, 1, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ /* Stg_Class_Delete parent */
+ _Stg_Class_Delete( self );
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+/** Print implementation */
+void _FeEquationNumber_Print( void* mesh, Stream* stream ) {
+ FeEquationNumber* self = (FeEquationNumber*)mesh;
+
+ /* General info */
+ Journal_Printf( stream, "FeEquationNumber (ptr): %p\n", self );
+
+ /* Print parent */
+ _Stg_Class_Print( self, stream );
+
+ /* Virtual info */
+ Journal_Printf( stream, "\t_build (func ptr): %p\n", self->_build );
+ Journal_Printf( stream, "\t_intialise (func ptr): %p\n", self->_initialise );
+
+ /* FeEquationNumber info */
+ /* Don't print dofs or bcs as these will be printed by FeVariable */
+
+ if ( self->destinationArray ) {
+ FeEquationNumber_PrintDestinationArray( self, stream );
+ FeEquationNumber_PrintLocationMatrix( self, stream );
+ }
+ else {
+ Journal_Printf( stream, "\tdestinationArray: (null)... not built yet\n" );
+ Journal_Printf( stream, "\tlocationMatrix: (null)... not built yet\n" );
+ }
+}
+
+
+void* _FeEquationNumber_Copy( const void* feEquationNumber, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+#if 0
+ FeEquationNumber* self = (FeEquationNumber*)feEquationNumber;
+ Mesh* mesh;
+ FeEquationNumber* newFeEquationNumber;
+ PtrMap* map = ptrMap;
+ Bool ownMap = False;
+
+ mesh = (Mesh*)self->feMesh;
+
+ if( !map ) {
+ map = PtrMap_New( 10 );
+ ownMap = True;
+ }
+
+ newFeEquationNumber = _Stg_Class_Copy( self, dest, deep, nameExt, map );
+
+ /* Virtual methods */
+ newFeEquationNumber->_build = self->_build;
+ newFeEquationNumber->_initialise = self->_initialise;
+
+ newFeEquationNumber->_highestLocalEqNum = self->_highestLocalEqNum;
+ newFeEquationNumber->_lowestLocalEqNum = self->_lowestLocalEqNum;
+ newFeEquationNumber->_eqNumsPerProcDivisor = self->_eqNumsPerProcDivisor;
+ newFeEquationNumber->_eqNumsRemainder = self->_eqNumsRemainder;
+ newFeEquationNumber->_remNotAddedChangeover = self->_remNotAddedChangeover;
+ newFeEquationNumber->firstOwnedEqNum = self->firstOwnedEqNum;
+ newFeEquationNumber->lastOwnedEqNum = self->lastOwnedEqNum;
+ newFeEquationNumber->localEqNumsOwnedCount = self->localEqNumsOwnedCount;
+ newFeEquationNumber->globalSumUnconstrainedDofs = self->globalSumUnconstrainedDofs;
+ newFeEquationNumber->locationMatrixBuilt = self->locationMatrixBuilt;
+ newFeEquationNumber->remappingActivated = self->remappingActivated;
+
+ if( deep ) {
+ newFeEquationNumber->debug = (Stream*)Stg_Class_Copy( self->debug, NULL, deep, nameExt, map );
+ newFeEquationNumber->debugLM = (Stream*)Stg_Class_Copy( self->debugLM, NULL, deep, nameExt, map );
+ newFeEquationNumber->warning = (Stream*)Stg_Class_Copy( self->warning, NULL, deep, nameExt, map );
+ newFeEquationNumber->feMesh = (FeMesh*)Stg_Class_Copy( self->feMesh, NULL, deep, nameExt, map );
+ newFeEquationNumber->dofLayout = (DofLayout*)Stg_Class_Copy( self->dofLayout, NULL, deep, nameExt, map );
+ newFeEquationNumber->bcs = (VariableCondition*)Stg_Class_Copy( self->bcs, NULL, deep, nameExt, map );
+ newFeEquationNumber->linkedDofInfo = (LinkedDofInfo*)Stg_Class_Copy( self->linkedDofInfo, NULL, deep, nameExt, map );
+
+ if( (newFeEquationNumber->remappedNodeInfos = PtrMap_Find( map, self->remappedNodeInfos )) == NULL && self->remappedNodeInfos ) {
+ Node_DomainIndex nodeDomainCount;
+
+ nodeDomainCount = Mesh_GetDomainSize( mesh, MT_VERTEX );
+
+ newFeEquationNumber->remappedNodeInfos = Memory_Alloc_Array( RemappedNodeInfo, nodeDomainCount, "FeEquationNumber->remappedNodeInfos" );
+ memcpy( newFeEquationNumber->remappedNodeInfos, self->remappedNodeInfos, sizeof(RemappedNodeInfo) * nodeDomainCount );
+ PtrMap_Append( map, self->remappedNodeInfos, newFeEquationNumber->remappedNodeInfos );
+ }
+
+ if( (newFeEquationNumber->destinationArray = PtrMap_Find( map, self->destinationArray )) == NULL && self->destinationArray ) {
+ Node_DomainIndex nodeDomainCount;
+ Node_DomainIndex node_dI;
+
+ nodeDomainCount = Mesh_GetDomainSize( mesh, MT_VERTEX );
+
+ newFeEquationNumber->destinationArray = Memory_Alloc_2DComplex( Dof_EquationNumber, nodeDomainCount, self->dofLayout->dofCounts, "FeEquationNumber->destinationArray" );
+ for( node_dI = 0; node_dI < nodeDomainCount; node_dI++ ) {
+ memcpy( newFeEquationNumber->destinationArray[node_dI], self->destinationArray[node_dI], sizeof(Dof_EquationNumber) * self->dofLayout->dofCounts[node_dI] );
+ }
+ PtrMap_Append( map, self->destinationArray, newFeEquationNumber->destinationArray );
+ }
+
+ if( (newFeEquationNumber->_lowestGlobalEqNums = PtrMap_Find( map, self->_lowestGlobalEqNums )) == NULL && self->_lowestGlobalEqNums ) {
+ Partition_Index nProc;
+
+ nProc = Mesh_GetCommTopology( mesh, MT_VERTEX )->nProcs;
+
+ newFeEquationNumber->_lowestGlobalEqNums = Memory_Alloc_Array( Dof_EquationNumber, nProc, "FeEquationNumber->_lowestGlobalEqNums" );
+ memcpy( newFeEquationNumber->_lowestGlobalEqNums, self->_lowestGlobalEqNums, sizeof(Dof_EquationNumber) * nProc );
+ PtrMap_Append( map, self->_lowestGlobalEqNums, newFeEquationNumber->_lowestGlobalEqNums );
+ }
+
+ if( (newFeEquationNumber->locationMatrix = PtrMap_Find( map, self->locationMatrix )) == NULL && self->locationMatrix ) {
+ FeMesh* mesh = self->feMesh;
+ Element_LocalIndex lElement_I;
+ Node_LocalIndex numNodesThisElement;
+ Node_LocalIndex elLocalNode_I;
+ Dof_Index numDofsThisNode;
+ Element_LocalIndex elementLocalCount = mesh->elementLocalCount;
+ Dof_Index** dofCountsAtElementNodesArray;
+
+ dofCountsAtElementNodesArray = Memory_Alloc_3DSetup( elementLocalCount, mesh->elementNodeCountTbl );
+ for ( lElement_I = 0; lElement_I < elementLocalCount; lElement_I++ ) {
+ numNodesThisElement = mesh->elementNodeCountTbl[lElement_I];
+
+ for( elLocalNode_I = 0; elLocalNode_I < numNodesThisElement; elLocalNode_I++) {
+ Node_LocalIndex dNode_I = mesh->elementNodeTbl[lElement_I][elLocalNode_I];
+
+ numDofsThisNode = self->dofLayout->dofCounts[dNode_I];
+ dofCountsAtElementNodesArray[lElement_I][elLocalNode_I] = numDofsThisNode;
+ }
+ }
+
+ newFeEquationNumber->locationMatrix = Memory_Alloc_3DComplex( Dof_EquationNumber, elementLocalCount, mesh->elementNodeCountTbl, dofCountsAtElementNodesArray, "FeEquationNumber->locationMatrix" );
+ for( lElement_I = 0; lElement_I < elementLocalCount; lElement_I++ ) {
+ for( elLocalNode_I = 0; elLocalNode_I < mesh->elementNodeCountTbl[lElement_I]; elLocalNode_I++ ) {
+ memcpy( newFeEquationNumber->locationMatrix[lElement_I][elLocalNode_I], self->locationMatrix[lElement_I][elLocalNode_I], sizeof(Dof_EquationNumber) * dofCountsAtElementNodesArray[lElement_I][elLocalNode_I] );
+ }
+ }
+
+ Memory_Free( dofCountsAtElementNodesArray );
+ PtrMap_Append( map, self->locationMatrix, newFeEquationNumber->locationMatrix );
+ }
+ }
+ else {
+ newFeEquationNumber->debug = self->debug;
+ newFeEquationNumber->debugLM = self->debugLM;
+ newFeEquationNumber->warning = self->warning;
+ newFeEquationNumber->feMesh = self->feMesh;
+ newFeEquationNumber->dofLayout = self->dofLayout;
+ newFeEquationNumber->bcs = self->bcs;
+ newFeEquationNumber->linkedDofInfo = self->linkedDofInfo;
+ newFeEquationNumber->remappedNodeInfos = self->remappedNodeInfos;
+ newFeEquationNumber->destinationArray = self->destinationArray;
+ newFeEquationNumber->_lowestGlobalEqNums = self->_lowestGlobalEqNums;
+ newFeEquationNumber->locationMatrix = self->locationMatrix;
+ }
+
+ if( ownMap ) {
+ Stg_Class_Delete( map );
+ }
+
+ return (void*)newFeEquationNumber;
+#endif
+ abort();
+}
+
+void _FeEquationNumber_Build( void* feEquationNumber, void* data ) {
+ FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
+
+ assert(self);
+
+ Journal_DPrintf( self->debug, "In %s:\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ Stg_Component_Build( self->feMesh , data, False );
+ Stg_Component_Build( self->dofLayout, data, False );
+ if ( self->linkedDofInfo ) Stg_Component_Build( self->dofLayout, data, False );
+ if ( self->bcs ) Stg_Component_Build( self->bcs , data, False );
+ /* If we have new mesh topology information, do this differently. */
+ /* if( self->feMesh->topo->domains && self->feMesh->topo->domains[MT_VERTEX] ) { */
+
+ if( Mesh_HasExtension( self->feMesh, "vertexGrid" ) )
+ FeEquationNumber_BuildWithDave( self );
+ else
+ FeEquationNumber_BuildWithTopology( self );
+
+ /* If not removing BCs, construct a table of which equation numbers are actually BCs. */
+ if( !self->removeBCs ) {
+ FeMesh* mesh = self->feMesh;
+ DofLayout* dofLayout = self->dofLayout;
+ VariableCondition* bcs = self->bcs;
+ int nDofs, varInd;
+ unsigned ii;
+ int jj;
+
+ for( ii = 0; ii < FeMesh_GetNodeLocalSize( mesh ); ii++ ) {
+ nDofs = dofLayout->dofCounts[ii];
+ for( jj = 0; jj < nDofs; jj++ ) {
+ varInd = dofLayout->varIndices[ii][jj];
+ if( bcs && VariableCondition_IsCondition( bcs, ii, varInd ) ) {
+ if( !STree_Has( self->bcEqNums, self->destinationArray[ii] + jj ) )
+ STree_Insert( self->bcEqNums, self->destinationArray[ii] + jj );
+ }
+ }
+ }
+ }
+
+ /*}
+ else {
+ _FeEquationNumber_BuildRemappedNodeInfoTable( self );
+ _FeEquationNumber_BuildDestinationArray( self );
+ _FeEquationNumber_CalculateGlobalUnconstrainedDofTotal( self );
+ _FeEquationNumber_CalculateEqNumsDecomposition( self );
+ }*/
+
+ if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+ FeEquationNumber_PrintDestinationArray( self, self->debug );
+ }
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+/** Initialise implementation. Currently does nothing. */
+void _FeEquationNumber_Initialise( void* feEquationNumber, void* data ) {
+ FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
+
+ Stg_Component_Initialise( self->feMesh , data, False );
+ Stg_Component_Initialise( self->dofLayout, data, False );
+ if ( self->linkedDofInfo ) Stg_Component_Initialise( self->dofLayout, data, False );
+ if ( self->bcs ) Stg_Component_Initialise( self->bcs , data, False );
+}
+
+
+#if 0
+Node_RemappedGlobalIndex _FeEquationNumber_RemapNode(
+ HexaMD* hexaMD,
+ Index newDimOrder[3],
+ Node_GlobalIndex gNode_I )
+{
+ Node_RemappedGlobalIndex remappedGlobalIndex = 0;
+ Index dim_I = 0;
+ Index currNewDim = 0;
+ IJK defaultIJK;
+ IJK newOrderIJK;
+ IJK newOrderNodeCounts;
+
+ Dimension_1DTo3D( gNode_I, hexaMD->nodeGlobal3DCounts, defaultIJK );
+
+ for ( dim_I = I_AXIS; dim_I < 3; dim_I++ ) {
+ currNewDim = newDimOrder[dim_I];
+ newOrderIJK[dim_I] = defaultIJK[currNewDim];
+ newOrderNodeCounts[dim_I] = hexaMD->nodeGlobal3DCounts[currNewDim];
+ }
+
+ Dimension_3DTo1D( newOrderIJK, newOrderNodeCounts, &remappedGlobalIndex );
+
+ return remappedGlobalIndex;
+}
+
+
+static void _FeEquationNumber_BuildRemappedNodeInfoTable( void* feEquationNumber ) {
+ FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
+ FeMesh* mesh = self->feMesh;
+ Node_DomainIndex nodeDomainCount = Mesh_GetDomainSize( mesh, MT_VERTEX );
+ CommTopology* commTopo = Mesh_GetCommTopology( mesh, MT_VERTEX );
+ Node_GlobalIndex gNode_I = 0;
+ Node_DomainIndex dNode_I = 0;
+/*#if DEBUG*/
+ RemappedNodeInfo_Index rNodeInfo_I;
+/*#endif*/
+
+ Journal_DPrintfL( self->debug, 1, "In %s:\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ self->remappedNodeInfos = Memory_Alloc_Array( RemappedNodeInfo, nodeDomainCount,
+ "FeEquationNumber->remappedNodeInfos" );
+
+ if ( 1 == commTopo->nProcs ) {
+ Journal_DPrintfL( self->debug, 1, "Serial code: No remapping required...filling remapping table with normal values.\n" );
+ for (dNode_I = 0; dNode_I < nodeDomainCount; dNode_I++ ) {
+ gNode_I = mesh->nodeD2G[dNode_I];
+ self->remappedNodeInfos[dNode_I].remappedGlobal = gNode_I;
+ self->remappedNodeInfos[dNode_I].domain = dNode_I;
+ }
+ }
+ else if ( meshDecomp->type != HexaMD_Type ) {
+ Node_GlobalIndex prevGNode_I = (unsigned int)-1;
+ RemappedNodeInfo_Index insertIndex;
+
+ Journal_DPrintfL( self->debug, 1, "Parallel, but non-hexa decomp: building the remapping table by "
+ "insertion-sorting based on global node number order.\n" );
+ for (dNode_I = 0; dNode_I < nodeDomainCount; dNode_I++ ) {
+ gNode_I = mesh->nodeD2G[dNode_I];
+
+ if ( gNode_I > prevGNode_I ) {
+ self->remappedNodeInfos[dNode_I].remappedGlobal = gNode_I;
+ self->remappedNodeInfos[dNode_I].domain = dNode_I;
+ prevGNode_I = gNode_I;
+ continue;
+ }
+ else {
+ insertIndex = 0;
+ while ( gNode_I > self->remappedNodeInfos[insertIndex].remappedGlobal ) insertIndex++;
+ memmove( &self->remappedNodeInfos[insertIndex+1], &self->remappedNodeInfos[insertIndex],
+ sizeof(RemappedNodeInfo) * (dNode_I - insertIndex + 1) );
+ self->remappedNodeInfos[insertIndex].remappedGlobal = gNode_I;
+ self->remappedNodeInfos[insertIndex].domain = dNode_I;
+ }
+ }
+ }
+ else if ( ((HexaMD*)meshDecomp)->numPartitionedDims > 1 )
+ {
+ Node_GlobalIndex nextShadowGlobalMap;
+ Node_LocalIndex lNode_I;
+ Node_ShadowIndex sNode_I = mesh->nodeLocalCount;
+ RemappedNodeInfo_Index insertIndex = 0;
+
+ Journal_DPrintfL( self->debug, 1, "Parallel, hexa decomp but multiple partition dims:\n"
+ "filling remapping table with insertion sort\n"
+ "of local & shadow elements.\n" );
+
+ if ( meshDecomp->shadowDepth > 0 ) {
+ nextShadowGlobalMap = mesh->nodeD2G[sNode_I];
+ }
+ else {
+ nextShadowGlobalMap = mesh->nodeGlobalCount;
+ }
+
+ insertIndex = 0;
+ for (lNode_I = 0; lNode_I < mesh->nodeLocalCount; lNode_I++ ) {
+ gNode_I = mesh->nodeL2G[lNode_I];
+
+ while ( nextShadowGlobalMap < gNode_I ) {
+ self->remappedNodeInfos[insertIndex].remappedGlobal = nextShadowGlobalMap;
+ self->remappedNodeInfos[insertIndex++].domain = sNode_I++;
+ if ( sNode_I < mesh->nodeDomainCount ) {
+ nextShadowGlobalMap = mesh->nodeD2G[sNode_I];
+ }
+ else {
+ nextShadowGlobalMap = mesh->nodeGlobalCount;
+ }
+ }
+ self->remappedNodeInfos[insertIndex].remappedGlobal = gNode_I;
+ self->remappedNodeInfos[insertIndex++].domain = lNode_I;
+ }
+
+ /* now know all local elements inserted, so ensure all shadow elements have also been inserted */
+ for ( ; sNode_I < mesh->nodeDomainCount; sNode_I++ ) {
+ gNode_I = mesh->nodeD2G[sNode_I];
+ self->remappedNodeInfos[insertIndex].remappedGlobal = gNode_I;
+ self->remappedNodeInfos[insertIndex++].domain = sNode_I;
+ }
+ Journal_Firewall( (insertIndex == mesh->nodeDomainCount), self->debug,
+ "Stuffup: should have inserted exactly the right number of values by here.\n" );
+ }
+ else {
+ /* Otherwise, we remap each of the global node values, so the eqNums
+ will cause minimal communication during mesh assembly */
+ Node_RemappedGlobalIndex currRemappedGNode_I = 0;
+ Node_RemappedGlobalIndex firstRemappedGNode_I = 0;
+ Index newDimOrder[3] = {0,0,0};
+ Index newOrder_I = 0;
+ Index partitionedAxis = I_AXIS;
+ Index dim_I;
+ RemappedNodeInfo_Index insertIndex;
+ Bool lowestIsShadow = False;
+
+ self->remappingActivated = True;
+
+ Journal_DPrintfL( self->debug, 1, "Parallel, hexa decomp with 1 partition dim:\n"
+ "remapping eqNum traversal order to be aligned with mesh decomposition:\n" );
+
+ /* Work out the new dimension order for the EqNums. The partitioned index
+ goes last */
+ for ( dim_I = I_AXIS; dim_I < 3; dim_I++ ) {
+ if (True == ((HexaMD*)meshDecomp)->partitionedAxis[dim_I]) {
+ partitionedAxis = dim_I;
+ newDimOrder[2] = partitionedAxis;
+ } else {
+ newDimOrder[newOrder_I++] = dim_I;
+ }
+ }
+ Journal_DPrintfL( self->debug, 1, "Given partition axis is %c, calc. remapping dimension order as %c,%c,%c\n",
+ IJKTopology_DimNumToDimLetter[partitionedAxis],
+ IJKTopology_DimNumToDimLetter[newDimOrder[0]],
+ IJKTopology_DimNumToDimLetter[newDimOrder[1]],
+ IJKTopology_DimNumToDimLetter[newDimOrder[2]] );
+
+ Journal_DPrintfL( self->debug, 4, "Calculating over %d domain nodes, %d local, %d shadow.\n",
+ mesh->nodeDomainCount, mesh->nodeLocalCount, mesh->nodeShadowCount );
+
+ /* Work out the lowest remapped global index (so we know where to insert into the table) */
+ gNode_I = mesh->nodeD2G[0];
+ firstRemappedGNode_I = _FeEquationNumber_RemapNode( (HexaMD*)meshDecomp, newDimOrder, gNode_I );
+ /* if shadow elements are enabled, check if the first shadow element has lower
+ global index than first local element */
+ if ( meshDecomp->shadowDepth > 0 ) {
+ Node_RemappedGlobalIndex firstRemappedShadowGNode_I;
+
+ gNode_I = mesh->nodeD2G[mesh->nodeLocalCount];
+ firstRemappedShadowGNode_I = _FeEquationNumber_RemapNode( (HexaMD*)meshDecomp,
+ newDimOrder, gNode_I );
+
+ if ( firstRemappedShadowGNode_I < firstRemappedGNode_I ) {
+ firstRemappedGNode_I = firstRemappedShadowGNode_I;
+ lowestIsShadow = True;
+ }
+ }
+ Journal_DPrintfL( self->debug, 4, "Calculated lowest remapped global index is %d",
+ firstRemappedGNode_I );
+ if ( lowestIsShadow ) {
+ Journal_DPrintfL( self->debug, 4, " (a shadow node.)\n" );
+ }
+ else {
+ Journal_DPrintfL( self->debug, 4, " (a local node.)\n" );
+ }
+
+ Stream_IndentBranch( StgFEM_Debug );
+ /* Now add the rest, relative to the first */
+ for (dNode_I = 0; dNode_I < nodeDomainCount; dNode_I++ ) {
+ gNode_I = mesh->nodeD2G[dNode_I];
+ currRemappedGNode_I = _FeEquationNumber_RemapNode( (HexaMD*)meshDecomp, newDimOrder, gNode_I );
+ insertIndex = currRemappedGNode_I - firstRemappedGNode_I;
+ self->remappedNodeInfos[insertIndex].remappedGlobal = currRemappedGNode_I;
+ self->remappedNodeInfos[insertIndex].domain = dNode_I;
+ Journal_DPrintfL( self->debug, 4, "Processing domain node %d: original global = %d, remaps to %d.\n",
+ dNode_I, gNode_I, currRemappedGNode_I );
+ }
+ Stream_UnIndentBranch( StgFEM_Debug );
+ }
+
+/*#if DEBUG*/
+ if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+ Journal_DPrintf( self->debug, "Calculated remapped node info table as:\n{\n" );
+ for (rNodeInfo_I = 0; rNodeInfo_I < nodeDomainCount; rNodeInfo_I++ ) {
+ Journal_DPrintf( self->debug, " %d:(remap=%d,domain=%d),\n", rNodeInfo_I,
+ self->remappedNodeInfos[rNodeInfo_I].remappedGlobal,
+ self->remappedNodeInfos[rNodeInfo_I].domain );
+ }
+ Journal_DPrintf( self->debug, "}\n");
+ }
+/*#endif*/
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+/* Build the processor's ID (destination) array */
+void _FeEquationNumber_BuildDestinationArray( FeEquationNumber* self ) {
+ MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
+ Node_DomainIndex nodeDomainCount = meshDecomp->nodeDomainCount;
+ CritPointInfo* critPointsIHave = NULL;
+ Index critPointsIHaveTotal = 0;
+ CritPointInfo* critPointsToSend = NULL;
+ Index critPointsToSendTotal = 0;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
+
+ Journal_DPrintfL( self->debug, 1, "In %s:\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ Journal_Firewall( ( nodeDomainCount == self->dofLayout->_numItemsInLayout ),
+ errorStream, "Error: In %s: DofLayout's size is %d, which isn't equal to "
+ "Node domain count of %d. Did you create the dofLayout of size node local count? "
+ "It should be aset up to size node domain count.\n",
+ __func__, self->dofLayout->_numItemsInLayout, nodeDomainCount );
+
+
+ self->destinationArray = Memory_Alloc_2DComplex( Dof_EquationNumber, nodeDomainCount,
+ self->dofLayout->dofCounts, "FeEquationNumber->destinationArray" );
+
+
+ if (meshDecomp->procsInUse == 1)
+ {
+ /* for serial jobs, don't worry about the critical points, just calculate
+ the totals normally */
+ critPointsIHave = Memory_Alloc( CritPointInfo, "critPointsIHave (BuildDestinationArray)" );
+ critPointsToSend = Memory_Alloc( CritPointInfo, "critPointsToSend (BuildDestinationArray)" );
+ critPointsIHave[0].index = meshDecomp->nodeGlobalCount;
+ critPointsToSend[0].index = meshDecomp->nodeGlobalCount;
+ _FeEquationNumber_DoPartialTotals( self, critPointsIHave, 0, critPointsToSend, 0 );
+ self->_lowestLocalEqNum = 0;
+ }
+ else {
+ Node_GlobalIndex* myWantedCriticalPoints = NULL;
+ Index myWantedCriticalPointsTotal = 0;
+ CritPointInfo* allSendCriticalPoints = NULL;
+ Index* procSendCritPointsTotals = NULL;
+ Index maxSendCritPointsPerProc = 0;
+
+ critPointsIHave = Memory_Alloc_Array( CritPointInfo, nodeDomainCount,
+ "critPointsIHave (BuildDestinationArray)" );
+ critPointsToSend = Memory_Alloc_Array( CritPointInfo, nodeDomainCount,
+ "critPointsToSend (BuildDestinationArray)" );
+ myWantedCriticalPoints = Memory_Alloc_Array( Node_GlobalIndex, nodeDomainCount,
+ "myWantedCritialPoints (BuildDestinationArray)" );
+
+ /* Go through all domain nodes, work out end of runs, and interfaces needed */
+ _FeEquationNumber_CalculateDomainKnownCriticalPoints( self, nodeDomainCount, critPointsIHave, &critPointsIHaveTotal,
+ myWantedCriticalPoints, &myWantedCriticalPointsTotal );
+
+ /* initialise the below to the set end critical nodes I already worked out I have */
+ critPointsToSend = (CritPointInfo*) memcpy( critPointsToSend, critPointsIHave, (critPointsIHaveTotal * sizeof(CritPointInfo)) );
+ critPointsToSendTotal = critPointsIHaveTotal;
+
+ /* work out critical points (inc. those needed by others) I hold, and those to send.
+ The list I have could be greater than my end of runs, in an irregular mesh case */
+ _FeEquationNumber_CalculateCritPointsIHave( self,
+ &myWantedCriticalPoints, myWantedCriticalPointsTotal, &critPointsIHave, &critPointsIHaveTotal,
+ critPointsToSend, &critPointsToSendTotal );
+
+ Memory_Free( myWantedCriticalPoints );
+
+ /* OK: We now know all the critical points on this processor, so go ahead and work out the partial ID number
+ at all of them. */
+
+ Journal_DPrintfL( self->debug, 2, "Looping through nodes again, calculating eq nums (re-setting to 0 at critical points)\n,"
+ "and storing subtotal of each each critical node:\n" );
+ _FeEquationNumber_DoPartialTotals( self, critPointsIHave, critPointsIHaveTotal,
+ critPointsToSend, critPointsToSendTotal );
+
+ Journal_DPrintfL( self->debug, 2, "Now sub-totals have been calculated, share all of my critical point sub-totals "
+ "and get any that I need:\n" );
+ _FeEquationNumber_ShareCritPointInfo( self, &critPointsToSend, critPointsToSendTotal,
+ &allSendCriticalPoints, &procSendCritPointsTotals, &maxSendCritPointsPerProc, PRINT_VALUES );
+
+ Journal_DPrintfL( self->debug, 2, "Final loop: add the sub-totals at all the critical points to the existing values:\n" );
+ _FeEquationNumber_AddAllPartialTotals( self, critPointsIHave, critPointsIHaveTotal,
+ allSendCriticalPoints, procSendCritPointsTotals, maxSendCritPointsPerProc );
+
+ /* Post process the linked dofs */
+ if ( self->linkedDofInfo ) {
+ _FeEquationNumber_PostProcessLinkedDofs( self );
+ }
+
+ Memory_Free( allSendCriticalPoints );
+ Memory_Free( procSendCritPointsTotals );
+ }
+
+ /* If not removing BCs, construct a table of which equation numbers are actually BCs. */
+ if( !self->removeBCs ) {
+ FeMesh* feMesh = self->feMesh;
+ DofLayout* dofLayout = self->dofLayout;
+ VariableCondition* bcs = self->bcs;
+ unsigned lNode_i;
+
+ /* New index set. */
+ self->bcEqNums = IndexSet_New( self->_highestLocalEqNum - self->_lowestLocalEqNum );
+
+ /* Fill it up. */
+ for( lNode_i = 0; lNode_i < feMesh->nodeLocalCount; lNode_i++ ) {
+ unsigned nDofs = dofLayout->dofCounts[lNode_i];
+ unsigned dof_i;
+
+ for( dof_i = 0; dof_i < nDofs; dof_i++ ) {
+ unsigned varInd = dofLayout->varIndices[lNode_i][dof_i];
+
+ if( bcs && VariableCondition_IsCondition( bcs, lNode_i, varInd ) ) {
+ IndexSet_Add( self->bcEqNums, self->destinationArray[lNode_i][dof_i] );
+ }
+ }
+ }
+ }
+
+ Memory_Free( critPointsIHave );
+ Memory_Free( critPointsToSend );
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+
+
+/** Works out 'critical nodes' I know from domain information (those I want are the start
+ of my runs -1, those I know others want are the end of my runs. */
+static void _FeEquationNumber_CalculateDomainKnownCriticalPoints(
+ FeEquationNumber* self,
+ Node_DomainIndex nodeDomainCount,
+ CritPointInfo* mySetEnds,
+ Index* const mySetEndsTotal,
+ Node_GlobalIndex* myWantedCriticalPoints,
+ Index* const myWantedCriticalPointsTotal )
+{
+ RemappedNodeInfo_Index rNodeInfo_I = 0;
+ Node_RemappedGlobalIndex remappedGlobal_I = 0;
+ MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ if ( self->remappingActivated ) {
+ /* if remapping has been done, the only possible crit points are the first and last
+ points */
+ remappedGlobal_I = self->remappedNodeInfos[0].remappedGlobal;
+ if (remappedGlobal_I != 0) {
+ Journal_DPrintfL( self->debug, 3, "Adding interface c.p. to myWantedCriticalPoints[%d] = %d\n",
+ (*myWantedCriticalPointsTotal), remappedGlobal_I-1 );
+ myWantedCriticalPoints[(*myWantedCriticalPointsTotal)++] = remappedGlobal_I-1;
+ }
+
+ remappedGlobal_I = self->remappedNodeInfos[nodeDomainCount-1].remappedGlobal;
+ if ( remappedGlobal_I != (meshDecomp->nodeGlobalCount-1) ) {
+ Journal_DPrintfL( self->debug, 3, "Adding set end c.p. mySetEnds[%d] = %d\n",
+ (*mySetEndsTotal), remappedGlobal_I );
+ mySetEnds[(*mySetEndsTotal)++].index = remappedGlobal_I;
+ }
+ Stream_UnIndentBranch( StgFEM_Debug );
+ return;
+ }
+
+ while ( rNodeInfo_I < nodeDomainCount ) {
+ /* save start of set */
+ remappedGlobal_I = self->remappedNodeInfos[rNodeInfo_I].remappedGlobal;
+
+ if (remappedGlobal_I != 0) {
+ Journal_DPrintfL( self->debug, 3, "Adding interface c.p. to myWantedCriticalPoints[%d] = %d\n",
+ (*myWantedCriticalPointsTotal), remappedGlobal_I-1 );
+ myWantedCriticalPoints[(*myWantedCriticalPointsTotal)++] = remappedGlobal_I-1;
+ }
+ rNodeInfo_I++;
+
+ /* skip to end of contiguous set */
+ while ( (rNodeInfo_I < nodeDomainCount)
+ && (self->remappedNodeInfos[rNodeInfo_I].remappedGlobal ==
+ (self->remappedNodeInfos[rNodeInfo_I-1].remappedGlobal + 1) ) )
+ {
+ Journal_DPrintfL( self->debug, 4, "skipping remapped gNode[%d] domain = %d\n",
+ self->remappedNodeInfos[rNodeInfo_I].remappedGlobal,
+ self->remappedNodeInfos[rNodeInfo_I].domain );
+ rNodeInfo_I++;
+ }
+
+ /* and add the critical point, if not the last node */
+ remappedGlobal_I = self->remappedNodeInfos[rNodeInfo_I-1].remappedGlobal;
+ if ( remappedGlobal_I != (meshDecomp->nodeGlobalCount-1) ) {
+ Journal_DPrintfL( self->debug, 3, "Adding set end c.p. mySetEnds[%d] = %d\n",
+ (*mySetEndsTotal), remappedGlobal_I );
+ mySetEnds[(*mySetEndsTotal)++].index = remappedGlobal_I;
+ }
+ }
+
+/*#if DEBUG*/
+ if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
+ Index cPoint_I;
+
+ Journal_DPrintf( self->debug, "My set end Crit Points:[0-%d][ ", (*mySetEndsTotal) );
+ for (cPoint_I = 0 ; cPoint_I < (*mySetEndsTotal) ; cPoint_I++) {
+ Journal_DPrintf( self->debug, "%2d, ", mySetEnds[cPoint_I].index );
+ }
+ Journal_DPrintf( self->debug, "]\n" );
+
+ Journal_DPrintf( self->debug, "interface Crit Points I want:[0-%d][ ", (*myWantedCriticalPointsTotal) );
+ for (cPoint_I = 0 ; cPoint_I < (*myWantedCriticalPointsTotal) ; cPoint_I++) {
+ Journal_DPrintf( self->debug, "%2d, ", myWantedCriticalPoints[cPoint_I] );
+ }
+ Journal_DPrintf( self->debug, "]\n" );
+ }
+/*#endif*/
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+/* work out critical points (inc. those needed by others) I hold, and those to send.
+ The list I have could be greater than my end of runs, in an irregular mesh case */
+static void _FeEquationNumber_CalculateCritPointsIHave( FeEquationNumber* self,
+ Node_GlobalIndex** const myWantedCriticalPointsPtr, Node_GlobalIndex myWantedCriticalPointsTotal,
+ CritPointInfo** const critPointsIHavePtr, Index* const critPointsIHaveTotal,
+ CritPointInfo* const critPointsToSend, Index* const critPointsToSendTotal )
+{
+ MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
+ Partition_Index proc_I;
+ Node_GlobalIndex* allWantedCriticalPoints = NULL;
+ CritPointInfo* allHaveCriticalPoints = NULL;
+ Node_GlobalIndex* procWantedCritPointsTotals = NULL;
+ Index* procHaveCritPointsTotals = NULL;
+ Node_GlobalIndex maxWantedCritPointsPerProc = 0;
+ Node_GlobalIndex maxHaveCritPointsPerProc = 0;
+ Index myCritPoint_I = 0;
+ PartitionIndex myRank = meshDecomp->rank;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ Journal_DPrintfL( self->debug, 2, "Globally sharing locally known wanted C.N. lists:\n", __func__ );
+ _FeEquationNumber_ShareCriticalPoints( self, myWantedCriticalPointsPtr, myWantedCriticalPointsTotal,
+ &allWantedCriticalPoints, &procWantedCritPointsTotals, &maxWantedCritPointsPerProc );
+
+ Journal_DPrintfL( self->debug, 2, "Globally sharing locally known 'have' C.N. lists:\n", __func__ );
+ _FeEquationNumber_ShareCritPointInfo( self, critPointsIHavePtr, (*critPointsIHaveTotal),
+ &allHaveCriticalPoints, &procHaveCritPointsTotals, &maxHaveCritPointsPerProc, DONT_PRINT_VALUES );
+
+ /* now we build our lists of crit points on my processor, and crit points on my processor to send to others */
+ for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
+ Index otherCritPoint_I = proc_I * maxWantedCritPointsPerProc;
+ Index otherCritPoint_End_I = (proc_I * maxWantedCritPointsPerProc) + procWantedCritPointsTotals[proc_I];
+ myCritPoint_I = 0;
+
+ /* don't try and add my own */
+ if ( myRank == proc_I ) continue;
+
+ /* for each crit point they want, if I have it add it to my have and send lists */
+ for (; otherCritPoint_I < otherCritPoint_End_I; otherCritPoint_I++) {
+ Node_GlobalIndex otherCritPoint = allWantedCriticalPoints[otherCritPoint_I];
+
+ if ( _FeEquationNumber_IHaveCritPoint( self, otherCritPoint ) ) {
+
+ while ( (myCritPoint_I < (*critPointsIHaveTotal) ) &&
+ (otherCritPoint > (*critPointsIHavePtr)[myCritPoint_I].index) ) {
+ /* skip ahead to right spot */
+ myCritPoint_I++;
+ }
+ if ( myCritPoint_I == (*critPointsIHaveTotal) ) {
+ (*critPointsIHavePtr)[(*critPointsIHaveTotal)++].index = otherCritPoint;
+ critPointsToSend[(*critPointsToSendTotal)++].index = otherCritPoint;
+ }
+ else if ( otherCritPoint != (*critPointsIHavePtr)[myCritPoint_I].index ) {
+ memmove( &((*critPointsIHavePtr)[myCritPoint_I+1]),
+ &((*critPointsIHavePtr)[myCritPoint_I]),
+ ((*critPointsIHaveTotal) - myCritPoint_I) * sizeof(CritPointInfo) );
+ (*critPointsIHavePtr)[myCritPoint_I].index = otherCritPoint;
+ (*critPointsIHaveTotal)++;
+ memmove( &critPointsToSend[myCritPoint_I+1], &critPointsToSend[myCritPoint_I],
+ ((*critPointsToSendTotal) - myCritPoint_I) * sizeof(CritPointInfo) );
+ critPointsToSend[myCritPoint_I].index = otherCritPoint;
+ (*critPointsToSendTotal)++;
+ }
+ /* move to the next point in any case */
+ myCritPoint_I++;
+ }
+ }
+ }
+
+ /* For each crit point the others have, if I have it add it to my have list */
+ for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
+ Index otherCritPointInfo_I = proc_I * maxHaveCritPointsPerProc;
+ Index otherCritPointInfo_End_I = (proc_I * maxHaveCritPointsPerProc) + procHaveCritPointsTotals[proc_I];
+ myCritPoint_I = 0;
+
+ /* don't try and add my own */
+ if ( myRank == proc_I ) continue;
+
+ for (; otherCritPointInfo_I < otherCritPointInfo_End_I; otherCritPointInfo_I++) {
+ Node_GlobalIndex otherCritPoint = allHaveCriticalPoints[otherCritPointInfo_I].index;
+
+ if ( _FeEquationNumber_IHaveCritPoint( self, otherCritPoint ) ) {
+
+ while ( (myCritPoint_I < (*critPointsIHaveTotal) ) &&
+ (otherCritPoint > (*critPointsIHavePtr)[myCritPoint_I].index) ) {
+ myCritPoint_I++;
+ /* skip ahead to right spot */
+ }
+ if ( myCritPoint_I == (*critPointsIHaveTotal) ) {
+ (*critPointsIHavePtr)[(*critPointsIHaveTotal)++].index = otherCritPoint;
+ }
+ else if ( otherCritPoint != (*critPointsIHavePtr)[myCritPoint_I].index ) {
+ memmove( &((*critPointsIHavePtr)[myCritPoint_I+1]),
+ &((*critPointsIHavePtr)[myCritPoint_I]),
+ ((*critPointsIHaveTotal) - myCritPoint_I) * sizeof(CritPointInfo) );
+ (*critPointsIHavePtr)[myCritPoint_I].index = otherCritPoint;
+ (*critPointsIHaveTotal)++;
+ }
+ /* move to the next point in any case */
+ myCritPoint_I++;
+ }
+ }
+ }
+/*#if DEBUG*/
+ if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
+ Journal_DPrintf( self->debug, "Calculated crit points I Have:\n[" );
+ for ( myCritPoint_I = 0; myCritPoint_I < (*critPointsIHaveTotal); myCritPoint_I++ ) {
+ Journal_DPrintf( self->debug, "%3d, ", (*critPointsIHavePtr)[myCritPoint_I].index );
+ }
+ Journal_DPrintf( self->debug, "]\nCalculated crit points To Send:\n[" );
+ for ( myCritPoint_I = 0; myCritPoint_I < (*critPointsToSendTotal); myCritPoint_I++ ) {
+ Journal_DPrintf( self->debug, "%3d, ", critPointsToSend[myCritPoint_I].index );
+ }
+ Journal_DPrintf( self->debug, "]\n");
+ }
+/*#endif*/
+
+ Memory_Free( allWantedCriticalPoints );
+ Memory_Free( procWantedCritPointsTotals );
+ Memory_Free( allHaveCriticalPoints );
+ Memory_Free( procHaveCritPointsTotals );
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+static Bool _FeEquationNumber_IHaveCritPoint(
+ FeEquationNumber* self,
+ Node_RemappedGlobalIndex critPoint )
+{
+ MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
+ Node_DomainIndex nodeDomainCount = meshDecomp->nodeDomainCount;
+ PartitionIndex myRank = meshDecomp->rank;
+
+ /* Case 1: for remapped hexa mesh, just check if its between max and min numbers */
+ if ( self->remappingActivated ) {
+ if ( ( self->remappedNodeInfos[0].remappedGlobal <= critPoint ) &&
+ ( critPoint <= self->remappedNodeInfos[nodeDomainCount-1].remappedGlobal ) )
+ {
+ return True;
+ }
+ else {
+ return False;
+ }
+ }
+ /* Case 2: 2D+ hexa decomps or other decomp strategy, use local (and shadow if enabled) node IndexSet */
+ else {
+ if ( IndexSet_IsMember( meshDecomp->localNodeSets[myRank], critPoint ) ) {
+ return True;
+ }
+ else if ( (meshDecomp->shadowDepth > 0)
+ && IndexSet_IsMember( meshDecomp->shadowNodeSets[myRank], critPoint ) ) {
+ return True;
+ }
+ else {
+ return False;
+ }
+ }
+}
+
+
+/** Performs an AllGather on a set of critical points: Each processer will afterwards have all the critical points
+ of all the processors, in one large array. The user must then index into the array by processor carefully. */
+static void _FeEquationNumber_ShareCriticalPoints(
+ FeEquationNumber* self,
+ Node_GlobalIndex** const myCriticalPoints,
+ Node_GlobalIndex myCriticalPointsTotal,
+ Node_GlobalIndex** allCriticalPoints,
+ Index** procCritPointsTotals,
+ Node_GlobalIndex* const maxCritPointsPerProc)
+{
+ MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
+ Partition_Index proc_I;
+/*#if DEBUG*/
+ Index point_I = 0;
+/*#endif*/
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ (*maxCritPointsPerProc) = 0;
+
+/*#if DEBUG*/
+ if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
+ Journal_DPrintf( self->debug, "myCriticalPointsTotal=%u\n", myCriticalPointsTotal);
+ Journal_DPrintf( self->debug, "myCritPoints:(" );
+ for ( point_I = 0; point_I < myCriticalPointsTotal; point_I++)
+ {
+ Journal_DPrintf( self->debug, "%u, ", (*myCriticalPoints)[point_I]);
+ }
+ Journal_DPrintf( self->debug, ")\n");
+ }
+/*#endif*/
+
+ /* First, we allocate and calculate how many critical points are on each node (this way, we don't have to guess
+ how much memory to allocate in the main array.) */
+ (*procCritPointsTotals) = Memory_Alloc_Array( Node_GlobalIndex, meshDecomp->nproc,
+ "*procCritPointsTotals (ShareCriticalPoints)" );
+
+ MPI_Allgather( &myCriticalPointsTotal, 1, MPI_UNSIGNED,
+ (*procCritPointsTotals), 1, MPI_UNSIGNED,
+ meshDecomp->communicator );
+
+ for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
+ if ( (*procCritPointsTotals)[proc_I] > (*maxCritPointsPerProc) )
+ (*maxCritPointsPerProc) = (*procCritPointsTotals)[proc_I];
+ }
+
+/*#if DEBUG*/
+ Journal_DPrintfL( self->debug, 2, "procCritPoints totals:(");
+ for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
+ Journal_DPrintfL( self->debug, 2, "%d, ", (*procCritPointsTotals)[proc_I]);
+ }
+ Journal_DPrintfL( self->debug, 2, ")\n");
+ Journal_DPrintfL( self->debug, 2, "MaxCritPointsPerProc = %d\n", (*maxCritPointsPerProc));
+/*#endif*/
+
+ /* Now share the actual point values */
+ (*myCriticalPoints) = Memory_Realloc_Array( (*myCriticalPoints), Node_GlobalIndex, *maxCritPointsPerProc );
+ (*allCriticalPoints) = Memory_Alloc_Array( Node_GlobalIndex, meshDecomp->nproc * (*maxCritPointsPerProc),
+ "*allCriticalPoints (ShareCriticalPoints)" );
+
+ MPI_Allgather( (*myCriticalPoints), (*maxCritPointsPerProc), MPI_UNSIGNED,
+ (*allCriticalPoints), (*maxCritPointsPerProc), MPI_UNSIGNED,
+ meshDecomp->communicator );
+
+/*#if DEBUG*/
+ Journal_DPrintfL( self->debug, 2, "procCritPoints:(" );
+ for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
+ for ( point_I = 0; point_I < (*procCritPointsTotals)[proc_I]; point_I++)
+ {
+ Journal_DPrintfL( self->debug, 2, "%u, ",
+ (*allCriticalPoints)[(*maxCritPointsPerProc)*proc_I + point_I]);
+ }
+ }
+ Journal_DPrintfL( self->debug, 2, ")\n");
+/*#endif*/
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+
+/** Performs an AllGather on a set of CritPointInfo structs: Each processer will afterwards have all the CritPointInfo
+ structs of all the processors, in one large array. The user must then index into the array by processor
+ carefully. */
+static void _FeEquationNumber_ShareCritPointInfo(
+ FeEquationNumber* self,
+ CritPointInfo** const myCritPointInfo,
+ Index myCritPointInfoTotal,
+ CritPointInfo** allCritPointInfo,
+ Index** procCritPointInfoTotals,
+ Index* const maxCritPointInfoPerProc,
+ PrintValuesFlag printValuesFlag )
+{
+ MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
+ Partition_Index proc_I;
+/*#if DEBUG*/
+ Index point_I = 0;
+/*#endif*/
+
+ Journal_DPrintfL( self->debug, 1, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+ (*maxCritPointInfoPerProc) = 0;
+
+ /* allgather the totals (to save allocating unnecessary memory) */
+ (*procCritPointInfoTotals) = Memory_Alloc_Array( Node_GlobalIndex, meshDecomp->nproc, "*procCritPointInfoTotals" );
+
+ MPI_Allgather( &myCritPointInfoTotal, 1, MPI_INT, (*procCritPointInfoTotals), 1, MPI_INT,
+ meshDecomp->communicator );
+
+ for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
+ if ( (*procCritPointInfoTotals)[proc_I] > (*maxCritPointInfoPerProc) )
+ (*maxCritPointInfoPerProc) = (*procCritPointInfoTotals)[proc_I];
+ }
+
+/*#if DEBUG*/
+ if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
+ Journal_DPrintf( self->debug, "procCritPointInfo totals:(" );
+ for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
+ Journal_DPrintf( self->debug, "%d, ", (*procCritPointInfoTotals)[proc_I]);
+ }
+ Journal_DPrintf( self->debug, ")\n");
+ Journal_DPrintf( self->debug, "MaxCritPointInfoPerProc = %d\n", (*maxCritPointInfoPerProc));
+ }
+/*#endif*/
+
+ /* Now share the actual critPointInfo arrays */
+ (*allCritPointInfo) = Memory_Alloc_Array( CritPointInfo, meshDecomp->nproc * (*maxCritPointInfoPerProc),
+ "allCritPointInfo (ShareCritPointInfo)" );
+
+ /* below changed by PatrickSunter 27/1/2004 to work on grendel */
+ MPI_Allgather( (*myCritPointInfo), (*maxCritPointInfoPerProc), MPI_critPointInfoType,
+ (*allCritPointInfo), (*maxCritPointInfoPerProc), MPI_critPointInfoType,
+ meshDecomp->communicator );
+
+/*#if DEBUG*/
+ if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
+ Journal_DPrintf( self->debug, "procCritPointInfos" );
+ if ( DONT_PRINT_VALUES == printValuesFlag ) {
+ Journal_DPrintf( self->debug, "(indices only)" );
+ }
+ Journal_DPrintf( self->debug, ": (" );
+ for (proc_I = 0; proc_I < meshDecomp->nproc; proc_I++) {
+ for ( point_I = 0; point_I < (*procCritPointInfoTotals)[proc_I]; point_I++)
+ {
+ Index current = (*maxCritPointInfoPerProc)*proc_I + point_I;
+ Journal_DPrintf( self->debug, "%u", (*allCritPointInfo)[current].index );
+ if ( PRINT_VALUES == printValuesFlag ) {
+ Journal_DPrintf( self->debug, "= %d", (*allCritPointInfo)[current].eqNum );
+ }
+ Journal_DPrintf( self->debug, ", " );
+ }
+ }
+ Journal_DPrintf( self->debug, ")\n");
+ }
+/*#endif*/
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+/** For each domain node, calculate the Equation number, restarting at 0 whenever a critical node is reached and
+ saving the value I was up to. */
+static void _FeEquationNumber_DoPartialTotals( FeEquationNumber* self,
+ CritPointInfo* const critPointsIHave, Index critPointsIHaveTotal,
+ CritPointInfo* const critPointsToSend, Index critPointsToSendTotal )
+{
+ MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
+ Node_DomainIndex nodeDomainCount = meshDecomp->nodeDomainCount;
+ RemappedNodeInfo_Index rNodeInfo_I = 0;
+ Node_RemappedGlobalIndex remappedGlobal_I = 0;
+ Node_DomainIndex dNode_I = 0;
+ Index haveCritPoint_I = 0;
+ Index sendCritPoint_I = 0;
+ Dof_EquationNumber currSubTotalEqNum = 0;
+
+ Journal_DPrintf( self->debug, "In %s:\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ while ( (rNodeInfo_I < nodeDomainCount) ) {
+ remappedGlobal_I = self->remappedNodeInfos[rNodeInfo_I].remappedGlobal;
+ dNode_I = self->remappedNodeInfos[rNodeInfo_I].domain;
+
+ _FeEquationNumber_HandleNode( self, dNode_I, &currSubTotalEqNum );
+
+ /* if the node is next critical point */
+ if ( ( haveCritPoint_I < critPointsIHaveTotal )
+ && ( remappedGlobal_I == critPointsIHave[haveCritPoint_I].index ) )
+ {
+ Journal_DPrintfL( self->debug, 3, "storing c.p. subtotal at remapped global index %u = %d\n",
+ remappedGlobal_I, currSubTotalEqNum );
+ /* store current value */
+ critPointsIHave[haveCritPoint_I++].eqNum = currSubTotalEqNum;
+
+ /* check if its also a to send point */
+ if ( ( sendCritPoint_I < critPointsToSendTotal )
+ && ( remappedGlobal_I == critPointsToSend[sendCritPoint_I].index ) )
+ {
+ /* store current value */
+ critPointsToSend[sendCritPoint_I++].eqNum = currSubTotalEqNum;
+ }
+ /* reset counter and move to next point */
+ currSubTotalEqNum = 0;
+ }
+ rNodeInfo_I++;
+ }
+
+/*#if DEBUG*/
+ if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
+ Journal_DPrintf( self->debug, "Totals I have:[ " );
+ haveCritPoint_I = 0;
+ for ( haveCritPoint_I = 0; haveCritPoint_I < critPointsIHaveTotal; haveCritPoint_I++ )
+ {
+ Journal_DPrintf( self->debug, "%2u=%d, ", critPointsIHave[haveCritPoint_I].index, critPointsIHave[haveCritPoint_I].eqNum );
+ }
+ Journal_DPrintf( self->debug, "]\n" );
+ Journal_DPrintf( self->debug, "Totals to send:[ " );
+ sendCritPoint_I = 0;
+ for ( sendCritPoint_I = 0; sendCritPoint_I < critPointsToSendTotal; sendCritPoint_I++ )
+ {
+ Journal_DPrintf( self->debug, "%2u=%d, ", critPointsToSend[sendCritPoint_I].index, critPointsToSend[sendCritPoint_I].eqNum );
+ }
+ Journal_Printf( self->debug, "]\n" );
+ }
+/*#endif*/
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+/** Called right at the end of calculating ID array, to add the locally calculated partial totals with the final
+ global information, and arrive at the complete figures. */
+static void _FeEquationNumber_AddAllPartialTotals( FeEquationNumber* self, CritPointInfo* mySubTotals,
+ Index myCritPointInfoTotal, CritPointInfo* allSubTotals, Index* procCritPointInfoTotals,
+ Index maxSubTotalsPerProc )
+{
+ Partition_Index proc_I;
+ FeMesh* mesh = self->feMesh;
+ MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
+ Index myRank = meshDecomp->rank;
+ Node_GlobalIndex nodeDomainCount = meshDecomp->nodeDomainCount;
+ RemappedNodeInfo_Index rNodeInfo_I = 0;
+ Node_RemappedGlobalIndex remappedGlobal_I = 0;
+ Node_DomainIndex dNode_I = 0;
+ Node_GlobalIndex gNode_I = 0;
+ Index myCritPointInfo_I = 0;
+ Index* procCritPointInfo_Is = NULL;
+ Dof_EquationNumber adjustSum = 0;
+ Dof_EquationNumber currEqNum;
+ Dof_Index currNodeNumDofs;
+ Dof_Index nodeLocalDof_I;
+ AddListEntry* addListStart;
+ AddListEntry* addListPtr;
+ AddListEntry* addListPrev;
+ Bool firstOfSet;
+ Bool* haveUpdatedLinkedDofSetTbl = NULL;
+ Index linkedDof_I;
+ Index linkedDofSet;
+#define NEXT_PROCESSOR_SECTION_START ( maxSubTotalsPerProc * (proc_I) + procCritPointInfoTotals[proc_I] )
+
+ Journal_DPrintfL( self->debug, 1, "In %s:\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ gNode_I += 0;
+
+ self->_lowestLocalEqNum = -1;
+ self->_highestLocalEqNum = -1;
+ procCritPointInfo_Is = Memory_Alloc_Array( Index, meshDecomp->nproc, "procCritPointInfo_Is (AddAllPartialTotals)" );
+
+ /* set iterators into processors */
+ for ( proc_I = 0; proc_I < meshDecomp->nproc; proc_I++ ) {
+ procCritPointInfo_Is[proc_I] = maxSubTotalsPerProc * proc_I;
+ }
+
+ if ( self->linkedDofInfo ) {
+ haveUpdatedLinkedDofSetTbl = Memory_Alloc_Array( Bool, self->linkedDofInfo->linkedDofSetsCount,
+ "haveUpdatedLinkedDofSetTbl" );
+ for ( linkedDof_I=0; linkedDof_I < self->linkedDofInfo->linkedDofSetsCount; linkedDof_I++ ) {
+ haveUpdatedLinkedDofSetTbl[linkedDof_I] = False;
+ }
+ }
+
+
+ Journal_DPrintfL( self->debug, 3, "beginning sequential run through nodes...\n" );
+
+ while (rNodeInfo_I < nodeDomainCount) {
+ Node_GlobalIndex newCritInfoIndex;
+ /* reset the add list information */
+ addListPtr = addListStart = NULL;
+ remappedGlobal_I = self->remappedNodeInfos[rNodeInfo_I].remappedGlobal;
+ dNode_I = self->remappedNodeInfos[rNodeInfo_I].domain;
+
+ Journal_DPrintfL( self->debug, 3, "At remapped gNode[%d]: ", remappedGlobal_I );
+ Journal_DPrintfL( self->debug, 3, "...adding critical node totals from the block we just skipped...\n" );
+
+ /* Ok, now add critical node totals from other processors in the block we just skipped. */
+ for ( proc_I = 0; proc_I < meshDecomp->nproc; proc_I++ ) {
+ if ( proc_I == myRank ) continue;
+
+ /* reset the add list back to start */
+ addListPtr = addListStart;
+ addListPrev = NULL;
+
+
+ /* Only add critical node totals from other processors lower than current index */
+ while (( procCritPointInfo_Is[proc_I] < NEXT_PROCESSOR_SECTION_START ) &&
+ (newCritInfoIndex = allSubTotals[(procCritPointInfo_Is[proc_I])].index) < remappedGlobal_I )
+ {
+ /* See if we are scheduled to add this critical point yet, and if not where it should go */
+ while ( addListPtr && ( newCritInfoIndex > addListPtr->critPointInfo->index ) ) {
+ addListPrev = addListPtr;
+ addListPtr = addListPtr->next;
+ }
+ /* Note: The 2nd condition guards against trying to add a duplicate. In that case we
+ * just progress on. */
+ if ( (addListPtr == NULL) || ( addListPtr->critPointInfo->index != newCritInfoIndex )) {
+ /*
+ if inside this condition we are either:
+ 1. Adding the first crit node to be added
+ 2. Have found a non-duplicate crit node to be added, either at the end or
+ partway through.
+ So go ahead and add to the addList, reconnecting both the prev and next.
+ */
+ AddListEntry* newAddListEntry = Memory_Alloc( AddListEntry,
+ "newAddListEntry (AddAllPartialTotals)" );
+ adjustSum += allSubTotals[procCritPointInfo_Is[proc_I]].eqNum;
+ Journal_DPrintfL( self->debug, 3, "at other c.p. (%d):incrementing adjustSum by %d to = %d\n",
+ allSubTotals[procCritPointInfo_Is[proc_I]].index,
+ allSubTotals[procCritPointInfo_Is[proc_I]].eqNum,
+ adjustSum );
+ newAddListEntry->critPointInfo = &allSubTotals[procCritPointInfo_Is[proc_I]];
+ newAddListEntry->next = addListPtr;
+ if ( addListPrev ) {
+ addListPrev->next = newAddListEntry;
+ }
+ else {
+ addListStart = newAddListEntry;
+ }
+ addListPtr = newAddListEntry;
+ }
+ /* Move to the next potential crit node from that processor, regardless of whether we
+ * added the last one or not. */
+ (procCritPointInfo_Is[proc_I])++;
+ }
+ }
+
+ /* free the add list */
+ while ( addListStart ) {
+ addListPrev = addListStart;
+ addListStart = addListStart->next;
+ Memory_Free( addListPrev );
+ }
+
+ /* Now go through a run of nodes this processor owns, and add subtotals locally calculated */
+ firstOfSet = True;
+
+ while ( (firstOfSet) ||
+ ( (rNodeInfo_I < nodeDomainCount)
+ && (self->remappedNodeInfos[rNodeInfo_I].remappedGlobal ==
+ (self->remappedNodeInfos[rNodeInfo_I-1].remappedGlobal + 1) ) ) )
+ {
+ remappedGlobal_I = self->remappedNodeInfos[rNodeInfo_I].remappedGlobal;
+ dNode_I = self->remappedNodeInfos[rNodeInfo_I].domain;
+ gNode_I = mesh->nodeD2G[dNode_I];
+ firstOfSet = False;
+
+ Journal_DPrintfL( self->debug, 3, "At remapped gNode[%d]: I own it, so adjusting EqNums\n",
+ remappedGlobal_I );
+
+ /* increment the value at each non-bc dof by adjustSum */
+ currNodeNumDofs = self->dofLayout->dofCounts[ dNode_I ];
+
+ for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
+ if( !self->bcs || !VariableCondition_IsCondition( self->bcs, dNode_I,
+ self->dofLayout->varIndices[dNode_I][nodeLocalDof_I] ) )
+ {
+ if ( (NULL == self->linkedDofInfo) || /* TAG: bcs */
+ ( self->linkedDofInfo->linkedDofTbl[dNode_I][nodeLocalDof_I] == -1 ) )
+ {
+ /* A normal point, so increment */
+ self->destinationArray[dNode_I][nodeLocalDof_I] += adjustSum;
+ }
+ else {
+ /* Handling of linked dofs: the first time we encounter one of a set,
+ add the adjust sum. Afterwards, just set to the updated value. */
+ linkedDofSet = self->linkedDofInfo->linkedDofTbl[dNode_I][nodeLocalDof_I];
+ if ( False == haveUpdatedLinkedDofSetTbl[linkedDofSet] ) {
+ self->destinationArray[dNode_I][nodeLocalDof_I] += adjustSum;
+ self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet] += adjustSum;
+ haveUpdatedLinkedDofSetTbl[linkedDofSet] = True;
+ }
+ else {
+ self->destinationArray[dNode_I][nodeLocalDof_I] =
+ self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet];
+ }
+ }
+
+ currEqNum = self->destinationArray[dNode_I][nodeLocalDof_I];
+ /* If current node not a shadow, then check totals */
+ if ( dNode_I < mesh->nodeLocalCount ) {
+ if ( currEqNum != -1 ) { /* TAG: bcs */
+ if ( self->_lowestLocalEqNum == -1 ) {
+ /* We need this if statement to initialise this */
+ self->_lowestLocalEqNum = currEqNum;
+ }
+ else if ( currEqNum < self->_lowestLocalEqNum ) {
+ self->_lowestLocalEqNum = currEqNum;
+ }
+
+ if ( currEqNum > self->_highestLocalEqNum ) {
+ self->_highestLocalEqNum = currEqNum;
+ }
+ }
+ }
+ }
+ }
+
+ /* if the node is my next critical point, add the sub-total */
+ if ( ( myCritPointInfo_I < myCritPointInfoTotal ) &&
+ ( remappedGlobal_I == mySubTotals[myCritPointInfo_I].index) )
+ {
+ adjustSum += mySubTotals[myCritPointInfo_I].eqNum;
+ Journal_DPrintfL( self->debug, 3, "at my c.p. %d(%d):incrementing adjustSum by %d to = %d\n",
+ myCritPointInfo_I, remappedGlobal_I, mySubTotals[myCritPointInfo_I].eqNum, adjustSum );
+ myCritPointInfo_I++;
+ }
+
+ rNodeInfo_I++;
+ }
+
+ /* If any of the other processors had sub-totals I've just added, jump past them */
+ if (rNodeInfo_I < nodeDomainCount) {
+ for ( proc_I = 0; proc_I < meshDecomp->nproc; proc_I++ ) {
+
+ while (( procCritPointInfo_Is[proc_I] < NEXT_PROCESSOR_SECTION_START ) &&
+ allSubTotals[(procCritPointInfo_Is[proc_I])].index <= remappedGlobal_I )
+ {
+ (procCritPointInfo_Is[proc_I])++;
+ }
+
+ }
+ }
+ }
+
+ if ( self->linkedDofInfo ) {
+ Memory_Free( haveUpdatedLinkedDofSetTbl );
+ }
+ Memory_Free( procCritPointInfo_Is );
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+/** Updates the currEqNum argument for the number of dofs at the current node, and increments the ID Eq. Num for each
+ dof where appropriate (setting it to -1 if its a B.C.) */
+static void _FeEquationNumber_HandleNode( FeEquationNumber* self, const Node_DomainIndex dNode_I,
+ Dof_EquationNumber* const currEqNum )
+{
+ Dof_Index currNodeNumDofs;
+ Dof_Index nodeLocalDof_I;
+/*#if DEBUG*/
+ Stream* error;
+/*#endif*/
+
+ Journal_DPrintfL( self->debug, 3, "In %s:", __func__ );
+/*#if DEBUG*/
+ error = Journal_Register( Error_Type, (Name)self->type );
+ Journal_Firewall( (dNode_I < self->feMesh->nodeDomainCount ), error, "Stuffup: %s() asked to operate on node %d, bigger "
+ "than domain count %d. Exiting.\n", __func__, dNode_I, self->feMesh->nodeDomainCount );
+/*#endif*/
+
+ /* get the number of dofs */
+ currNodeNumDofs = self->dofLayout->dofCounts[ dNode_I ];
+ Journal_DPrintfL( self->debug, 3, " domain node %d, has %d dofs.\n", dNode_I, currNodeNumDofs );
+ /* process each dof, at the same time updating the updatePtr for the next node. */
+ for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
+ Journal_DPrintfL( self->debug, 3, "dof %d: ", nodeLocalDof_I );
+
+ /* if dof is a boundary condition, set eq num=-1. Otherwise increment counter. */
+ /* Also, only set to -1 if we want the BCs removed from the matrix. - Luke */
+ if( self->removeBCs &&
+ self->bcs && VariableCondition_IsCondition( self->bcs, dNode_I, self->dofLayout->varIndices[dNode_I][nodeLocalDof_I] ) )
+ {
+ Journal_DPrintfL( self->debug, 3, "is a BC, setting ID[%d][%d] = -1.\n", dNode_I, nodeLocalDof_I );
+ self->destinationArray[dNode_I][nodeLocalDof_I] = -1;
+ }
+ /* Check if node,dof is a linked dof */
+ else if ( self->linkedDofInfo && ( self->linkedDofInfo->linkedDofTbl[dNode_I][nodeLocalDof_I] != -1 ) ) {
+ Index linkedDofSet = self->linkedDofInfo->linkedDofTbl[dNode_I][nodeLocalDof_I];
+
+ if ( self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet] != -1 ) {
+ Journal_DPrintfL( self->debug, 3, "is a linked Dof, so setting ID[%d][%d] to the "
+ "previous value = %d.\n", dNode_I, nodeLocalDof_I,
+ self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet] );
+ /* value is same as the first part of the linked node set */
+ self->destinationArray[dNode_I][nodeLocalDof_I] =
+ self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet];
+ }
+ else /* This is the first time we've hit this linked eq num, so treat as normal */
+ {
+ Journal_DPrintfL( self->debug, 3, "is a linked Dof hit the first time, so setting "
+ "ID[%d][%d] = %d.\n", dNode_I, nodeLocalDof_I, *currEqNum );
+
+ self->destinationArray[dNode_I][nodeLocalDof_I] = (*currEqNum)++;
+ if ( dNode_I < self->feMesh->nodeLocalCount ) {
+ self->_highestLocalEqNum = self->destinationArray[dNode_I][nodeLocalDof_I];
+ }
+ /* And save the value at the linked eq num for later */
+ self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet] =
+ self->destinationArray[dNode_I][nodeLocalDof_I];
+ }
+ }
+ else {
+ Journal_DPrintfL( self->debug, 3, "is a normal node, setting ID[%d][%d] = %d.\n", dNode_I, nodeLocalDof_I, *currEqNum );
+ self->destinationArray[dNode_I][nodeLocalDof_I] = (*currEqNum)++;
+ if ( dNode_I < self->feMesh->nodeLocalCount ) {
+ self->_highestLocalEqNum = self->destinationArray[dNode_I][nodeLocalDof_I];
+ }
+ }
+ }
+}
+
+
+void _FeEquationNumber_PostProcessLinkedDofs( FeEquationNumber* self ) {
+ Index linkedDof_I;
+ int valueToReduce;
+ int minimumValue;
+ Node_Index rNodeInfo_I;
+ Node_DomainIndex dNode_I;
+ MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
+ Dof_Index nodeLocalDof_I;
+ Dof_Index currNodeNumDofs;
+ Index linkedDofSet;
+ Bool* adjustDueToNonLocalLinkedDofsTbl = NULL;
+ unsigned int subtractionAdjustmentTotal;
+ Dof_EquationNumber currEqNum;
+
+ Journal_DPrintfL( self->debug, 1, "In Func %s():\n", __func__ );
+ adjustDueToNonLocalLinkedDofsTbl = Memory_Alloc_Array( Bool, self->linkedDofInfo->linkedDofSetsCount,
+ "adjustDueToNonLocalLinkedDofsTbl" );
+
+ /* We need to re-calculate these, since the post processing may alter both the lowest and higest eqNum values */
+ self->_lowestLocalEqNum = -1;
+ self->_highestLocalEqNum = -1;
+
+ Journal_DPrintfL( self->debug, 2, "Note: in reductions to follow, value of %d, the node global count, "
+ "denotes that this processor doesn't hold any of that linked dof.\n", self->feMesh->nodeGlobalCount );
+
+ Stream_Indent( self->debug );
+ for ( linkedDof_I=0; linkedDof_I < self->linkedDofInfo->linkedDofSetsCount; linkedDof_I++ ) {
+ if ( -1 != self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDof_I] ) {
+ valueToReduce = self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDof_I];
+ }
+ else {
+ valueToReduce = self->feMesh->nodeGlobalCount;
+ }
+
+ Journal_DPrintfL( self->debug, 2, "Reducing linked Dof %d: this proc has value %d\n", linkedDof_I, valueToReduce );
+ MPI_Allreduce( &valueToReduce, &minimumValue, 1, MPI_INT, MPI_MIN, meshDecomp->communicator );
+
+ Journal_DPrintfL( self->debug, 2, "\tMinimum val = %d\n", minimumValue );
+ self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDof_I] = minimumValue;
+
+ if ( valueToReduce != minimumValue ) {
+ adjustDueToNonLocalLinkedDofsTbl[linkedDof_I] = True;
+ }
+ else {
+ adjustDueToNonLocalLinkedDofsTbl[linkedDof_I] = False;
+ }
+ }
+ Stream_UnIndent( self->debug );
+
+ Journal_DPrintfL( self->debug, 2, "Post-processing totals to correct based on non-local linked dofs\n" );
+ subtractionAdjustmentTotal = 0;
+
+ Stream_Indent( self->debug );
+ for ( rNodeInfo_I = 0; rNodeInfo_I < self->feMesh->nodeDomainCount; rNodeInfo_I++ ) {
+ dNode_I = self->remappedNodeInfos[rNodeInfo_I].domain;
+ Journal_DPrintfL( self->debug, 3, "At remapped node %d (dNode %d):\n", rNodeInfo_I, dNode_I );
+ currNodeNumDofs = self->dofLayout->dofCounts[ dNode_I ];
+
+ for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
+
+ Stream_Indent( self->debug );
+ Journal_DPrintfL( self->debug, 3, "At dof %d: ", nodeLocalDof_I );
+
+ if( self->bcs && VariableCondition_IsCondition( self->bcs, dNode_I,
+ self->dofLayout->varIndices[dNode_I][nodeLocalDof_I] ) )
+ {
+ Journal_DPrintfL( self->debug, 3, "is a BC: ignoring.\n" );
+ }
+ else if ( self->linkedDofInfo->linkedDofTbl[dNode_I][nodeLocalDof_I] != -1 ) {
+ linkedDofSet = self->linkedDofInfo->linkedDofTbl[dNode_I][nodeLocalDof_I];
+
+ Journal_DPrintfL( self->debug, 3, "is a linked Dof, so setting value to %d\n",
+ self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet] );
+
+ self->destinationArray[dNode_I][nodeLocalDof_I] -= subtractionAdjustmentTotal;
+
+ if ( True == adjustDueToNonLocalLinkedDofsTbl[linkedDofSet] ) {
+ /* We now need to test, after the subtraction adjustment has been made, if the
+ value of this linked dof now matches the minimum. If so, don't subtract further. */
+ if ( self->destinationArray[dNode_I][nodeLocalDof_I] !=
+ self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet] )
+ {
+ subtractionAdjustmentTotal++;
+ Journal_DPrintfL( self->debug, 3, "And since first was non-local, increasing "
+ "subtraction adj. to %d\n", subtractionAdjustmentTotal );
+ }
+
+ /* Make sure we only adjust once */
+ adjustDueToNonLocalLinkedDofsTbl[linkedDofSet] = False;
+ }
+
+ self->destinationArray[dNode_I][nodeLocalDof_I] =
+ self->linkedDofInfo->eqNumsOfLinkedDofs[linkedDofSet];
+
+ }
+ else {
+ Journal_DPrintfL( self->debug, 3, "subtracting %d\n", subtractionAdjustmentTotal );
+ self->destinationArray[dNode_I][nodeLocalDof_I] -= subtractionAdjustmentTotal;
+ }
+
+ currEqNum = self->destinationArray[dNode_I][nodeLocalDof_I];
+ if ( dNode_I < self->feMesh->nodeLocalCount ) {
+ if ( currEqNum != -1 ) { /* TAG: bcs */
+ if ( self->_lowestLocalEqNum == -1 ) {
+ /* We need this if statement to initialise this */
+ self->_lowestLocalEqNum = currEqNum;
+ }
+ else if ( currEqNum < self->_lowestLocalEqNum ) {
+ self->_lowestLocalEqNum = currEqNum;
+ }
+
+ if ( currEqNum > self->_highestLocalEqNum ) {
+ self->_highestLocalEqNum = currEqNum;
+ }
+ }
+ }
+ Stream_UnIndent( self->debug );
+ }
+ }
+ Stream_UnIndent( self->debug );
+
+ Memory_Free( adjustDueToNonLocalLinkedDofsTbl );
+}
+#endif
+
+
+Index FeEquationNumber_CalculateActiveEqCountAtNode(
+ void* feEquationNumber,
+ Node_DomainIndex dNode_I,
+ Dof_EquationNumber* lowestActiveEqNumAtNodePtr )
+{
+ FeEquationNumber* self = (FeEquationNumber*) feEquationNumber;
+ Dof_Index nodalDof_I = 0;
+ Index activeEqsAtCurrRowNode = 0;
+ Dof_EquationNumber currEqNum;
+ Bool foundLowest = False;
+
+ for ( nodalDof_I = 0; nodalDof_I < self->dofLayout->dofCounts[dNode_I]; nodalDof_I++ ) {
+ currEqNum = self->destinationArray[dNode_I][nodalDof_I];
+ if ( currEqNum != -1 ) {
+ activeEqsAtCurrRowNode++;
+ if ( False == foundLowest ) {
+ (*lowestActiveEqNumAtNodePtr) = currEqNum;
+ foundLowest = True;
+ }
+ }
+ }
+
+ return activeEqsAtCurrRowNode;
+}
+
+
+void FeEquationNumber_BuildLocationMatrix( void* feEquationNumber ) {
+ FeEquationNumber* self = (FeEquationNumber*)feEquationNumber;
+ FeMesh* feMesh;
+ unsigned nDims;
+ unsigned nDomainEls;
+ unsigned nLocalNodes;
+ unsigned* nNodalDofs;
+ unsigned nElNodes;
+ unsigned* elNodes;
+ int** dstArray;
+ int*** locMat;
+ IArray* inc;
+ unsigned e_i, n_i, dof_i;
+
+ assert( self );
+
+ /* Don't build if already done. */
+ if( self->locationMatrixBuilt ) {
+ Journal_DPrintf( self->debugLM, "In %s: LM already built, so just returning.\n", __func__ );
+ Stream_UnIndentBranch( StgFEM_Debug );
+ return;
+ }
+
+ inc = IArray_New();
+
+ /* Shortcuts. */
+ feMesh = self->feMesh;
+ nDims = Mesh_GetDimSize( feMesh );
+ nDomainEls = FeMesh_GetElementDomainSize( feMesh );
+ nLocalNodes = FeMesh_GetNodeLocalSize( feMesh );
+ nNodalDofs = self->dofLayout->dofCounts;
+ dstArray = self->destinationArray;
+
+ /* Allocate for the location matrix. */
+ locMat = AllocArray( int**, nDomainEls );
+ for( e_i = 0; e_i < nDomainEls; e_i++ ) {
+ FeMesh_GetElementNodes( feMesh, e_i, inc );
+ nElNodes = IArray_GetSize( inc );
+ elNodes = (unsigned*)IArray_GetPtr( inc );
+ locMat[e_i] = AllocArray( int*, nElNodes );
+ for( n_i = 0; n_i < nElNodes; n_i++ )
+ locMat[e_i][n_i] = AllocArray( int, nNodalDofs[elNodes[n_i]] );
+ }
+
+ /* Build location matrix. */
+ for( e_i = 0; e_i < nDomainEls; e_i++ ) {
+ FeMesh_GetElementNodes( feMesh, e_i, inc );
+ nElNodes = IArray_GetSize( inc );
+ elNodes = (unsigned*)IArray_GetPtr( inc );
+ for( n_i = 0; n_i < nElNodes; n_i++ ) {
+ for( dof_i = 0; dof_i < nNodalDofs[elNodes[n_i]]; dof_i++ )
+ locMat[e_i][n_i][dof_i] = dstArray[elNodes[n_i]][dof_i];
+ }
+ }
+
+ NewClass_Delete( inc );
+
+ /* Store result. */
+ self->locationMatrix = locMat;
+}
+
+
+#if 0
+/** build the element location matrix mapping elements, element node, dof -> eq num */
+void FeEquationNumber_BuildLocationMatrix( FeEquationNumber* self ) {
+ FeMesh* mesh = self->feMesh;
+ Element_LocalIndex lElement_I;
+ Node_LocalIndex numNodesThisElement = 0;
+ Node_LocalIndex elLocalNode_I = 0;
+ Dof_Index numDofsThisNode = 0;
+ Dof_Index** dofCountsAtElementNodesArray = NULL;
+ Element_LocalIndex elementLocalCount = Mesh_GetLocalSize( mesh, Mesh_GetDimSize( mesh ) );
+
+ Journal_DPrintf( self->debug, "In %s():\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ if (self->locationMatrixBuilt) {
+ Journal_DPrintf( self->debugLM, "In %s: LM already built, so just returning.\n", __func__ );
+ Stream_UnIndentBranch( StgFEM_Debug );
+ return;
+ }
+
+ Journal_DPrintf( self->debugLM, "In %s: building over %d elements.\n", __func__, elementLocalCount );
+
+ /* Allocate the LM 3D array using the Memory module, in 2 stage process */
+ dofCountsAtElementNodesArray = Memory_Alloc_3DSetup( elementLocalCount,
+ mesh->topo->nIncEls[nDims][MT_VERTEX] );
+
+ for ( lElement_I = 0; lElement_I < elementLocalCount; lElement_I++ ) {
+ numNodesThisElement = mesh->elementNodeCountTbl[lElement_I];
+
+ for( elLocalNode_I = 0; elLocalNode_I < numNodesThisElement; elLocalNode_I++) {
+ Node_LocalIndex dNode_I = mesh->elementNodeTbl[lElement_I][elLocalNode_I];
+ numDofsThisNode = self->dofLayout->dofCounts[dNode_I];
+ dofCountsAtElementNodesArray[lElement_I][elLocalNode_I] = numDofsThisNode;
+ }
+ }
+
+ self->locationMatrix = Memory_Alloc_3DComplex( Dof_EquationNumber, elementLocalCount, mesh->elementNodeCountTbl,
+ dofCountsAtElementNodesArray, "FeEquationNumber->locationMatrix" );
+ /* Free the dof counts array:- we have to look up domain node numbers anyway later, might as
+ well just use the dof counts array then. */
+ Memory_Free( dofCountsAtElementNodesArray );
+
+ for ( lElement_I = 0; lElement_I < elementLocalCount; lElement_I++ ) {
+ FeEquationNumber_BuildOneElementLocationMatrix( self, lElement_I );
+ }
+
+ self->locationMatrixBuilt = True;
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+#endif
+
+
+/** Build an element's local location matrix */
+Dof_EquationNumber** FeEquationNumber_BuildOneElementLocationMatrix( void* feEquationNumber, Element_LocalIndex lElement_I ) {
+ FeEquationNumber* self = (FeEquationNumber*)feEquationNumber;
+ /* Node_DomainIndex elLocalNode_I; */
+ Node_DomainIndex numNodesThisElement, *elInc;
+ Dof_EquationNumber** localLocationMatrix = NULL;
+ FeMesh* feMesh = self->feMesh;
+ /* Dof_Index numDofsThisNode = 0; */
+ IArray* inc;
+
+ inc = IArray_New();
+ FeMesh_GetElementNodes( feMesh, lElement_I, inc );
+ numNodesThisElement = IArray_GetSize( inc );
+ elInc = (Node_DomainIndex*)IArray_GetPtr( inc );
+
+ /* HACK: Make sure global element location matrix is built. */
+ if( !self->locationMatrixBuilt )
+ abort();
+
+ /* if ( big LM allocated ) set pointer into it correctly */
+ if ( self->locationMatrix ) {
+ /* set ptr to correct set of local nodes ptrs */
+ localLocationMatrix = self->locationMatrix[lElement_I];
+ Journal_DPrintfL( self->debugLM, 3, "set localLocationMatrix to pt. to big LM[%d] = %p\n", lElement_I, self->locationMatrix[lElement_I] ) ;
+ }
+
+#if 0
+ else {
+ Dof_Index* numDofsEachNode = NULL;
+
+ /* allocate memory for local LM to return */
+ numDofsEachNode = Memory_Alloc_Array_Unnamed( Dof_Index, numNodesThisElement );
+
+ for( elLocalNode_I = 0; elLocalNode_I < numNodesThisElement; elLocalNode_I++) {
+ Node_LocalIndex localNode = mesh->elementNodeTbl[lElement_I][elLocalNode_I];
+ numDofsEachNode[elLocalNode_I] = self->dofLayout->dofCounts[localNode];
+ }
+
+ localLocationMatrix = Memory_Alloc_2DComplex( Dof_EquationNumber, numNodesThisElement, numDofsEachNode,
+ "localLocationMatrix (set of ptrs to dof lists, indexed by element-local node)" );
+ Memory_Free( numDofsEachNode );
+ }
+#endif
+
+#if 0
+ /* If we haven't yet built full LM, copy ID values across */
+ if ( False == self->locationMatrixBuilt ) {
+ /* for (each el-local node) */
+ for ( elLocalNode_I = 0; elLocalNode_I < numNodesThisElement; elLocalNode_I++ ) {
+ /* look up processor local node number. */
+ Node_LocalIndex procDomainNode = mesh->elementNodeTbl[lElement_I][elLocalNode_I];
+ numDofsThisNode = self->dofLayout->dofCounts[procDomainNode];
+
+ /* copy pointers to dof eq nums from ID array relevant to that node */
+ Journal_DPrintfL( self->debugLM, 3, "copying %d dof eq. numbers from ID[%d] to LM[%d][%d]\n",
+ numDofsThisNode, procDomainNode, lElement_I, elLocalNode_I );
+ memcpy( localLocationMatrix[elLocalNode_I],
+ self->destinationArray[procDomainNode], numDofsThisNode * sizeof(Dof_EquationNumber) );
+ }
+ }
+#endif
+
+ NewClass_Delete( inc );
+
+ return localLocationMatrix;
+}
+
+
+void FeEquationNumber_PrintDestinationArray( void* feFeEquationNumber, Stream* stream ) {
+ FeEquationNumber* self = (FeEquationNumber*) feFeEquationNumber;
+ FeMesh* feMesh = self->feMesh;
+ MPI_Comm comm = Comm_GetMPIComm( Mesh_GetCommTopology( feMesh, MT_VERTEX ) );
+ unsigned rank;
+ Node_GlobalIndex gNode_I;
+ Node_GlobalIndex nodeGlobalCount = FeMesh_GetNodeGlobalSize( feMesh );
+
+ MPI_Comm_rank( comm, (int*)&rank );
+ Journal_Printf( stream, "%d: *** Printing destination array ***\n", rank );
+
+ for (gNode_I =0; gNode_I < nodeGlobalCount; gNode_I++) {
+ Node_DomainIndex dNode_I;
+
+ if ( !Mesh_GlobalToDomain( feMesh, MT_VERTEX, gNode_I, &dNode_I ) ) {
+ Journal_Printf( stream, "\tdestinationArray[(gnode)%2d]: on another proc\n", gNode_I);
+ }
+ else {
+ Dof_Index currNodeNumDofs = self->dofLayout->dofCounts[ dNode_I ];
+ Dof_Index nodeLocalDof_I;
+
+ Journal_Printf( stream, "\tdestinationArray[(gnode)%2d][(dof)0-%d]:",gNode_I, currNodeNumDofs );
+ for( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
+ Journal_Printf( stream, "%3d, ", self->destinationArray[dNode_I][nodeLocalDof_I] );
+ }
+ Journal_Printf( stream, "\n" );
+ }
+ }
+}
+
+void FeEquationNumber_PrintDestinationArrayBox( void* feFeEquationNumber, Stream* stream ) {
+ FeEquationNumber* self = (FeEquationNumber*) feFeEquationNumber;
+ FeMesh* feMesh = self->feMesh;
+ MPI_Comm comm = Comm_GetMPIComm( Mesh_GetCommTopology( feMesh, MT_VERTEX ) );
+ unsigned rank;
+ Grid* vGrid;
+ unsigned ijk[3];
+ Element_LocalIndex lNode_I;
+ Node_GlobalIndex gNode_I;
+ Node_Index sizeI, sizeJ, sizeK;
+ Dof_Index nDofs;
+ Dof_Index dof_I;
+
+ MPI_Comm_rank( comm, (int*)&rank );
+ Journal_Printf( stream, "%d: *** Printing destination array ***\n", rank );
+
+ vGrid = *Mesh_GetExtension( feMesh, Grid**, "vertexGrid" );
+ nDofs = self->dofLayout->dofCounts[0];
+ sizeI = vGrid->sizes[ I_AXIS ];
+ sizeJ = vGrid->sizes[ J_AXIS ];
+ sizeK = vGrid->sizes[ K_AXIS ] ? vGrid->sizes[ K_AXIS ] : 1;
+
+ for ( ijk[2] = 0 ; ijk[2] < sizeK ; ijk[2]++ ) {
+ if ( sizeK != 1 )
+ Journal_Printf( stream, "\nk = %d\n", ijk[2] );
+ for ( ijk[1] = sizeJ - 1 ; ijk[1] >= 0 ; ijk[1]-- ) {
+ Journal_Printf( stream, "%2d - ", ijk[1] );
+ for ( ijk[0] = 0 ; ijk[0] < sizeI ; ijk[0]++ ) {
+ gNode_I = Grid_Project( vGrid, ijk );
+ Journal_Printf( stream, "{ " );
+ if ( Mesh_GlobalToDomain( feMesh, MT_VERTEX, gNode_I, &lNode_I ) ) {
+ for ( dof_I = 0 ; dof_I < nDofs ; dof_I++ )
+ Journal_Printf( stream, "%3d ", self->destinationArray[lNode_I][dof_I] );
+ }
+ else {
+ for ( dof_I = 0 ; dof_I < nDofs ; dof_I++ )
+ Journal_Printf( stream, " XX " );
+ }
+ Journal_Printf( stream, "}" );
+ }
+ Journal_Printf( stream, "\n" );
+ }
+ /* Bottom row */
+ Journal_Printf( stream, " " );
+ for ( ijk[0] = 0 ; ijk[0] < sizeI ; ijk[0]++ ) {
+ Journal_Printf( stream, " %3d ", ijk[0] );
+ if ( nDofs == 3 )
+ Journal_Printf( stream, " " );
+ }
+ Journal_Printf( stream, "\n" );
+ }
+}
+
+void FeEquationNumber_PrintLocationMatrix( void* feFeEquationNumber, Stream* stream ) {
+ FeEquationNumber* self = (FeEquationNumber*) feFeEquationNumber;
+ FeMesh* feMesh = self->feMesh;
+ MPI_Comm comm = Comm_GetMPIComm( Mesh_GetCommTopology( feMesh, MT_VERTEX ) );
+ unsigned rank;
+ Element_GlobalIndex gEl_I;
+ unsigned nDims = Mesh_GetDimSize( feMesh );
+ Element_GlobalIndex elementGlobalCount = FeMesh_GetElementGlobalSize( feMesh );
+ unsigned nLocalEls = FeMesh_GetElementLocalSize( feMesh );
+
+ Journal_Printf( stream, "%d: *** Printing location matrix ***\n", rank );
+
+ MPI_Comm_rank( comm, (int*)&rank );
+
+ for (gEl_I =0; gEl_I < elementGlobalCount; gEl_I++ ) {
+ Element_LocalIndex lEl_I;
+
+ if ( !Mesh_GlobalToDomain( feMesh, (MeshTopology_Dim)nDims, gEl_I, &lEl_I ) || lEl_I >= nLocalEls ) {
+ Journal_Printf( stream, "\tLM[(g/l el)%2d/XXX]: on another proc\n", gEl_I);
+ }
+ else {
+ Node_LocalIndex numNodesAtElement;
+ Node_LocalIndex elLocalNode_I;
+ unsigned* incNodes;
+ IArray* inc;
+
+ inc = IArray_New();
+ FeMesh_GetElementNodes( self->feMesh, lEl_I, inc );
+ numNodesAtElement = IArray_GetSize( inc );
+ incNodes = (unsigned*)IArray_GetPtr( inc );
+
+ Journal_Printf( stream, "\tLM[(g/l el)%2d/%2d][(enodes)0-%d]", gEl_I, lEl_I, numNodesAtElement);
+ /* print the nodes and dofs */
+ for ( elLocalNode_I = 0; elLocalNode_I < numNodesAtElement; elLocalNode_I++ ) {
+ /* look up processor local node number. */
+ Element_LocalIndex currNode = incNodes[elLocalNode_I == 2 ? 3 :
+ elLocalNode_I == 3 ? 2 :
+ elLocalNode_I == 6 ? 7 :
+ elLocalNode_I == 7 ? 6 :
+ elLocalNode_I];
+ /* get the number of dofs at current node */
+ Dof_Index currNodeNumDofs = self->dofLayout->dofCounts[ currNode ];
+ Dof_Index nodeLocalDof_I;
+
+ Journal_Printf( stream, "({%2d}", currNode );
+ for( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
+ Journal_Printf( stream, "%3d,", self->destinationArray[currNode][nodeLocalDof_I] );
+ }
+ Journal_Printf( stream, "), " );
+ }
+
+ Journal_Printf( stream, "\n" );
+
+ NewClass_Delete( inc );
+ }
+
+ }
+}
+
+
+#if 0
+void FeEquationNumber_PrintElementLocationMatrix(
+ void* feEquationNumber,
+ Dof_EquationNumber** elementLM,
+ Element_LocalIndex element_lI,
+ Stream* stream )
+{
+ FeEquationNumber* self = (FeEquationNumber*)feEquationNumber;
+ Dof_Index dof_elLocalI;
+ Node_ElementLocalIndex nodeCountThisEl = self->feMesh->elementNodeCountTbl[element_lI];
+ Node_LocalIndex node_lI = self->feMesh->elementNodeTbl[element_lI][nodeCountThisEl-1];
+ Dof_Index dofCountLastNode = self->dofLayout->dofCounts[node_lI];
+ Dof_Index totalDofsThisElement = 0;
+
+ totalDofsThisElement = &elementLM[nodeCountThisEl-1][dofCountLastNode-1] - &elementLM[0][0] + 1;
+
+ Journal_DPrintf( stream, "LM[ el %d ], dofs[0-%d] = {", element_lI, totalDofsThisElement );
+
+ for( dof_elLocalI=0; dof_elLocalI < totalDofsThisElement; dof_elLocalI++ ) {
+ Journal_DPrintf( stream, "%d, ", elementLM[0][dof_elLocalI] );
+ }
+ Journal_DPrintf( stream, "}\n" );
+}
+
+
+/* Calculates global sum unconstrained dofs */
+void _FeEquationNumber_CalculateGlobalUnconstrainedDofTotal( FeEquationNumber* self ) {
+ int globalSumUnconstrainedDofs;
+ MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
+
+ Journal_DPrintfL( self->debug, 1, "In %s:\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+ MPI_Allreduce( &self->_highestLocalEqNum, &globalSumUnconstrainedDofs, 1, MPI_INT, MPI_MAX, meshDecomp->communicator );
+ self->globalSumUnconstrainedDofs = (unsigned)(globalSumUnconstrainedDofs+1);
+
+ Journal_DPrintf( self->debug, "Calculated total (across all processors) unconstrained dofs as:%d\n", self->globalSumUnconstrainedDofs );
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+/* calculate the minimum and maximum parts that my processor is responsible for holding */
+void _FeEquationNumber_CalculateEqNumsDecomposition( FeEquationNumber* self ) {
+ MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
+ Partition_Index myRank = meshDecomp->rank;
+ Partition_Index nProc = meshDecomp->nproc;
+
+ Journal_DPrintfL( self->debug, 1, "In %s:\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ if ( (self->remappingActivated) && ( (self->linkedDofInfo == NULL) || (self->linkedDofInfo->linkedDofSetsCount == 0 ) ) ) {
+ /* If the remapping is activated, and things aren't complicated by periodic BCs,
+ then each processor should hold the Matrix/Vector
+ component corresponding to the lowest local eqNum, to the lowest eqNum of the next
+ processor. This means that _only shared boundary nodes_ will need to be communicated,
+ and the last processor will have no communication. */
+ Journal_DPrintfL( self->debug, 2, "Remapping active and no periodic bcs: using lowest local eqNums as boundaries.\n");
+
+ self->_lowestGlobalEqNums = Memory_Alloc_Array( Dof_EquationNumber, nProc,
+ "FeEquationNumber->_lowestGlobalEqNums" );
+ MPI_Allgather(
+ &self->_lowestLocalEqNum, 1, MPI_INT,
+ self->_lowestGlobalEqNums, 1, MPI_INT,
+ meshDecomp->communicator );
+
+ self->firstOwnedEqNum = self->_lowestLocalEqNum;
+ if (myRank == nProc-1) {
+ self->lastOwnedEqNum = self->_highestLocalEqNum;
+ }
+ else {
+ Node_LocalIndex nextProcLowestEqNum = self->_lowestGlobalEqNums[myRank+1] - 1;
+ if ( (unsigned int)-1 == nextProcLowestEqNum ) {
+ /* Pathological case of next proc having all B.C.s */
+ self->lastOwnedEqNum = self->_highestLocalEqNum;
+ }
+ else {
+ self->lastOwnedEqNum = nextProcLowestEqNum;
+ }
+ }
+
+ self->localEqNumsOwnedCount = self->lastOwnedEqNum - self->firstOwnedEqNum + 1;
+ }
+ else {
+ /* If the remapping isn't activated and the eqNum ordering isn't aligned with the mesh
+ decomposition, or there are periodic BCs, we can't get a clear idea of where the processor boundaries are:
+ therefore just split up the EqNums equally between processors: still should be
+ fairly good alignment. */
+ Journal_DPrintfL( self->debug, 2, "Remapping inactive and/or periodic bcs used: just dividing eqNums as evenly as possible.\n");
+
+ self->_eqNumsPerProcDivisor = self->globalSumUnconstrainedDofs / nProc;
+ self->_eqNumsRemainder = self->globalSumUnconstrainedDofs % nProc;
+ Journal_DPrintfL( self->debug, 2, "Calculated %d eqNums per proc, with %d remainder\n",
+ self->_eqNumsPerProcDivisor, self->_eqNumsRemainder );
+ self->_remNotAddedChangeover = (self->_eqNumsPerProcDivisor+1) * self->_eqNumsRemainder;
+
+ self->localEqNumsOwnedCount = self->_eqNumsPerProcDivisor;
+ if ( myRank < self->_eqNumsRemainder ) {
+ self->localEqNumsOwnedCount++;
+ }
+
+ if ( myRank < self->_eqNumsRemainder ) {
+ self->firstOwnedEqNum = myRank * (self->_eqNumsPerProcDivisor+1);
+ }
+ else {
+ self->firstOwnedEqNum = self->_remNotAddedChangeover
+ + (myRank - self->_eqNumsRemainder) * self->_eqNumsPerProcDivisor;
+ }
+ self->lastOwnedEqNum = self->firstOwnedEqNum + self->localEqNumsOwnedCount - 1;
+ }
+
+ Journal_DPrintfL( self->debug, 1, "Calculated I own %d eqNums, between indices %d to %d\n",
+ self->localEqNumsOwnedCount, self->firstOwnedEqNum, self->lastOwnedEqNum );
+ Journal_DPrintfL( self->debug, 1, "(Range of eqNums on local mesh segment is %d to %d)\n",
+ self->_lowestLocalEqNum, self->_highestLocalEqNum );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+#endif
+
+
+Partition_Index FeEquationNumber_CalculateOwningProcessorOfEqNum( void* feEquationNumber, Dof_EquationNumber eqNum ) {
+ FeEquationNumber* self = (FeEquationNumber*)feEquationNumber;
+ /* Partition_Index ownerProc = (unsigned int)-1; */
+ Comm* comm = Mesh_GetCommTopology( self->feMesh, MT_VERTEX );
+ MPI_Comm mpiComm = Comm_GetMPIComm( comm );
+ unsigned nProcs;
+ unsigned p_i;
+
+ MPI_Comm_size( mpiComm, (int*)&nProcs );
+ for( p_i = 1; p_i < nProcs; p_i++ ) {
+ if( eqNum < self->_lowestGlobalEqNums[p_i] )
+ break;
+ }
+
+ return p_i - 1;
+
+#if 0
+ if ( (self->remappingActivated) && ( (self->linkedDofInfo == NULL) || (self->linkedDofInfo->linkedDofSetsCount == 0 ) ) ) {
+ MeshDecomp* meshDecomp = self->feMesh->layout->decomp;
+ Partition_Index myRank = meshDecomp->rank;
+ Partition_Index nProc = meshDecomp->nproc;
+
+ /* Expect it to be on the next processor, so try there first */
+ if ( eqNum > self->lastOwnedEqNum ) {
+ ownerProc = myRank + 1;
+ while ( (ownerProc+1) < nProc ) {
+ if ( eqNum >= self->_lowestGlobalEqNums[ownerProc+1] ) {
+ ownerProc++;
+ }
+ else {
+ break;
+ }
+ }
+ }
+ /* otherwise count back from current */
+ else {
+ ownerProc = myRank;
+ while ( ownerProc > 0 ) {
+ if ( eqNum < self->_lowestGlobalEqNums[ownerProc] ) {
+ ownerProc--;
+ }
+ else {
+ break;
+ }
+ }
+ }
+ }
+ else {
+ if ( eqNum < self->_remNotAddedChangeover ) {
+ ownerProc = eqNum / (self->_eqNumsPerProcDivisor+1);
+ }
+ else {
+ ownerProc = self->_eqNumsRemainder + (eqNum - self->_remNotAddedChangeover) / self->_eqNumsPerProcDivisor;
+ }
+ }
+}
+
+return ownerProc;
+#endif
+}
+
+
+#if 0
+void FeEquationNumber_Create_CritPointInfo_MPI_Datatype( void ) {
+#define CRIT_POINT_INFO_NBLOCKS 2
+ MPI_Aint indexExtent = 0;
+ MPI_Datatype critPointInfoTypes[CRIT_POINT_INFO_NBLOCKS] = {MPI_UNSIGNED, MPI_INT };
+ MPI_Aint critPointInfoBlockDisplacements[CRIT_POINT_INFO_NBLOCKS];
+ int critPointInfoBlockLengths[CRIT_POINT_INFO_NBLOCKS] = { 1, 1 };
+
+ MPI_Type_extent(MPI_UNSIGNED, &indexExtent);
+ critPointInfoBlockDisplacements[0] = 0;
+ critPointInfoBlockDisplacements[1] = indexExtent;
+
+ MPI_Type_struct( CRIT_POINT_INFO_NBLOCKS, critPointInfoBlockLengths, critPointInfoBlockDisplacements,
+ critPointInfoTypes, &MPI_critPointInfoType );
+
+ MPI_Type_commit( &MPI_critPointInfoType );
+}
+#endif
+
+
+void FeEquationNumber_BuildWithTopology( FeEquationNumber* self ) {
+ Stream* stream;
+ double startTime, endTime, time, tmin, tmax;
+ FeMesh* feMesh;
+ Sync* sync;
+ Comm* comm;
+ MPI_Comm mpiComm;
+ unsigned rank, nProcs;
+ unsigned nDims;
+ unsigned nDomainNodes;
+ unsigned nLocalNodes;
+ unsigned* nNodalDofs;
+ unsigned nElNodes, *elNodes;
+ int** dstArray;
+ int *nLocMatDofs, ***locMat;
+ unsigned varInd;
+ unsigned curEqNum;
+ unsigned base;
+ unsigned subTotal;
+ MPI_Status status;
+ unsigned maxDofs;
+ unsigned* tuples;
+ LinkedDofInfo* links;
+ unsigned highest;
+ IArray* inc;
+ unsigned e_i, n_i, dof_i, s_i;
+ int ii;
+
+ assert( self );
+
+ inc = IArray_New();
+
+ stream = Journal_Register( Info_Type, (Name)self->type );
+ Stream_SetPrintingRank( stream, 0 );
+
+ Journal_RPrintf( stream, "FeEquationNumber: '%s'\n", self->name );
+ Stream_Indent( stream );
+ Journal_RPrintf( stream, "Generating equation numbers...\n" );
+ Stream_Indent( stream );
+ if( self->removeBCs )
+ Journal_RPrintf( stream, "BCs set to be removed.\n" );
+ else
+ Journal_RPrintf( stream, "BCs will not be removed.\n" );
+
+ startTime = MPI_Wtime();
+
+ /* Shortcuts. */
+ feMesh = self->feMesh;
+ comm = Mesh_GetCommTopology( feMesh, MT_VERTEX );
+ mpiComm = Comm_GetMPIComm( comm );
+ MPI_Comm_size( mpiComm, (int*)&nProcs );
+ MPI_Comm_rank( mpiComm, (int*)&rank );
+ nDims = Mesh_GetDimSize( feMesh );
+ nDomainNodes = FeMesh_GetNodeDomainSize( feMesh );
+ self->nDomainEls = FeMesh_GetElementDomainSize( feMesh );
+ nLocalNodes = FeMesh_GetNodeLocalSize( feMesh );
+ nNodalDofs = self->dofLayout->dofCounts;
+ links = self->linkedDofInfo;
+
+ /* Allocate for destination array. */
+ dstArray = Memory_Alloc_2DComplex( int, nDomainNodes, nNodalDofs,
+ "FeEquationNumber::destinationArray" );
+
+ /* If needed, allocate for linked equation numbers. */
+ if( links ) {
+ unsigned s_i;
+
+ links->eqNumsOfLinkedDofs = ReallocArray( links->eqNumsOfLinkedDofs, int, links->linkedDofSetsCount );
+ for( s_i = 0; s_i < links->linkedDofSetsCount; s_i++ )
+ links->eqNumsOfLinkedDofs[s_i] = -1;
+ }
+
+ /* Allocate for the location matrix. */
+ nLocMatDofs = NULL;
+ locMat = AllocArray( int**, self->nDomainEls );
+ for( e_i = 0; e_i < self->nDomainEls; e_i++ ) {
+ FeMesh_GetElementNodes( feMesh, e_i, inc );
+ nElNodes = IArray_GetSize( inc );
+ elNodes = (unsigned*)IArray_GetPtr( inc );
+ nLocMatDofs = ReallocArray( nLocMatDofs, int, nElNodes );
+ for( n_i = 0; n_i < nElNodes; n_i++ )
+ nLocMatDofs[n_i] = nNodalDofs[elNodes[n_i]];
+ locMat[e_i] = AllocComplex2D( int, nElNodes, (Index*)nLocMatDofs );
+ }
+ FreeArray( nLocMatDofs );
+
+ /* Build initial destination array and store max dofs. */
+ curEqNum = 0;
+ maxDofs = 0;
+ for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
+ if( nNodalDofs[n_i] > maxDofs )
+ maxDofs = nNodalDofs[n_i];
+
+ for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
+ varInd = self->dofLayout->varIndices[n_i][dof_i];
+ if( !self->bcs || !VariableCondition_IsCondition( self->bcs, n_i, varInd ) ||
+ !self->removeBCs )
+ {
+ if( links && links->linkedDofTbl[n_i][dof_i] != -1 ) {
+ if( rank > 0 ) {
+ dstArray[n_i][dof_i] = -2;
+ continue;
+ }
+ if( links->eqNumsOfLinkedDofs[links->linkedDofTbl[n_i][dof_i]] == -1 )
+ links->eqNumsOfLinkedDofs[links->linkedDofTbl[n_i][dof_i]] = curEqNum++;
+ dstArray[n_i][dof_i] = links->eqNumsOfLinkedDofs[links->linkedDofTbl[n_i][dof_i]];
+ }
+ else
+ dstArray[n_i][dof_i] = curEqNum++;
+ }
+ else
+ dstArray[n_i][dof_i] = -1;
+ }
+ }
+
+ /* Order the equation numbers based on processor rank; cascade counts forward. */
+ base = 0;
+ if( rank > 0 )
+ MPI_Recv( &base, 1, MPI_UNSIGNED, rank - 1, 6669, mpiComm, &status );
+ subTotal = base + curEqNum;
+ if( rank < nProcs - 1 )
+ MPI_Send( &subTotal, 1, MPI_UNSIGNED, rank + 1, 6669, mpiComm );
+
+ if( links ) {
+ /* Reduce to find lowest linked DOFs. */
+ for( s_i = 0; s_i < links->linkedDofSetsCount; s_i++ ) {
+ if( links->eqNumsOfLinkedDofs[s_i] != -1 )
+ links->eqNumsOfLinkedDofs[s_i] += base;
+/*
+ MPI_Allreduce( links->eqNumsOfLinkedDofs + s_i, &lowest, 1, MPI_UNSIGNED, MPI_MAX, mpiComm );
+*/
+ MPI_Allreduce( links->eqNumsOfLinkedDofs + s_i, &highest, 1, MPI_INT, MPI_MAX, mpiComm );
+/*
+ assert( (lowest == (unsigned)-1) ? lowest == highest : 1 );
+*/
+ links->eqNumsOfLinkedDofs[s_i] = highest;
+ }
+ }
+
+ /* Modify existing destination array and dump to a tuple array. */
+ tuples = AllocArray( unsigned, nDomainNodes * maxDofs );
+ for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
+ for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
+ varInd = self->dofLayout->varIndices[n_i][dof_i];
+ if( !self->bcs || !VariableCondition_IsCondition( self->bcs, n_i, varInd ) ||
+ !self->removeBCs )
+ {
+ if( links && links->linkedDofTbl[n_i][dof_i] != -1 ) {
+ highest = links->eqNumsOfLinkedDofs[links->linkedDofTbl[n_i][dof_i]];
+ dstArray[n_i][dof_i] = highest;
+ }
+ else
+ dstArray[n_i][dof_i] += base;
+ }
+ tuples[n_i * maxDofs + dof_i] = dstArray[n_i][dof_i];
+ }
+ }
+
+ /* Update all other procs. */
+ sync = Mesh_GetSync( feMesh, MT_VERTEX );
+ Sync_SyncArray( sync, tuples, maxDofs * sizeof(unsigned),
+ tuples + nLocalNodes * maxDofs, maxDofs * sizeof(unsigned),
+ maxDofs * sizeof(unsigned) );
+
+ /* Update destination array's domain indices. */
+ for( n_i = nLocalNodes; n_i < nDomainNodes; n_i++ ) {
+ for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
+ varInd = self->dofLayout->varIndices[n_i][dof_i];
+ if( !self->bcs || !VariableCondition_IsCondition( self->bcs, n_i, varInd ) ||
+ !self->removeBCs )
+ {
+ dstArray[n_i][dof_i] = tuples[n_i * maxDofs + dof_i];
+ }
+ else
+ dstArray[n_i][dof_i] = -1;
+ }
+ }
+
+ /* Destroy tuple array. */
+ FreeArray( tuples );
+
+ /* Build location matrix. */
+ for( e_i = 0; e_i < self->nDomainEls; e_i++ ) {
+ FeMesh_GetElementNodes( feMesh, e_i, inc );
+ nElNodes = IArray_GetSize( inc );
+ elNodes = (unsigned*)IArray_GetPtr( inc );
+ for( n_i = 0; n_i < nElNodes; n_i++ ) {
+ for( dof_i = 0; dof_i < nNodalDofs[elNodes[n_i]]; dof_i++ )
+ locMat[e_i][n_i][dof_i] = dstArray[elNodes[n_i]][dof_i];
+ }
+ }
+
+ /* Store stuff on class. */
+ self->destinationArray = dstArray;
+ self->locationMatrix = locMat;
+ self->locationMatrixBuilt = True;
+ self->remappingActivated = False;
+ self->localEqNumsOwnedCount = curEqNum;
+ self->firstOwnedEqNum = base;
+ self->lastOwnedEqNum = subTotal - 1;
+ self->_lowestLocalEqNum = self->firstOwnedEqNum;
+
+ /* Setup owned mapping. */
+ STree_Clear( self->ownedMap );
+ for( ii = self->firstOwnedEqNum; ii <= self->lastOwnedEqNum; ii++ ) {
+ int val = ii - self->firstOwnedEqNum;
+ STreeMap_Insert( self->ownedMap, &ii, &val );
+ }
+
+ /* Bcast global sum from highest rank. */
+ if( rank == nProcs - 1 )
+ self->globalSumUnconstrainedDofs = self->lastOwnedEqNum + 1;
+ MPI_Bcast( &self->globalSumUnconstrainedDofs, 1, MPI_UNSIGNED, nProcs - 1, mpiComm );
+
+ /* Construct lowest global equation number list. */
+ self->_lowestGlobalEqNums = AllocArray( int, nProcs );
+ MPI_Allgather( &self->firstOwnedEqNum, 1, MPI_UNSIGNED, self->_lowestGlobalEqNums, 1, MPI_UNSIGNED, mpiComm );
+
+ endTime = MPI_Wtime();
+
+ Journal_RPrintf( stream, "Assigned %d global equation numbers.\n", self->globalSumUnconstrainedDofs );
+ Journal_Printf( stream, "[%u] Assigned %d local equation numbers, within range %d to %d.\n",
+ rank, self->lastOwnedEqNum - self->firstOwnedEqNum + 1, self->firstOwnedEqNum, self->lastOwnedEqNum + 1 );
+ Stream_UnIndent( stream );
+
+ time = endTime - startTime;
+ MPI_Reduce( &time, &tmin, 1, MPI_DOUBLE, MPI_MIN, 0, mpiComm );
+ MPI_Reduce( &time, &tmax, 1, MPI_DOUBLE, MPI_MAX, 0, mpiComm );
+ Journal_RPrintf( stream, "... Completed in %g [min] / %g [max] seconds.\n", tmin, tmax );
+ Stream_UnIndent( stream );
+
+ NewClass_Delete( inc );
+}
+
+#if 0
+void FeEquationNumber_BuildVariableIndices( FeEquationNumber* self, int* nInds, int** inds, int* maxDofs ) {
+ int maxDofs;
+ ISet indSetObj, *indSet = &indSetObj;
+
+ *maxDofs = 0;
+ for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
+ if( nNodalDofs[n_i] > *maxDofs )
+ *maxDofs = nNodalDofs[n_i];
+ }
+
+ ISet_Construct( indSet );
+ ISet_SetMaxSize( indSet, *maxDofs );
+ for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
+ for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
+ varInd = self->dofLayout->varIndices[n_i][dof_i];
+ ISet_TryInsert( indSet, varInd );
+ }
+ }
+
+ *nInds = ISet_GetSize( indSet );
+ *inds = MemArray( int, *nInds, FeEquationNumber_Type );
+ ISet_GetArray( indSet, NULL, inds );
+ ISet_Destruct( indSet );
+}
+#endif
+
+
+#if 0
+void FeEquationNumber_Invert( void* feEqNum, int equation, unsigned* node, unsigned* dof ) {
+ FeEquationNumber* self = (FeEquationNumber*)feEqNum;
+
+ assert( self && Stg_CheckType( self, FeEquationNumber ) );
+ assert( equation - self->firstOwnedEqNum < self->localEqNumsOwnedCount );
+ assert( node );
+ assert( dof );
+
+ eq = equation - self->firstOwnedEqNum;
+ *node = self->eqToNode[eq];
+ *dof = self->eqToDof[eq];
+}
+
+Bool FeEquationNumber_IsKnown( void* feEqNum, int equation ) {
+ FeEquationNumber* self = (FeEquationNumber*)feEqNum;
+ unsigned node, dof;
+ unsigned varInd;
+
+ assert( self && Stg_CheckType( self, FeEquationNumber ) );
+
+ if( !self->bcs ) return False;
+ FeEquationNumber_Invert( self, equation, &node, &dof );
+
+ assert( self->dofLayout );
+ assert( self->dofLayout->varIndices );
+ assert( self->dofLayout->varIndices[node] );
+ varInd = self->dofLayout->varIndices[node][dof];
+ return VariableCondition_IsCondition( self->bcs, n_i, varInd );
+}
+#endif
+
+
+int GenerateEquationNumbering(
+ int NX, int NY, int NZ,
+ int nlocal, int g_node_id[],
+ int dof, int nglobal,
+ PetscTruth periodic_x, PetscTruth periodic_y, PetscTruth periodic_z,
+ int npx, int npy, int npz,
+ int periodic_x_gnode_id[], int periodic_y_gnode_id[], int periodic_z_gnode_id[],
+ int eqnums[], int *neqnums );
+
+void FeEquationNumber_BuildWithDave( FeEquationNumber* self ) {
+ int nLocals, *locals;
+ Grid *vGrid;
+ int varInd;
+ int nEqNums, **dstArray;
+ IArray *inc;
+ int nDofs;
+ int *periodic;
+ int ***locMat;
+ int nDims;
+ int *elNodes;
+ Comm *comm;
+ MPI_Comm mpiComm;
+ int nRanks, rank;
+ Sync *sync;
+ Bool isCond;
+ int nPeriodicInds[3];
+ int *periodicInds[3];
+ int inds[3];
+ Bool usePeriodic;
+ int *tmpArray, nLocalEqNums;
+ int lastOwnedEqNum, ind;
+ STree *doneSet;
+ int ii, jj, kk;
+
+ comm = Mesh_GetCommTopology( self->feMesh, (MeshTopology_Dim)0 );
+ mpiComm = Comm_GetMPIComm( comm );
+ MPI_Comm_size( mpiComm, &nRanks );
+ MPI_Comm_rank( mpiComm, &rank );
+
+ /* Setup an array containing global indices of all locally owned nodes. */
+ nLocals = Mesh_GetLocalSize( self->feMesh, (MeshTopology_Dim)0 );
+ locals = AllocArray( int, nLocals );
+ for( ii = 0; ii < nLocals; ii++ )
+ locals[ii] = Mesh_DomainToGlobal( self->feMesh, (MeshTopology_Dim)0, ii );
+
+ /* Allocate for destination array. */
+ nDofs = self->dofLayout->dofCounts[0];
+ dstArray = AllocArray2D( int, Mesh_GetDomainSize( self->feMesh, (MeshTopology_Dim)0 ), nDofs );
+
+ /* Get the vertex grid extension and any periodicity. */
+ nDims = Mesh_GetDimSize( self->feMesh );
+ vGrid = *Mesh_GetExtension( self->feMesh, Grid**, "vertexGrid" );
+ periodic = Mesh_GetExtension( self->feMesh, int*, "periodic" );
+
+ /* Fill destination array with initial values, setting dirichlet BCs as we go. */
+ for( ii = 0; ii < nLocals; ii++ ) {
+ Grid_Lift( vGrid, locals[ii], (unsigned*)inds );
+ usePeriodic = False;
+ for( jj = 0; jj < nDims; jj++ ) {
+ if( periodic[jj] && (inds[jj] == 0 || inds[jj] == (int)(vGrid->sizes[jj] - 1)) ) {
+ usePeriodic = True;
+ break;
+ }
+ }
+ for( jj = 0; jj < nDofs; jj++ ) {
+ varInd = self->dofLayout->varIndices[ii][jj];
+ if( self->bcs )
+ isCond = VariableCondition_IsCondition( self->bcs, ii, varInd );
+ else
+ isCond = False;
+ if( isCond && self->removeBCs )
+ dstArray[ii][jj] = -1;
+ else
+ dstArray[ii][jj] = 0;
+ }
+ }
+
+ /* Generate opposing indices for periodicity. */
+ for( ii = 0; ii < nDims; ii++ ) {
+ nPeriodicInds[ii] = 0;
+ periodicInds[ii] = NULL;
+ if( periodic[ii] ) {
+ periodicInds[ii] = AllocArray( int, nLocals );
+ for( jj = 0; jj < nLocals; jj++ ) {
+ Grid_Lift( vGrid, locals[jj], (unsigned*)inds );
+ if( inds[ii] != (int)(vGrid->sizes[ii] - 1) ) continue;
+/*
+ for( kk = 0; kk < nDofs; kk++ )
+ if( dstArray[jj][kk] == -1 ) break;
+ if( kk < nDofs ) continue;
+*/
+ periodicInds[ii][nPeriodicInds[ii]++] = locals[jj];
+ }
+ }
+ }
+
+ /* Call Dave's equation number generation routine. */
+ if( nDims == 2 ) {
+ GenerateEquationNumbering( vGrid->sizes[0], vGrid->sizes[1], 1,
+ nLocals, locals,
+ nDofs, Mesh_GetGlobalSize( self->feMesh, (MeshTopology_Dim)0 ),
+ (PetscTruth)periodic[0], (PetscTruth)periodic[1], (PetscTruth)False,
+ nPeriodicInds[0], nPeriodicInds[1], 0,
+ periodicInds[0], periodicInds[1], NULL,
+ dstArray[0], &nEqNums );
+ }
+ else {
+ GenerateEquationNumbering( vGrid->sizes[0], vGrid->sizes[1], vGrid->sizes[2],
+ nLocals, locals,
+ nDofs, Mesh_GetGlobalSize( self->feMesh, (MeshTopology_Dim)0 ),
+ (PetscTruth)periodic[0], (PetscTruth)periodic[1], (PetscTruth)periodic[2],
+ nPeriodicInds[0], nPeriodicInds[1], nPeriodicInds[2],
+ periodicInds[0], periodicInds[1], periodicInds[2],
+ dstArray[0], &nEqNums );
+ }
+
+ /* Free periodic arrays. */
+ for( ii = 0; ii < nDims; ii++ ) {
+ if( periodicInds[ii] )
+ FreeArray( periodicInds[ii] );
+ }
+
+ /* Setup owned mapping part 1. */
+ STree_Clear( self->ownedMap );
+ for( ii = 0; ii < nLocals; ii++ ) {
+ Grid_Lift( vGrid, locals[ii], (unsigned*)inds );
+ for( jj = 0; jj < nDims; jj++ ) {
+ if( periodic[jj] && inds[jj] == (int)(vGrid->sizes[jj] - 1) ) {
+ inds[jj] = 0;
+ ind = Grid_Project( vGrid, (unsigned*)inds );
+ if( !FeMesh_NodeGlobalToDomain( self->feMesh, ind, (unsigned*)(&ind) ) )
+ break;
+ }
+ }
+ if( jj < nDims ) continue;
+ for( jj = 0; jj < nDofs; jj++ ) {
+ if( dstArray[ii][jj] == -1 || STreeMap_HasKey( self->ownedMap, dstArray[ii] + jj ) )
+ continue;
+ STreeMap_Insert( self->ownedMap, dstArray[ii] + jj, &ii );
+ }
+ }
+
+ /* Setup owned mapping. */
+ tmpArray = AllocArray( int, nLocals * nDofs );
+ memcpy( tmpArray, dstArray[0], nLocals * nDofs * sizeof(int) );
+ qsort( tmpArray, nLocals * nDofs, sizeof(int), stgCmpInt );
+ doneSet = STree_New();
+ STree_SetItemSize( doneSet, sizeof(int) );
+ STree_SetIntCallbacks( doneSet );
+ for( nLocalEqNums = 0, ii = 0; ii < nLocals * nDofs; ii++ ) {
+ if( tmpArray[ii] != -1 &&
+ STreeMap_HasKey( self->ownedMap, tmpArray + ii ) &&
+ !STree_Has( doneSet, tmpArray + ii ) )
+ {
+ if( !nLocalEqNums )
+ self->_lowestLocalEqNum = tmpArray[ii];
+ *(int*)STreeMap_Map( self->ownedMap, tmpArray + ii ) = nLocalEqNums;
+ STree_Insert( doneSet, tmpArray + ii );
+ nLocalEqNums++;
+ }
+ }
+ lastOwnedEqNum = -1; /* Don't need this anymore. */
+ FreeArray( tmpArray );
+ NewClass_Delete( doneSet );
+
+ /* Transfer remote equation numbers. */
+ sync = Mesh_GetSync( self->feMesh, (MeshTopology_Dim)0 );
+ Sync_SyncArray( sync, dstArray[0], nDofs * sizeof(int),
+ dstArray[0] + nLocals * nDofs, nDofs * sizeof(int),
+ nDofs * sizeof(int) );
+
+ /* Allocate for location matrix. */
+ /* first store nDomainEls for usage during destroy */
+ self->nDomainEls = Mesh_GetDomainSize( self->feMesh, (MeshTopology_Dim)nDims );
+ locMat = AllocArray( int**, self->nDomainEls );
+ for( ii = 0; ii < (int)(self->nDomainEls); ii++ )
+ locMat[ii] = AllocArray2D( int, FeMesh_GetElementNodeSize( self->feMesh, 0 ), nDofs );
+
+ /* Fill in location matrix. */
+ inc = IArray_New();
+ for( ii = 0; ii < (int)Mesh_GetDomainSize( self->feMesh, (MeshTopology_Dim)nDims ); ii++ ) {
+ FeMesh_GetElementNodes( self->feMesh, ii, inc );
+ elNodes = IArray_GetPtr( inc );
+ for( jj = 0; jj < (int)FeMesh_GetElementNodeSize( self->feMesh, 0 ); jj++ ) {
+ for( kk = 0; kk < nDofs; kk++ )
+ locMat[ii][jj][kk] = dstArray[elNodes[jj]][kk];
+ }
+ }
+ NewClass_Delete( inc );
+
+ /* Fill in our other weird values. */
+ self->destinationArray = dstArray;
+ self->locationMatrix = locMat;
+ self->locationMatrixBuilt = True;
+ self->remappingActivated = False;
+ self->localEqNumsOwnedCount = nLocalEqNums;
+
+ /* Bcast global sum from highest rank. */
+ self->globalSumUnconstrainedDofs = nEqNums;
+
+ /* Construct lowest global equation number list. */
+ self->_lowestGlobalEqNums = AllocArray( int, nRanks );
+ MPI_Allgather( &self->_lowestLocalEqNum, 1, MPI_UNSIGNED,
+ self->_lowestGlobalEqNums, 1, MPI_UNSIGNED,
+ mpiComm );
+
+ FreeArray( locals );
+
+ /*
+ printf( "%d: localEqNumsOwned = %d\n", rank, self->localEqNumsOwnedCount );
+ printf( "%d: globalSumUnconstrainedDofs = %d\n", rank, self->globalSumUnconstrainedDofs );
+ */
+}
+
+
+
+
+/*
+
+Input:
+ nlocal - number of locally ownded nodes
+ g_node_id - global indices of nodes owned locally. Size nlocal
+ dof - degrees of freedom per node
+ nglobal - number of global nodes
+ npx - number of consider to be periodic in x (local to this proc)
+ npy - number of consider to be periodic in y (local to this proc)
+ periodic_x_gnode_id - global indices of nodes (on this proc) which are on right hand side boundary
+ periodic_y_gnode_id - global indices of nodes (on this proc) which are on top boundary
+ eqnums - contains any dirichlet boundary conditions. Size nlocal*dof
+
+Output;
+ eqnums - contains full list of eqnums
+
+Assumptions:
+- Ordering eqnums[] = { (node_0,[dof_0,dof_1,..,dof_x]), (node_1,[dof_0,dof_1,..,dof_x]), ... }
+- Any dirichlet set along a boundary deemed to be periodic will be clobbered.
+- Processors may have duplicate nodes in the g_node_id[] list.
+- A number in the corner is considered part of both boundaries (horiz and vert)
+- If npx is not 0, then periodicity is assumed in x
+- If npy is not 0, then periodicity is assumed in y
+- Dofs constrained to be dirichlet must be marked with a negative number.
+- Dofs are NOT split across processors.
+- We can define a logical i,j,k ordering to uniquely identify nodes.
+
+*/
+
+PetscErrorCode _VecScatterBeginEnd( VecScatter vscat, Vec FROM, Vec TO, InsertMode addv,ScatterMode mode )
+{
+#if( (PETSC_VERSION_MAJOR==2) && (PETSC_VERSION_MINOR==3) && (PETSC_VERSION_SUBMINOR==2) )
+ // 2.3.2 ordering of args
+ VecScatterBegin( FROM, TO, addv, mode, vscat );
+ VecScatterEnd( FROM, TO, addv, mode, vscat );
+#else
+ // 2.3.3 or 3.0.0
+ VecScatterBegin( vscat, FROM, TO, addv, mode );
+ VecScatterEnd( vscat, FROM, TO, addv, mode );
+#endif
+
+ PetscFunctionReturn(0);
+}
+
+int GenerateEquationNumbering(
+ int NX, int NY, int NZ,
+ int nlocal, int g_node_id[],
+ int dof, int nglobal,
+ PetscTruth periodic_x, PetscTruth periodic_y, PetscTruth periodic_z,
+ int npx, int npy, int npz,
+ int periodic_x_gnode_id[], int periodic_y_gnode_id[], int periodic_z_gnode_id[],
+ int eqnums[], int *neqnums )
+{
+ PetscErrorCode ierr;
+ PetscInt periodic_mask;
+ Vec global_eqnum, g_ownership;
+ PetscInt i;
+ PetscMPIInt rank; /* processor rank */
+ PetscMPIInt size; /* size of communicator */
+ Vec local_ownership, local_eqnum;
+ PetscInt *_g_node_id;
+ IS is_gnode, is_eqnum;
+ VecScatter vscat_ownership, vscat_eqnum;
+ PetscScalar *_local_ownership, *_local_eqnum;
+ PetscInt local_eqnum_count,global_eqnum_count;
+ PetscScalar val[10];
+ PetscInt d,idx[10];
+ PetscInt *to_fetch,cnt,number_to_fetch;
+ PetscInt eq_cnt;
+ Vec offset_list;
+ VecScatter vscat_offset;
+ Vec seq_offset_list;
+ PetscInt offset, inc;
+
+ PetscInt spanx,spany,spanz,total;
+ PetscInt loc;
+ PetscReal max;
+ PetscInt n_inserts;
+
+
+ ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr);
+ ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr);
+
+ if( dof>=10 ) {
+ SETERRQ(PETSC_ERR_SUP, "Max allowable degrees of freedom per node = 10. Change static size" );
+ }
+
+
+ /*
+ Claim locally owned nodes. Duplicate nodes on the interior will be resolved by the processor
+ which inserts last.
+ */
+ VecCreate( PETSC_COMM_WORLD, &g_ownership );
+ VecSetSizes( g_ownership, PETSC_DECIDE, nglobal );
+ VecSetFromOptions( g_ownership );
+
+ for( i=0; i<nlocal; i++ ) {
+ VecSetValue( g_ownership, g_node_id[i], rank, INSERT_VALUES );
+ }
+ VecAssemblyBegin(g_ownership);
+ VecAssemblyEnd(g_ownership);
+
+
+ /* Mask out the periodic boundaries. */
+ periodic_mask = -6699.0;
+ if (periodic_x_gnode_id!=NULL) {
+ for( i=0; i<npx; i++ ) {
+ VecSetValue( g_ownership, periodic_x_gnode_id[i], periodic_mask, INSERT_VALUES );
+ }
+ }
+ if (periodic_y_gnode_id!=NULL) {
+ for( i=0; i<npy; i++ ) {
+ VecSetValue( g_ownership, periodic_y_gnode_id[i], periodic_mask, INSERT_VALUES );
+ }
+ }
+ if (periodic_z_gnode_id!=NULL) {
+ for( i=0; i<npz; i++ ) {
+ VecSetValue( g_ownership, periodic_z_gnode_id[i], periodic_mask, INSERT_VALUES );
+ }
+ }
+ VecAssemblyBegin(g_ownership);
+ VecAssemblyEnd(g_ownership);
+
+ /*
+ PetscPrintf(PETSC_COMM_WORLD, "g_ownership \n");
+ VecView( g_ownership, PETSC_VIEWER_STDOUT_WORLD );
+ */
+
+ /* Get all locally owned nodes */
+ VecCreate( PETSC_COMM_SELF, &local_ownership );
+ VecSetSizes( local_ownership, PETSC_DECIDE, nlocal );
+ VecSetFromOptions( local_ownership );
+
+ PetscMalloc( sizeof(PetscInt)*nlocal, &_g_node_id);
+ for( i=0; i<nlocal; i++ ) {
+ _g_node_id[i] = g_node_id[i];
+ }
+ ISCreateGeneralWithArray( PETSC_COMM_WORLD, nlocal, _g_node_id, &is_gnode );
+ VecScatterCreate( g_ownership, is_gnode, local_ownership, PETSC_NULL, &vscat_ownership );
+
+
+ /* assign unique equation numbers */
+ VecSet( local_ownership, -6699 );
+ _VecScatterBeginEnd( vscat_ownership, g_ownership, local_ownership, INSERT_VALUES, SCATTER_FORWARD );
+
+
+ /* Count instances of rank in the local_ownership vector */
+ VecGetArray( local_ownership, &_local_ownership );
+ local_eqnum_count = 0;
+ for( i=0; i<nlocal; i++ ) {
+ if( ((PetscInt)_local_ownership[i]) == rank ) {
+ local_eqnum_count++;
+ }
+ }
+
+ MPI_Allreduce( &local_eqnum_count, &global_eqnum_count, 1, MPI_INT, MPI_SUM, PETSC_COMM_WORLD );
+ /* PetscPrintf( PETSC_COMM_SELF,
+ "[%d] number of local,global equations (without dofs) %d,%d \n", rank, local_eqnum_count, global_eqnum_count ); */
+ /* check */
+ spanx = NX;
+ spany = NY;
+ spanz = NZ;
+ if( periodic_x==PETSC_TRUE ) {
+ spanx--;
+ }
+ if( periodic_y==PETSC_TRUE ) {
+ spany--;
+ }
+ if( periodic_z==PETSC_TRUE ) {
+ spanz--;
+ }
+ total = spanx*spany*spanz;
+ if( total!=global_eqnum_count ) {
+ SETERRQ(PETSC_ERR_SUP, "Something stinks. Computed global size for nodes does not match expected" );
+ }
+
+
+
+ VecCreate( PETSC_COMM_WORLD, &global_eqnum );
+ VecSetSizes( global_eqnum, PETSC_DECIDE, nglobal*dof );
+ VecSetFromOptions( global_eqnum );
+ VecSet( global_eqnum, 0.0 );
+
+ /* Load existing eqnums in */
+ for( i=0; i<nlocal; i++ ) {
+ n_inserts = 0;
+ for( d=0; d<dof; d++ ) {
+/*
+ idx[d] = -(g_node_id[i]*dof + d);
+ val[d] = 0.0;
+*/
+ if( eqnums[ i*dof + d ] < 0.0 ) {
+ idx[n_inserts] = g_node_id[i]*dof + d;
+ val[n_inserts] = eqnums[ i*dof + d ];
+ n_inserts++;
+ }
+ }
+ /* only insert dirichlet bc's */
+ VecSetValues( global_eqnum, n_inserts, idx, val, INSERT_VALUES );
+ }
+ VecAssemblyBegin(global_eqnum);
+ VecAssemblyEnd(global_eqnum);
+
+
+
+
+
+ /* Generate list of eqnums to get */
+ PetscMalloc( sizeof(PetscInt)*nlocal*dof, &to_fetch );
+ cnt = 0;
+ for( i=0; i<nlocal; i++ ) {
+ if( _local_ownership[i]==rank ) {
+ for( d=0; d<dof; d++ ) {
+ to_fetch[cnt] = g_node_id[i]*dof + d;
+ cnt++;
+ }
+ }
+ }
+ number_to_fetch = cnt;
+
+
+ VecCreate( PETSC_COMM_SELF, &local_eqnum );
+ VecSetSizes( local_eqnum, PETSC_DECIDE, number_to_fetch);
+ VecSetFromOptions( local_eqnum );
+
+ ISCreateGeneralWithArray( PETSC_COMM_SELF, number_to_fetch, to_fetch, &is_eqnum );
+ VecScatterCreate( global_eqnum, is_eqnum, local_eqnum, PETSC_NULL, &vscat_eqnum );
+
+ VecSet( local_eqnum, -6699 );
+ _VecScatterBeginEnd( vscat_eqnum, global_eqnum, local_eqnum, INSERT_VALUES, SCATTER_FORWARD );
+
+
+ /* compute offset */
+ /* count how many entries there are */
+ VecGetArray( local_eqnum, &_local_eqnum );
+ eq_cnt = 0;
+ for( i=0; i<number_to_fetch; i++ ) {
+ if( (PetscInt)_local_eqnum[i]==0 ) {
+ eq_cnt++;
+ }
+ }
+ VecRestoreArray( local_eqnum, &_local_eqnum );
+
+ VecCreate( PETSC_COMM_WORLD, &offset_list );
+ VecSetSizes( offset_list, PETSC_DECIDE, (size+1) );
+ VecSetFromOptions( offset_list );
+ for( i=rank; i<size; i++ ) {
+ VecSetValue( offset_list, i+1, eq_cnt, ADD_VALUES );
+ }
+ VecAssemblyBegin(offset_list);
+ VecAssemblyEnd(offset_list);
+ /*
+ PetscPrintf(PETSC_COMM_WORLD, "offset_list \n");
+ VecView( offset_list, PETSC_VIEWER_STDOUT_WORLD );
+ */
+
+ VecScatterCreateToAll(offset_list,&vscat_offset,&seq_offset_list);
+ _VecScatterBeginEnd( vscat_offset, offset_list, seq_offset_list, INSERT_VALUES, SCATTER_FORWARD );
+
+ {
+ PetscScalar *_seq_offset_list;
+
+ VecGetArray( seq_offset_list, &_seq_offset_list );
+ offset = _seq_offset_list[ rank ];
+ VecRestoreArray( seq_offset_list, &_seq_offset_list );
+ }
+ VecScatterDestroy(vscat_offset);
+ VecDestroy(offset_list);
+ VecDestroy(seq_offset_list);
+
+ /* PetscPrintf( PETSC_COMM_SELF, "[%d]: offset = %d \n", rank, offset ); */
+
+
+ VecGetArray( local_eqnum, &_local_eqnum );
+ inc = 0;
+ for( i=0; i<number_to_fetch; i++ ) {
+ if( (PetscInt)_local_eqnum[i]==0 ) {
+ _local_eqnum[i] = offset+inc;
+ inc++;
+ }
+ }
+ VecRestoreArray( local_eqnum, &_local_eqnum );
+
+ _VecScatterBeginEnd( vscat_eqnum, local_eqnum, global_eqnum, INSERT_VALUES, SCATTER_REVERSE );
+ /*
+ PetscPrintf(PETSC_COMM_WORLD, "global_eqnum \n");
+ VecView( global_eqnum, PETSC_VIEWER_STDOUT_WORLD );
+ */
+
+ /* For each periodic boundary, get the mapped nodes */
+
+ if( periodic_x==PETSC_TRUE ) {
+ VecScatter vscat_p;
+ IS is_from;
+ PetscInt *from, *to;
+ Vec mapped;
+ PetscScalar *_mapped;
+ PetscInt c;
+
+ PetscMalloc( sizeof(PetscInt)*npx*dof, &from );
+ PetscMalloc( sizeof(PetscInt)*npx*dof, &to );
+
+ c = 0;
+ for( i=0; i<npx; i++ ) {
+ PetscInt I,J,K,gid,from_gid;
+
+ gid = periodic_x_gnode_id[i];
+ K = gid/(NX*NY);
+ J = (gid - K*(NX*NY))/NX;
+ I = gid - K*(NX*NY) - J*NX;
+ from_gid = (I-(NX-1)) + J*NX + K*(NX*NY);
+
+ for( d=0; d<dof; d++ ) {
+ to[c] = gid * dof + d;
+ from[c] = from_gid * dof + d;
+ c++;
+ }
+ }
+
+
+ VecCreate( PETSC_COMM_SELF, &mapped );
+ VecSetSizes( mapped, PETSC_DECIDE, npx*dof );
+ VecSetFromOptions( mapped );
+
+ ISCreateGeneralWithArray( PETSC_COMM_SELF, npx*dof, from, &is_from );
+ VecScatterCreate( global_eqnum, is_from, mapped, PETSC_NULL, &vscat_p );
+
+ _VecScatterBeginEnd( vscat_p, global_eqnum, mapped, INSERT_VALUES, SCATTER_FORWARD );
+ if( npx>0 ) {
+ VecGetArray( mapped, &_mapped );
+ VecSetValues( global_eqnum, npx*dof, to, _mapped, INSERT_VALUES );
+ VecRestoreArray( mapped, &_mapped );
+ }
+
+ VecAssemblyBegin(global_eqnum);
+ VecAssemblyEnd(global_eqnum);
+
+ VecScatterDestroy( vscat_p );
+ ISDestroy( is_from );
+ VecDestroy( mapped );
+ PetscFree( from );
+ PetscFree( to );
+ }
+
+
+ if( periodic_y==PETSC_TRUE ) {
+ VecScatter vscat_p;
+ IS is_from;
+ PetscInt *from, *to;
+ Vec mapped;
+ PetscScalar *_mapped;
+ PetscInt c;
+
+ PetscMalloc( sizeof(PetscInt)*npy*dof, &from );
+ PetscMalloc( sizeof(PetscInt)*npy*dof, &to );
+
+ c = 0;
+ for( i=0; i<npy; i++ ) {
+ PetscInt I,J,K,gid,from_gid;
+
+ gid = periodic_y_gnode_id[i];
+ K = gid/(NX*NY);
+ J = (gid - K*(NX*NY))/NX;
+ I = gid - K*(NX*NY) - J*NX;
+ from_gid = I + (J - (NY - 1))*NX + K*(NX*NY);
+
+ for( d=0; d<dof; d++ ) {
+ to[c] = gid * dof + d;
+ from[c] = from_gid * dof + d;
+ c++;
+ }
+ }
+
+
+ VecCreate( PETSC_COMM_SELF, &mapped );
+ VecSetSizes( mapped, PETSC_DECIDE, npy*dof );
+ VecSetFromOptions( mapped );
+
+ ISCreateGeneralWithArray( PETSC_COMM_SELF, npy*dof, from, &is_from );
+ VecScatterCreate( global_eqnum, is_from, mapped, PETSC_NULL, &vscat_p );
+
+ _VecScatterBeginEnd( vscat_p, global_eqnum, mapped, INSERT_VALUES, SCATTER_FORWARD );
+ if( npy>0 ) {
+ VecGetArray( mapped, &_mapped );
+ VecSetValues( global_eqnum, npy*dof, to, _mapped, INSERT_VALUES );
+ VecRestoreArray( mapped, &_mapped );
+ }
+
+ VecAssemblyBegin(global_eqnum);
+ VecAssemblyEnd(global_eqnum);
+
+ VecScatterDestroy( vscat_p );
+ ISDestroy( is_from );
+ VecDestroy( mapped );
+ PetscFree( from );
+ PetscFree( to );
+ }
+
+ if( periodic_z==PETSC_TRUE ) {
+ VecScatter vscat_p;
+ IS is_from;
+ PetscInt *from, *to;
+ Vec mapped;
+ PetscScalar *_mapped;
+ PetscInt c;
+
+ PetscMalloc( sizeof(PetscInt)*npz*dof, &from );
+ PetscMalloc( sizeof(PetscInt)*npz*dof, &to );
+
+ c = 0;
+ for( i=0; i<npz; i++ ) {
+ PetscInt I,J,K,gid,from_gid;
+
+ gid = periodic_z_gnode_id[i];
+ K = gid/(NX*NY);
+ J = (gid - K*(NX*NY))/NX;
+ I = gid - K*(NX*NY) - J*NX;
+ from_gid = I + J*NX + (K - (NZ-1))*(NX*NY);
+
+ for( d=0; d<dof; d++ ) {
+ to[c] = gid * dof + d;
+ from[c] = from_gid * dof + d;
+ c++;
+ }
+ }
+
+
+ VecCreate( PETSC_COMM_SELF, &mapped );
+ VecSetSizes( mapped, PETSC_DECIDE, npz*dof );
+ VecSetFromOptions( mapped );
+
+ ISCreateGeneralWithArray( PETSC_COMM_SELF, npz*dof, from, &is_from );
+ VecScatterCreate( global_eqnum, is_from, mapped, PETSC_NULL, &vscat_p );
+
+ _VecScatterBeginEnd( vscat_p, global_eqnum, mapped, INSERT_VALUES, SCATTER_FORWARD );
+ if( npz>0 ) {
+ VecGetArray( mapped, &_mapped );
+ VecSetValues( global_eqnum, npz*dof, to, _mapped, INSERT_VALUES );
+ VecRestoreArray( mapped, &_mapped );
+ }
+
+ VecAssemblyBegin(global_eqnum);
+ VecAssemblyEnd(global_eqnum);
+
+ VecScatterDestroy( vscat_p );
+ ISDestroy( is_from );
+ VecDestroy( mapped );
+ PetscFree( from );
+ PetscFree( to );
+ }
+
+
+ /*
+ PetscPrintf(PETSC_COMM_WORLD, "global_eqnum following periodic \n");
+ VecView( global_eqnum, PETSC_VIEWER_STDOUT_WORLD );
+ */
+
+
+ /* Finally, scatter stuff from global_eqnums into MY array */
+ {
+ IS is_all_my_eqnums;
+ PetscInt *all_my_eqnum_index;
+ PetscInt _I,_D,CNT;
+ Vec all_my_eqnums;
+ PetscScalar *_all_my_eqnums;
+ VecScatter vscat_p;
+
+ PetscMalloc( sizeof(PetscInt)*dof*nlocal, &all_my_eqnum_index );
+
+ CNT = 0;
+ for( _I=0; _I<nlocal; _I++ ) {
+ for( _D=0; _D<dof; _D++ ) {
+ all_my_eqnum_index[CNT] = g_node_id[_I]*dof + _D;
+ CNT++;
+ }
+ }
+
+ ISCreateGeneralWithArray( PETSC_COMM_SELF, nlocal*dof, all_my_eqnum_index, &is_all_my_eqnums );
+ VecCreate( PETSC_COMM_SELF, &all_my_eqnums );
+ VecSetSizes( all_my_eqnums, PETSC_DECIDE, nlocal*dof );
+ VecSetFromOptions( all_my_eqnums );
+ VecScatterCreate( global_eqnum, is_all_my_eqnums, all_my_eqnums, PETSC_NULL, &vscat_p );
+ _VecScatterBeginEnd( vscat_p, global_eqnum, all_my_eqnums, INSERT_VALUES, SCATTER_FORWARD );
+ VecGetArray( all_my_eqnums, &_all_my_eqnums );
+
+ for( i=0; i<nlocal*dof; i++ ) {
+ eqnums[i] = (int)_all_my_eqnums[i];
+ }
+ VecRestoreArray( all_my_eqnums, &_all_my_eqnums );
+
+ VecScatterDestroy( vscat_p );
+ VecDestroy( all_my_eqnums );
+ ISDestroy( is_all_my_eqnums );
+ PetscFree( all_my_eqnum_index );
+ }
+
+ VecMax( global_eqnum, &loc, &max );
+ *neqnums = (int)max;
+ (*neqnums)++;
+
+ /* tidy up */
+ VecRestoreArray( local_ownership, &_local_ownership );
+
+
+ VecDestroy( g_ownership );
+ VecDestroy( local_ownership );
+ PetscFree( _g_node_id );
+ ISDestroy( is_gnode );
+ VecScatterDestroy( vscat_ownership );
+
+ VecDestroy( global_eqnum );
+ VecDestroy( local_eqnum );
+ PetscFree( to_fetch );
+ ISDestroy( is_eqnum );
+ VecScatterDestroy( vscat_eqnum );
+
+ return 0;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FeMesh.c
--- a/Discretisation/src/FeMesh.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,453 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: FeMesh.c 992 2008-01-03 04:46:19Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <mpi.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "Discretisation.h"
-
-
-/* Textual name of this class */
-const Type FeMesh_Type = "FeMesh";
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-FeMesh* FeMesh_New( Name name, AbstractContext* context ) {
- FeMesh* self = _FeMesh_DefaultNew( name );
- _Mesh_Init( (Mesh*)self, context );
- /* FeMesh info */
- _FeMesh_Init( self, NULL, NULL, False ); /* this is a useless Init() */
-
- return self;
-}
-
-FeMesh* _FeMesh_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(FeMesh);
- Type type = FeMesh_Type;
- Stg_Class_DeleteFunction* _delete = _FeMesh_Delete;
- Stg_Class_PrintFunction* _print = _FeMesh_Print;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_FeMesh_New;
- Stg_Component_ConstructFunction* _construct = _FeMesh_AssignFromXML;
- Stg_Component_BuildFunction* _build = _FeMesh_Build;
- Stg_Component_InitialiseFunction* _initialise = _FeMesh_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FeMesh_Execute;
- Stg_Component_DestroyFunction* _destroy = _FeMesh_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
-
- /* The following terms are parameters that have been passed into or defined in this function but are being set before being passed onto the parent */
- Stg_Class_CopyFunction* _copy = NULL;
-
- return _FeMesh_New( FEMESH_PASSARGS );
-}
-
-FeMesh* _FeMesh_New( FEMESH_DEFARGS ) {
- FeMesh* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(FeMesh) );
- self = (FeMesh*)_Mesh_New( MESH_PASSARGS );
-
- return self;
-}
-
-void _FeMesh_Init( FeMesh* self, ElementType* elType, Name family, Bool elementMesh ) {
- Stream* stream;
-
- assert( self && Stg_CheckType( self, FeMesh ) );
-
- stream = Journal_Register( Info_Type, (Name)self->type );
- Stream_SetPrintingRank( stream, 0 );
-
- self->feElType = elType;
- self->feElFamily = family;
- self->elementMesh = elementMesh;
-
- /* checkpoint non-constant meshes */
- if ( self->feElFamily && strcmp( self->feElFamily, "constant" ) ){
- self->isCheckpointedAndReloaded = True;
- self->requiresCheckpointing = True;
- }
-
- self->inc = IArray_New();
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _FeMesh_Delete( void* feMesh ) {
- FeMesh* self = (FeMesh*)feMesh;
- /* Delete the parent. */
- _Mesh_Delete( self );
-}
-
-void _FeMesh_Print( void* feMesh, Stream* stream ) {
- FeMesh* self = (FeMesh*)feMesh;
-
- /* Set the Journal for printing informations */
- Stream* feMeshStream;
- feMeshStream = Journal_Register( InfoStream_Type, (Name)"FeMeshStream" );
-
- /* Print parent */
- Journal_Printf( stream, "FeMesh (ptr): (%p)\n", self );
- _Mesh_Print( self, stream );
-}
-
-void _FeMesh_AssignFromXML( void* feMesh, Stg_ComponentFactory* cf, void* data ) {
- FeMesh* self = (FeMesh*)feMesh;
-
- assert( self );
-
- _Mesh_AssignFromXML( self, cf, data );
-
- _FeMesh_Init( self, NULL, Stg_ComponentFactory_GetString( cf, self->name, (Dictionary_Entry_Key)"elementType", "linear" ),
- Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"isElementMesh", False ) );
-}
-
-void _FeMesh_Build( void* feMesh, void* data ) {
- FeMesh* self = (FeMesh*)feMesh;
- Stream* stream;
- ElementType* elType;
-
- assert( self );
-
- stream = Journal_Register( Info_Type, (Name)self->type );
-
- _Mesh_Build( self, data );
-
- Stream_Indent( stream );
- Journal_Printf( stream, "Assigning FeMesh element types...\n" );
- Stream_Indent( stream );
-
- if( !strcmp( self->feElFamily, "quadratic" ) ) {
- unsigned nDims;
-
- nDims = Mesh_GetDimSize( self );
- if( nDims == 3 )
- elType = (ElementType*)Triquadratic_New( "" );
- else if( nDims == 2 )
- elType = (ElementType*)Biquadratic_New( "" );
- else
- abort();
- }
- else if( !strcmp( self->feElFamily, "linear" ) ) {
- unsigned nDims;
-
- nDims = Mesh_GetDimSize( self );
- if( nDims == 3 )
- elType = (ElementType*)TrilinearElementType_New( "" );
- else if( nDims == 2 )
- elType = (ElementType*)BilinearElementType_New( "" );
- else
- abort();
- }
- else if( !strcmp( self->feElFamily, "linear-regular" ) ) {
- unsigned nDims;
-
- nDims = Mesh_GetDimSize( self );
- if( nDims == 3 )
- elType = (ElementType*)RegularTrilinear_New( "" );
- else if( nDims == 2 )
- elType = (ElementType*)RegularBilinear_New( "" );
- else
- abort();
- }
- else if( !strcmp( self->feElFamily, "linear-inner" ) ) {
- unsigned nDims;
-
- nDims = Mesh_GetDimSize( self );
- if( nDims == 3 )
- elType = (ElementType*)TrilinearInnerElType_New( "" );
- else if( nDims == 2 )
- elType = (ElementType*)BilinearInnerElType_New( "" );
- else
- abort();
- }
- else if( !strcmp( self->feElFamily, "constant" ) ) {
- elType = (ElementType*)ConstantElementType_New( "" );
- }
- else if( !strcmp( self->feElFamily, "p1" ) ) {
- elType = (ElementType*)P1_New( "" );
- }
- else
- abort();
- FeMesh_SetElementType( self, elType );
- if( self->feElType )
- Stg_Component_Build( self->feElType, data, False );
-
- /*
- ** Reset the element type to FeMesh_ElementType.
- **/
-
- if( self->elementMesh ) {
- Stg_Class_Delete( self->algorithms );
- self->algorithms = (Mesh_Algorithms*)FeMesh_Algorithms_New( "", NULL );
- Mesh_Algorithms_SetMesh( self->algorithms, self );
- Mesh_Algorithms_Update( self->algorithms );
-
- Stg_Class_Delete( self->elTypes[0] );
- self->elTypes[0] = (Mesh_ElementType*)FeMesh_ElementType_New();
- Mesh_ElementType_SetMesh( self->elTypes[0], self );
- Mesh_ElementType_Update( self->elTypes[0] );
- }
-
- Journal_Printf( stream, "... FE element types are '%s',\n", elType->type );
- Journal_Printf( stream, "... done.\n" );
- Stream_UnIndent( stream );
- Stream_UnIndent( stream );
-}
-
-void _FeMesh_Initialise( void* feMesh, void* data ) {
- FeMesh* self = (FeMesh*)feMesh;
-
- assert( self );
-
- _Mesh_Initialise( self, data );
-
- if( self->feElType )
- Stg_Component_Initialise( self->feElType, data, False );
-}
-
-void _FeMesh_Execute( void* feMesh, void* data ) {
-}
-
-void _FeMesh_Destroy( void* feMesh, void* data ) {
- FeMesh* self = (FeMesh*)feMesh;
-
- FeMesh_Destruct( self );
- NewClass_Delete( self->inc );
- _Mesh_Destroy( self, data );
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-void FeMesh_SetElementType( void* feMesh, ElementType* elType ) {
- FeMesh* self = (FeMesh*)feMesh;
-
- assert( self );
-
- if( self->feElType ) Stg_Class_Delete( self->feElType );
- self->feElType = elType;
-}
-
-void FeMesh_SetElementFamily( void* feMesh, Name family ) {
- FeMesh* self = (FeMesh*)feMesh;
-
- assert( self );
-
- self->feElFamily = family;
-}
-
-ElementType* FeMesh_GetElementType( void* feMesh, unsigned element ) {
- FeMesh* self = (FeMesh*)feMesh;
-
- assert( self );
-
- return self->feElType;
-}
-
-unsigned FeMesh_GetNodeLocalSize( void* feMesh ) {
- return Mesh_GetLocalSize( feMesh, MT_VERTEX );
-}
-
-unsigned FeMesh_GetNodeRemoteSize( void* feMesh ) {
- return Mesh_GetRemoteSize( feMesh, MT_VERTEX );
-}
-
-unsigned FeMesh_GetNodeDomainSize( void* feMesh ) {
- return Mesh_GetDomainSize( feMesh, MT_VERTEX );
-}
-
-unsigned FeMesh_GetNodeGlobalSize( void* feMesh ) {
- return Mesh_GetGlobalSize( feMesh, MT_VERTEX );
-}
-
-unsigned FeMesh_GetElementLocalSize( void* feMesh ) {
- return Mesh_GetLocalSize( feMesh, Mesh_GetDimSize( feMesh ) );
-}
-
-unsigned FeMesh_GetElementRemoteSize( void* feMesh ) {
- return Mesh_GetRemoteSize( feMesh, Mesh_GetDimSize( feMesh ) );
-}
-
-unsigned FeMesh_GetElementDomainSize( void* feMesh ) {
- return Mesh_GetDomainSize( feMesh, Mesh_GetDimSize( feMesh ) );
-}
-
-unsigned FeMesh_GetElementGlobalSize( void* feMesh ) {
- return Mesh_GetGlobalSize( feMesh, Mesh_GetDimSize( feMesh ) );
-}
-
-unsigned FeMesh_GetElementNodeSize( void* feMesh, unsigned element ) {
- return Mesh_GetIncidenceSize( feMesh, Mesh_GetDimSize( feMesh ), element, MT_VERTEX );
-}
-
-unsigned FeMesh_GetNodeElementSize( void* feMesh, unsigned node ) {
- return Mesh_GetIncidenceSize( feMesh, MT_VERTEX, node, Mesh_GetDimSize( feMesh ) );
-}
-
-void FeMesh_GetElementNodes( void* feMesh, unsigned element, IArray* inc ) {
- Mesh_GetIncidence( feMesh, Mesh_GetDimSize( feMesh ), element, MT_VERTEX, inc );
-}
-
-void FeMesh_GetNodeElements( void* feMesh, unsigned node, IArray* inc ) {
- Mesh_GetIncidence( feMesh, MT_VERTEX, node, Mesh_GetDimSize( feMesh ), inc );
-}
-
-unsigned FeMesh_ElementDomainToGlobal( void* feMesh, unsigned domain ) {
- return Mesh_DomainToGlobal( feMesh, Mesh_GetDimSize( feMesh ), domain );
-}
-
-Bool FeMesh_ElementGlobalToDomain( void* feMesh, unsigned global, unsigned* domain ) {
- return Mesh_GlobalToDomain( feMesh, Mesh_GetDimSize( feMesh ), global, domain );
-}
-
-unsigned FeMesh_NodeDomainToGlobal( void* feMesh, unsigned domain ) {
- return Mesh_DomainToGlobal( feMesh, MT_VERTEX, domain );
-}
-
-Bool FeMesh_NodeGlobalToDomain( void* feMesh, unsigned global, unsigned* domain ) {
- return Mesh_GlobalToDomain( feMesh, MT_VERTEX, global, domain );
-}
-
-void FeMesh_CoordGlobalToLocal( void* feMesh, unsigned element, double* global, double* local ) {
- FeMesh* self = (FeMesh*)feMesh;
- ElementType* elType;
-
- assert( self );
- assert( element < FeMesh_GetElementDomainSize( self ) );
- assert( global );
- assert( local );
-
- elType = FeMesh_GetElementType( self, element );
- ElementType_ConvertGlobalCoordToElLocal( elType, self, element, global, local );
-}
-
-void FeMesh_CoordLocalToGlobal( void* feMesh, unsigned element, double* local, double* global ) {
- FeMesh* self = (FeMesh*)feMesh;
- unsigned nDims;
- ElementType* elType;
- double* basis;
- unsigned nElNodes, *elNodes;
- double dimBasis;
- double* vert;
- unsigned n_i, d_i;
-
- assert( self );
- assert( element < FeMesh_GetElementDomainSize( self ) );
- assert( global );
- assert( local );
-
- nDims = Mesh_GetDimSize( self );
- elType = FeMesh_GetElementType( self, element );
- FeMesh_GetElementNodes( self, element, self->inc );
- nElNodes = IArray_GetSize( self->inc );
- elNodes = (unsigned*)IArray_GetPtr( self->inc );
- basis = AllocArray( double, nElNodes );
- ElementType_EvaluateShapeFunctionsAt( elType, local, basis );
-
- memset( global, 0, nDims * sizeof(double) );
- for( n_i = 0; n_i < nElNodes; n_i++ ) {
- dimBasis = basis[n_i];
- vert = Mesh_GetVertex( self, elNodes[n_i] );
- for( d_i = 0; d_i < nDims; d_i++ )
- global[d_i] += dimBasis * vert[d_i];
- }
-
- FreeArray( basis );
-}
-
-void FeMesh_EvalBasis( void* feMesh, unsigned element, double* localCoord, double* basis ) {
- FeMesh* self = (FeMesh*)feMesh;
- ElementType* elType;
-
- assert( self );
- assert( localCoord );
-
- elType = FeMesh_GetElementType( self, element );
- ElementType_EvaluateShapeFunctionsAt( elType, localCoord, basis );
-}
-
-void FeMesh_EvalLocalDerivs( void* feMesh, unsigned element, double* localCoord, double** derivs ) {
- FeMesh* self = (FeMesh*)feMesh;
- ElementType* elType;
-
- assert( self );
- assert( localCoord );
- assert( derivs );
-
- elType = FeMesh_GetElementType( self, element );
- ElementType_EvaluateShapeFunctionLocalDerivsAt( elType, localCoord, derivs );
-}
-
-void FeMesh_EvalGlobalDerivs( void* feMesh, unsigned element, double* localCoord, double** derivs, double* jacDet ) {
- FeMesh* self = (FeMesh*)feMesh;
- unsigned nDims;
- ElementType* elType;
- double jd;
-
- assert( self );
- assert( localCoord );
- assert( derivs );
-
- nDims = Mesh_GetDimSize( self );
- elType = FeMesh_GetElementType( self, element );
- ElementType_ShapeFunctionsGlobalDerivs( elType, self, element, localCoord, nDims,
- &jd, derivs );
- if( jacDet )
- *jacDet = jd;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-void FeMesh_Destruct( FeMesh* self ) {
- Stg_Class_Delete( self->feElType );
- self->feElFamily = NULL;
- /* Disabling the killing of this object from within this
- component as this will be destroyed by the LiveComponentRegister_DestroyAll function 101109 */
- /*KillObject( self->feElType );*/
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FeMesh.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/FeMesh.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,453 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: FeMesh.c 992 2008-01-03 04:46:19Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type FeMesh_Type = "FeMesh";
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+FeMesh* FeMesh_New( Name name, AbstractContext* context ) {
+ FeMesh* self = _FeMesh_DefaultNew( name );
+ _Mesh_Init( (Mesh*)self, context );
+ /* FeMesh info */
+ _FeMesh_Init( self, NULL, NULL, False ); /* this is a useless Init() */
+
+ return self;
+}
+
+FeMesh* _FeMesh_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(FeMesh);
+ Type type = FeMesh_Type;
+ Stg_Class_DeleteFunction* _delete = _FeMesh_Delete;
+ Stg_Class_PrintFunction* _print = _FeMesh_Print;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_FeMesh_New;
+ Stg_Component_ConstructFunction* _construct = _FeMesh_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _FeMesh_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FeMesh_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FeMesh_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FeMesh_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+
+ /* The following terms are parameters that have been passed into or defined in this function but are being set before being passed onto the parent */
+ Stg_Class_CopyFunction* _copy = NULL;
+
+ return _FeMesh_New( FEMESH_PASSARGS );
+}
+
+FeMesh* _FeMesh_New( FEMESH_DEFARGS ) {
+ FeMesh* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(FeMesh) );
+ self = (FeMesh*)_Mesh_New( MESH_PASSARGS );
+
+ return self;
+}
+
+void _FeMesh_Init( FeMesh* self, ElementType* elType, Name family, Bool elementMesh ) {
+ Stream* stream;
+
+ assert( self && Stg_CheckType( self, FeMesh ) );
+
+ stream = Journal_Register( Info_Type, (Name)self->type );
+ Stream_SetPrintingRank( stream, 0 );
+
+ self->feElType = elType;
+ self->feElFamily = family;
+ self->elementMesh = elementMesh;
+
+ /* checkpoint non-constant meshes */
+ if ( self->feElFamily && strcmp( self->feElFamily, "constant" ) ){
+ self->isCheckpointedAndReloaded = True;
+ self->requiresCheckpointing = True;
+ }
+
+ self->inc = IArray_New();
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _FeMesh_Delete( void* feMesh ) {
+ FeMesh* self = (FeMesh*)feMesh;
+ /* Delete the parent. */
+ _Mesh_Delete( self );
+}
+
+void _FeMesh_Print( void* feMesh, Stream* stream ) {
+ FeMesh* self = (FeMesh*)feMesh;
+
+ /* Set the Journal for printing informations */
+ Stream* feMeshStream;
+ feMeshStream = Journal_Register( InfoStream_Type, (Name)"FeMeshStream" );
+
+ /* Print parent */
+ Journal_Printf( stream, "FeMesh (ptr): (%p)\n", self );
+ _Mesh_Print( self, stream );
+}
+
+void _FeMesh_AssignFromXML( void* feMesh, Stg_ComponentFactory* cf, void* data ) {
+ FeMesh* self = (FeMesh*)feMesh;
+
+ assert( self );
+
+ _Mesh_AssignFromXML( self, cf, data );
+
+ _FeMesh_Init( self, NULL, Stg_ComponentFactory_GetString( cf, self->name, (Dictionary_Entry_Key)"elementType", "linear" ),
+ Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"isElementMesh", False ) );
+}
+
+void _FeMesh_Build( void* feMesh, void* data ) {
+ FeMesh* self = (FeMesh*)feMesh;
+ Stream* stream;
+ ElementType* elType;
+
+ assert( self );
+
+ stream = Journal_Register( Info_Type, (Name)self->type );
+
+ _Mesh_Build( self, data );
+
+ Stream_Indent( stream );
+ Journal_Printf( stream, "Assigning FeMesh element types...\n" );
+ Stream_Indent( stream );
+
+ if( !strcmp( self->feElFamily, "quadratic" ) ) {
+ unsigned nDims;
+
+ nDims = Mesh_GetDimSize( self );
+ if( nDims == 3 )
+ elType = (ElementType*)Triquadratic_New( "" );
+ else if( nDims == 2 )
+ elType = (ElementType*)Biquadratic_New( "" );
+ else
+ abort();
+ }
+ else if( !strcmp( self->feElFamily, "linear" ) ) {
+ unsigned nDims;
+
+ nDims = Mesh_GetDimSize( self );
+ if( nDims == 3 )
+ elType = (ElementType*)TrilinearElementType_New( "" );
+ else if( nDims == 2 )
+ elType = (ElementType*)BilinearElementType_New( "" );
+ else
+ abort();
+ }
+ else if( !strcmp( self->feElFamily, "linear-regular" ) ) {
+ unsigned nDims;
+
+ nDims = Mesh_GetDimSize( self );
+ if( nDims == 3 )
+ elType = (ElementType*)RegularTrilinear_New( "" );
+ else if( nDims == 2 )
+ elType = (ElementType*)RegularBilinear_New( "" );
+ else
+ abort();
+ }
+ else if( !strcmp( self->feElFamily, "linear-inner" ) ) {
+ unsigned nDims;
+
+ nDims = Mesh_GetDimSize( self );
+ if( nDims == 3 )
+ elType = (ElementType*)TrilinearInnerElType_New( "" );
+ else if( nDims == 2 )
+ elType = (ElementType*)BilinearInnerElType_New( "" );
+ else
+ abort();
+ }
+ else if( !strcmp( self->feElFamily, "constant" ) ) {
+ elType = (ElementType*)ConstantElementType_New( "" );
+ }
+ else if( !strcmp( self->feElFamily, "p1" ) ) {
+ elType = (ElementType*)P1_New( "" );
+ }
+ else
+ abort();
+ FeMesh_SetElementType( self, elType );
+ if( self->feElType )
+ Stg_Component_Build( self->feElType, data, False );
+
+ /*
+ ** Reset the element type to FeMesh_ElementType.
+ **/
+
+ if( self->elementMesh ) {
+ Stg_Class_Delete( self->algorithms );
+ self->algorithms = (Mesh_Algorithms*)FeMesh_Algorithms_New( "", NULL );
+ Mesh_Algorithms_SetMesh( self->algorithms, self );
+ Mesh_Algorithms_Update( self->algorithms );
+
+ Stg_Class_Delete( self->elTypes[0] );
+ self->elTypes[0] = (Mesh_ElementType*)FeMesh_ElementType_New();
+ Mesh_ElementType_SetMesh( self->elTypes[0], self );
+ Mesh_ElementType_Update( self->elTypes[0] );
+ }
+
+ Journal_Printf( stream, "... FE element types are '%s',\n", elType->type );
+ Journal_Printf( stream, "... done.\n" );
+ Stream_UnIndent( stream );
+ Stream_UnIndent( stream );
+}
+
+void _FeMesh_Initialise( void* feMesh, void* data ) {
+ FeMesh* self = (FeMesh*)feMesh;
+
+ assert( self );
+
+ _Mesh_Initialise( self, data );
+
+ if( self->feElType )
+ Stg_Component_Initialise( self->feElType, data, False );
+}
+
+void _FeMesh_Execute( void* feMesh, void* data ) {
+}
+
+void _FeMesh_Destroy( void* feMesh, void* data ) {
+ FeMesh* self = (FeMesh*)feMesh;
+
+ FeMesh_Destruct( self );
+ NewClass_Delete( self->inc );
+ _Mesh_Destroy( self, data );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+void FeMesh_SetElementType( void* feMesh, ElementType* elType ) {
+ FeMesh* self = (FeMesh*)feMesh;
+
+ assert( self );
+
+ if( self->feElType ) Stg_Class_Delete( self->feElType );
+ self->feElType = elType;
+}
+
+void FeMesh_SetElementFamily( void* feMesh, Name family ) {
+ FeMesh* self = (FeMesh*)feMesh;
+
+ assert( self );
+
+ self->feElFamily = family;
+}
+
+ElementType* FeMesh_GetElementType( void* feMesh, unsigned element ) {
+ FeMesh* self = (FeMesh*)feMesh;
+
+ assert( self );
+
+ return self->feElType;
+}
+
+unsigned FeMesh_GetNodeLocalSize( void* feMesh ) {
+ return Mesh_GetLocalSize( feMesh, MT_VERTEX );
+}
+
+unsigned FeMesh_GetNodeRemoteSize( void* feMesh ) {
+ return Mesh_GetRemoteSize( feMesh, MT_VERTEX );
+}
+
+unsigned FeMesh_GetNodeDomainSize( void* feMesh ) {
+ return Mesh_GetDomainSize( feMesh, MT_VERTEX );
+}
+
+unsigned FeMesh_GetNodeGlobalSize( void* feMesh ) {
+ return Mesh_GetGlobalSize( feMesh, MT_VERTEX );
+}
+
+unsigned FeMesh_GetElementLocalSize( void* feMesh ) {
+ return Mesh_GetLocalSize( feMesh, Mesh_GetDimSize( feMesh ) );
+}
+
+unsigned FeMesh_GetElementRemoteSize( void* feMesh ) {
+ return Mesh_GetRemoteSize( feMesh, Mesh_GetDimSize( feMesh ) );
+}
+
+unsigned FeMesh_GetElementDomainSize( void* feMesh ) {
+ return Mesh_GetDomainSize( feMesh, Mesh_GetDimSize( feMesh ) );
+}
+
+unsigned FeMesh_GetElementGlobalSize( void* feMesh ) {
+ return Mesh_GetGlobalSize( feMesh, Mesh_GetDimSize( feMesh ) );
+}
+
+unsigned FeMesh_GetElementNodeSize( void* feMesh, unsigned element ) {
+ return Mesh_GetIncidenceSize( feMesh, Mesh_GetDimSize( feMesh ), element, MT_VERTEX );
+}
+
+unsigned FeMesh_GetNodeElementSize( void* feMesh, unsigned node ) {
+ return Mesh_GetIncidenceSize( feMesh, MT_VERTEX, node, Mesh_GetDimSize( feMesh ) );
+}
+
+void FeMesh_GetElementNodes( void* feMesh, unsigned element, IArray* inc ) {
+ Mesh_GetIncidence( feMesh, Mesh_GetDimSize( feMesh ), element, MT_VERTEX, inc );
+}
+
+void FeMesh_GetNodeElements( void* feMesh, unsigned node, IArray* inc ) {
+ Mesh_GetIncidence( feMesh, MT_VERTEX, node, Mesh_GetDimSize( feMesh ), inc );
+}
+
+unsigned FeMesh_ElementDomainToGlobal( void* feMesh, unsigned domain ) {
+ return Mesh_DomainToGlobal( feMesh, Mesh_GetDimSize( feMesh ), domain );
+}
+
+Bool FeMesh_ElementGlobalToDomain( void* feMesh, unsigned global, unsigned* domain ) {
+ return Mesh_GlobalToDomain( feMesh, Mesh_GetDimSize( feMesh ), global, domain );
+}
+
+unsigned FeMesh_NodeDomainToGlobal( void* feMesh, unsigned domain ) {
+ return Mesh_DomainToGlobal( feMesh, MT_VERTEX, domain );
+}
+
+Bool FeMesh_NodeGlobalToDomain( void* feMesh, unsigned global, unsigned* domain ) {
+ return Mesh_GlobalToDomain( feMesh, MT_VERTEX, global, domain );
+}
+
+void FeMesh_CoordGlobalToLocal( void* feMesh, unsigned element, double* global, double* local ) {
+ FeMesh* self = (FeMesh*)feMesh;
+ ElementType* elType;
+
+ assert( self );
+ assert( element < FeMesh_GetElementDomainSize( self ) );
+ assert( global );
+ assert( local );
+
+ elType = FeMesh_GetElementType( self, element );
+ ElementType_ConvertGlobalCoordToElLocal( elType, self, element, global, local );
+}
+
+void FeMesh_CoordLocalToGlobal( void* feMesh, unsigned element, double* local, double* global ) {
+ FeMesh* self = (FeMesh*)feMesh;
+ unsigned nDims;
+ ElementType* elType;
+ double* basis;
+ unsigned nElNodes, *elNodes;
+ double dimBasis;
+ double* vert;
+ unsigned n_i, d_i;
+
+ assert( self );
+ assert( element < FeMesh_GetElementDomainSize( self ) );
+ assert( global );
+ assert( local );
+
+ nDims = Mesh_GetDimSize( self );
+ elType = FeMesh_GetElementType( self, element );
+ FeMesh_GetElementNodes( self, element, self->inc );
+ nElNodes = IArray_GetSize( self->inc );
+ elNodes = (unsigned*)IArray_GetPtr( self->inc );
+ basis = AllocArray( double, nElNodes );
+ ElementType_EvaluateShapeFunctionsAt( elType, local, basis );
+
+ memset( global, 0, nDims * sizeof(double) );
+ for( n_i = 0; n_i < nElNodes; n_i++ ) {
+ dimBasis = basis[n_i];
+ vert = Mesh_GetVertex( self, elNodes[n_i] );
+ for( d_i = 0; d_i < nDims; d_i++ )
+ global[d_i] += dimBasis * vert[d_i];
+ }
+
+ FreeArray( basis );
+}
+
+void FeMesh_EvalBasis( void* feMesh, unsigned element, double* localCoord, double* basis ) {
+ FeMesh* self = (FeMesh*)feMesh;
+ ElementType* elType;
+
+ assert( self );
+ assert( localCoord );
+
+ elType = FeMesh_GetElementType( self, element );
+ ElementType_EvaluateShapeFunctionsAt( elType, localCoord, basis );
+}
+
+void FeMesh_EvalLocalDerivs( void* feMesh, unsigned element, double* localCoord, double** derivs ) {
+ FeMesh* self = (FeMesh*)feMesh;
+ ElementType* elType;
+
+ assert( self );
+ assert( localCoord );
+ assert( derivs );
+
+ elType = FeMesh_GetElementType( self, element );
+ ElementType_EvaluateShapeFunctionLocalDerivsAt( elType, localCoord, derivs );
+}
+
+void FeMesh_EvalGlobalDerivs( void* feMesh, unsigned element, double* localCoord, double** derivs, double* jacDet ) {
+ FeMesh* self = (FeMesh*)feMesh;
+ unsigned nDims;
+ ElementType* elType;
+ double jd;
+
+ assert( self );
+ assert( localCoord );
+ assert( derivs );
+
+ nDims = Mesh_GetDimSize( self );
+ elType = FeMesh_GetElementType( self, element );
+ ElementType_ShapeFunctionsGlobalDerivs( elType, self, element, localCoord, nDims,
+ &jd, derivs );
+ if( jacDet )
+ *jacDet = jd;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+void FeMesh_Destruct( FeMesh* self ) {
+ Stg_Class_Delete( self->feElType );
+ self->feElFamily = NULL;
+ /* Disabling the killing of this object from within this
+ component as this will be destroyed by the LiveComponentRegister_DestroyAll function 101109 */
+ /*KillObject( self->feElType );*/
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FeMesh_Algorithms.c
--- a/Discretisation/src/FeMesh_Algorithms.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,205 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: FeMesh_Algorithms.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <mpi.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "Discretisation.h"
-
-
-/* Textual name of this class */
-const Type FeMesh_Algorithms_Type = "FeMesh_Algorithms";
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-FeMesh_Algorithms* FeMesh_Algorithms_New( Name name, AbstractContext* context ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(FeMesh_Algorithms);
- Type type = FeMesh_Algorithms_Type;
- Stg_Class_DeleteFunction* _delete = _FeMesh_Algorithms_Delete;
- Stg_Class_PrintFunction* _print = _FeMesh_Algorithms_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_FeMesh_Algorithms_New;
- Stg_Component_ConstructFunction* _construct = _FeMesh_Algorithms_AssignFromXML;
- Stg_Component_BuildFunction* _build = _FeMesh_Algorithms_Build;
- Stg_Component_InitialiseFunction* _initialise = _FeMesh_Algorithms_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FeMesh_Algorithms_Execute;
- Stg_Component_DestroyFunction* _destroy = _FeMesh_Algorithms_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- Mesh_Algorithms_SetMeshFunc* setMeshFunc = _Mesh_Algorithms_SetMesh;
- Mesh_Algorithms_UpdateFunc* updateFunc = _Mesh_Algorithms_Update;
- Mesh_Algorithms_NearestVertexFunc* nearestVertexFunc = _Mesh_Algorithms_NearestVertex;
- Mesh_Algorithms_SearchFunc* searchFunc = _FeMesh_Algorithms_Search;
- Mesh_Algorithms_SearchElementsFunc* searchElementsFunc = _FeMesh_Algorithms_SearchElements;
- Mesh_Algorithms_GetMinimumSeparationFunc* getMinimumSeparationFunc = _Mesh_Algorithms_GetMinimumSeparation;
- Mesh_Algorithms_GetLocalCoordRangeFunc* getLocalCoordRangeFunc = _Mesh_Algorithms_GetLocalCoordRange;
- Mesh_Algorithms_GetDomainCoordRangeFunc* getDomainCoordRangeFunc = _Mesh_Algorithms_GetDomainCoordRange;
- Mesh_Algorithms_GetGlobalCoordRangeFunc* getGlobalCoordRangeFunc = _Mesh_Algorithms_GetGlobalCoordRange;
-
- FeMesh_Algorithms* self = _FeMesh_Algorithms_New( FEMESH_ALGORITHMS_PASSARGS );
-
- _Mesh_Algorithms_Init( (Mesh_Algorithms*)self, context );
- _FeMesh_Algorithms_Init( self );
- return self;
-}
-
-FeMesh_Algorithms* _FeMesh_Algorithms_New( FEMESH_ALGORITHMS_DEFARGS ) {
- FeMesh_Algorithms* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(FeMesh_Algorithms) );
- self = (FeMesh_Algorithms*)_Mesh_Algorithms_New( MESH_ALGORITHMS_PASSARGS );
-
- return self;
-}
-
-void _FeMesh_Algorithms_Init( FeMesh_Algorithms* self ) {
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _FeMesh_Algorithms_Delete( void* algorithms ) {
- FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
-
- /* Delete the parent. */
- _Mesh_Algorithms_Delete( self );
-}
-
-void _FeMesh_Algorithms_Print( void* algorithms, Stream* stream ) {
- FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
-
- /* Set the Journal for printing informations */
- Stream* algorithmsStream;
- algorithmsStream = Journal_Register( InfoStream_Type, (Name)"FeMesh_AlgorithmsStream" );
-
- /* Print parent */
- Journal_Printf( stream, "FeMesh_Algorithms (ptr): (%p)\n", self );
- _Stg_Component_Print( self, stream );
-}
-
-void _FeMesh_Algorithms_AssignFromXML( void* algorithms, Stg_ComponentFactory* cf, void* data ) {
- _FeMesh_Algorithms_Init( (FeMesh_Algorithms*)algorithms );
-}
-
-void _FeMesh_Algorithms_Build( void* algorithms, void* data ) {
- FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
- _Mesh_Algorithms_Build( self, data );
-}
-
-void _FeMesh_Algorithms_Initialise( void* algorithms, void* data ) {
- FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
- _Mesh_Algorithms_Initialise( self, data );
-}
-
-void _FeMesh_Algorithms_Execute( void* algorithms, void* data ) {
-}
-
-void _FeMesh_Algorithms_Destroy( void* algorithms, void* data ) {
- FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
- _Mesh_Algorithms_Destroy( self, data );
-}
-
-Bool _FeMesh_Algorithms_Search( void* algorithms, double* point,
- MeshTopology_Dim* dim, unsigned* ind )
-{
- FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
-
- return FeMesh_Algorithms_SearchWithTree( self, point, (unsigned*)dim, ind );
-}
-
-Bool _FeMesh_Algorithms_SearchElements( void* algorithms, double* point,
- unsigned* elInd )
-{
- FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
- unsigned dim;
-
- assert( self );
-
- return FeMesh_Algorithms_SearchWithTree( self, point, &dim, elInd );
-}
-
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-Bool FeMesh_Algorithms_SearchWithTree( void* _self, double* pnt, unsigned* dim, unsigned* el ) {
- FeMesh_Algorithms* self = (FeMesh_Algorithms*)_self;
- int nEls, *els;
- int curRank, ii;
- unsigned curDim, curEl;
- int nLocals, owner;
- Mesh_ElementType* elType;
-
- *dim = Mesh_GetDimSize( self->mesh );
- MPI_Comm_size( MPI_COMM_WORLD, &curRank );
- nLocals = Mesh_GetLocalSize( self->mesh, (MeshTopology_Dim)(*dim) );
- if( !SpatialTree_Search( self->tree, pnt, &nEls, &els ) )
- return False;
-
- *el = nLocals;
- elType = Mesh_GetElementType( self->mesh, 0 );
- for( ii = 0; ii < nEls; ii++ ) {
- if( FeMesh_ElementType_ElementHasPoint( elType, els[ii], pnt, (MeshTopology_Dim*)(&curDim), &curEl ) ) {
- if( curEl >= (unsigned)nLocals ) {
- owner = Mesh_GetOwner( self->mesh, (MeshTopology_Dim)curDim, curEl - nLocals );
- owner = Comm_RankLocalToGlobal( self->mesh->topo->comm, owner );
- if( owner <= curRank ) {
- curRank = owner;
- *el = curEl;
- }
- } else if( self->rank <= curRank && curEl < *el ) {
- curRank = self->rank;
- *el = curEl;
- }
- }
- }
-
- return True;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FeMesh_Algorithms.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/FeMesh_Algorithms.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,205 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: FeMesh_Algorithms.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type FeMesh_Algorithms_Type = "FeMesh_Algorithms";
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+FeMesh_Algorithms* FeMesh_Algorithms_New( Name name, AbstractContext* context ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(FeMesh_Algorithms);
+ Type type = FeMesh_Algorithms_Type;
+ Stg_Class_DeleteFunction* _delete = _FeMesh_Algorithms_Delete;
+ Stg_Class_PrintFunction* _print = _FeMesh_Algorithms_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_FeMesh_Algorithms_New;
+ Stg_Component_ConstructFunction* _construct = _FeMesh_Algorithms_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _FeMesh_Algorithms_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FeMesh_Algorithms_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FeMesh_Algorithms_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FeMesh_Algorithms_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ Mesh_Algorithms_SetMeshFunc* setMeshFunc = _Mesh_Algorithms_SetMesh;
+ Mesh_Algorithms_UpdateFunc* updateFunc = _Mesh_Algorithms_Update;
+ Mesh_Algorithms_NearestVertexFunc* nearestVertexFunc = _Mesh_Algorithms_NearestVertex;
+ Mesh_Algorithms_SearchFunc* searchFunc = _FeMesh_Algorithms_Search;
+ Mesh_Algorithms_SearchElementsFunc* searchElementsFunc = _FeMesh_Algorithms_SearchElements;
+ Mesh_Algorithms_GetMinimumSeparationFunc* getMinimumSeparationFunc = _Mesh_Algorithms_GetMinimumSeparation;
+ Mesh_Algorithms_GetLocalCoordRangeFunc* getLocalCoordRangeFunc = _Mesh_Algorithms_GetLocalCoordRange;
+ Mesh_Algorithms_GetDomainCoordRangeFunc* getDomainCoordRangeFunc = _Mesh_Algorithms_GetDomainCoordRange;
+ Mesh_Algorithms_GetGlobalCoordRangeFunc* getGlobalCoordRangeFunc = _Mesh_Algorithms_GetGlobalCoordRange;
+
+ FeMesh_Algorithms* self = _FeMesh_Algorithms_New( FEMESH_ALGORITHMS_PASSARGS );
+
+ _Mesh_Algorithms_Init( (Mesh_Algorithms*)self, context );
+ _FeMesh_Algorithms_Init( self );
+ return self;
+}
+
+FeMesh_Algorithms* _FeMesh_Algorithms_New( FEMESH_ALGORITHMS_DEFARGS ) {
+ FeMesh_Algorithms* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(FeMesh_Algorithms) );
+ self = (FeMesh_Algorithms*)_Mesh_Algorithms_New( MESH_ALGORITHMS_PASSARGS );
+
+ return self;
+}
+
+void _FeMesh_Algorithms_Init( FeMesh_Algorithms* self ) {
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _FeMesh_Algorithms_Delete( void* algorithms ) {
+ FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
+
+ /* Delete the parent. */
+ _Mesh_Algorithms_Delete( self );
+}
+
+void _FeMesh_Algorithms_Print( void* algorithms, Stream* stream ) {
+ FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
+
+ /* Set the Journal for printing informations */
+ Stream* algorithmsStream;
+ algorithmsStream = Journal_Register( InfoStream_Type, (Name)"FeMesh_AlgorithmsStream" );
+
+ /* Print parent */
+ Journal_Printf( stream, "FeMesh_Algorithms (ptr): (%p)\n", self );
+ _Stg_Component_Print( self, stream );
+}
+
+void _FeMesh_Algorithms_AssignFromXML( void* algorithms, Stg_ComponentFactory* cf, void* data ) {
+ _FeMesh_Algorithms_Init( (FeMesh_Algorithms*)algorithms );
+}
+
+void _FeMesh_Algorithms_Build( void* algorithms, void* data ) {
+ FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
+ _Mesh_Algorithms_Build( self, data );
+}
+
+void _FeMesh_Algorithms_Initialise( void* algorithms, void* data ) {
+ FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
+ _Mesh_Algorithms_Initialise( self, data );
+}
+
+void _FeMesh_Algorithms_Execute( void* algorithms, void* data ) {
+}
+
+void _FeMesh_Algorithms_Destroy( void* algorithms, void* data ) {
+ FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
+ _Mesh_Algorithms_Destroy( self, data );
+}
+
+Bool _FeMesh_Algorithms_Search( void* algorithms, double* point,
+ MeshTopology_Dim* dim, unsigned* ind )
+{
+ FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
+
+ return FeMesh_Algorithms_SearchWithTree( self, point, (unsigned*)dim, ind );
+}
+
+Bool _FeMesh_Algorithms_SearchElements( void* algorithms, double* point,
+ unsigned* elInd )
+{
+ FeMesh_Algorithms* self = (FeMesh_Algorithms*)algorithms;
+ unsigned dim;
+
+ assert( self );
+
+ return FeMesh_Algorithms_SearchWithTree( self, point, &dim, elInd );
+}
+
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+Bool FeMesh_Algorithms_SearchWithTree( void* _self, double* pnt, unsigned* dim, unsigned* el ) {
+ FeMesh_Algorithms* self = (FeMesh_Algorithms*)_self;
+ int nEls, *els;
+ int curRank, ii;
+ unsigned curDim, curEl;
+ int nLocals, owner;
+ Mesh_ElementType* elType;
+
+ *dim = Mesh_GetDimSize( self->mesh );
+ MPI_Comm_size( MPI_COMM_WORLD, &curRank );
+ nLocals = Mesh_GetLocalSize( self->mesh, (MeshTopology_Dim)(*dim) );
+ if( !SpatialTree_Search( self->tree, pnt, &nEls, &els ) )
+ return False;
+
+ *el = nLocals;
+ elType = Mesh_GetElementType( self->mesh, 0 );
+ for( ii = 0; ii < nEls; ii++ ) {
+ if( FeMesh_ElementType_ElementHasPoint( elType, els[ii], pnt, (MeshTopology_Dim*)(&curDim), &curEl ) ) {
+ if( curEl >= (unsigned)nLocals ) {
+ owner = Mesh_GetOwner( self->mesh, (MeshTopology_Dim)curDim, curEl - nLocals );
+ owner = Comm_RankLocalToGlobal( self->mesh->topo->comm, owner );
+ if( owner <= curRank ) {
+ curRank = owner;
+ *el = curEl;
+ }
+ } else if( self->rank <= curRank && curEl < *el ) {
+ curRank = self->rank;
+ *el = curEl;
+ }
+ }
+ }
+
+ return True;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FeMesh_ElementType.c
--- a/Discretisation/src/FeMesh_ElementType.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: FeMesh_ElementType.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <mpi.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "Discretisation.h"
-
-
-/* Textual name of this class */
-const Type FeMesh_ElementType_Type = "FeMesh_ElementType";
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-FeMesh_ElementType* FeMesh_ElementType_New() {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(FeMesh_ElementType);
- Type type = FeMesh_ElementType_Type;
- Stg_Class_DeleteFunction* _delete = _FeMesh_ElementType_Delete;
- Stg_Class_PrintFunction* _print = _FeMesh_ElementType_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Mesh_ElementType_UpdateFunc* updateFunc = Mesh_HexType_Update;
- Mesh_ElementType_ElementHasPointFunc* elementHasPointFunc = FeMesh_ElementType_ElementHasPoint;
- Mesh_ElementType_GetMinimumSeparationFunc* getMinimumSeparationFunc = Mesh_HexType_GetMinimumSeparation;
- Mesh_ElementType_GetCentroidFunc* getCentroidFunc = _Mesh_ElementType_GetCentroid;
-
- return _FeMesh_ElementType_New( FEMESH_ELEMENTTYPE_PASSARGS );
-}
-
-FeMesh_ElementType* _FeMesh_ElementType_New( FEMESH_ELEMENTTYPE_DEFARGS ) {
- FeMesh_ElementType* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(FeMesh_ElementType) );
- self = (FeMesh_ElementType*)_Mesh_HexType_New( MESH_HEXTYPE_PASSARGS );
-
- /* Virtual info */
-
- /* FeMesh_ElementType info */
- _FeMesh_ElementType_Init( self );
-
- return self;
-}
-
-void _FeMesh_ElementType_Init( FeMesh_ElementType* self ) {
- assert( self && Stg_CheckType( self, FeMesh_ElementType ) );
-
- _Mesh_HexType_Init( (Mesh_HexType*)self );
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _FeMesh_ElementType_Delete( void* elementType ) {
- FeMesh_ElementType* self = (FeMesh_ElementType*)elementType;
-
- /* Delete the parent. */
- _Mesh_HexType_Delete( self );
-}
-
-void _FeMesh_ElementType_Print( void* elementType, Stream* stream ) {
- FeMesh_ElementType* self = (FeMesh_ElementType*)elementType;
- Stream* elementTypeStream;
-
- elementTypeStream = Journal_Register( InfoStream_Type, (Name)"FeMesh_ElementTypeStream" );
-
- /* Print parent */
- Journal_Printf( stream, "FeMesh_ElementType (ptr): (%p)\n", self );
- _Mesh_HexType_Print( self, stream );
-}
-
-Bool FeMesh_ElementType_ElementHasPoint( void* hexType, unsigned elInd, double* point,
- MeshTopology_Dim* dim, unsigned* ind )
-{
- FeMesh_ElementType* self = (FeMesh_ElementType*)hexType;
- int nDims, ii;
-
- assert( self && Stg_CheckType( self, FeMesh_ElementType ) );
- assert( Mesh_GetDimSize( self->mesh ) <= 3 );
-
- FeMesh_CoordGlobalToLocal( self->mesh, elInd, point, self->local );
- nDims = Mesh_GetDimSize( self->mesh );
- for( ii = 0; ii < nDims; ii++ ) {
- if( self->local[ii] < -1.0 || self->local[ii] > 1.0 )
- return False;
- }
-
- *dim = (MeshTopology_Dim)nDims;
- *ind = elInd;
- return True;
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FeMesh_ElementType.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/FeMesh_ElementType.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,142 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: FeMesh_ElementType.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type FeMesh_ElementType_Type = "FeMesh_ElementType";
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+FeMesh_ElementType* FeMesh_ElementType_New() {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(FeMesh_ElementType);
+ Type type = FeMesh_ElementType_Type;
+ Stg_Class_DeleteFunction* _delete = _FeMesh_ElementType_Delete;
+ Stg_Class_PrintFunction* _print = _FeMesh_ElementType_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Mesh_ElementType_UpdateFunc* updateFunc = Mesh_HexType_Update;
+ Mesh_ElementType_ElementHasPointFunc* elementHasPointFunc = FeMesh_ElementType_ElementHasPoint;
+ Mesh_ElementType_GetMinimumSeparationFunc* getMinimumSeparationFunc = Mesh_HexType_GetMinimumSeparation;
+ Mesh_ElementType_GetCentroidFunc* getCentroidFunc = _Mesh_ElementType_GetCentroid;
+
+ return _FeMesh_ElementType_New( FEMESH_ELEMENTTYPE_PASSARGS );
+}
+
+FeMesh_ElementType* _FeMesh_ElementType_New( FEMESH_ELEMENTTYPE_DEFARGS ) {
+ FeMesh_ElementType* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(FeMesh_ElementType) );
+ self = (FeMesh_ElementType*)_Mesh_HexType_New( MESH_HEXTYPE_PASSARGS );
+
+ /* Virtual info */
+
+ /* FeMesh_ElementType info */
+ _FeMesh_ElementType_Init( self );
+
+ return self;
+}
+
+void _FeMesh_ElementType_Init( FeMesh_ElementType* self ) {
+ assert( self && Stg_CheckType( self, FeMesh_ElementType ) );
+
+ _Mesh_HexType_Init( (Mesh_HexType*)self );
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _FeMesh_ElementType_Delete( void* elementType ) {
+ FeMesh_ElementType* self = (FeMesh_ElementType*)elementType;
+
+ /* Delete the parent. */
+ _Mesh_HexType_Delete( self );
+}
+
+void _FeMesh_ElementType_Print( void* elementType, Stream* stream ) {
+ FeMesh_ElementType* self = (FeMesh_ElementType*)elementType;
+ Stream* elementTypeStream;
+
+ elementTypeStream = Journal_Register( InfoStream_Type, (Name)"FeMesh_ElementTypeStream" );
+
+ /* Print parent */
+ Journal_Printf( stream, "FeMesh_ElementType (ptr): (%p)\n", self );
+ _Mesh_HexType_Print( self, stream );
+}
+
+Bool FeMesh_ElementType_ElementHasPoint( void* hexType, unsigned elInd, double* point,
+ MeshTopology_Dim* dim, unsigned* ind )
+{
+ FeMesh_ElementType* self = (FeMesh_ElementType*)hexType;
+ int nDims, ii;
+
+ assert( self && Stg_CheckType( self, FeMesh_ElementType ) );
+ assert( Mesh_GetDimSize( self->mesh ) <= 3 );
+
+ FeMesh_CoordGlobalToLocal( self->mesh, elInd, point, self->local );
+ nDims = Mesh_GetDimSize( self->mesh );
+ for( ii = 0; ii < nDims; ii++ ) {
+ if( self->local[ii] < -1.0 || self->local[ii] > 1.0 )
+ return False;
+ }
+
+ *dim = (MeshTopology_Dim)nDims;
+ *ind = elInd;
+ return True;
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FeSwarmVariable.c
--- a/Discretisation/src/FeSwarmVariable.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: FeSwarmVariable.c 1117 2008-05-02 02:50:02Z JulianGiordani $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <string.h>
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "types.h"
-#include "FeVariable.h"
-#include "FeMesh.h"
-#include "FeSwarmVariable.h"
-
-#include <assert.h>
-
-const Type FeSwarmVariable_Type = "FeSwarmVariable";
-
-void* _FeSwarmVariable_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(FeSwarmVariable);
- Type type = FeSwarmVariable_Type;
- Stg_Class_DeleteFunction* _delete = _FeSwarmVariable_Delete;
- Stg_Class_PrintFunction* _print = _FeSwarmVariable_Print;
- Stg_Class_CopyFunction* _copy = _FeSwarmVariable_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _FeSwarmVariable_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _FeSwarmVariable_AssignFromXML;
- Stg_Component_BuildFunction* _build = _FeSwarmVariable_Build;
- Stg_Component_InitialiseFunction* _initialise = _FeSwarmVariable_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FeSwarmVariable_Execute;
- Stg_Component_DestroyFunction* _destroy = _FeSwarmVariable_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- SwarmVariable_ValueAtFunction* _valueAt = _FeSwarmVariable_ValueAt;
- SwarmVariable_GetGlobalValueFunction* _getMinGlobalMagnitude = _FeSwarmVariable_GetMinGlobalMagnitude;
- SwarmVariable_GetGlobalValueFunction* _getMaxGlobalMagnitude = _FeSwarmVariable_GetMaxGlobalMagnitude;
-
- return _FeSwarmVariable_New( FESWARMVARIABLE_PASSARGS );
-}
-
-FeSwarmVariable* _FeSwarmVariable_New( FESWARMVARIABLE_DEFARGS ) {
- FeSwarmVariable* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(FeSwarmVariable) );
- self = (FeSwarmVariable*) _SwarmVariable_New( SWARMVARIABLE_PASSARGS );
-
- return self;
-}
-
-void _FeSwarmVariable_Init( void* swarmVariable, FeVariable* feVariable ) {
- FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
-
- self->feVariable = feVariable;
- /* variable does not store data, so is not checkpointed */
- self->isCheckpointedAndReloaded = False;
-}
-
-void _FeSwarmVariable_Delete( void* _swarmVariable ) {
- FeSwarmVariable* self = (FeSwarmVariable*) _swarmVariable;
-
- _SwarmVariable_Delete( self );
-}
-
-void _FeSwarmVariable_Print( void* _swarmVariable, Stream* stream ) {
- FeSwarmVariable* self = (FeSwarmVariable*) _swarmVariable;
-
- _SwarmVariable_Print( self, stream );
-
- Journal_PrintPointer( stream, self->feVariable );
-}
-
-void* _FeSwarmVariable_Copy( const void* swarmVariable, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- FeSwarmVariable* self = (FeSwarmVariable*)swarmVariable;
- FeSwarmVariable* newFeSwarmVariable;
-
- newFeSwarmVariable = (FeSwarmVariable*)_SwarmVariable_Copy( self, dest, deep, nameExt, ptrMap );
-
- newFeSwarmVariable->feVariable = self->feVariable;
-
- return (void*)newFeSwarmVariable;
-}
-
-void _FeSwarmVariable_AssignFromXML( void* swarmVariable, Stg_ComponentFactory* cf, void* data ) {
- FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
-
- _SwarmVariable_AssignFromXML( self, cf, data );
-
- _FeSwarmVariable_Init( self, Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"FeVariable", FeVariable, True, data ) );
-}
-
-void _FeSwarmVariable_Build( void* swarmVariable, void* data ) {
- FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
-
- Stg_Component_Build( self->feVariable, data, False );
-}
-
-void _FeSwarmVariable_Initialise( void* swarmVariable, void* data ) {
- FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
-
- Stg_Component_Initialise( self->feVariable, data, False );
-}
-
-void _FeSwarmVariable_Execute( void* swarmVariable, void* data ) {}
-
-void _FeSwarmVariable_Destroy( void* swarmVariable, void* data ) {
- FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
-
- _SwarmVariable_Destroy( self, data );
-}
-
-void _FeSwarmVariable_ValueAt( void* swarmVariable, Particle_Index lParticle_I, double* value ) {
- FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
- FeMesh* mesh = self->feVariable->feMesh;
- Swarm* swarm = self->swarm;
- GlobalParticle* particle = (GlobalParticle*) Swarm_ParticleAt( swarm, lParticle_I );
- double xi[3];
-
- /* check if the swarm is using a GlobalCoordSystem, if not FAIL */
- Journal_Firewall( (swarm->particleLayout->coordSystem == GlobalCoordSystem),
- Journal_Register( Error_Type, (Name)"FeSwarmVariable" ),
- "Error in function %s: FeSwarmVariables require swarms with GlobalCoordSystems\n"
- "This FeSwarmVariable, %s, uses the swarm %s, which doesn't have a GlobalCoordSystem\n",
- __func__, self->name, swarm->name );
- FeMesh_CoordGlobalToLocal( mesh, particle->owningCell, particle->coord, xi );
- FeVariable_InterpolateWithinElement( self->feVariable, particle->owningCell, xi, value );
-}
-
-
-double _FeSwarmVariable_GetMinGlobalMagnitude( void* swarmVariable ) {
- FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
-
- return FieldVariable_GetMinGlobalFieldMagnitude( self->feVariable );
-}
-double _FeSwarmVariable_GetMaxGlobalMagnitude( void* swarmVariable ) {
- FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
-
- return FieldVariable_GetMaxGlobalFieldMagnitude( self->feVariable );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FeSwarmVariable.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/FeSwarmVariable.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,177 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: FeSwarmVariable.c 1117 2008-05-02 02:50:02Z JulianGiordani $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <string.h>
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "types.h"
+#include "FeVariable.h"
+#include "FeMesh.h"
+#include "FeSwarmVariable.h"
+
+#include <assert.h>
+
+const Type FeSwarmVariable_Type = "FeSwarmVariable";
+
+void* _FeSwarmVariable_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(FeSwarmVariable);
+ Type type = FeSwarmVariable_Type;
+ Stg_Class_DeleteFunction* _delete = _FeSwarmVariable_Delete;
+ Stg_Class_PrintFunction* _print = _FeSwarmVariable_Print;
+ Stg_Class_CopyFunction* _copy = _FeSwarmVariable_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _FeSwarmVariable_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _FeSwarmVariable_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _FeSwarmVariable_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FeSwarmVariable_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FeSwarmVariable_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FeSwarmVariable_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ SwarmVariable_ValueAtFunction* _valueAt = _FeSwarmVariable_ValueAt;
+ SwarmVariable_GetGlobalValueFunction* _getMinGlobalMagnitude = _FeSwarmVariable_GetMinGlobalMagnitude;
+ SwarmVariable_GetGlobalValueFunction* _getMaxGlobalMagnitude = _FeSwarmVariable_GetMaxGlobalMagnitude;
+
+ return _FeSwarmVariable_New( FESWARMVARIABLE_PASSARGS );
+}
+
+FeSwarmVariable* _FeSwarmVariable_New( FESWARMVARIABLE_DEFARGS ) {
+ FeSwarmVariable* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(FeSwarmVariable) );
+ self = (FeSwarmVariable*) _SwarmVariable_New( SWARMVARIABLE_PASSARGS );
+
+ return self;
+}
+
+void _FeSwarmVariable_Init( void* swarmVariable, FeVariable* feVariable ) {
+ FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
+
+ self->feVariable = feVariable;
+ /* variable does not store data, so is not checkpointed */
+ self->isCheckpointedAndReloaded = False;
+}
+
+void _FeSwarmVariable_Delete( void* _swarmVariable ) {
+ FeSwarmVariable* self = (FeSwarmVariable*) _swarmVariable;
+
+ _SwarmVariable_Delete( self );
+}
+
+void _FeSwarmVariable_Print( void* _swarmVariable, Stream* stream ) {
+ FeSwarmVariable* self = (FeSwarmVariable*) _swarmVariable;
+
+ _SwarmVariable_Print( self, stream );
+
+ Journal_PrintPointer( stream, self->feVariable );
+}
+
+void* _FeSwarmVariable_Copy( const void* swarmVariable, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ FeSwarmVariable* self = (FeSwarmVariable*)swarmVariable;
+ FeSwarmVariable* newFeSwarmVariable;
+
+ newFeSwarmVariable = (FeSwarmVariable*)_SwarmVariable_Copy( self, dest, deep, nameExt, ptrMap );
+
+ newFeSwarmVariable->feVariable = self->feVariable;
+
+ return (void*)newFeSwarmVariable;
+}
+
+void _FeSwarmVariable_AssignFromXML( void* swarmVariable, Stg_ComponentFactory* cf, void* data ) {
+ FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
+
+ _SwarmVariable_AssignFromXML( self, cf, data );
+
+ _FeSwarmVariable_Init( self, Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"FeVariable", FeVariable, True, data ) );
+}
+
+void _FeSwarmVariable_Build( void* swarmVariable, void* data ) {
+ FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
+
+ Stg_Component_Build( self->feVariable, data, False );
+}
+
+void _FeSwarmVariable_Initialise( void* swarmVariable, void* data ) {
+ FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
+
+ Stg_Component_Initialise( self->feVariable, data, False );
+}
+
+void _FeSwarmVariable_Execute( void* swarmVariable, void* data ) {}
+
+void _FeSwarmVariable_Destroy( void* swarmVariable, void* data ) {
+ FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
+
+ _SwarmVariable_Destroy( self, data );
+}
+
+void _FeSwarmVariable_ValueAt( void* swarmVariable, Particle_Index lParticle_I, double* value ) {
+ FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
+ FeMesh* mesh = self->feVariable->feMesh;
+ Swarm* swarm = self->swarm;
+ GlobalParticle* particle = (GlobalParticle*) Swarm_ParticleAt( swarm, lParticle_I );
+ double xi[3];
+
+ /* check if the swarm is using a GlobalCoordSystem, if not FAIL */
+ Journal_Firewall( (swarm->particleLayout->coordSystem == GlobalCoordSystem),
+ Journal_Register( Error_Type, (Name)"FeSwarmVariable" ),
+ "Error in function %s: FeSwarmVariables require swarms with GlobalCoordSystems\n"
+ "This FeSwarmVariable, %s, uses the swarm %s, which doesn't have a GlobalCoordSystem\n",
+ __func__, self->name, swarm->name );
+ FeMesh_CoordGlobalToLocal( mesh, particle->owningCell, particle->coord, xi );
+ FeVariable_InterpolateWithinElement( self->feVariable, particle->owningCell, xi, value );
+}
+
+
+double _FeSwarmVariable_GetMinGlobalMagnitude( void* swarmVariable ) {
+ FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
+
+ return FieldVariable_GetMinGlobalFieldMagnitude( self->feVariable );
+}
+double _FeSwarmVariable_GetMaxGlobalMagnitude( void* swarmVariable ) {
+ FeSwarmVariable* self = (FeSwarmVariable*) swarmVariable;
+
+ return FieldVariable_GetMaxGlobalFieldMagnitude( self->feVariable );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FeVariable.c
--- a/Discretisation/src/FeVariable.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2725 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: FeVariable.c 1224 2008-09-10 13:28:46Z DavidLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-#include "units.h"
-#include "types.h"
-#include "ElementType.h"
-#include "ElementType_Register.h"
-#include "Element.h"
-#include "FeMesh.h"
-#include "FeEquationNumber.h"
-#include "FeVariable.h"
-#include "LinkedDofInfo.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-#if defined(READ_HDF5) || defined(WRITE_HDF5)
-#include <hdf5.h>
-#endif
-
-const Type FeVariable_Type = "FeVariable";
-const Name defaultFeVariableFeEquationNumberName = "defaultFeVariableFeEqName";
-
-/** MPI Tags */
-static const int DOF_VALUES_TAG = 10;
-
-/** Global objects */
-Stg_ObjectList* FeVariable_FileFormatImportExportList = NULL;
-
-FeVariable* FeVariable_New_FromTemplate(
- Name name,
- DomainContext* context,
- void* _templateFeVariable,
- DofLayout* dofLayout,
- void* ics,
- Bool isReferenceSolution,
- Bool loadReferenceEachTimestep,
- FieldVariable_Register* fV_Register )
-{
- FeVariable* templateFeVariable = (FeVariable*)_templateFeVariable;
- FeVariable* newFeVariable = NULL;
-
- newFeVariable = FeVariable_New_Full(
- name,
- context,
- templateFeVariable->feMesh,
- templateFeVariable->geometryMesh,
- dofLayout,
- templateFeVariable->bcs,
- ics,
- templateFeVariable->linkedDofInfo,
- templateFeVariable,
- templateFeVariable->fieldComponentCount,
- templateFeVariable->dim,
- templateFeVariable->isCheckpointedAndReloaded,
- isReferenceSolution,
- loadReferenceEachTimestep,
- templateFeVariable->communicator,
- fV_Register );
-
- newFeVariable->templateFeVariable = templateFeVariable;
-
- return newFeVariable;
-}
-
-FeVariable* FeVariable_New(
- Name name,
- DomainContext* context,
- void* feMesh,
- void* geometryMesh,
- DofLayout* dofLayout,
- void* bcs,
- void* ics,
- void* linkedDofInfo,
- Dimension_Index dim,
- Bool isCheckpointedAndReloaded,
- Bool isReferenceSolution,
- Bool loadReferenceEachTimestep,
- FieldVariable_Register* fV_Register )
-{
- assert( Class_IsSuper( ((FeMesh*)feMesh)->topo, IGraph ) );
-
- return FeVariable_New_Full(
- name,
- context,
- feMesh,
- geometryMesh,
- dofLayout,
- bcs,
- ics,
- linkedDofInfo,
- NULL,
- dofLayout->_totalVarCount,
- dim,
- isCheckpointedAndReloaded,
- isReferenceSolution,
- loadReferenceEachTimestep,
- ((IGraph*)((FeMesh*)feMesh)->topo)->remotes[MT_VERTEX]->comm->mpiComm,
- fV_Register );
-}
-
-FeVariable* FeVariable_New_Full(
- Name name,
- DomainContext* context,
- void* feMesh,
- void* geometryMesh,
- DofLayout* dofLayout,
- void* bcs,
- void* ics,
- void* linkedDofInfo,
- void* templateFeVariable,
- Index fieldComponentCount,
- Dimension_Index dim,
- Bool isCheckpointedAndReloaded,
- Bool isReferenceSolution,
- Bool loadReferenceEachTimestep,
- MPI_Comm communicator,
- FieldVariable_Register* fieldVariable_Register )
-{
- FeVariable* self = (FeVariable*)_FeVariable_DefaultNew( name );
-
- self->isConstructed = True;
- _FieldVariable_Init( (FieldVariable*)self, context, fieldComponentCount, dim, isCheckpointedAndReloaded, communicator, fieldVariable_Register );
- _FeVariable_Init( self, feMesh, geometryMesh, dofLayout, bcs, ics, linkedDofInfo, templateFeVariable, isReferenceSolution, loadReferenceEachTimestep );
-
- return self;
-}
-
-void* _FeVariable_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(FeVariable);
- Type type = FeVariable_Type;
- Stg_Class_DeleteFunction* _delete = _FeVariable_Delete;
- Stg_Class_PrintFunction* _print = _FeVariable_Print;
- Stg_Class_CopyFunction* _copy = _FeVariable_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (Stg_Component_DefaultConstructorFunction*)_FeVariable_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _FeVariable_AssignFromXML;
- Stg_Component_BuildFunction* _build = _FeVariable_Build;
- Stg_Component_InitialiseFunction* _initialise = _FeVariable_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FeVariable_Execute;
- Stg_Component_DestroyFunction* _destroy = _FeVariable_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- FieldVariable_InterpolateValueAtFunction* _interpolateValueAt = _FeVariable_InterpolateValueAt;
- FieldVariable_GetValueFunction* _getMinGlobalFieldMagnitude = _FeVariable_GetMinGlobalFieldMagnitude;
- FieldVariable_GetValueFunction* _getMaxGlobalFieldMagnitude = _FeVariable_GetMaxGlobalFieldMagnitude;
- FieldVariable_GetCoordFunction* _getMinAndMaxLocalCoords = _FeVariable_GetMinAndMaxLocalCoords;
- FieldVariable_GetCoordFunction* _getMinAndMaxGlobalCoords = _FeVariable_GetMinAndMaxGlobalCoords;
- FeVariable_InterpolateWithinElementFunction* _interpolateWithinElement = _FeVariable_InterpolateNodeValuesToElLocalCoord;
- FeVariable_GetValueAtNodeFunction* _getValueAtNode = _FeVariable_GetValueAtNode;
- FeVariable_SyncShadowValuesFunc* _syncShadowValues = _FeVariable_SyncShadowValues;
-
- return _FeVariable_New( FEVARIABLE_PASSARGS ); /* feVariableList */
-}
-
-FeVariable* _FeVariable_New( FEVARIABLE_DEFARGS ) {
- FeVariable* self;
-
- /** Allocate memory */
- assert( _sizeOfSelf >= sizeof(FeVariable) );
-
- self = (FeVariable*) _FieldVariable_New( FIELDVARIABLE_PASSARGS );
-
- /** General info */
-
- /** Virtual functions */
- self->_interpolateWithinElement = _interpolateWithinElement;
- self->_getValueAtNode = _getValueAtNode;
- self->_syncShadowValues = _syncShadowValues;
-
- /** FeVariable info */
-
- return self;
-}
-
-
-void _FeVariable_Init(
- FeVariable* self,
- void* feMesh,
- void* geometryMesh,
- DofLayout* dofLayout,
- void* bcs,
- void* ics,
- void* linkedDofInfo,
- void* templateFeVariable,
- Bool isReferenceSolution,
- Bool loadReferenceEachTimestep )
-{
- Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
- /** General and Virtual info should already be set */
-
- /** FeVariable info */
- self->debug = Stream_RegisterChild( StgFEM_Discretisation_Debug, self->type );
- self->feMesh = Stg_CheckType( feMesh, FeMesh );
- /** Set pointer for geometry mesh - if none is provided then it'll use the feMesh */
- self->geometryMesh = ( geometryMesh ? Stg_CheckType( geometryMesh, FeMesh ) : Stg_CheckType( feMesh, FeMesh ) );
- self->dofLayout = dofLayout;
- if ( bcs )
- self->bcs = Stg_CheckType( bcs, VariableCondition );
- if ( ics )
- self->ics = Stg_CheckType( ics, VariableCondition );
- if ( linkedDofInfo )
- self->linkedDofInfo = Stg_CheckType( linkedDofInfo, LinkedDofInfo );
- self->shadowValuesSynchronised = False;
-
- if ( templateFeVariable )
- self->templateFeVariable = Stg_CheckType( templateFeVariable, FeVariable );
- if( !isReferenceSolution ) {
- if ( self->templateFeVariable ) {
- self->eqNum = self->templateFeVariable->eqNum;
- }
- else {
- self->eqNum = FeEquationNumber_New( defaultFeVariableFeEquationNumberName, self->context, self->feMesh, self->dofLayout, self->bcs, (LinkedDofInfo*)linkedDofInfo );
- self->eqNum->removeBCs = self->removeBCs;
- }
- }
- else
- self->eqNum = NULL;
-
- self->isReferenceSolution = isReferenceSolution;
- self->loadReferenceEachTimestep = loadReferenceEachTimestep;
- Journal_Firewall( (self->loadReferenceEachTimestep != True), errorStream, "The loadReferenceEachTimestep feature isn't implemented yet, sorry.\n" );
-
- self->dynamicBCs[0] = NULL;
- self->dynamicBCs[1] = NULL;
- self->dynamicBCs[2] = NULL;
-
- self->buildEqNums = True;
-
- self->inc = IArray_New();
-}
-
-void _FeVariable_Delete( void* variable ) {
- FeVariable* self = (FeVariable*)variable;
- Journal_DPrintf( self->debug, "In %s- for \"%s\":\n", __func__, self->name );
-
- /** Stg_Class_Delete parent*/
- _Stg_Component_Delete( self );
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-/** --- Virtual Function Implementations --- */
-
-void _FeVariable_Print( void* variable, Stream* stream ) {
- FeVariable* self = (FeVariable*)variable;
-
- /** General info */
- Journal_Printf( stream, "FeVariable (ptr): %p\n", self );
-
- /** Print parent */
- _Stg_Component_Print( self, stream );
-
- /** Virtual info */
-
- /** FeVariable info */
- Stg_Class_Print( self->feMesh, stream );
- if ( self->dofLayout ) {
- Stg_Class_Print( self->dofLayout, stream );
- }
- else {
- Journal_Printf( stream, "\tdofLayout: (null)... not provided (may be Operator type)\n" );
- }
- if ( self->bcs ) {
- Stg_Class_Print( self->bcs, stream );
- }
- else {
- Journal_Printf( stream, "\tbcs: (null)... not provided (may be Operator type)\n" );
- }
- if ( self->ics ) {
- Stg_Class_Print( self->ics, stream );
- }
- else {
- Journal_Printf( stream, "\tics: (null)... not provided (may be Operator type)\n" );
- }
-
- if ( self->linkedDofInfo ) {
- Stg_Class_Print( self->linkedDofInfo, stream );
- }
- else {
- Journal_Printf( stream, "\tlinkedDofInfo: (null)... not provided\n" );
- }
-
- if( self->eqNum ) {
- Stg_Class_Print( self->eqNum, stream );
- }
- else {
- Journal_Printf( stream, "\teqNum: (null)... not built yet\n" );
- }
-}
-
-void* _FeVariable_Copy( const void* feVariable, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- FeVariable* self = (FeVariable*)feVariable;
- FeVariable* newFeVariable;
- PtrMap* map = ptrMap;
- Bool ownMap = False;
-
- if( !map ) {
- map = PtrMap_New( 10 );
- ownMap = True;
- }
-
- newFeVariable = (FeVariable*)_FieldVariable_Copy( self, dest, deep, nameExt, map );
-
- newFeVariable->templateFeVariable = self->templateFeVariable;
-
- if( deep ) {
- newFeVariable->debug = self->debug;
- newFeVariable->feMesh = (FeMesh*)Stg_Class_Copy( self->feMesh, NULL, deep, nameExt, map );
- newFeVariable->dofLayout = (DofLayout*)Stg_Class_Copy( self->dofLayout, NULL, deep, nameExt, map );
- newFeVariable->bcs = (VariableCondition*)Stg_Class_Copy( self->bcs, NULL, deep, nameExt, map );
- newFeVariable->ics = self->ics ? (VariableCondition*)Stg_Class_Copy( self->ics, NULL, deep, nameExt, map ) : NULL;
- if ( self->linkedDofInfo == NULL ) {
- newFeVariable->linkedDofInfo = NULL;
- }
- else {
- newFeVariable->linkedDofInfo = (LinkedDofInfo*)Stg_Class_Copy( self->linkedDofInfo, NULL,
- deep, nameExt, map );
- }
-
- if( !self->isReferenceSolution ) {
- if ( self->templateFeVariable ) {
- newFeVariable->eqNum = self->eqNum;
- }
- else {
- newFeVariable->eqNum = (FeEquationNumber*)Stg_Class_Copy( self->eqNum, NULL, deep, nameExt, map );
- }
- }
- else
- newFeVariable->eqNum = NULL;
- }
- else {
- newFeVariable->debug = self->debug;
- newFeVariable->feMesh = self->feMesh;
- newFeVariable->geometryMesh = self->geometryMesh;
- newFeVariable->dofLayout = self->dofLayout;
- newFeVariable->bcs = self->bcs;
- newFeVariable->ics = self->ics;
- newFeVariable->linkedDofInfo = self->linkedDofInfo;
- newFeVariable->eqNum = self->eqNum;
- }
-
- if( ownMap ) {
- Stg_Class_Delete( map );
- }
-
- return (void*)newFeVariable;
-}
-
-
-void _FeVariable_Build( void* variable, void* data ) {
- FeVariable* self = (FeVariable*)variable;
- DomainContext* context = (DomainContext*)data;
- unsigned dim, numNodes;
-
- if ( False == self->isBuilt ) {
- self->isBuilt = True;
-
- Journal_DPrintf( self->debug, "In %s- for %s:\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
-
- /** build the BCs */
- Stg_Component_Build( self->feMesh, data, False );
- if ( self->dofLayout ) Stg_Component_Build( self->dofLayout, data, False );
- if ( self->bcs ) Stg_Component_Build( self->bcs, data, False );
-
- /** only bother building the ics specified via XML/construct if we are not in restart mode
- - otherwise, we will use the checkpointed values anyway */
- if ( self->ics && !(context && (True == context->loadFromCheckPoint) ) ) {
- Stg_Component_Build( self->ics, data, False );
- }
-
- if ( self->linkedDofInfo ) Stg_Component_Build( self->linkedDofInfo, data, False );
-
-
- /** Extract component count. */
- if ( self->dofLayout ) self->fieldComponentCount = self->dofLayout->_totalVarCount;
-
- dim = Mesh_GetDimSize(self->feMesh);
- /** allocate GNx here */
- /* At least this will work for meshes with names other
- than those listed above. I spent three hours finding
- this out.*/
- numNodes = FeMesh_GetElementNodeSize(self->feMesh, 0);
-
- self->GNx = Memory_Alloc_2DArray( double, dim, numNodes, (Name)"Global Shape Function Derivatives" );
-
- /** don't build the equation numbers for fields that aren't being solved for
- * (ie: error and reference fields) */
- if( !self->isReferenceSolution && self->buildEqNums ) {
- Stg_Component_Build( self->eqNum, data, False );
- }
-
- Stream_UnIndentBranch( StgFEM_Debug );
- }
-}
-
-void _FeVariable_AssignFromXML( void* variable, Stg_ComponentFactory* cf, void* data ) {
- FeVariable* self = (FeVariable*)variable;
- FeMesh* feMesh = NULL;
- FeMesh* geometryMesh = NULL;
- DofLayout* dofLayout = NULL;
- VariableCondition* bc = NULL;
- VariableCondition* ic = NULL;
- LinkedDofInfo* linkedDofInfo = NULL;
- Bool isReferenceSolution = False;
- Bool loadReferenceEachTimestep = False;
-
- _FieldVariable_AssignFromXML( self, cf, data );
-
- feMesh = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"FEMesh", FeMesh, True, data );
- geometryMesh = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"GeometryMesh", FeMesh, False, data );
- dofLayout = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)DofLayout_Type, DofLayout, True, data );
-
- ic = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"IC", VariableCondition, False, data );
- bc = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"BC", VariableCondition, False, data );
- linkedDofInfo = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"LinkedDofInfo", LinkedDofInfo, False, data );
-
- isReferenceSolution = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"isReferenceSolution", False );
- loadReferenceEachTimestep = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"loadReferenceEachTimestep", False );
-
- /** TODO: should really be a parameter */
- self->removeBCs = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"removeBCs", True );
-
- _FeVariable_Init( self, feMesh, geometryMesh, dofLayout, bc, ic, linkedDofInfo, NULL, isReferenceSolution, loadReferenceEachTimestep );
-}
-
-void _FeVariable_Initialise( void* variable, void* data ) {
- FeVariable* self = (FeVariable*)variable;
- DomainContext* context = self->context;
- char* inputPathString = NULL;
- Dictionary_Entry_Value* feVarsList = NULL;
-
- Journal_DPrintf( self->debug, "In %s- for %s:\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
-
- /** do basic mesh initialisation */
- Stg_Component_Initialise( self->feMesh, data, False );
- Stg_Component_Initialise( self->dofLayout, data, False );
-
- if ( self->linkedDofInfo ) {
- Stg_Component_Initialise( self->linkedDofInfo, data, False );
- }
-
- if( !self->isReferenceSolution ) {
- Stg_Component_Initialise( self->eqNum, data, False );
- }
-
- if ( context ) {
- /** Get the input path string once here - single point of control */
- inputPathString = Context_GetCheckPointReadPrefixString( context );
- }
- /** If the reference solution option is enabled, just load this up regardless of checkpointing options below.
- * Want to allow option of disabling this feature, if you're manually setting up a FeVariable without a context etc. */
- if ( context && self->isReferenceSolution ) {
- char * filename = NULL;
- Journal_DPrintf( self->debug, "Reference FeVariable -> loading nodal values from file.\n" );
-
-
-#ifdef READ_HDF5
- Stg_asprintf( &filename, "%s%s.%.5u.h5", inputPathString, self->name, context->restartTimestep );
-#else
- Stg_asprintf( &filename, "%s%s.%.5u.dat", inputPathString, self->name, context->restartTimestep );
-#endif
- FeVariable_ReadFromFile( self, filename );
-
- Memory_Free( filename );
- Stream_UnIndentBranch( StgFEM_Debug );
- return;
- }
-
- /** Setting up whether to load from checkpointing */
- if ( self->ics || ((context && (True == context->loadFromCheckPoint) )&& (self->isCheckpointedAndReloaded)) ) {
- Journal_DPrintf( self->debug, "applying the I.C.s for this Variable:\n" );
- Stream_Indent( self->debug );
-
- if ( self->ics && !(context && (True == context->loadFromCheckPoint) && (True == self->isCheckpointedAndReloaded)) ) {
- Journal_DPrintf( self->debug, "regular (non-restart) mode -> applying ICs specified in XML/constructor\n" );
- Stg_Component_Initialise( self->ics, context, False );
- VariableCondition_Apply( self->ics, context );
- }
- else {
- char * filename = NULL;
- Journal_DPrintf( self->debug, "restart from checkpoint mode -> loading checkpointed "
- "nodal values as initial conditions, ignoring ics specified via XML/constructor\n" );
-
-#ifdef READ_HDF5
- Stg_asprintf( &filename, "%s%s.%.5u.h5", inputPathString, self->name, context->restartTimestep );
- if (!context->interpolateRestart)
- FeVariable_ReadFromFile( self, filename );
- else {
- char * meshFilename = NULL;
- if (!strcmp(self->feMesh->generator->type, CartesianGenerator_Type))
- Stg_asprintf( &meshFilename, "%sMesh.%s.%.5u.h5", inputPathString, self->feMesh->name, context->restartTimestep );
- else
- Stg_asprintf( &meshFilename, "%sMesh.%s.%.5u.h5", inputPathString, ((C0Generator*)(self->feMesh->generator))->elMesh->name, context->restartTimestep );
- FeVariable_InterpolateFromFile( self, context, filename, meshFilename );
- Memory_Free( meshFilename );
- }
-
-#else
- Stg_asprintf( &filename, "%s%s.%.5u.dat", inputPathString, self->name, context->restartTimestep );
- FeVariable_ReadFromFile( self, filename );
-#endif
-
- Memory_Free( filename );
-
- }
- }
- Memory_Free( inputPathString );
- Stream_UnIndent( self->debug );
-
- if( context ) {
- /** also include check to see if this fevariable should be checkpointed, just incase it didn't go through the
- fieldvariable construct phase */
- feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"fieldVariablesToCheckpoint" );
- if ( NULL == feVarsList ) {
- feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"FieldVariablesToCheckpoint" );
- }
- if (feVarsList != NULL ) {
- Index listLength = Dictionary_Entry_Value_GetCount( feVarsList );
- Index var_I = 0;
- Dictionary_Entry_Value* feVarDictValue = NULL;
- char* fieldVariableName;
-
- for ( var_I = 0; var_I < listLength; var_I++ ) {
- feVarDictValue = Dictionary_Entry_Value_GetElement( feVarsList, var_I );
- fieldVariableName = Dictionary_Entry_Value_AsString( feVarDictValue );
- if ( 0 == strcmp( self->name, fieldVariableName ) ) {
- self->isCheckpointedAndReloaded = True;
- break;
- }
- }
- }
-
- feVarsList = NULL;
- /** also include check to see if this fevariable should be saved for analysis purposes */
- feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"fieldVariablesToSave" );
- if ( NULL == feVarsList ) {
- feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"FieldVariablesToSave" );
- }
- if (feVarsList != NULL ) {
- Index listLength = Dictionary_Entry_Value_GetCount( feVarsList );
- Index var_I = 0;
- Dictionary_Entry_Value* feVarDictValue = NULL;
- char* fieldVariableName;
-
- for ( var_I = 0; var_I < listLength; var_I++ ) {
- feVarDictValue = Dictionary_Entry_Value_GetElement( feVarsList, var_I );
- fieldVariableName = Dictionary_Entry_Value_AsString( feVarDictValue );
- if ( 0 == strcmp( self->name, fieldVariableName ) ) {
- self->isSavedData = True;
- break;
- }
- }
- }
- }
-
- if ( self->bcs ) {
- Stg_Component_Initialise( self->bcs, context, False );
- Journal_DPrintf( self->debug, "applying the B.C.s for this Variable.\n" );
- VariableCondition_Apply( self->bcs, context );
- }
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void FeVariable_ApplyBCs( void* variable, void* data ) {
- FeVariable* self = (FeVariable*)variable;
-
- /** This is an unpleasant hack; we really need to reevaluate our BC code. */
- if( self->dynamicBCs[0] ) {
- VariableCondition_Apply( self->dynamicBCs[0], data );
- }
- if( self->dynamicBCs[1] ) {
- VariableCondition_Apply( self->dynamicBCs[1], data );
- }
- if( self->dynamicBCs[2] ) {
- VariableCondition_Apply( self->dynamicBCs[2], data );
- }
- if ( self->bcs ) {
- Journal_DPrintf( self->debug, "In %s- for %s:\n", __func__, self->name );
- Journal_DPrintf( self->debug, "applying the B.C.s for this Variable.\n" );
- VariableCondition_Apply( self->bcs, data );
- }
-}
-
-Bool FeVariable_IsBC( void* variable, int node, int dof ) {
- FeVariable* self = (FeVariable*)variable;
-
- assert( self );
- if( self->dynamicBCs[0] &&
- self->dynamicBCs[0]->var == DofLayout_GetVariable( self->dofLayout, node, dof ) &&
- IMap_Has( self->dynamicBCs[0]->vcMap, node ) )
- {
- return True;
- }
-
- if( self->dynamicBCs[1] &&
- self->dynamicBCs[1]->var == DofLayout_GetVariable( self->dofLayout, node, dof ) &&
- IMap_Has( self->dynamicBCs[1]->vcMap, node ) )
- {
- return True;
- }
-
- if( self->dynamicBCs[2] &&
- self->dynamicBCs[2]->var == DofLayout_GetVariable( self->dofLayout, node, dof ) &&
- IMap_Has( self->dynamicBCs[2]->vcMap, node ) )
- {
- return True;
- }
-
- if( self->bcs &&
- VariableCondition_IsCondition( self->bcs, node, self->dofLayout->varIndices[node][dof] ) )
- {
- return True;
- }
-
- return False;
-}
-
-
-void _FeVariable_Execute( void* variable, void* data ) {
-}
-
-void _FeVariable_Destroy( void* variable, void* data ) {
- FeVariable* self = (FeVariable*)variable;
-
- Memory_Free( self->GNx );
-
- Stream_IndentBranch( StgFEM_Debug );
-
- if( self->eqNum && ( NULL == self->templateFeVariable ) ) {
- _Stg_Component_Delete( self->eqNum );
- self->eqNum = NULL;
- }
- /** feMesh bc and doflayout are purposely not deleted */
-
- if( self->inc == NULL ) {
- NewClass_Delete( self->inc );
- self->inc = NULL;
- }
-
- _FieldVariable_Destroy( self, data );
-}
-
-void FeVariable_PrintLocalDiscreteValues( void* variable, Stream* stream ) {
- FeVariable* self = (FeVariable*)variable;
-
- Journal_Printf( stream, "In %s: for FeVariable \"%s\":\n", __func__, self->name );
-
- _FeVariable_PrintLocalOrDomainValues( variable, FeMesh_GetNodeLocalSize( self->feMesh ), stream );
-}
-
-unsigned _FeVariable_ClosestNode( FeVariable* self, double* crd ) {
- assert( self );
- return Mesh_NearestVertex( self->feMesh, crd );
-}
-
-
-InterpolationResult _FeVariable_InterpolateValueAt( void* variable, double* globalCoord, double* value ) {
- FeVariable* self = (FeVariable*)variable;
- Element_DomainIndex elementCoordIn = (unsigned)-1;
- Coord elLocalCoord={0,0,0};
- InterpolationResult retValue;
-
-
- retValue = FeVariable_GetElementLocalCoordAtGlobalCoord( self, globalCoord, elLocalCoord, &elementCoordIn );
-
- if ( retValue == LOCAL ) {
- /** Now interpolate the value at that coordinate, using shape functions */
- self->_interpolateWithinElement( self, elementCoordIn, elLocalCoord, value );
- }
- else if ( retValue == SHADOW ) {
- if ( False == self->shadowValuesSynchronised ) {
- Stream* warningStr = Journal_Register( Error_Type, (Name)self->type );
- Journal_Printf( warningStr, "Warning - in %s: user asking to interpolate a value at "
- "coord (%g,%g,%g), which is in shadow space, but "
- "FeVariable_SyncShadowValues() hasn't been called yet.\n",
- __func__, globalCoord[0], globalCoord[1], globalCoord[2] );
- return retValue;
- }
- /** Now interpolate the value at that coordinate, using shape functions */
- self->_interpolateWithinElement( self, elementCoordIn, elLocalCoord, value );
- }
-
- return retValue;
-}
-
-
-double _FeVariable_GetMinGlobalFieldMagnitude( void* feVariable ) {
- FeVariable* self = (FeVariable*)feVariable;
- FeMesh* feMesh = self->feMesh;
- int node_lI=0;
- int nodeLocalCount = FeMesh_GetNodeLocalSize( feMesh );
- double min = 0;
- double globalMin = 0;
- double currValue;
-
- min = FeVariable_GetScalarAtNode( self, 0 );
-
- /** Find upper and lower bounds on this processor */
- for ( node_lI = 0 ; node_lI < nodeLocalCount ; node_lI++ ) {
- currValue = FeVariable_GetScalarAtNode( self, node_lI );
- if ( currValue < min ) {
- min = currValue;
- }
- }
-
- /** Find upper and lower bounds on all processors */
- MPI_Allreduce( &min, &globalMin, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD );
- return globalMin;
-}
-
-
-double _FeVariable_GetMaxGlobalFieldMagnitude( void* feVariable ) {
- FeVariable* self = (FeVariable*)feVariable;
- int node_lI=0;
- int nodeLocalCount = FeMesh_GetNodeLocalSize( self->feMesh );
- double max = 0;
- double globalMax = 0;
- double currValue;
-
- max = FeVariable_GetScalarAtNode( self, 0 );
-
- /** Find upper and lower bounds on this processor */
- for ( node_lI = 0 ; node_lI < nodeLocalCount ; node_lI++ ) {
- currValue = FeVariable_GetScalarAtNode( self, node_lI );
- if ( currValue > max ) {
- max = currValue;
- }
- }
-
- /** Find upper and lower bounds on all processors */
- MPI_Allreduce( &max, &globalMax, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD );
- return globalMax;
-}
-
-void _FeVariable_GetMinAndMaxLocalCoords( void* feVariable, double* min, double* max ) {
- FeVariable* self = (FeVariable*)feVariable;
-
- assert( self && Stg_CheckType( self, FeVariable ) );
-
- Mesh_GetLocalCoordRange( self->feMesh, min, max );
-}
-
-
-void _FeVariable_GetMinAndMaxGlobalCoords( void* feVariable, double* min, double* max ) {
- FeVariable* self = (FeVariable*)feVariable;
-
- assert( self && Stg_CheckType( self, FeVariable ) );
-
- Mesh_GetGlobalCoordRange( self->feMesh, min, max );
-}
-
-double FeVariable_GetScalarAtNode( void* feVariable, Node_LocalIndex lNode_I ) {
- FeVariable* self = (FeVariable*)feVariable;
- Dof_Index dofCountThisNode = 0;
- Dof_Index nodeLocalDof_I = 0;
- double value[ MAX_FIELD_COMPONENTS ];
-
- /**
- if( self->type != OperatorFeVariable_Type && self->dofLayout )
- dofCountThisNode = self->dofLayout->dofCounts[lNode_I];
- else {
- */
- dofCountThisNode = self->fieldComponentCount;
- /**
- }
- */
-
- FeVariable_GetValueAtNode( self, lNode_I, value );
-
- if ( dofCountThisNode > 1) {
- double magnitude=0;
- for ( nodeLocalDof_I=0; nodeLocalDof_I < dofCountThisNode; nodeLocalDof_I++ ) {
- magnitude += value[ nodeLocalDof_I ] * value[ nodeLocalDof_I ];
- }
- return sqrt( magnitude );
- }
- else
- return value[0];
-
-}
-
-
-void _FeVariable_GetValueAtNode( void* feVariable, Node_DomainIndex dNode_I, double* value ) {
- FeVariable* self = (FeVariable*)feVariable;
- Variable* currVariable = NULL;
- Dof_Index dofCountThisNode = 0;
- Dof_Index nodeLocalDof_I = 0;
-
- dofCountThisNode = self->dofLayout->dofCounts[dNode_I];
-
- for ( nodeLocalDof_I=0; nodeLocalDof_I < dofCountThisNode; nodeLocalDof_I++ ) {
- currVariable = DofLayout_GetVariable( self->dofLayout, dNode_I, nodeLocalDof_I );
- value[ nodeLocalDof_I ] = Variable_GetValueDouble( currVariable, dNode_I );
- }
-}
-
-/** Finds the value of the field at the node and broadcasts it to the rest of the processors */
-void FeVariable_GetValueAtNodeGlobal( void* feVariable, Node_GlobalIndex gNode_I, double* value ) {
- FeVariable* self = (FeVariable*) feVariable;
- FeMesh* mesh = self->feMesh;
- Element_LocalIndex lNode_I;
- int rootRankL = 0;
- int rootRankG = 0;
- MPI_Comm comm = self->communicator;
-
- /** Find Local Index */
- if ( Mesh_GlobalToDomain( mesh, MT_VERTEX, gNode_I, &lNode_I ) ) {
- /** If node is on local processor, then get value of field */
- FeVariable_GetValueAtNode( self, lNode_I, value );
- MPI_Comm_rank( comm, (int*)&rootRankL );
- }
-
- /** Send to other processors */
- MPI_Allreduce( &rootRankL, &rootRankG, 1, MPI_INT, MPI_MAX, comm );
- MPI_Bcast( value, self->fieldComponentCount, MPI_DOUBLE, rootRankG, comm );
-}
-
-/** Finds the coordinate of the node and broadcasts it to the rest of the processors */
-void FeVariable_GetCoordAtNodeGlobal( void* feVariable, Node_GlobalIndex gNode_I, double* coord ) {
- FeVariable* self = (FeVariable*) feVariable;
- FeMesh* mesh = self->feMesh;
- Element_LocalIndex lNode_I;
- int rootRankL = 0;
- int rootRankG = 0;
- MPI_Comm comm = self->communicator;
-
- /** Find Local Index */
- if ( Mesh_GlobalToDomain( mesh, MT_VERTEX, gNode_I, &lNode_I ) ) {
- /** If node is on local processor, then get value of field */
- memcpy( coord, Mesh_GetVertex( mesh, lNode_I ), self->dim * sizeof(double) );
- MPI_Comm_rank( comm, (int*)&rootRankL );
- }
-
- /** Send to other processors */
- MPI_Allreduce( &rootRankL, &rootRankG, 1, MPI_INT, MPI_MAX, comm );
- MPI_Bcast( coord, self->dim, MPI_DOUBLE, rootRankG, comm );
-}
-
-
-void FeVariable_ZeroField( void* feVariable ) {
- FeVariable* self = (FeVariable*) feVariable;
- double* values = Memory_Alloc_Array( double, self->fieldComponentCount, "tempValues" );
- Index lNode_I, lNodeCount;
-
- lNodeCount = FeMesh_GetNodeLocalSize( self->feMesh );
-
- memset( values, 0, self->fieldComponentCount * sizeof(double) );
-
- for( lNode_I = 0 ; lNode_I < lNodeCount; lNode_I++ ) {
- FeVariable_SetValueAtNode( self, lNode_I, values );
- }
-
- Memory_Free( values );
-}
-
-/** --- Public Functions --- */
-
-InterpolationResult FeVariable_GetElementLocalCoordAtGlobalCoord( void* feVariable, double* globalCoord, double* elLocalCoord,
- Element_DomainIndex* elementCoordInPtr )
-{
- FeVariable* self = (FeVariable*)feVariable;
- InterpolationResult retValue;
- unsigned elInd;
-
- /** locate which mesh element given coord is in : use inclusive upper boundaries to save
- the need to use shadow space if possible */
- if( !Mesh_SearchElements( self->feMesh, globalCoord, &elInd ) ) {
- Bool outsideGlobal = False;
- double min[3], max[3];
- Dimension_Index dim_I=0;
-
- FieldVariable_GetMinAndMaxGlobalCoords( self, min, max );
- for ( dim_I = 0; dim_I < self->dim; dim_I++ ) {
- if ( ( globalCoord[dim_I] < min[dim_I] ) || (globalCoord[dim_I] > max[dim_I] ) ) {
- outsideGlobal = True;
- }
- }
-
- if ( outsideGlobal == True ) {
- return OUTSIDE_GLOBAL;
- }
- else {
- return OTHER_PROC;
- }
- }
- else /** We found the coord is within a local or shadow element */ {
- ElementType* elementType = NULL;
-
- *elementCoordInPtr = elInd;
- if ( elInd < FeMesh_GetElementLocalSize( self->feMesh ) ) {
- retValue = LOCAL;
- }
- else {
- retValue = SHADOW;
- }
-
- /** convert global coordinate to local co-ordinates of element the coord is in */
- elementType = FeMesh_GetElementType( self->feMesh, (*elementCoordInPtr) );
- ElementType_ConvertGlobalCoordToElLocal( elementType, self->feMesh, *elementCoordInPtr,
- globalCoord, elLocalCoord );
- }
-
- return retValue;
-}
-
-
-void FeVariable_SetValueAtNode( void* feVariable, Node_DomainIndex dNode_I, double* componentValues ) {
- FeVariable* self = (FeVariable*)feVariable;
- Dof_Index dofCountThisNode = 0;
- Dof_Index nodeLocalDof_I = 0;
-
- dofCountThisNode = self->dofLayout->dofCounts[dNode_I];
-
- for ( nodeLocalDof_I=0; nodeLocalDof_I < dofCountThisNode; nodeLocalDof_I++ ) {
- DofLayout_SetValueDouble( (self)->dofLayout, dNode_I, nodeLocalDof_I, componentValues[nodeLocalDof_I] );
- }
-}
-
-
-void FeVariable_PrintLocalDiscreteValues_2dBox( void* variable, Stream* stream ) {
- FeVariable* self = (FeVariable*)variable;
- Node_LocalIndex node_lI=0;
- Index x_I, y_I;
- Index ii;
- Dof_Index dof_I=0;
- Dof_Index currNodeNumDofs=0;
- Index nx = 0;
- Index ny = 0;
- double dx = 0;
- double dy = 0;
- DofLayout* dofLayout = self->dofLayout;
- Stream* eStream = Journal_Register( Error_Type, (Name)self->type );
- Index minLocalNodeX;
- Index minLocalNodeY;
- Index maxLocalNodeX;
- Index maxLocalNodeY;
- Grid* vertGrid;
- unsigned inds[2];
- unsigned vertInd;
- double* verts[2];
- unsigned *localOrigin, *localRange;
- double min[2], max[2];
-
- if( ExtensionManager_GetHandle( self->feMesh->info, (Name)"vertexGrid" ) == (unsigned)-1 ||
- Mesh_GetDimSize( self->feMesh ) != 2 )
- {
- Journal_Printf( eStream, "Warning: %s called on variable \"%s\", but this isn't stored on a "
- "regular 2D mesh - so just returning.\n", __func__, self->name );
- return;
- }
-
- vertGrid = *(Grid**)ExtensionManager_Get( self->feMesh->info, self->feMesh,
- ExtensionManager_GetHandle( self->feMesh->info, (Name)"vertexGrid" ) );
- localOrigin = (unsigned* )ExtensionManager_Get( self->feMesh->info, self->feMesh,
- ExtensionManager_GetHandle( self->feMesh->info, (Name)"localOrigin" ) );
- localRange = (unsigned* )ExtensionManager_Get( self->feMesh->info, self->feMesh,
- ExtensionManager_GetHandle( self->feMesh->info, (Name)"localRange" ) );
-
- memcpy( inds, localOrigin, Mesh_GetDimSize( self->feMesh ) * sizeof(unsigned) );
- insist( Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, Grid_Project( vertGrid, inds ), &vertInd ), == True );
- verts[0] = Mesh_GetVertex( self->feMesh, vertInd );
- inds[0]++;
- inds[1]++;
- insist( Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, Grid_Project( vertGrid, inds ), &vertInd ), == True );
- verts[1] = Mesh_GetVertex( self->feMesh, vertInd );
-
- nx = vertGrid->sizes[0];
- ny = vertGrid->sizes[1];
- dx = verts[1][0] - verts[0][0];
- dy = verts[1][1] - verts[0][1];
-
-
-
- minLocalNodeX = localOrigin[0];
- minLocalNodeY = localOrigin[1];
- maxLocalNodeX = minLocalNodeX + localRange[0] + 1;
- maxLocalNodeY = minLocalNodeY + localRange[1] + 1;
-
- Mesh_GetGlobalCoordRange( self->feMesh, min, max );
-
- Journal_Printf( stream, "display of Values in 2D box X:{%5.2f-%5.2f}, Y:{%5.2f-%5.2f}\n",
- min[I_AXIS], max[I_AXIS],
- min[J_AXIS], max[J_AXIS] );
- Journal_Printf( stream, "\twith %d elements in X (dx=%5.2f) and %d elements in Y (dy=%5.2f)\n\n",
- nx-1, dx, ny-1, dy );
-
- /**Header*/
- for (ii=0;ii<10;ii++) Journal_Printf( stream, " " );
- for ( x_I=0; x_I < nx; x_I++ ) {
- Journal_Printf( stream, "| xNode=%3d ", x_I );
- }
- Journal_Printf( stream, "|\n", x_I );
-
- for ( y_I= ny-1; y_I != (unsigned)-1; y_I-- ) {
- /**Blocks */
- for (ii=0;ii<10;ii++) Journal_Printf( stream, " " );
- for ( x_I=0; x_I < nx; x_I++ ) {
- if (y_I == ny-1) {
- Journal_Printf( stream, "-" );
- }
- else if (x_I==0) {
- Journal_Printf( stream, "|" );
- }
- else {
- Journal_Printf( stream, "*" );
- }
- for (ii=0;ii<14;ii++) Journal_Printf( stream, "-" );
- }
- if (y_I == ny-1) {
- Journal_Printf( stream, "-\n" );
- }
- else {
- Journal_Printf( stream, "|\n" );
- }
-
-
- /** Now a row of y values */
- Journal_Printf( stream, "yNode=%3d |", y_I );
- for ( x_I=0; x_I < nx; x_I++ ) {
-
- if ( ( y_I >= minLocalNodeY ) && ( y_I < maxLocalNodeY )
- && ( x_I >= minLocalNodeX ) && ( x_I < maxLocalNodeX ) ) {
-
- inds[0] = x_I;
- inds[1] = y_I;
- node_lI = RegularMeshUtils_Node_3DTo1D( self->feMesh, inds );
- insist( Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, node_lI, &node_lI ), == True );
- currNodeNumDofs = dofLayout->dofCounts[node_lI];
-
- if ( currNodeNumDofs == 1 ) {
- Journal_Printf( stream, " " );
- }
- Journal_Printf( stream, "(" );
- for ( dof_I=0; dof_I < currNodeNumDofs - 1 ; dof_I++ ) {
- Journal_Printf( stream, "%5.2f,", DofLayout_GetValueDouble( dofLayout, node_lI, dof_I ) );
- }
- Journal_Printf( stream, "%5.2f )", DofLayout_GetValueDouble( dofLayout, node_lI, dof_I ) );
-
- if ( currNodeNumDofs == 1 ) {
- Journal_Printf( stream, " " );
- }
- Journal_Printf( stream, "|" );
- }
- else {
- for (ii=0;ii<14;ii++) Journal_Printf( stream, "X" );
- Journal_Printf( stream, "|" );
- }
- }
- Journal_Printf( stream, "\n" );
- }
-
- /**Blocks */
- for (ii=0;ii<10;ii++) Journal_Printf( stream, " " );
- for ( x_I=0; x_I < nx; x_I++ ) {
- Journal_Printf( stream, "-" );
- for (ii=0;ii<14;ii++) Journal_Printf( stream, "-" );
- }
- Journal_Printf( stream, "-\n", x_I );
-}
-
-
-Bool FeVariable_InterpolateDerivativesAt( void* variable, double* globalCoord, double* value ) {
- FeVariable* self = (FeVariable*)variable;
- Element_DomainIndex elementCoordIn = (unsigned)-1;
- Coord elLocalCoord = {0,0,0};
-
- /** Need a special rule for points on this processor's boundary: instead of the normal
- rule, "round" the point to lie inside the local space, rather than shadow */
-
- /** locate which mesh element given coord is in : use inclusive upper boundaries to save
- the need to use shadow space if possible */
- if ( !Mesh_Algorithms_SearchElements( self->feMesh->algorithms, globalCoord,
- &elementCoordIn ) )
- {
- /** If coord isn't inside domain elements list, bail out */
- return False;
- }
- else /** We found the coord is within a local or shadow element */ {
- if ( elementCoordIn >= FeMesh_GetElementLocalSize( self->feMesh ) ) {
- if ( False == self->shadowValuesSynchronised ) {
- Stream* warningStr = Journal_Register( Error_Type, (Name)self->type );
- Journal_Printf( warningStr, "Warning - in %s: user asking to interpolate derivatives "
- "to coord (%g,%g,%g), which is in shadow space, but "
- "FeVariable_SyncShadowValues() hasn't been called yet.\n",
- __func__, globalCoord[0], globalCoord[1], globalCoord[2] );
- return False;
- }
- }
-
- /** convert global coordinate to local co-ordinates of element the coord is in */
- FeMesh_CoordGlobalToLocal( self->feMesh, elementCoordIn, globalCoord, elLocalCoord );
-
- /** Now interpolate the value at that coordinate, using shape functions */
- FeVariable_InterpolateDerivativesToElLocalCoord( self, elementCoordIn, elLocalCoord, value );
- }
-
- return True;
-}
-
-void FeVariable_InterpolateDerivativesToElLocalCoord( void* _feVariable, Element_DomainIndex lElement_I, Coord elLocalCoord, double* value ) {
- FeVariable* self = (FeVariable*) _feVariable;
- ElementType* elementType = FeMesh_GetElementType( self->feMesh, lElement_I );
- double** GNx;
- double detJac;
- Dimension_Index dim = self->dim;
-
- GNx = self->GNx;
-
- /** Evaluate Global Shape Functions */
- ElementType_ShapeFunctionsGlobalDerivs(
- elementType,
- self->feMesh, lElement_I,
- elLocalCoord, dim, &detJac, GNx );
-
- /** Do Interpolation */
- FeVariable_InterpolateDerivatives_WithGNx( self, lElement_I, GNx, value );
-}
-
-void FeVariable_InterpolateDerivatives_WithGNx( void* _feVariable, Element_LocalIndex lElement_I, double** GNx, double* value ) {
- FeVariable* self = (FeVariable*) _feVariable;
- Node_ElementLocalIndex elLocalNode_I;
- Node_LocalIndex lNode_I;
- Dof_Index dof_I;
- Dof_Index dofCount;
- /* Variable* dofVariable; */
- double nodeValue;
- unsigned nInc, *inc;
- Dimension_Index dim = self->dim;
- double* tmpVal;
-
- /** Gets number of degrees of freedom - assuming it is the same throughout the mesh */
- dofCount = self->dofLayout->dofCounts[0];
-
- /** Initialise */
- memset( value, 0, sizeof( double ) * dofCount * dim );
- tmpVal = (double*)malloc( dim*dofCount*sizeof(double) );
-
- FeMesh_GetElementNodes( self->feMesh, lElement_I, self->inc );
- nInc = IArray_GetSize( self->inc );
- inc = (unsigned*)IArray_GetPtr( self->inc );
-
- /** Interpolate derivative from nodes */
- for ( elLocalNode_I = 0 ; elLocalNode_I < nInc ; elLocalNode_I++) {
-
- lNode_I = inc[ elLocalNode_I ];
- FeVariable_GetValueAtNode( self, lNode_I, tmpVal );
- /*dofVariable = DofLayout_GetVariable( self->dofLayout, lNode_I, dof_I );*/
- /*nodeValue = Variable_GetValueDouble( dofVariable, lNode_I );*/
-
- for ( dof_I = 0 ; dof_I < dofCount ; dof_I++ ) {
- nodeValue = tmpVal[dof_I];
-
- value[dof_I*dim + 0] += GNx[0][elLocalNode_I] * nodeValue;
- value[dof_I*dim + 1] += GNx[1][elLocalNode_I] * nodeValue;
- if( dim == 3 )
- value[dof_I*dim + 2] += GNx[2][elLocalNode_I] * nodeValue;
- }
- }
-
- free( tmpVal );
-}
-
-void FeVariable_InterpolateValue_WithNi( void* _feVariable, Element_LocalIndex lElement_I, double* Ni, double* value ) {
- FeVariable* self = (FeVariable*) _feVariable;
- Node_ElementLocalIndex elLocalNode_I;
- Node_LocalIndex lNode_I;
- Dof_Index dof_I;
- Dof_Index dofCount;
- Variable* dofVariable;
- double nodeValue;
- unsigned nInc, *inc;
-
- /** Gets number of degrees of freedom - assuming it is the same throughout the mesh */
- dofCount = self->dofLayout->dofCounts[0];
-
- /** Initialise */
- memset( value, 0, sizeof( double ) * dofCount );
-
- FeMesh_GetElementNodes( self->feMesh, lElement_I, self->inc );
- nInc = IArray_GetSize( self->inc );
- inc = (unsigned*)IArray_GetPtr( self->inc );
-
- for ( dof_I = 0 ; dof_I < dofCount ; dof_I++ ) {
- /** Interpolate derivative from nodes */
- for ( elLocalNode_I = 0 ; elLocalNode_I < nInc ; elLocalNode_I++) {
- lNode_I = inc[ elLocalNode_I ];
- dofVariable = DofLayout_GetVariable( self->dofLayout, lNode_I, dof_I );
- nodeValue = Variable_GetValueDouble( dofVariable, lNode_I );
-
- value[dof_I] += Ni[elLocalNode_I] * nodeValue;
- }
- }
-}
-
-void FeVariable_GetMinimumSeparation( void* feVariable, double* minSeparationPtr, double minSeparationEachDim[3] ) {
- FeVariable* self = (FeVariable*)feVariable;
-
- assert( self && Stg_CheckType( self, FeVariable ) );
-
- Mesh_GetMinimumSeparation( self->feMesh, minSeparationPtr, minSeparationEachDim );
-}
-
-
-void _FeVariable_SyncShadowValues( void* feVariable ) {
- FeVariable* self = (FeVariable*)feVariable;
- DofLayout* dofLayout;
- Sync* vertSync;
- unsigned var_i;
-
- assert( self );
-
- /** Shortcuts. */
- dofLayout = self->dofLayout;
- if( !dofLayout ) {
- self->shadowValuesSynchronised = True;
- return;
- }
-
- /** Create a distributed array based on the mesh's vertices. */
- vertSync = Mesh_GetSync( self->feMesh, MT_VERTEX );
-
- /**
- ** For each variable in the dof layout, we need to create a distributed array and update
- ** shadow values.
- */
-
- for( var_i = 0; var_i < dofLayout->_totalVarCount; var_i++ ) {
- unsigned varInd;
- Variable* var;
- unsigned field_i;
-
- /** Get the variable. */
- varInd = dofLayout->_varIndicesMapping[var_i];
- var = Variable_Register_GetByIndex( dofLayout->_variableRegister, varInd );
-
- /** Each field of the variable will need to be handled individually. */
- for( field_i = 0; field_i < var->offsetCount; field_i++ ) {
- unsigned offs, size;
- Stg_Byte *arrayStart, *arrayEnd;
-
- offs = var->offsets[field_i];
- size = var->dataSizes[field_i];
-
- arrayStart = (Stg_Byte*)var->arrayPtr + offs;
- arrayEnd = arrayStart + var->structSize * FeMesh_GetNodeLocalSize( self->feMesh );
- Sync_SyncArray( vertSync, arrayStart, var->structSize,
- arrayEnd, var->structSize,
- size );
- }
- }
-
- self->shadowValuesSynchronised = True;
-
-#if 0
- Neighbour_Index nbr_I = 0;
- Node_Index node_stI = 0;
- Node_DomainIndex node_dI = 0;
- Node_LocalIndex node_lI = 0;
- Dof_Index nodalDof_I = 0;
- Processor_Index nbrRank = 0;
- Index* incomingDofTotals = NULL;
- double** incomingDofValues = NULL;
- MPI_Request** incomingDofValRequests = NULL;
- Node_Index myShadowNodesOnThisNbrCount = 0;
- Dof_Index incomingDof_I;
- Index* outgoingDofTotals = NULL;
- double** outgoingDofValues = NULL;
- MPI_Request** outgoingDofValRequests = NULL;
- Node_Index nbrShadowNodesOnMeCount = 0;
- Dof_Index outgoingDof_I;
- MPI_Status status;
- int incomingDofValueSetsYetToReceive;
- Bool* incomingDofValueSetsReceived;
-
- Journal_DPrintf( self->debug, "In %s- for feVariable \"%s\":\n", __func__, self->name );
- Stream_Indent( self->debug );
-
- if ( ( 1 == mesh->layout->decomp->procsInUse ) || ( 0 == mesh->layout->decomp->shadowDepth ) ) {
- Journal_DPrintf( self->debug, "No shadow nodes: nothing to do - returning.\n" );
- Stream_UnIndent( self->debug );
- return;
- }
-
- self->shadowValuesSynchronised = True;
-
- /** allocate memory for incoming info */
- incomingDofTotals = Memory_Alloc_Array( Index, mesh->procNbrInfo->procNbrCnt, "incomingDofTotals" );
- incomingDofValues = Memory_Alloc_Array( double*, mesh->procNbrInfo->procNbrCnt, "incomingDofValues" );
- incomingDofValRequests = Memory_Alloc_Array( MPI_Request*, mesh->procNbrInfo->procNbrCnt, "incomingDofValRequests" );
- incomingDofValueSetsReceived = Memory_Alloc_Array( Bool, mesh->procNbrInfo->procNbrCnt, "incomingDofValueSets" );
- incomingDofValueSetsYetToReceive = 0;
- for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
- myShadowNodesOnThisNbrCount = mesh->nodeShadowInfo->procShadowCnt[nbr_I];
- incomingDofTotals[nbr_I] = 0;
- incomingDofValues[nbr_I] = NULL;
- incomingDofValRequests[nbr_I] = NULL;
- incomingDofValueSetsReceived[nbr_I] = False;
-
- if ( myShadowNodesOnThisNbrCount > 0 ) {
- for( node_stI = 0; node_stI < myShadowNodesOnThisNbrCount; node_stI++ ) {
- node_dI = mesh->nodeShadowInfo->procShadowTbl[nbr_I][node_stI];
- incomingDofTotals[nbr_I] += self->dofLayout->dofCounts[node_dI];
- }
- incomingDofValues[nbr_I] = Memory_Alloc_Array( double, incomingDofTotals[nbr_I],
- "incomingDofValues[]" );
- incomingDofValRequests[nbr_I] = Memory_Alloc( MPI_Request, "incomingDofValRequest" );
- incomingDofValueSetsYetToReceive++;
- }
- }
- /** allocate memory for outgoing info */
- outgoingDofTotals = Memory_Alloc_Array( Index, mesh->procNbrInfo->procNbrCnt, "outgoingDofTotals" );
- outgoingDofValues = Memory_Alloc_Array( double*, mesh->procNbrInfo->procNbrCnt, "outgoingDofValues" );
- outgoingDofValRequests = Memory_Alloc_Array( MPI_Request*, mesh->procNbrInfo->procNbrCnt, "outgoingDofValRequests" );
- for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
- nbrShadowNodesOnMeCount = mesh->nodeShadowInfo->procShadowedCnt[nbr_I];
- outgoingDofTotals[nbr_I] = 0;
- outgoingDofValues[nbr_I] = NULL;
- outgoingDofValRequests[nbr_I] = NULL;
-
- if ( nbrShadowNodesOnMeCount > 0 ) {
- for( node_stI = 0; node_stI < nbrShadowNodesOnMeCount; node_stI++ ) {
- node_lI = mesh->nodeShadowInfo->procShadowedTbl[nbr_I][node_stI];
- outgoingDofTotals[nbr_I] += self->dofLayout->dofCounts[node_lI];
- }
- outgoingDofValues[nbr_I] = Memory_Alloc_Array( double, outgoingDofTotals[nbr_I],
- "outgoingDofValues[]" );
- outgoingDofValRequests[nbr_I] = Memory_Alloc( MPI_Request, "outgoingDofValRequest" );
- }
- }
-
- Journal_DPrintfL( self->debug, 2, "Starting non-blocking recv's of incoming values\n" );
- Stream_Indent( self->debug );
- for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
- myShadowNodesOnThisNbrCount = mesh->nodeShadowInfo->procShadowCnt[nbr_I];
- if ( myShadowNodesOnThisNbrCount > 0 ) {
- nbrRank = mesh->procNbrInfo->procNbrTbl[nbr_I];
- Journal_DPrintfL( self->debug, 2, "Start recv from proc %u - %u values\n", nbrRank, incomingDofTotals[nbr_I] );
- MPI_Irecv( incomingDofValues[nbr_I], incomingDofTotals[nbr_I], MPI_DOUBLE, nbrRank,
- DOF_VALUES_TAG, self->communicator, incomingDofValRequests[nbr_I] );
- }
- }
- Stream_UnIndent( self->debug );
-
- Journal_DPrintfL( self->debug, 2, "Non-blocking send out required shadow values to neighbours\n" );
- Stream_Indent( self->debug );
- for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
- if ( mesh->nodeShadowInfo->procShadowedCnt[nbr_I] > 0 ) {
- nbrRank = mesh->procNbrInfo->procNbrTbl[nbr_I];
-
- outgoingDof_I = 0;
- for( node_stI = 0; node_stI < mesh->nodeShadowInfo->procShadowedCnt[nbr_I]; node_stI++ ) {
- node_lI = mesh->nodeShadowInfo->procShadowedTbl[nbr_I][node_stI];
- for ( nodalDof_I=0; nodalDof_I < self->dofLayout->dofCounts[node_lI]; nodalDof_I++ ) {
- outgoingDofValues[nbr_I][outgoingDof_I] =
- DofLayout_GetValueDouble( self->dofLayout, node_lI, nodalDof_I );
- outgoingDof_I++;
- }
- }
- Journal_DPrintfL( self->debug, 2, "Start send to proc %u - %u values\n", nbrRank, outgoingDofTotals[nbr_I] );
- MPI_Isend( outgoingDofValues[nbr_I], outgoingDofTotals[nbr_I], MPI_DOUBLE, nbrRank,
- DOF_VALUES_TAG, self->communicator, outgoingDofValRequests[nbr_I] );
- }
- }
- Stream_UnIndent( self->debug );
-
- Journal_DPrintfL( self->debug, 2, "Receiving and updating shadow values I need from neighbours:\n" );
- Stream_Indent( self->debug );
- while ( incomingDofValueSetsYetToReceive > 0 ) {
- int testFlag = 0;
-
- for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
-
- if ( ( mesh->nodeShadowInfo->procShadowCnt[nbr_I] > 0 )
- && ( False == incomingDofValueSetsReceived[nbr_I] ) )
- {
- MPI_Test( incomingDofValRequests[nbr_I], &testFlag, &status );
- if ( False == testFlag ) {
- continue;
- }
- else {
- Journal_DPrintfL( self->debug, 2, "Recv'd a batch of values from proc %u: updating...\n",
- nbrRank );
- /** update the appropriate values from recv'd set */
- incomingDof_I = 0;
- for( node_stI = 0; node_stI < mesh->nodeShadowInfo->procShadowCnt[nbr_I]; node_stI++ ) {
- node_dI = mesh->nodeShadowInfo->procShadowTbl[nbr_I][node_stI];
- for ( nodalDof_I=0; nodalDof_I < self->dofLayout->dofCounts[node_dI]; nodalDof_I++ ) {
- DofLayout_SetValueDouble( self->dofLayout, node_dI, nodalDof_I,
- incomingDofValues[nbr_I][incomingDof_I] );
- incomingDof_I++;
- }
- }
- incomingDofValueSetsReceived[nbr_I] = True;
- incomingDofValueSetsYetToReceive--;
- }
- }
- }
- }
- Journal_DPrintfL( self->debug, 2, "Done.\n" );
- Stream_UnIndent( self->debug );
-
- Journal_DPrintfL( self->debug, 2, "Making sure outgoing sends have completed...\n" );
- for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
- if ( mesh->nodeShadowInfo->procShadowCnt[nbr_I] > 0 ) {
- MPI_Wait( outgoingDofValRequests[nbr_I], &status );
- }
- }
- Journal_DPrintfL( self->debug, 2, "Done.\n" );
-
- /** clean up temporary memory */
- for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
- myShadowNodesOnThisNbrCount = mesh->nodeShadowInfo->procShadowCnt[nbr_I];
- if ( myShadowNodesOnThisNbrCount > 0 ) {
- Memory_Free( incomingDofValues[nbr_I] );
- Memory_Free( incomingDofValRequests[nbr_I] );
- }
- }
- Memory_Free( incomingDofTotals );
- Memory_Free( incomingDofValues );
- Memory_Free( incomingDofValRequests );
- for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
- nbrShadowNodesOnMeCount = mesh->nodeShadowInfo->procShadowedCnt[nbr_I];
- if ( nbrShadowNodesOnMeCount > 0 ) {
- Memory_Free( outgoingDofValues[nbr_I] );
- Memory_Free( outgoingDofValRequests[nbr_I] );
- }
- }
- Memory_Free( outgoingDofTotals );
- Memory_Free( outgoingDofValues );
- Memory_Free( outgoingDofValRequests );
-
- Stream_UnIndent( self->debug );
-#endif
-}
-
-
-void FeVariable_PrintDomainDiscreteValues( void* variable, Stream* stream ) {
- FeVariable* self = (FeVariable*)variable;
-
- Journal_Printf( stream, "In %s: for FeVariable \"%s\":\n", __func__, self->name );
-
- _FeVariable_PrintLocalOrDomainValues( variable, FeMesh_GetNodeDomainSize( self->feMesh ), stream );
-}
-
-void FeVariable_PrintCoordsAndValues( void* _feVariable, Stream* stream ) {
- FeVariable* self = (FeVariable*) _feVariable;
- Node_LocalIndex node_I = 0;
- Node_LocalIndex nodeLocalCount = FeMesh_GetNodeLocalSize( self->feMesh );
- Dof_Index currNodeNumDofs;
- Dof_Index nodeLocalDof_I;
- Variable* currVariable;
- double* nodeCoord;
-
- /** Print Header of stream */
- Journal_Printf( stream, "# FeVariable - %s\n", self->name );
- Journal_Printf( stream, "# x coord | y coord | z coord" );
- currNodeNumDofs = self->dofLayout->dofCounts[ 0 ];
- for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
- currVariable = DofLayout_GetVariable( self->dofLayout, node_I, nodeLocalDof_I );
- Journal_Printf( stream, " | %s", currVariable->name );
- }
- Journal_Printf(stream, "\n");
-
- /** Loop over local nodes */
- for( node_I=0; node_I < nodeLocalCount ; node_I++ ) {
- currNodeNumDofs = self->dofLayout->dofCounts[ node_I ];
-
- /** Get Coordinate of Node */
- nodeCoord = Mesh_GetVertex( self->feMesh, node_I );
- Journal_Printf( stream, "%12.6g %12.6g %12.6g ",
- nodeCoord[ I_AXIS ], nodeCoord[ J_AXIS ], nodeCoord[ K_AXIS ] );
-
- /** Print each dof */
- for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
- currVariable = DofLayout_GetVariable( self->dofLayout, node_I, nodeLocalDof_I );
- Journal_Printf( stream, "%12.6g ", Variable_GetValueDouble( currVariable, node_I ) );
- }
- Journal_Printf( stream, "\n" );
- }
-}
-
-
-/** --- Private Functions --- */
-
-void _FeVariable_InterpolateNodeValuesToElLocalCoord( void* feVariable, Element_DomainIndex element_lI, Coord elLocalCoord, double* value ) {
- FeVariable* self = (FeVariable*) feVariable;
- ElementType* elementType=NULL;
- Dof_Index nodeLocalDof_I=0;
- Dof_Index dofCountThisNode=0;
- Node_ElementLocalIndex elLocalNode_I=0;
- double* shapeFuncsEvaluatedAtCoord=NULL;
- Node_LocalIndex lNode_I=0;
- Variable* currVariable=NULL;
- double dofValueAtCurrNode=0;
- unsigned nInc, *inc;
-
- FeMesh_GetElementNodes( self->feMesh, element_lI, self->inc );
- nInc = IArray_GetSize( self->inc );
- inc = (unsigned*)IArray_GetPtr( self->inc );
-
- /** Gets number of degrees of freedom - assuming it is the same throughout the mesh */
- dofCountThisNode = self->dofLayout->dofCounts[lNode_I];
-
- /** evaluate shape function values of current element at elLocalCoords */
- elementType = FeMesh_GetElementType( self->feMesh, element_lI );
- shapeFuncsEvaluatedAtCoord = AllocArray( double, nInc );
- ElementType_EvaluateShapeFunctionsAt( elementType, elLocalCoord, shapeFuncsEvaluatedAtCoord );
-
- for ( nodeLocalDof_I=0; nodeLocalDof_I < dofCountThisNode; nodeLocalDof_I++ ) {
- value[nodeLocalDof_I] = 0;
- }
-
- /** Now for each node, add that node's contribution at point */
- for ( elLocalNode_I=0; elLocalNode_I < nInc; elLocalNode_I++ ) {
- lNode_I = inc[elLocalNode_I];
-
- for ( nodeLocalDof_I=0; nodeLocalDof_I < dofCountThisNode; nodeLocalDof_I++ ) {
- currVariable = DofLayout_GetVariable( self->dofLayout, lNode_I, nodeLocalDof_I );
- dofValueAtCurrNode = Variable_GetValueDouble( currVariable, lNode_I );
- value[nodeLocalDof_I] += dofValueAtCurrNode * shapeFuncsEvaluatedAtCoord[elLocalNode_I];
- }
- }
- FreeArray( shapeFuncsEvaluatedAtCoord );
-}
-
-void _FeVariable_PrintLocalOrDomainValues( void* variable, Index localOrDomainCount, Stream* stream ) {
- FeVariable* self = (FeVariable*)variable;
- Node_Index node_I = 0;
- Node_GlobalIndex gNode_I = 0;
- Dof_Index currNodeNumDofs;
- Dof_Index nodeLocalDof_I;
- Dof_EquationNumber currEqNum;
- Variable* currVariable;
-
- for( node_I=0; node_I < localOrDomainCount; node_I++ ) {
- gNode_I = FeMesh_NodeDomainToGlobal( self->feMesh, node_I );
- Journal_Printf( stream, "node %d (global index %d):\n", node_I, gNode_I );
-
- currNodeNumDofs = self->fieldComponentCount;
-
-
- /** Print each dof */
- for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
- currVariable = DofLayout_GetVariable( self->dofLayout, node_I, nodeLocalDof_I );
- Journal_Printf( stream, "\tdof %d \"%s\": %6g - ", nodeLocalDof_I, currVariable->name,
- Variable_GetValueDouble( currVariable, node_I ) );
- currEqNum = self->eqNum->destinationArray[node_I][nodeLocalDof_I];
- if ( currEqNum == -1 ) {
- Journal_Printf( stream, "(from BC)", currEqNum );
- }
- else {
- Journal_Printf( stream, "(eq num %d)", currEqNum );
- }
- Journal_Printf( stream, "\n", currEqNum );
- }
- }
-}
-
-InterpolationResult FeVariable_InterpolateFromMeshLocalCoord( void* feVariable, FeMesh* mesh, Element_DomainIndex dElement_I, double* localCoord, double* value ) {
- FeVariable* self = (FeVariable*) feVariable;
-
- if ( mesh == self->feMesh ) {
- /** If the meshes are identical - then we can just interpolate within the elements because the elements are the same */
- FeVariable_InterpolateWithinElement( self, dElement_I, localCoord, value );
- return LOCAL;
- }
- else {
- Coord globalCoord;
-
- /** If the meshes are different - then we must find the global coordinates and interpolate to that */
- FeMesh_CoordLocalToGlobal( mesh, dElement_I, localCoord, globalCoord );
- return FieldVariable_InterpolateValueAt( feVariable, globalCoord, value );
- }
-
-}
-
-/** TODO: can't assume all swarms have particles of type integrationPoint anymore.
- should check that the given swarm does have I.P for the rest of these functions.*/
-double FeVariable_IntegrateElement_AxisIndependent(
- void* feVariable, void* _swarm,
- Element_DomainIndex dElement_I, Dimension_Index dim,
- Axis axis0, Axis axis1, Axis axis2 )
-{
- FeVariable* self = (FeVariable*) feVariable;
- Swarm* swarm = (Swarm*) _swarm;
- FeMesh* feMesh = self->feMesh;
- FeMesh* mesh;
- ElementType* elementType;
- Cell_LocalIndex cell_I;
- Particle_InCellIndex cParticle_I;
- Particle_InCellIndex cellParticleCount;
- IntegrationPoint* particle;
- double detJac;
- double integral;
- double value;
-
- /** Initialise Summation of Integral */
- integral = 0.0;
-
- /** Use feVariable's mesh as geometry mesh if one isn't passed in */
- if( Stg_Class_IsInstance( feMesh->algorithms, Mesh_CentroidAlgorithms_Type ) )
- mesh = (FeMesh*)((Mesh_CentroidAlgorithms*)feMesh->algorithms)->elMesh;
- else
- mesh = feMesh;
- elementType = FeMesh_GetElementType( mesh, dElement_I );
-
- /** Determine number of particles in element */
- cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, dElement_I );
- cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
-
- /** Loop over all particles in element */
- for( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
- /** Get Pointer to particle */
- particle = (IntegrationPoint*) Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
-
- /** Interpolate Value of Field at Particle */
- FeVariable_InterpolateWithinElement( feVariable, dElement_I, particle->xi, &value );
-
- Journal_DPrintfL( self->debug, 3, "%s: Integrating element %d - particle %d - Value = %g\n", self->name, dElement_I, cParticle_I, value );
-
- /** Calculate Determinant of Jacobian */
- detJac = ElementType_JacobianDeterminant_AxisIndependent(
- elementType, mesh, dElement_I, particle->xi, dim, axis0, axis1, axis2 );
-
- /** Sum Integral */
- integral += detJac * particle->weight * value;
- }
-
- return integral;
-}
-
-double FeVariable_Integrate( void* feVariable, void* _swarm ) {
- FeVariable* self = (FeVariable*) feVariable;
- Swarm* swarm = (Swarm*) _swarm;
- FeMesh* feMesh = self->feMesh;
- Element_LocalIndex lElement_I;
- Element_LocalIndex elementLocalCount = FeMesh_GetElementLocalSize( feMesh );
- double integral, integralGlobal;
-
- /** Initialise Summation of Integral */
- integral = 0.0;
-
- /** Loop over all local elements */
- for ( lElement_I = 0 ; lElement_I < elementLocalCount ; lElement_I++ ) {
- integral += FeVariable_IntegrateElement( self, swarm, lElement_I );
- Journal_DPrintfL( self->debug, 3, "%s: Integrating element %d - Accumulated Integral = %g\n", self->name, lElement_I, integral );
- }
-
- /** Gather and sum integrals from other processors */
- MPI_Allreduce( &integral, &integralGlobal, 1, MPI_DOUBLE, MPI_SUM, self->communicator );
-
- return integralGlobal;
-}
-
-double FeVariable_AverageTopLayer( void* feVariable, void* swarm, Axis layerAxis ) {
- FeVariable* self = (FeVariable*) feVariable;
- Grid* elGrid;
-
- elGrid = *(Grid**)ExtensionManager_Get( self->feMesh->info, self->feMesh,
- ExtensionManager_GetHandle( self->feMesh->info, (Name)"elementGrid" ) );
-
- return FeVariable_AverageLayer( self, swarm, layerAxis, elGrid->sizes[1] - 1 );
-}
-
-double FeVariable_AverageBottomLayer( void* feVariable, void* swarm, Axis layerAxis ) {
- FeVariable* self = (FeVariable*) feVariable;
-
- return FeVariable_AverageLayer( self, swarm, layerAxis, 0 );
-}
-
-double FeVariable_AverageLayer( void* feVariable, void* swarm, Axis layerAxis, Index layerIndex ) {
- FeVariable* self = (FeVariable*) feVariable;
- Axis aAxis = ( layerAxis == I_AXIS ? J_AXIS : I_AXIS );
- Axis bAxis = ( layerAxis == K_AXIS ? J_AXIS : K_AXIS );
- Dimension_Index dim = self->dim;
- double integral;
- double layerThickness = 0.0;
- double sendThickness;
- Grid* vertGrid;
- unsigned* inds;
- double heights[2];
- unsigned localInd[2], globalInd[2];
- double *min, *max;
- int d_i;
-
- integral = FeVariable_IntegrateLayer( self, swarm, layerAxis, layerIndex );
-
- /** Calculate layer thickness. This assumes the mesh is regular. */
- vertGrid = *(Grid**)ExtensionManager_Get( self->feMesh->info, self->feMesh,
- ExtensionManager_GetHandle( self->feMesh->info, (Name)"vertexGrid" ) );
- inds = Memory_Alloc_Array_Unnamed( unsigned, Mesh_GetDimSize( self->feMesh ) );
- for( d_i = 0; d_i < Mesh_GetDimSize( self->feMesh ); d_i++ ) {
- if( d_i != layerAxis )
- inds[d_i] = 0;
- else
- inds[d_i] = layerIndex;
- }
- globalInd[0] = Grid_Project( vertGrid, inds );
- inds[layerAxis]++;
- globalInd[1] = Grid_Project( vertGrid, inds );
- if( Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, globalInd[0], &localInd[0] ) &&
- Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, globalInd[1], &localInd[1] ) )
- {
- heights[0] = Mesh_GetVertex( self->feMesh, localInd[0] )[layerAxis];
- heights[1] = Mesh_GetVertex( self->feMesh, localInd[1] )[layerAxis];
- sendThickness = heights[1] - heights[0];
- }
- else {
- sendThickness = 0.0;
- }
- MPI_Allreduce( &sendThickness, &layerThickness, 1, MPI_DOUBLE, MPI_MAX, self->communicator );
- FreeArray( inds );
-
- min = Memory_Alloc_Array_Unnamed( double, Mesh_GetDimSize( self->feMesh ) );
- max = Memory_Alloc_Array_Unnamed( double, Mesh_GetDimSize( self->feMesh ) );
- Mesh_GetGlobalCoordRange( self->feMesh, min, max );
- integral /= layerThickness * (max[aAxis] - min[aAxis]);
- if ( dim == 3 )
- integral /= max[ bAxis ] - min[ bAxis ];
- FreeArray( min );
- FreeArray( max );
-
- return integral;
-}
-
-
-double FeVariable_IntegrateLayer_AxisIndependent(
- void* feVariable, void* _swarm,
- Axis layerAxis, Index layerIndex, Dimension_Index dim,
- Axis axis0, Axis axis1, Axis axis2 )
-{
- FeVariable* self = (FeVariable*) feVariable;
- Swarm* swarm = (Swarm*) _swarm;
- Element_LocalIndex lElement_I;
- Element_GlobalIndex gElement_I;
- IJK elementIJK;
- double elementIntegral;
- double integral;
- double integralGlobal;
-
- Journal_DPrintf( self->debug, "In %s() for FeVariable \"%s\":\n", __func__, self->name );
-
- /** Initialise Sumation of Integral */
- integral = 0.0;
-
- Stream_Indent( self->debug );
- for ( gElement_I = 0 ; gElement_I < FeMesh_GetElementGlobalSize( self->feMesh ); gElement_I++ ) {
- RegularMeshUtils_Element_1DTo3D( self->feMesh, gElement_I, elementIJK );
-
- /** Check if element is in layer plane */
- if ( elementIJK[ layerAxis ] != layerIndex )
- continue;
-
- /** Check if element is local */
- if( !FeMesh_ElementGlobalToDomain( self->feMesh, gElement_I, &lElement_I ) ||
- lElement_I >= FeMesh_GetElementLocalSize( self->feMesh ) )
- {
- continue;
- }
-
- elementIntegral = FeVariable_IntegrateElement_AxisIndependent( self, swarm, lElement_I, dim, axis0, axis1, axis2 );
- Journal_DPrintfL( self->debug, 2, "Integral of element %d was %f\n", lElement_I, elementIntegral );
- integral += elementIntegral;
- }
- Stream_UnIndent( self->debug );
-
-
- /** Gather and sum integrals from other processors */
- MPI_Allreduce( &integral, &integralGlobal, 1, MPI_DOUBLE, MPI_SUM, self->communicator );
-
- Journal_DPrintf( self->debug, "Calculated global integral of layer %d in Axis %d was %f\n", layerIndex, layerAxis, integralGlobal );
- return integralGlobal;
-}
-
-
-double FeVariable_AveragePlane( void* feVariable, Axis planeAxis, double planeHeight ) {
- FeVariable* self = (FeVariable*) feVariable;
- double integral;
- Axis aAxis = ( planeAxis == I_AXIS ? J_AXIS : I_AXIS );
- Axis bAxis = ( planeAxis == K_AXIS ? J_AXIS : K_AXIS );
- Dimension_Index dim = self->dim;
- double min[3], max[3];
-
- integral = FeVariable_IntegratePlane( self, planeAxis, planeHeight );
-
- Mesh_GetGlobalCoordRange( self->feMesh, min, max );
-
- integral /= max[ aAxis ] - min[ aAxis ];
- if ( dim == 3 )
- integral /= max[ bAxis ] - min[ bAxis ];
-
- return integral;
-}
-
-double FeVariable_IntegratePlane( void* feVariable, Axis planeAxis, double planeHeight ) {
- FeVariable* self = (FeVariable*) feVariable;
- IJK planeIJK;
- Element_LocalIndex lElement_I;
- Element_GlobalIndex gElement_I;
- Element_LocalIndex elementLocalCount = FeMesh_GetElementLocalSize( self->feMesh );
- Axis aAxis = ( planeAxis == I_AXIS ? J_AXIS : I_AXIS );
- Axis bAxis = ( planeAxis == K_AXIS ? J_AXIS : K_AXIS );
- double integral;
- /** Swarm Stuff */
- Swarm* tmpSwarm;
- Bool dimExists[] = { False, False, False };
- ExtensionManager_Register* extensionMgr_Register;
- SingleCellLayout* singleCellLayout;
- GaussParticleLayout* gaussParticleLayout;
- Particle_Index lParticle_I;
- IntegrationPoint* particle;
- /** Plane location stuff */
- double storedXi_J_AXIS;
- Coord planeCoord;
- double planeXi = -1;
- double planeXiGlobal;
- Index planeLayer = 0;
- Index planeLayerGlobal;
- Particle_InCellIndex particlesPerDim[] = {2,2,2};
-
- /** Find Elements which plane cuts through */
- memcpy( planeCoord, Mesh_GetVertex( self->feMesh, 0 ), sizeof( Coord ) );
- planeCoord[ planeAxis ] = planeHeight;
-
- if( Mesh_Algorithms_SearchElements( self->feMesh->algorithms, planeCoord, &lElement_I ) &&
- lElement_I < elementLocalCount )
- {
- Coord planeXiCoord;
-
- gElement_I = FeMesh_ElementDomainToGlobal( self->feMesh, lElement_I );
- RegularMeshUtils_Element_1DTo3D( self->feMesh, gElement_I, planeIJK );
- planeLayer = planeIJK[ planeAxis ];
-
- /** Find Local Coordinate of plane */
- FeMesh_CoordGlobalToLocal( self->feMesh, lElement_I, planeCoord, planeXiCoord );
- planeXi = planeXiCoord[ planeAxis ];
- }
-
- /** Should be broadcast */
- MPI_Allreduce( &planeXi, &planeXiGlobal, 1, MPI_DOUBLE, MPI_MAX, self->communicator );
- MPI_Allreduce( &planeLayer, &planeLayerGlobal, 1, MPI_UNSIGNED, MPI_MAX, self->communicator );
-
- /** Create Swarm in plane */
- extensionMgr_Register = ExtensionManager_Register_New();
- dimExists[ aAxis ] = True;
- if (self->dim == 3)
- dimExists[ bAxis ] = True;
-
- singleCellLayout = SingleCellLayout_New( "cellLayout", (AbstractContext*)self->context, dimExists, NULL, NULL );
- particlesPerDim[ planeAxis ] = 1;
- gaussParticleLayout = GaussParticleLayout_New( "particleLayout", NULL, LocalCoordSystem, True, self->dim - 1, particlesPerDim );
- tmpSwarm = Swarm_New(
- "tmpgaussSwarm", NULL,
- singleCellLayout,
- gaussParticleLayout,
- self->dim,
- sizeof(IntegrationPoint),
- extensionMgr_Register,
- NULL,
- self->communicator,
- NULL );
- Stg_Component_Build( tmpSwarm, NULL, False );
-
- /** Change Positions of the particles */
- Stg_Component_Initialise( tmpSwarm, NULL, False );
- for ( lParticle_I = 0 ; lParticle_I < tmpSwarm->particleLocalCount ; lParticle_I++ ) {
- particle = (IntegrationPoint*) Swarm_ParticleAt( tmpSwarm, lParticle_I );
-
- storedXi_J_AXIS = particle->xi[ J_AXIS ];
- particle->xi[ aAxis ] = particle->xi[ I_AXIS ];
- particle->xi[ bAxis ] = storedXi_J_AXIS;
- particle->xi[ planeAxis ] = planeXiGlobal;
- }
-
- integral = FeVariable_IntegrateLayer_AxisIndependent( self, tmpSwarm, planeAxis, planeLayerGlobal,
- self->dim - 1, aAxis, bAxis, planeAxis );
-
- /** Delete */
- Stg_Class_Delete( tmpSwarm );
- Stg_Class_Delete( gaussParticleLayout );
- Stg_Class_Delete( singleCellLayout );
- Stg_Class_Delete( extensionMgr_Register );
-
- return integral;
-}
-
-
-void FeVariable_ImportExportInfo_Delete( void* ptr ) {
- /** Nothing to do - the ObjectAdaptor will take care of deleting the actual struct itself */
-}
-
-void FeVariable_SaveToFile( void* feVariable, Name filename, Bool saveCoords ) {
- FeVariable* self = (FeVariable*)feVariable;
- Node_LocalIndex lNode_I;
- Node_GlobalIndex gNode_I;
- double* coord;
- Dof_Index dof_I;
- Dof_Index dofAtEachNodeCount;
- double variableValues[MAX_FIELD_COMPONENTS];
- MPI_Comm comm = Comm_GetMPIComm( Mesh_GetCommTopology( self->feMesh, MT_VERTEX ) );
- int myRank;
- int nProcs;
- MPI_Status status;
- Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
- const int FINISHED_WRITING_TAG = 100;
- int confirmation = 0;
- MeshGenerator* theGenerator;
-
-#ifdef WRITE_HDF5
- hid_t file, fileSpace, fileData;
- hid_t memSpace;
- hsize_t start[2], count[2], size[2];
- double* buf;
-#else
- FILE* outputFile;
-#endif
-
- lNode_I = 0; gNode_I = 0;
-
- MPI_Comm_size( comm, (int*)&nProcs );
- MPI_Comm_rank( comm, (int*)&myRank );
-
- /** Note: assumes same number of dofs at each node */
- dofAtEachNodeCount = self->fieldComponentCount;
-
-#ifdef WRITE_HDF5
- /** wait for go-ahead from process ranked lower than me, to avoid competition writing to file */
- if ( myRank != 0 ) {
- MPI_Recv( &confirmation, 1, MPI_INT, myRank - 1, FINISHED_WRITING_TAG, comm, &status );
- }
-
- /** Open the file */
- if ( myRank == 0 ) {
- hid_t attribData_id, attrib_id, group_id;
- hsize_t a_dims;
- int attribData;
- Grid** grid;
- unsigned* sizes;
-
- /** Open the HDF5 output file. */
- file = H5Fcreate( filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT );
- Journal_Firewall( file >= 0, errorStr,
- "Error in %s for %s '%s' - Cannot create file %s.\n",
- __func__, self->type, self->name, filename );
-
- /** create file attribute */
- /** first store the fevariable checkpointing version */
- a_dims = 1;
- attribData = FeCHECKPOINT_V2;
- attribData_id = H5Screate_simple(1, &a_dims, NULL);
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- group_id = H5Gopen(file, "/");
- attrib_id = H5Acreate(group_id, "checkpoint file version", H5T_STD_I32BE, attribData_id, H5P_DEFAULT);
- #else
- group_id = H5Gopen2(file, "/", H5P_DEFAULT);
- attrib_id = H5Acreate2(group_id, "checkpoint file version", H5T_STD_I32BE, attribData_id, H5P_DEFAULT, H5P_DEFAULT);
- #endif
- H5Awrite(attrib_id, H5T_NATIVE_INT, &attribData);
- H5Aclose(attrib_id);
- H5Gclose(group_id);
- H5Sclose(attribData_id);
-
- /** store the fevariable dimensionality */
- a_dims = 1;
- attribData = self->dim;
- attribData_id = H5Screate_simple(1, &a_dims, NULL);
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- group_id = H5Gopen(file, "/");
- attrib_id = H5Acreate(group_id, "dimensions", H5T_STD_I32BE, attribData_id, H5P_DEFAULT);
- #else
- group_id = H5Gopen2(file, "/", H5P_DEFAULT);
- attrib_id = H5Acreate2(group_id, "dimensions", H5T_STD_I32BE, attribData_id, H5P_DEFAULT, H5P_DEFAULT);
- #endif
- H5Awrite(attrib_id, H5T_NATIVE_INT, &attribData);
- H5Aclose(attrib_id);
- H5Gclose(group_id);
- H5Sclose(attribData_id);
-
- /** get the generator */
- if( Stg_Class_IsInstance( self->feMesh->generator, MeshAdaptor_Type ))
- theGenerator = ((MeshAdaptor*)self->feMesh->generator)->generator;
- else
- theGenerator = self->feMesh->generator;
-
- /** store the mesh resolution if mesh is cartesian */
- if ( Stg_Class_IsInstance( theGenerator, CartesianGenerator_Type ) ) {
- a_dims = self->dim;
- grid = (Grid**) Mesh_GetExtension( self->feMesh, Grid*, "elementGrid" );
- sizes = Grid_GetSizes( *grid ); /** global no. of elements in each dim */
-
- attribData_id = H5Screate_simple(1, &a_dims, NULL);
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- group_id = H5Gopen(file, "/");
- attrib_id = H5Acreate(group_id, "mesh resolution", H5T_STD_I32BE, attribData_id, H5P_DEFAULT);
- #else
- group_id = H5Gopen2(file, "/", H5P_DEFAULT);
- attrib_id = H5Acreate2(group_id, "mesh resolution", H5T_STD_I32BE, attribData_id, H5P_DEFAULT, H5P_DEFAULT);
- #endif
- H5Awrite(attrib_id, H5T_NATIVE_INT, sizes);
- H5Aclose(attrib_id);
- H5Gclose(group_id);
- H5Sclose(attribData_id);
- }
- size[0] = Mesh_GetGlobalSize( self->feMesh, (MeshTopology_Dim)0 );;
- size[1] = dofAtEachNodeCount;
- if( saveCoords )
- size[1] += self->dim;
-
- /** Create filespace */
- fileSpace = H5Screate_simple( 2, size, NULL );
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- fileData = H5Dcreate( file, "/data", H5T_NATIVE_DOUBLE, fileSpace, H5P_DEFAULT );
- #else
- fileData = H5Dcreate2( file, "/data", H5T_NATIVE_DOUBLE, fileSpace,
- H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
- #endif
- } else {
- /** Open the HDF5 output file. */
- file = H5Fopen( filename, H5F_ACC_RDWR, H5P_DEFAULT );
- Journal_Firewall( file >= 0, errorStr,
- "Error in %s for %s '%s' - Cannot open file %s.\n",
- __func__, self->type, self->name, filename );
-
- /** get the filespace */
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- fileData = H5Dopen( file, "/data" );
- #else
- fileData = H5Dopen2( file, "/data", H5P_DEFAULT );
- #endif
- /** get the filespace handle */
- fileSpace = H5Dget_space(fileData);
- }
-
- /** get the section of fileSpace to write to... set start point to be the
- global index of first local node */
- count[0] = 1;
- count[1] = dofAtEachNodeCount;
- if( saveCoords )
- count[1] += self->dim;
-
- /** create memSpace */
- memSpace = H5Screate_simple( 2, count, NULL );
- H5Sselect_all( memSpace );
-
- buf = Memory_Alloc_Array( double, count[1], "fileBuffer" );
-
- for ( lNode_I = 0; lNode_I < FeMesh_GetNodeLocalSize( self->feMesh ); lNode_I++ ) {
-
- /** If required, add coords to array */
- if( saveCoords ) {
- coord = Mesh_GetVertex( self->feMesh, lNode_I );
- buf[0] = coord[0];
- buf[1] = coord[1];
- if( self->dim == 3 )
- buf[2] = coord[2];
- }
-
- /** Add field value at current node to array */
- FeVariable_GetValueAtNode( self, lNode_I, variableValues );
- for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
- if( saveCoords )
- buf[dof_I + self->dim] = variableValues[dof_I];
- else
- buf[dof_I] = variableValues[dof_I];
- }
-
- /** select the region of dataspace to write to */
- start[0] = FeMesh_NodeDomainToGlobal( self->feMesh, lNode_I );
- start[1] = 0;
- H5Sselect_hyperslab( fileSpace, H5S_SELECT_SET, start, NULL, count, NULL );
- /** Write the array to file */
- H5Dwrite( fileData, H5T_NATIVE_DOUBLE, memSpace, fileSpace, H5P_DEFAULT, buf );
- }
- /** free memory! */
- Memory_Free( buf );
-
- /** Close all handles */
- H5Dclose( fileData );
- H5Sclose( memSpace );
- H5Sclose( fileSpace );
- H5Fclose( file );
-
- /** send go-ahead to process ranked above me, to avoid competition writing to file */
- if ( myRank != nProcs - 1 ) {
- MPI_Ssend( &confirmation, 1, MPI_INT, myRank + 1, FINISHED_WRITING_TAG, comm );
- }
-
-#else
- /** wait for go-ahead from process ranked lower than me, to avoid competition writing to file */
- if ( myRank != 0 ) {
- MPI_Recv( &confirmation, 1, MPI_INT, myRank - 1, FINISHED_WRITING_TAG, comm, &status );
- }
-
- /** Open the file */
- if ( myRank == 0 ) {
- outputFile = fopen( filename, "w" );
- }
- else {
- outputFile = fopen( filename, "a" );
- }
-
- Journal_Firewall( outputFile != NULL, errorStr,
- "Error in %s for %s '%s' - Cannot create file %s.\n",
- __func__, self->type, self->name, filename );
-
- for ( lNode_I = 0; lNode_I < FeMesh_GetNodeLocalSize( self->feMesh ); lNode_I++ ) {
- gNode_I = FeMesh_NodeDomainToGlobal( self->feMesh, lNode_I );
- fprintf( outputFile, "%u ", gNode_I );
-
- /** If required, write the node coords to file */
- if( saveCoords ) {
- coord = Mesh_GetVertex( self->feMesh, lNode_I );
- if(self->dim == 2)
- fprintf( outputFile, "%.15g %.15g 0 ", coord[0], coord[1]);
- else
- fprintf( outputFile, "%.15g %.15g %.15g ", coord[0], coord[1], coord[2] );
- }
-
- /** Add field value at current node to the file */
- FeVariable_GetValueAtNode( self, lNode_I, variableValues );
- for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
- fprintf( outputFile, "%.15g ", variableValues[dof_I] );
- }
- fprintf( outputFile, "\n" );
- }
-
- /** Close the file */
- fclose( outputFile );
-
- /** send go-ahead to process ranked above me, to avoid competition writing to file */
- if ( myRank != nProcs - 1 ) {
- MPI_Ssend( &confirmation, 1, MPI_INT, myRank + 1, FINISHED_WRITING_TAG, comm );
- }
-
-#endif
-}
-
-
-#define MAX_LINE_LENGTH_DEFINE 1024
-
-void FeVariable_ReadFromFile( void* feVariable, Name filename ) {
- FeVariable* self = (FeVariable*)feVariable;
- Node_LocalIndex lNode_I = 0;
- Node_GlobalIndex gNode_I = 0;
- Dof_Index dof_I;
- Dof_Index dofAtEachNodeCount;
-#ifndef READ_HDF5
- FILE* inputFile;
-#endif
- double variableVal;
- Processor_Index proc_I;
- MPI_Comm comm = Comm_GetMPIComm( Mesh_GetCommTopology( self->feMesh, MT_VERTEX ) );
- unsigned rank;
- unsigned nRanks;
- int nDims;
- Bool savedCoords = False;
- Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
- MeshGenerator* theGenerator;
-
-#ifdef READ_HDF5
- hid_t file, fileSpace, fileData, error;
- unsigned totalNodes, ii, noffset;
- hid_t memSpace;
- hsize_t start[2], count[2], size[2], maxSize[2];
- double* buf;
- FeCheckpointFileVersion ver;
- hid_t attrib_id, group_id;
- herr_t status;
-#else
- unsigned uTemp;
- double temp[3];
- int count = 0;
- char lineString[MAX_LINE_LENGTH_DEFINE];
- const unsigned int MAX_LINE_LENGTH = MAX_LINE_LENGTH_DEFINE;
- int offset, n;
-#endif
-
- MPI_Comm_rank( comm, (int*)&rank );
- MPI_Comm_size( comm, (int*)&nRanks );
-
- dofAtEachNodeCount = self->fieldComponentCount;
- proc_I = 0;
- nDims = 0;
-
-#ifdef READ_HDF5
-
- /** Open the file and data set. */
- file = H5Fopen( filename, H5F_ACC_RDONLY, H5P_DEFAULT );
-
- Journal_Firewall( file >= 0, errorStr,
- "Error in %s for %s '%s' - Cannot open file %s.\n",
- __func__, self->type, self->name, filename );
-
- /** get the file attributes to sanity and version checks */
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- group_id = H5Gopen(file, "/");
- attrib_id = H5Aopen_name(group_id, "checkpoint file version");
- #else
- group_id = H5Gopen2(file, "/", H5P_DEFAULT);
- attrib_id = H5Aopen(group_id, "checkpoint file version", H5P_DEFAULT);
- #endif
- /** if this attribute does not exist (attrib_id < 0) then we assume FeCHECKPOINT_V1 and continue without checking attributes */
- if(attrib_id < 0)
- ver = FeCHECKPOINT_V1;
- else {
- int checkVer;
- int ndims;
- int res[self->dim];
- Grid** grid;
- unsigned* sizes;
-
- /** check for known checkpointing version type */
-
- status = H5Aread(attrib_id, H5T_NATIVE_INT, &checkVer);
- H5Aclose(attrib_id);
- if(checkVer == 2)
- ver = FeCHECKPOINT_V2;
- else
- Journal_Firewall( (0), errorStr,
- "\n\nError in %s for %s '%s'\n"
- "Unknown checkpoint version (%u) for checkpoint file (%s).\n",
- __func__, self->type, self->name, (unsigned int) checkVer, filename);
-
- /** check for correct number of dimensions */
-
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- attrib_id = H5Aopen_name(group_id, "dimensions");
- #else
- attrib_id = H5Aopen(group_id, "dimensions", H5P_DEFAULT);
- #endif
- status = H5Aread(attrib_id, H5T_NATIVE_INT, &ndims);
- H5Aclose(attrib_id);
- Journal_Firewall( (ndims == self->dim), errorStr,
- "\n\nError in %s for %s '%s'\n"
- "Number of dimensions (%u) for checkpoint file (%s) does not correspond to simulation dimensions (%u).\n",
- __func__, self->type, self->name, (unsigned int) ndims, filename,
- self->dim);
-
- /** get the generator */
- if( Stg_Class_IsInstance( self->feMesh->generator, MeshAdaptor_Type ))
- theGenerator = ((MeshAdaptor*)self->feMesh->generator)->generator;
- else
- theGenerator = self->feMesh->generator;
-
- /** check for correct mesh size if expecting a cartesian mesh*/
- if ( Stg_Class_IsInstance( theGenerator, CartesianGenerator_Type ) ) {
-
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- attrib_id = H5Aopen_name(group_id, "mesh resolution");
- #else
- attrib_id = H5Aopen(group_id, "mesh resolution", H5P_DEFAULT);
- #endif
- status = H5Aread(attrib_id, H5T_NATIVE_INT, &res);
- H5Aclose(attrib_id);
-
- grid = (Grid**) Mesh_GetExtension( self->feMesh, Grid*, "elementGrid" );
- sizes = Grid_GetSizes( *grid ); /** global no. of elements in each dim */
- if(self->dim == 2)
- Journal_Firewall(
- ( (sizes[0] == res[0]) && (sizes[1] == res[1]) ),
- errorStr,
- "\n\nError in %s for %s '%s'\n"
- "Size of mesh (%u,%u) for checkpoint file (%s) does not correspond to simulation mesh size (%u,%u).\n\n"
- "If you would like to interpolate checkpoint data to simulation mesh size\n"
- " please re-launch using '--interpolateRestart=1' flag\n\n",
- __func__, self->type, self->name,
- (unsigned int) res[0], (unsigned int) res[1],
- filename,
- (unsigned int) sizes[0], (unsigned int) sizes[1]);
- else
- Journal_Firewall(
- ( (sizes[0] == res[0]) && (sizes[1] == res[1]) && (sizes[2] == res[2]) ),
- errorStr,
- "\n\nError in %s for %s '%s'\n"
- "Size of mesh (%u,%u,%u) for checkpoint file (%s) does not correspond to simulation mesh size (%u,%u,%u).\n\n"
- "If you would like to interpolate checkpoint data to simulation mesh size\n"
- " please re-launch using '--interpolateRestart=1' flag\n\n",
- __func__, self->type, self->name,
- (unsigned int) res[0], (unsigned int) res[1], (unsigned int) res[2],
- filename,
- (unsigned int) sizes[0], (unsigned int) sizes[1], (unsigned int) sizes[2]);
- }
- }
- H5Gclose(group_id);
-
- /** account for different versions of checkpointing */
- switch ( ver ) {
- case FeCHECKPOINT_V1:
- noffset = 1;
- break;
- case FeCHECKPOINT_V2:
- noffset = 0;
- break;
- default:
- Journal_Firewall( 0, errorStr,
- "Error: in %s: unknown checkpoint file version.\n",
- __func__ );
- }
-
- /** Prepare to read vertices from file */
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- fileData = H5Dopen( file, "/data" );
- #else
- fileData = H5Dopen2( file, "/data", H5P_DEFAULT );
- #endif
- fileSpace = H5Dget_space( fileData );
-
- /** Get size of dataspace to determine if coords are in file */
- H5Sget_simple_extent_dims( fileSpace, size, maxSize );
-
- if( maxSize[1] > dofAtEachNodeCount + noffset )
- savedCoords = True;
-
- start[1] = 0;
- count[0] = 1;
- count[1] = dofAtEachNodeCount + noffset ;
- if( savedCoords )
- count[1] += self->dim;
-
- memSpace = H5Screate_simple( 2, count, NULL );
- totalNodes = Mesh_GetGlobalSize( self->feMesh, (MeshTopology_Dim)0 );
- buf = Memory_Alloc_Array( double, count[1], "fileBuffer" );
-
- Journal_Firewall( (maxSize[0] == totalNodes), errorStr,
- "\n\nError in %s for %s '%s'\n"
- "Number of node values (%u) stored in %s does not correspond to total number of requested mesh nodes (%u).\n",
- __func__, self->type, self->name, (unsigned int)maxSize[0], filename, totalNodes);
-
-
- /** Read from HDF5 checkpint file */
- for( ii=0; ii<totalNodes; ii++ ) {
- start[0] = ii;
-
- H5Sselect_hyperslab( fileSpace, H5S_SELECT_SET, start, NULL, count, NULL );
- H5Sselect_all( memSpace );
-
- error = H5Dread( fileData, H5T_NATIVE_DOUBLE, memSpace, fileSpace, H5P_DEFAULT, buf );
- gNode_I = ii;
-
- Journal_Firewall( error >= 0, errorStr,
- "\n\nError in %s for %s '%s' - Cannot read data in %s.\n",
- __func__, self->type, self->name, filename );
-
- if( Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, gNode_I, &lNode_I ) &&
- lNode_I < Mesh_GetLocalSize( self->feMesh, MT_VERTEX ) )
- {
- for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
- if( savedCoords )
- variableVal = buf[dof_I + self->dim + noffset ];
- else
- variableVal = buf[dof_I + noffset ];
- DofLayout_SetValueDouble( self->dofLayout, lNode_I, dof_I, variableVal );
- }
- }
- }
- Memory_Free( buf );
-
- /** Close all handles */
- H5Dclose( fileData );
- H5Sclose( memSpace );
- H5Sclose( fileSpace );
- H5Fclose( file );
-
-#else
-
- /** This loop used to stop 2 processors trying to open the file at the same time, which
- * seems to cause problems */
- for ( proc_I = 0; proc_I < nRanks; proc_I++ ) {
- MPI_Barrier( comm );
- if ( proc_I == rank ) {
- /** Do the following since in parallel on some systems, the file
- * doesn't get re-opened at the start automatically. */
- inputFile = fopen( filename, "r" );
-
- if ( False == inputFile ) {
- Journal_Firewall( 0, errorStr, "Error- in %s(), for feVariable \"%s\": Couldn't import from file: "
- "\"%s\" - aborting.\n", __func__, self->name, filename );
-
- }
- rewind( inputFile );
-
- }
- }
-
- /** Need to determine whether checkpoint file contains coordinates */
- fgets( lineString, MAX_LINE_LENGTH, inputFile );
-
- sscanf( lineString, "%u%n ", &uTemp, &offset );
- while( sscanf( lineString + offset, "%lf%n ", &temp[0], &n ) )
- {
- offset += n;
- count ++;
- if( offset >= strlen( lineString ) - 2 )
- break;
- }
-
- if( count > dofAtEachNodeCount + 1 )
- savedCoords = True;
-
- rewind( inputFile );
-
- /** Need to re-set the geometry here, in case we're loading from a checkpoint that had compression/squashing BCs,
- and hence ended up with a smaller mesh than the original */
- nDims = Mesh_GetDimSize( self->feMesh );
- while ( !feof(inputFile) ) {
- fscanf( inputFile, "%u ", &gNode_I );
-
- if( savedCoords )
- fscanf( inputFile, "%lg %lg %lg ", &temp[0], &temp[1], &temp[2] );
-
- if( FeMesh_NodeGlobalToDomain( self->feMesh, gNode_I, &lNode_I ) &&
- lNode_I < FeMesh_GetNodeLocalSize( self->feMesh ) )
- {
- for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
- fscanf( inputFile, "%lg ", &variableVal );
- DofLayout_SetValueDouble( self->dofLayout, lNode_I, dof_I, variableVal );
- }
- }
- else {
- fgets( lineString, MAX_LINE_LENGTH, inputFile );
- }
- }
- fclose( inputFile );
-#endif
-
- Mesh_DeformationUpdate( self->feMesh );
-
- /** Sync shadow values now, as all procs should have required input */
- FeVariable_SyncShadowValues( self );
-}
-
-void FeVariable_InterpolateFromFile( void* feVariable, DomainContext* context, Name feVarFilename, const char* meshFilename ){
- FeVariable* self = (FeVariable*)feVariable;
- Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
-#ifdef READ_HDF5
- CartesianGenerator* gen;
- C0Generator* C0gen;
- FeMesh *feMesh, *C0feMesh, *elementMesh;
- DofLayout* dofs;
- Variable_Register* varReg;
- Variable* var;
- FeVariable* feVar;
- hid_t file, fileData;
- unsigned totalNodes, ii;
- hid_t attrib_id, group_id;
- herr_t status;
- int res[3];
- int checkVer;
- int ndims;
- double crdMin[3], crdMax[3];
- double* value;
- unsigned nDomainVerts;
- static double* arrayPtr;
- char* varName[9];
-
- /** Open the file and data set. */
- file = H5Fopen( meshFilename, H5F_ACC_RDONLY, H5P_DEFAULT );
-
- Journal_Firewall( file >= 0, errorStr, "Error in %s for %s '%s' - Cannot open file %s.\n", __func__, self->type, self->name, meshFilename );
-
- /** get the file attributes to sanity and version checks */
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- group_id = H5Gopen(file, "/");
- attrib_id = H5Aopen_name(group_id, "checkpoint file version");
- #else
- group_id = H5Gopen2(file, "/", H5P_DEFAULT);
- attrib_id = H5Aopen(group_id, "checkpoint file version", H5P_DEFAULT);
- #endif
- /** if this attribute does not exist (attrib_id < 0) then we assume MeshCHECKPOINT_V1 which is not supported */
- if(attrib_id < 0)
- Journal_Firewall( 0, errorStr,"\nError in %s for %s '%s' \n\n Interpolation restart not supported for Version 1 Checkpoint files \n\n", __func__, self->type, self->name );
-
- /** check for known checkpointing version type */
-
- status = H5Aread(attrib_id, H5T_NATIVE_INT, &checkVer);
- H5Aclose(attrib_id);
- if(checkVer != 2)
- Journal_Firewall( (0), errorStr, "\n\nError in %s for %s '%s'\n" "Unknown checkpoint version (%u) for checkpoint file (%s).\n", __func__,
- self->type, self->name, (unsigned int) checkVer, meshFilename);
-
- /** check for correct number of dimensions */
-
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- attrib_id = H5Aopen_name(group_id, "dimensions");
- #else
- attrib_id = H5Aopen(group_id, "dimensions", H5P_DEFAULT);
- #endif
- status = H5Aread(attrib_id, H5T_NATIVE_INT, &ndims);
- H5Aclose(attrib_id);
- Journal_Firewall( (ndims == self->dim), errorStr,
- "\n\nError in %s for %s '%s'\n"
- "Number of dimensions (%u) for checkpoint file (%s) does not correspond to simulation dimensions (%u).\n",
- __func__, self->type, self->name, (unsigned int) ndims, meshFilename,
- self->dim);
-
- /** check for correct mesh size if expecting a cartesian mesh*/
-
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- attrib_id = H5Aopen_name(group_id, "mesh resolution");
- #else
- attrib_id = H5Aopen(group_id, "mesh resolution", H5P_DEFAULT);
- #endif
- status = H5Aread(attrib_id, H5T_NATIVE_INT, &res);
- H5Aclose(attrib_id);
-
- /** Read in minimum coord. */
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- fileData = H5Dopen( file, "/min" );
- #else
- fileData = H5Dopen2( file, "/min", H5P_DEFAULT );
- #endif
- H5Dread( fileData, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &crdMin );
- H5Dclose( fileData );
-
- /** Read in maximum coord. */
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- fileData = H5Dopen( file, "/max" );
- #else
- fileData = H5Dopen2( file, "/max", H5P_DEFAULT );
- #endif
- H5Dread( fileData, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &crdMax );
- H5Dclose( fileData );
-
- /** Close all handles */
- H5Gclose(group_id);
- H5Fclose( file );
-
- /** create a cartesian mesh generator which will be required for the fevariable creation */
- gen = CartesianGenerator_New( "", NULL );
- /** use the feVariable dimension size for mesh generator */
- CartesianGenerator_SetDimSize( gen, self->dim );
- /** use the element size read in from the checkpoint file for the new mesh generator */
- CartesianGenerator_SetTopologyParams( gen, (unsigned*)res, 0, NULL, NULL );
- /** use the feVariable's mesh's generator's crdMin and crdMax (which have been previously read in from checkpointed mesh file */
- CartesianGenerator_SetGeometryParams( gen, crdMin, crdMax );
- /** set it so that the generator does not read in the mesh from a file - we will
- explicitly do this after we build the feMesh using the provided mesh checkpoint file */
- gen->readFromFile = False;
- /** create a feMesh */
- feMesh = FeMesh_New( "", NULL );
- /** set feMesh to use generator we just created */
- Mesh_SetGenerator( feMesh, gen );
- /** set the feMesh family to be the same as that of the feVariable we are initialising/interpolating ie constant, linear, etc
- unless we are initialising a constant mesh, in which case we set the element family to linear, and the mesh will be used
- as the elementMesh for the C0 generator */
- if (!strcmp(self->feMesh->generator->type, CartesianGenerator_Type)){
- FeMesh_SetElementFamily( feMesh, self->feMesh->feElFamily );
- /** set periodicity according to current simulation */
- gen->periodic[0] = ((CartesianGenerator*)self->feMesh->generator)->periodic[0];
- gen->periodic[1] = ((CartesianGenerator*)self->feMesh->generator)->periodic[1];
- gen->periodic[2] = ((CartesianGenerator*)self->feMesh->generator)->periodic[2];
- } else if (!strcmp(self->feMesh->generator->type, C0Generator_Type)){
- FeMesh_SetElementFamily( feMesh, "linear" );
- /** set periodicity according to current simulation */
- gen->periodic[0] = ((CartesianGenerator*)((C0Generator*)self->feMesh->generator)->elMesh)->periodic[0];
- gen->periodic[1] = ((CartesianGenerator*)((C0Generator*)self->feMesh->generator)->elMesh)->periodic[1];
- gen->periodic[2] = ((CartesianGenerator*)((C0Generator*)self->feMesh->generator)->elMesh)->periodic[2];
- } else
- Journal_Firewall( 0, errorStr,"\nError in %s for %s '%s' \n\n Interpolation restart not supported for this mesh type \n\n", __func__, self->type, self->name );
-
- /** now build the mesh, then read in the required coordinates from the given file */
- Stg_Component_Build( feMesh, NULL, False );
- CartesianGenerator_ReadFromHDF5( gen, (Mesh*) feMesh, meshFilename );
-
- /** where we are dealing with a constant mesh feVariable, we have to build a new C0 mesh */
- if (!strcmp(self->feMesh->generator->type, C0Generator_Type)){
- elementMesh = feMesh;
- /** create the C0 generator */
- C0gen = C0Generator_New( "", (AbstractContext*)self->context );
- /** set it's element mesh to the feMesh create just above */
- C0Generator_SetElementMesh( C0gen, (void*) elementMesh );
- /** create a new feMesh */
- C0feMesh = FeMesh_New( "", NULL );
- /** set feMesh to use generator we just created, and set its type to constant mesh */
- Mesh_SetGenerator( C0feMesh, C0gen );
- FeMesh_SetElementFamily( C0feMesh, self->feMesh->feElFamily );
- /** now build the mesh, which will generate the mesh using the provided generator */
- Stg_Component_Build( C0feMesh, NULL, False );
- /** reset the feMesh pointer to point to this C0 mesh */
- feMesh = C0feMesh;
- }
- Stg_Component_Initialise( feMesh, NULL, False );
- /** get the number of mesh vertices stored locally */
- nDomainVerts = Mesh_GetDomainSize( feMesh, MT_VERTEX );
-
- varReg = Variable_Register_New();
- if (self->fieldComponentCount == 1){
- var = Variable_NewScalar( "interpolation_temp_scalar", (AbstractContext*)self->context, Variable_DataType_Double, (Index*)&nDomainVerts, NULL, (void **)(&arrayPtr), varReg );
- } else {
- unsigned var_I;
- for( var_I = 0; var_I < self->fieldComponentCount; var_I++ )
- Stg_asprintf( &varName[var_I], "%s-loaded-Component-%d", self->name, var_I );
- var = Variable_NewVector( "interpolation_temp_vector",
- (AbstractContext*)self->context,
- Variable_DataType_Double,
- self->fieldComponentCount,
- &nDomainVerts,
- NULL,
- (void**)&arrayPtr,
- varReg,
- varName[0], varName[1], varName[2], varName[3], varName[4],
- varName[5], varName[6], varName[7], varName[8] );
- }
- Variable_Register_Add( varReg, var);
- var->allocateSelf = True;
- Stg_Component_Build( var, NULL, False );
-
- dofs = DofLayout_New( "interpolation_temp_dof", self->context, varReg, nDomainVerts, feMesh );
- if( self->fieldComponentCount == 1 )
- DofLayout_AddAllFromVariableArray( dofs, 1, &var );
- else {
- unsigned var_I, node_I;
- Variable* variable;
- for( var_I = 0; var_I < self->fieldComponentCount; var_I++ ) {
- variable = Variable_Register_GetByName( varReg, varName[var_I] );
- variable->arrayPtrPtr = &var->arrayPtr;
-
- for( node_I = 0; node_I < nDomainVerts; node_I++ )
- DofLayout_AddDof_ByVarName( dofs, varName[var_I], node_I );
-
- Memory_Free( varName[var_I] );
- }
- }
- Stg_Component_Build( dofs, NULL, False );
- Stg_Component_Initialise( dofs, NULL, False );
-
- feVar = FeVariable_New(
- "interpolation_temp_fevar",
- self->context,
- feMesh,
- NULL,
- dofs,
- NULL,
- NULL,
- NULL,
- self->fieldComponentCount,
- False,
- True,
- False,
- NULL );
-
- Stg_Component_Build( feVar, context, False );
- /** not sure why these aren't being set correctly, so a little (tri/ha)ckery */
- feVar->fieldComponentCount = self->fieldComponentCount;
- feVar->dim = self->dim;
- FeVariable_ReadFromFile( feVar, feVarFilename );
- feVar->_syncShadowValues( feVar );
-
- totalNodes = Mesh_GetLocalSize( self->feMesh, MT_VERTEX );
- value = Memory_Alloc_Array( double, self->fieldComponentCount, "interValue" );
-
- /** step through nodes, interpolating the required values from our newly created feVariable */
- for( ii=0; ii<totalNodes; ii++ ) {
- feVar->_interpolateValueAt( feVar, Mesh_GetVertex( self->feMesh, ii ), value);
- FeVariable_SetValueAtNode( self, ii, value);
- }
- Memory_Free( value );
-
- /** our work is done, so we clean up after ourselves */
- _FeVariable_Delete(feVar);
- _DofLayout_Delete(dofs);
- _Variable_Delete(var);
- _Variable_Register_Delete(varReg);
- _FeMesh_Delete(feMesh);
-
- if (!strcmp(self->feMesh->generator->type, C0Generator_Type)){
- _C0Generator_Delete(C0gen);
- _FeMesh_Delete(elementMesh);
- }
- _CartesianGenerator_Delete(gen);
-
-#else
- Journal_Firewall(!context->interpolateRestart,
- errorStr,"\n\n Interpolation restart not supported for ASCII checkpoint files \n\n");
-#endif
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FeVariable.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/FeVariable.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,2725 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: FeVariable.c 1224 2008-09-10 13:28:46Z DavidLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+#include "units.h"
+#include "types.h"
+#include "ElementType.h"
+#include "ElementType_Register.h"
+#include "Element.h"
+#include "FeMesh.h"
+#include "FeEquationNumber.h"
+#include "FeVariable.h"
+#include "LinkedDofInfo.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#if defined(READ_HDF5) || defined(WRITE_HDF5)
+#include <hdf5.h>
+#endif
+
+const Type FeVariable_Type = "FeVariable";
+const Name defaultFeVariableFeEquationNumberName = "defaultFeVariableFeEqName";
+
+/** MPI Tags */
+static const int DOF_VALUES_TAG = 10;
+
+/** Global objects */
+Stg_ObjectList* FeVariable_FileFormatImportExportList = NULL;
+
+FeVariable* FeVariable_New_FromTemplate(
+ Name name,
+ DomainContext* context,
+ void* _templateFeVariable,
+ DofLayout* dofLayout,
+ void* ics,
+ Bool isReferenceSolution,
+ Bool loadReferenceEachTimestep,
+ FieldVariable_Register* fV_Register )
+{
+ FeVariable* templateFeVariable = (FeVariable*)_templateFeVariable;
+ FeVariable* newFeVariable = NULL;
+
+ newFeVariable = FeVariable_New_Full(
+ name,
+ context,
+ templateFeVariable->feMesh,
+ templateFeVariable->geometryMesh,
+ dofLayout,
+ templateFeVariable->bcs,
+ ics,
+ templateFeVariable->linkedDofInfo,
+ templateFeVariable,
+ templateFeVariable->fieldComponentCount,
+ templateFeVariable->dim,
+ templateFeVariable->isCheckpointedAndReloaded,
+ isReferenceSolution,
+ loadReferenceEachTimestep,
+ templateFeVariable->communicator,
+ fV_Register );
+
+ newFeVariable->templateFeVariable = templateFeVariable;
+
+ return newFeVariable;
+}
+
+FeVariable* FeVariable_New(
+ Name name,
+ DomainContext* context,
+ void* feMesh,
+ void* geometryMesh,
+ DofLayout* dofLayout,
+ void* bcs,
+ void* ics,
+ void* linkedDofInfo,
+ Dimension_Index dim,
+ Bool isCheckpointedAndReloaded,
+ Bool isReferenceSolution,
+ Bool loadReferenceEachTimestep,
+ FieldVariable_Register* fV_Register )
+{
+ assert( Class_IsSuper( ((FeMesh*)feMesh)->topo, IGraph ) );
+
+ return FeVariable_New_Full(
+ name,
+ context,
+ feMesh,
+ geometryMesh,
+ dofLayout,
+ bcs,
+ ics,
+ linkedDofInfo,
+ NULL,
+ dofLayout->_totalVarCount,
+ dim,
+ isCheckpointedAndReloaded,
+ isReferenceSolution,
+ loadReferenceEachTimestep,
+ ((IGraph*)((FeMesh*)feMesh)->topo)->remotes[MT_VERTEX]->comm->mpiComm,
+ fV_Register );
+}
+
+FeVariable* FeVariable_New_Full(
+ Name name,
+ DomainContext* context,
+ void* feMesh,
+ void* geometryMesh,
+ DofLayout* dofLayout,
+ void* bcs,
+ void* ics,
+ void* linkedDofInfo,
+ void* templateFeVariable,
+ Index fieldComponentCount,
+ Dimension_Index dim,
+ Bool isCheckpointedAndReloaded,
+ Bool isReferenceSolution,
+ Bool loadReferenceEachTimestep,
+ MPI_Comm communicator,
+ FieldVariable_Register* fieldVariable_Register )
+{
+ FeVariable* self = (FeVariable*)_FeVariable_DefaultNew( name );
+
+ self->isConstructed = True;
+ _FieldVariable_Init( (FieldVariable*)self, context, fieldComponentCount, dim, isCheckpointedAndReloaded, communicator, fieldVariable_Register );
+ _FeVariable_Init( self, feMesh, geometryMesh, dofLayout, bcs, ics, linkedDofInfo, templateFeVariable, isReferenceSolution, loadReferenceEachTimestep );
+
+ return self;
+}
+
+void* _FeVariable_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(FeVariable);
+ Type type = FeVariable_Type;
+ Stg_Class_DeleteFunction* _delete = _FeVariable_Delete;
+ Stg_Class_PrintFunction* _print = _FeVariable_Print;
+ Stg_Class_CopyFunction* _copy = _FeVariable_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (Stg_Component_DefaultConstructorFunction*)_FeVariable_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _FeVariable_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _FeVariable_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FeVariable_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FeVariable_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FeVariable_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ FieldVariable_InterpolateValueAtFunction* _interpolateValueAt = _FeVariable_InterpolateValueAt;
+ FieldVariable_GetValueFunction* _getMinGlobalFieldMagnitude = _FeVariable_GetMinGlobalFieldMagnitude;
+ FieldVariable_GetValueFunction* _getMaxGlobalFieldMagnitude = _FeVariable_GetMaxGlobalFieldMagnitude;
+ FieldVariable_GetCoordFunction* _getMinAndMaxLocalCoords = _FeVariable_GetMinAndMaxLocalCoords;
+ FieldVariable_GetCoordFunction* _getMinAndMaxGlobalCoords = _FeVariable_GetMinAndMaxGlobalCoords;
+ FeVariable_InterpolateWithinElementFunction* _interpolateWithinElement = _FeVariable_InterpolateNodeValuesToElLocalCoord;
+ FeVariable_GetValueAtNodeFunction* _getValueAtNode = _FeVariable_GetValueAtNode;
+ FeVariable_SyncShadowValuesFunc* _syncShadowValues = _FeVariable_SyncShadowValues;
+
+ return _FeVariable_New( FEVARIABLE_PASSARGS ); /* feVariableList */
+}
+
+FeVariable* _FeVariable_New( FEVARIABLE_DEFARGS ) {
+ FeVariable* self;
+
+ /** Allocate memory */
+ assert( _sizeOfSelf >= sizeof(FeVariable) );
+
+ self = (FeVariable*) _FieldVariable_New( FIELDVARIABLE_PASSARGS );
+
+ /** General info */
+
+ /** Virtual functions */
+ self->_interpolateWithinElement = _interpolateWithinElement;
+ self->_getValueAtNode = _getValueAtNode;
+ self->_syncShadowValues = _syncShadowValues;
+
+ /** FeVariable info */
+
+ return self;
+}
+
+
+void _FeVariable_Init(
+ FeVariable* self,
+ void* feMesh,
+ void* geometryMesh,
+ DofLayout* dofLayout,
+ void* bcs,
+ void* ics,
+ void* linkedDofInfo,
+ void* templateFeVariable,
+ Bool isReferenceSolution,
+ Bool loadReferenceEachTimestep )
+{
+ Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
+ /** General and Virtual info should already be set */
+
+ /** FeVariable info */
+ self->debug = Stream_RegisterChild( StgFEM_Discretisation_Debug, self->type );
+ self->feMesh = Stg_CheckType( feMesh, FeMesh );
+ /** Set pointer for geometry mesh - if none is provided then it'll use the feMesh */
+ self->geometryMesh = ( geometryMesh ? Stg_CheckType( geometryMesh, FeMesh ) : Stg_CheckType( feMesh, FeMesh ) );
+ self->dofLayout = dofLayout;
+ if ( bcs )
+ self->bcs = Stg_CheckType( bcs, VariableCondition );
+ if ( ics )
+ self->ics = Stg_CheckType( ics, VariableCondition );
+ if ( linkedDofInfo )
+ self->linkedDofInfo = Stg_CheckType( linkedDofInfo, LinkedDofInfo );
+ self->shadowValuesSynchronised = False;
+
+ if ( templateFeVariable )
+ self->templateFeVariable = Stg_CheckType( templateFeVariable, FeVariable );
+ if( !isReferenceSolution ) {
+ if ( self->templateFeVariable ) {
+ self->eqNum = self->templateFeVariable->eqNum;
+ }
+ else {
+ self->eqNum = FeEquationNumber_New( defaultFeVariableFeEquationNumberName, self->context, self->feMesh, self->dofLayout, self->bcs, (LinkedDofInfo*)linkedDofInfo );
+ self->eqNum->removeBCs = self->removeBCs;
+ }
+ }
+ else
+ self->eqNum = NULL;
+
+ self->isReferenceSolution = isReferenceSolution;
+ self->loadReferenceEachTimestep = loadReferenceEachTimestep;
+ Journal_Firewall( (self->loadReferenceEachTimestep != True), errorStream, "The loadReferenceEachTimestep feature isn't implemented yet, sorry.\n" );
+
+ self->dynamicBCs[0] = NULL;
+ self->dynamicBCs[1] = NULL;
+ self->dynamicBCs[2] = NULL;
+
+ self->buildEqNums = True;
+
+ self->inc = IArray_New();
+}
+
+void _FeVariable_Delete( void* variable ) {
+ FeVariable* self = (FeVariable*)variable;
+ Journal_DPrintf( self->debug, "In %s- for \"%s\":\n", __func__, self->name );
+
+ /** Stg_Class_Delete parent*/
+ _Stg_Component_Delete( self );
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+/** --- Virtual Function Implementations --- */
+
+void _FeVariable_Print( void* variable, Stream* stream ) {
+ FeVariable* self = (FeVariable*)variable;
+
+ /** General info */
+ Journal_Printf( stream, "FeVariable (ptr): %p\n", self );
+
+ /** Print parent */
+ _Stg_Component_Print( self, stream );
+
+ /** Virtual info */
+
+ /** FeVariable info */
+ Stg_Class_Print( self->feMesh, stream );
+ if ( self->dofLayout ) {
+ Stg_Class_Print( self->dofLayout, stream );
+ }
+ else {
+ Journal_Printf( stream, "\tdofLayout: (null)... not provided (may be Operator type)\n" );
+ }
+ if ( self->bcs ) {
+ Stg_Class_Print( self->bcs, stream );
+ }
+ else {
+ Journal_Printf( stream, "\tbcs: (null)... not provided (may be Operator type)\n" );
+ }
+ if ( self->ics ) {
+ Stg_Class_Print( self->ics, stream );
+ }
+ else {
+ Journal_Printf( stream, "\tics: (null)... not provided (may be Operator type)\n" );
+ }
+
+ if ( self->linkedDofInfo ) {
+ Stg_Class_Print( self->linkedDofInfo, stream );
+ }
+ else {
+ Journal_Printf( stream, "\tlinkedDofInfo: (null)... not provided\n" );
+ }
+
+ if( self->eqNum ) {
+ Stg_Class_Print( self->eqNum, stream );
+ }
+ else {
+ Journal_Printf( stream, "\teqNum: (null)... not built yet\n" );
+ }
+}
+
+void* _FeVariable_Copy( const void* feVariable, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ FeVariable* self = (FeVariable*)feVariable;
+ FeVariable* newFeVariable;
+ PtrMap* map = ptrMap;
+ Bool ownMap = False;
+
+ if( !map ) {
+ map = PtrMap_New( 10 );
+ ownMap = True;
+ }
+
+ newFeVariable = (FeVariable*)_FieldVariable_Copy( self, dest, deep, nameExt, map );
+
+ newFeVariable->templateFeVariable = self->templateFeVariable;
+
+ if( deep ) {
+ newFeVariable->debug = self->debug;
+ newFeVariable->feMesh = (FeMesh*)Stg_Class_Copy( self->feMesh, NULL, deep, nameExt, map );
+ newFeVariable->dofLayout = (DofLayout*)Stg_Class_Copy( self->dofLayout, NULL, deep, nameExt, map );
+ newFeVariable->bcs = (VariableCondition*)Stg_Class_Copy( self->bcs, NULL, deep, nameExt, map );
+ newFeVariable->ics = self->ics ? (VariableCondition*)Stg_Class_Copy( self->ics, NULL, deep, nameExt, map ) : NULL;
+ if ( self->linkedDofInfo == NULL ) {
+ newFeVariable->linkedDofInfo = NULL;
+ }
+ else {
+ newFeVariable->linkedDofInfo = (LinkedDofInfo*)Stg_Class_Copy( self->linkedDofInfo, NULL,
+ deep, nameExt, map );
+ }
+
+ if( !self->isReferenceSolution ) {
+ if ( self->templateFeVariable ) {
+ newFeVariable->eqNum = self->eqNum;
+ }
+ else {
+ newFeVariable->eqNum = (FeEquationNumber*)Stg_Class_Copy( self->eqNum, NULL, deep, nameExt, map );
+ }
+ }
+ else
+ newFeVariable->eqNum = NULL;
+ }
+ else {
+ newFeVariable->debug = self->debug;
+ newFeVariable->feMesh = self->feMesh;
+ newFeVariable->geometryMesh = self->geometryMesh;
+ newFeVariable->dofLayout = self->dofLayout;
+ newFeVariable->bcs = self->bcs;
+ newFeVariable->ics = self->ics;
+ newFeVariable->linkedDofInfo = self->linkedDofInfo;
+ newFeVariable->eqNum = self->eqNum;
+ }
+
+ if( ownMap ) {
+ Stg_Class_Delete( map );
+ }
+
+ return (void*)newFeVariable;
+}
+
+
+void _FeVariable_Build( void* variable, void* data ) {
+ FeVariable* self = (FeVariable*)variable;
+ DomainContext* context = (DomainContext*)data;
+ unsigned dim, numNodes;
+
+ if ( False == self->isBuilt ) {
+ self->isBuilt = True;
+
+ Journal_DPrintf( self->debug, "In %s- for %s:\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ /** build the BCs */
+ Stg_Component_Build( self->feMesh, data, False );
+ if ( self->dofLayout ) Stg_Component_Build( self->dofLayout, data, False );
+ if ( self->bcs ) Stg_Component_Build( self->bcs, data, False );
+
+ /** only bother building the ics specified via XML/construct if we are not in restart mode
+ - otherwise, we will use the checkpointed values anyway */
+ if ( self->ics && !(context && (True == context->loadFromCheckPoint) ) ) {
+ Stg_Component_Build( self->ics, data, False );
+ }
+
+ if ( self->linkedDofInfo ) Stg_Component_Build( self->linkedDofInfo, data, False );
+
+
+ /** Extract component count. */
+ if ( self->dofLayout ) self->fieldComponentCount = self->dofLayout->_totalVarCount;
+
+ dim = Mesh_GetDimSize(self->feMesh);
+ /** allocate GNx here */
+ /* At least this will work for meshes with names other
+ than those listed above. I spent three hours finding
+ this out.*/
+ numNodes = FeMesh_GetElementNodeSize(self->feMesh, 0);
+
+ self->GNx = Memory_Alloc_2DArray( double, dim, numNodes, (Name)"Global Shape Function Derivatives" );
+
+ /** don't build the equation numbers for fields that aren't being solved for
+ * (ie: error and reference fields) */
+ if( !self->isReferenceSolution && self->buildEqNums ) {
+ Stg_Component_Build( self->eqNum, data, False );
+ }
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+ }
+}
+
+void _FeVariable_AssignFromXML( void* variable, Stg_ComponentFactory* cf, void* data ) {
+ FeVariable* self = (FeVariable*)variable;
+ FeMesh* feMesh = NULL;
+ FeMesh* geometryMesh = NULL;
+ DofLayout* dofLayout = NULL;
+ VariableCondition* bc = NULL;
+ VariableCondition* ic = NULL;
+ LinkedDofInfo* linkedDofInfo = NULL;
+ Bool isReferenceSolution = False;
+ Bool loadReferenceEachTimestep = False;
+
+ _FieldVariable_AssignFromXML( self, cf, data );
+
+ feMesh = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"FEMesh", FeMesh, True, data );
+ geometryMesh = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"GeometryMesh", FeMesh, False, data );
+ dofLayout = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)DofLayout_Type, DofLayout, True, data );
+
+ ic = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"IC", VariableCondition, False, data );
+ bc = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"BC", VariableCondition, False, data );
+ linkedDofInfo = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"LinkedDofInfo", LinkedDofInfo, False, data );
+
+ isReferenceSolution = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"isReferenceSolution", False );
+ loadReferenceEachTimestep = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"loadReferenceEachTimestep", False );
+
+ /** TODO: should really be a parameter */
+ self->removeBCs = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"removeBCs", True );
+
+ _FeVariable_Init( self, feMesh, geometryMesh, dofLayout, bc, ic, linkedDofInfo, NULL, isReferenceSolution, loadReferenceEachTimestep );
+}
+
+void _FeVariable_Initialise( void* variable, void* data ) {
+ FeVariable* self = (FeVariable*)variable;
+ DomainContext* context = self->context;
+ char* inputPathString = NULL;
+ Dictionary_Entry_Value* feVarsList = NULL;
+
+ Journal_DPrintf( self->debug, "In %s- for %s:\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ /** do basic mesh initialisation */
+ Stg_Component_Initialise( self->feMesh, data, False );
+ Stg_Component_Initialise( self->dofLayout, data, False );
+
+ if ( self->linkedDofInfo ) {
+ Stg_Component_Initialise( self->linkedDofInfo, data, False );
+ }
+
+ if( !self->isReferenceSolution ) {
+ Stg_Component_Initialise( self->eqNum, data, False );
+ }
+
+ if ( context ) {
+ /** Get the input path string once here - single point of control */
+ inputPathString = Context_GetCheckPointReadPrefixString( context );
+ }
+ /** If the reference solution option is enabled, just load this up regardless of checkpointing options below.
+ * Want to allow option of disabling this feature, if you're manually setting up a FeVariable without a context etc. */
+ if ( context && self->isReferenceSolution ) {
+ char * filename = NULL;
+ Journal_DPrintf( self->debug, "Reference FeVariable -> loading nodal values from file.\n" );
+
+
+#ifdef READ_HDF5
+ Stg_asprintf( &filename, "%s%s.%.5u.h5", inputPathString, self->name, context->restartTimestep );
+#else
+ Stg_asprintf( &filename, "%s%s.%.5u.dat", inputPathString, self->name, context->restartTimestep );
+#endif
+ FeVariable_ReadFromFile( self, filename );
+
+ Memory_Free( filename );
+ Stream_UnIndentBranch( StgFEM_Debug );
+ return;
+ }
+
+ /** Setting up whether to load from checkpointing */
+ if ( self->ics || ((context && (True == context->loadFromCheckPoint) )&& (self->isCheckpointedAndReloaded)) ) {
+ Journal_DPrintf( self->debug, "applying the I.C.s for this Variable:\n" );
+ Stream_Indent( self->debug );
+
+ if ( self->ics && !(context && (True == context->loadFromCheckPoint) && (True == self->isCheckpointedAndReloaded)) ) {
+ Journal_DPrintf( self->debug, "regular (non-restart) mode -> applying ICs specified in XML/constructor\n" );
+ Stg_Component_Initialise( self->ics, context, False );
+ VariableCondition_Apply( self->ics, context );
+ }
+ else {
+ char * filename = NULL;
+ Journal_DPrintf( self->debug, "restart from checkpoint mode -> loading checkpointed "
+ "nodal values as initial conditions, ignoring ics specified via XML/constructor\n" );
+
+#ifdef READ_HDF5
+ Stg_asprintf( &filename, "%s%s.%.5u.h5", inputPathString, self->name, context->restartTimestep );
+ if (!context->interpolateRestart)
+ FeVariable_ReadFromFile( self, filename );
+ else {
+ char * meshFilename = NULL;
+ if (!strcmp(self->feMesh->generator->type, CartesianGenerator_Type))
+ Stg_asprintf( &meshFilename, "%sMesh.%s.%.5u.h5", inputPathString, self->feMesh->name, context->restartTimestep );
+ else
+ Stg_asprintf( &meshFilename, "%sMesh.%s.%.5u.h5", inputPathString, ((C0Generator*)(self->feMesh->generator))->elMesh->name, context->restartTimestep );
+ FeVariable_InterpolateFromFile( self, context, filename, meshFilename );
+ Memory_Free( meshFilename );
+ }
+
+#else
+ Stg_asprintf( &filename, "%s%s.%.5u.dat", inputPathString, self->name, context->restartTimestep );
+ FeVariable_ReadFromFile( self, filename );
+#endif
+
+ Memory_Free( filename );
+
+ }
+ }
+ Memory_Free( inputPathString );
+ Stream_UnIndent( self->debug );
+
+ if( context ) {
+ /** also include check to see if this fevariable should be checkpointed, just incase it didn't go through the
+ fieldvariable construct phase */
+ feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"fieldVariablesToCheckpoint" );
+ if ( NULL == feVarsList ) {
+ feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"FieldVariablesToCheckpoint" );
+ }
+ if (feVarsList != NULL ) {
+ Index listLength = Dictionary_Entry_Value_GetCount( feVarsList );
+ Index var_I = 0;
+ Dictionary_Entry_Value* feVarDictValue = NULL;
+ char* fieldVariableName;
+
+ for ( var_I = 0; var_I < listLength; var_I++ ) {
+ feVarDictValue = Dictionary_Entry_Value_GetElement( feVarsList, var_I );
+ fieldVariableName = Dictionary_Entry_Value_AsString( feVarDictValue );
+ if ( 0 == strcmp( self->name, fieldVariableName ) ) {
+ self->isCheckpointedAndReloaded = True;
+ break;
+ }
+ }
+ }
+
+ feVarsList = NULL;
+ /** also include check to see if this fevariable should be saved for analysis purposes */
+ feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"fieldVariablesToSave" );
+ if ( NULL == feVarsList ) {
+ feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"FieldVariablesToSave" );
+ }
+ if (feVarsList != NULL ) {
+ Index listLength = Dictionary_Entry_Value_GetCount( feVarsList );
+ Index var_I = 0;
+ Dictionary_Entry_Value* feVarDictValue = NULL;
+ char* fieldVariableName;
+
+ for ( var_I = 0; var_I < listLength; var_I++ ) {
+ feVarDictValue = Dictionary_Entry_Value_GetElement( feVarsList, var_I );
+ fieldVariableName = Dictionary_Entry_Value_AsString( feVarDictValue );
+ if ( 0 == strcmp( self->name, fieldVariableName ) ) {
+ self->isSavedData = True;
+ break;
+ }
+ }
+ }
+ }
+
+ if ( self->bcs ) {
+ Stg_Component_Initialise( self->bcs, context, False );
+ Journal_DPrintf( self->debug, "applying the B.C.s for this Variable.\n" );
+ VariableCondition_Apply( self->bcs, context );
+ }
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void FeVariable_ApplyBCs( void* variable, void* data ) {
+ FeVariable* self = (FeVariable*)variable;
+
+ /** This is an unpleasant hack; we really need to reevaluate our BC code. */
+ if( self->dynamicBCs[0] ) {
+ VariableCondition_Apply( self->dynamicBCs[0], data );
+ }
+ if( self->dynamicBCs[1] ) {
+ VariableCondition_Apply( self->dynamicBCs[1], data );
+ }
+ if( self->dynamicBCs[2] ) {
+ VariableCondition_Apply( self->dynamicBCs[2], data );
+ }
+ if ( self->bcs ) {
+ Journal_DPrintf( self->debug, "In %s- for %s:\n", __func__, self->name );
+ Journal_DPrintf( self->debug, "applying the B.C.s for this Variable.\n" );
+ VariableCondition_Apply( self->bcs, data );
+ }
+}
+
+Bool FeVariable_IsBC( void* variable, int node, int dof ) {
+ FeVariable* self = (FeVariable*)variable;
+
+ assert( self );
+ if( self->dynamicBCs[0] &&
+ self->dynamicBCs[0]->var == DofLayout_GetVariable( self->dofLayout, node, dof ) &&
+ IMap_Has( self->dynamicBCs[0]->vcMap, node ) )
+ {
+ return True;
+ }
+
+ if( self->dynamicBCs[1] &&
+ self->dynamicBCs[1]->var == DofLayout_GetVariable( self->dofLayout, node, dof ) &&
+ IMap_Has( self->dynamicBCs[1]->vcMap, node ) )
+ {
+ return True;
+ }
+
+ if( self->dynamicBCs[2] &&
+ self->dynamicBCs[2]->var == DofLayout_GetVariable( self->dofLayout, node, dof ) &&
+ IMap_Has( self->dynamicBCs[2]->vcMap, node ) )
+ {
+ return True;
+ }
+
+ if( self->bcs &&
+ VariableCondition_IsCondition( self->bcs, node, self->dofLayout->varIndices[node][dof] ) )
+ {
+ return True;
+ }
+
+ return False;
+}
+
+
+void _FeVariable_Execute( void* variable, void* data ) {
+}
+
+void _FeVariable_Destroy( void* variable, void* data ) {
+ FeVariable* self = (FeVariable*)variable;
+
+ Memory_Free( self->GNx );
+
+ Stream_IndentBranch( StgFEM_Debug );
+
+ if( self->eqNum && ( NULL == self->templateFeVariable ) ) {
+ _Stg_Component_Delete( self->eqNum );
+ self->eqNum = NULL;
+ }
+ /** feMesh bc and doflayout are purposely not deleted */
+
+ if( self->inc == NULL ) {
+ NewClass_Delete( self->inc );
+ self->inc = NULL;
+ }
+
+ _FieldVariable_Destroy( self, data );
+}
+
+void FeVariable_PrintLocalDiscreteValues( void* variable, Stream* stream ) {
+ FeVariable* self = (FeVariable*)variable;
+
+ Journal_Printf( stream, "In %s: for FeVariable \"%s\":\n", __func__, self->name );
+
+ _FeVariable_PrintLocalOrDomainValues( variable, FeMesh_GetNodeLocalSize( self->feMesh ), stream );
+}
+
+unsigned _FeVariable_ClosestNode( FeVariable* self, double* crd ) {
+ assert( self );
+ return Mesh_NearestVertex( self->feMesh, crd );
+}
+
+
+InterpolationResult _FeVariable_InterpolateValueAt( void* variable, double* globalCoord, double* value ) {
+ FeVariable* self = (FeVariable*)variable;
+ Element_DomainIndex elementCoordIn = (unsigned)-1;
+ Coord elLocalCoord={0,0,0};
+ InterpolationResult retValue;
+
+
+ retValue = FeVariable_GetElementLocalCoordAtGlobalCoord( self, globalCoord, elLocalCoord, &elementCoordIn );
+
+ if ( retValue == LOCAL ) {
+ /** Now interpolate the value at that coordinate, using shape functions */
+ self->_interpolateWithinElement( self, elementCoordIn, elLocalCoord, value );
+ }
+ else if ( retValue == SHADOW ) {
+ if ( False == self->shadowValuesSynchronised ) {
+ Stream* warningStr = Journal_Register( Error_Type, (Name)self->type );
+ Journal_Printf( warningStr, "Warning - in %s: user asking to interpolate a value at "
+ "coord (%g,%g,%g), which is in shadow space, but "
+ "FeVariable_SyncShadowValues() hasn't been called yet.\n",
+ __func__, globalCoord[0], globalCoord[1], globalCoord[2] );
+ return retValue;
+ }
+ /** Now interpolate the value at that coordinate, using shape functions */
+ self->_interpolateWithinElement( self, elementCoordIn, elLocalCoord, value );
+ }
+
+ return retValue;
+}
+
+
+double _FeVariable_GetMinGlobalFieldMagnitude( void* feVariable ) {
+ FeVariable* self = (FeVariable*)feVariable;
+ FeMesh* feMesh = self->feMesh;
+ int node_lI=0;
+ int nodeLocalCount = FeMesh_GetNodeLocalSize( feMesh );
+ double min = 0;
+ double globalMin = 0;
+ double currValue;
+
+ min = FeVariable_GetScalarAtNode( self, 0 );
+
+ /** Find upper and lower bounds on this processor */
+ for ( node_lI = 0 ; node_lI < nodeLocalCount ; node_lI++ ) {
+ currValue = FeVariable_GetScalarAtNode( self, node_lI );
+ if ( currValue < min ) {
+ min = currValue;
+ }
+ }
+
+ /** Find upper and lower bounds on all processors */
+ MPI_Allreduce( &min, &globalMin, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD );
+ return globalMin;
+}
+
+
+double _FeVariable_GetMaxGlobalFieldMagnitude( void* feVariable ) {
+ FeVariable* self = (FeVariable*)feVariable;
+ int node_lI=0;
+ int nodeLocalCount = FeMesh_GetNodeLocalSize( self->feMesh );
+ double max = 0;
+ double globalMax = 0;
+ double currValue;
+
+ max = FeVariable_GetScalarAtNode( self, 0 );
+
+ /** Find upper and lower bounds on this processor */
+ for ( node_lI = 0 ; node_lI < nodeLocalCount ; node_lI++ ) {
+ currValue = FeVariable_GetScalarAtNode( self, node_lI );
+ if ( currValue > max ) {
+ max = currValue;
+ }
+ }
+
+ /** Find upper and lower bounds on all processors */
+ MPI_Allreduce( &max, &globalMax, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD );
+ return globalMax;
+}
+
+void _FeVariable_GetMinAndMaxLocalCoords( void* feVariable, double* min, double* max ) {
+ FeVariable* self = (FeVariable*)feVariable;
+
+ assert( self && Stg_CheckType( self, FeVariable ) );
+
+ Mesh_GetLocalCoordRange( self->feMesh, min, max );
+}
+
+
+void _FeVariable_GetMinAndMaxGlobalCoords( void* feVariable, double* min, double* max ) {
+ FeVariable* self = (FeVariable*)feVariable;
+
+ assert( self && Stg_CheckType( self, FeVariable ) );
+
+ Mesh_GetGlobalCoordRange( self->feMesh, min, max );
+}
+
+double FeVariable_GetScalarAtNode( void* feVariable, Node_LocalIndex lNode_I ) {
+ FeVariable* self = (FeVariable*)feVariable;
+ Dof_Index dofCountThisNode = 0;
+ Dof_Index nodeLocalDof_I = 0;
+ double value[ MAX_FIELD_COMPONENTS ];
+
+ /**
+ if( self->type != OperatorFeVariable_Type && self->dofLayout )
+ dofCountThisNode = self->dofLayout->dofCounts[lNode_I];
+ else {
+ */
+ dofCountThisNode = self->fieldComponentCount;
+ /**
+ }
+ */
+
+ FeVariable_GetValueAtNode( self, lNode_I, value );
+
+ if ( dofCountThisNode > 1) {
+ double magnitude=0;
+ for ( nodeLocalDof_I=0; nodeLocalDof_I < dofCountThisNode; nodeLocalDof_I++ ) {
+ magnitude += value[ nodeLocalDof_I ] * value[ nodeLocalDof_I ];
+ }
+ return sqrt( magnitude );
+ }
+ else
+ return value[0];
+
+}
+
+
+void _FeVariable_GetValueAtNode( void* feVariable, Node_DomainIndex dNode_I, double* value ) {
+ FeVariable* self = (FeVariable*)feVariable;
+ Variable* currVariable = NULL;
+ Dof_Index dofCountThisNode = 0;
+ Dof_Index nodeLocalDof_I = 0;
+
+ dofCountThisNode = self->dofLayout->dofCounts[dNode_I];
+
+ for ( nodeLocalDof_I=0; nodeLocalDof_I < dofCountThisNode; nodeLocalDof_I++ ) {
+ currVariable = DofLayout_GetVariable( self->dofLayout, dNode_I, nodeLocalDof_I );
+ value[ nodeLocalDof_I ] = Variable_GetValueDouble( currVariable, dNode_I );
+ }
+}
+
+/** Finds the value of the field at the node and broadcasts it to the rest of the processors */
+void FeVariable_GetValueAtNodeGlobal( void* feVariable, Node_GlobalIndex gNode_I, double* value ) {
+ FeVariable* self = (FeVariable*) feVariable;
+ FeMesh* mesh = self->feMesh;
+ Element_LocalIndex lNode_I;
+ int rootRankL = 0;
+ int rootRankG = 0;
+ MPI_Comm comm = self->communicator;
+
+ /** Find Local Index */
+ if ( Mesh_GlobalToDomain( mesh, MT_VERTEX, gNode_I, &lNode_I ) ) {
+ /** If node is on local processor, then get value of field */
+ FeVariable_GetValueAtNode( self, lNode_I, value );
+ MPI_Comm_rank( comm, (int*)&rootRankL );
+ }
+
+ /** Send to other processors */
+ MPI_Allreduce( &rootRankL, &rootRankG, 1, MPI_INT, MPI_MAX, comm );
+ MPI_Bcast( value, self->fieldComponentCount, MPI_DOUBLE, rootRankG, comm );
+}
+
+/** Finds the coordinate of the node and broadcasts it to the rest of the processors */
+void FeVariable_GetCoordAtNodeGlobal( void* feVariable, Node_GlobalIndex gNode_I, double* coord ) {
+ FeVariable* self = (FeVariable*) feVariable;
+ FeMesh* mesh = self->feMesh;
+ Element_LocalIndex lNode_I;
+ int rootRankL = 0;
+ int rootRankG = 0;
+ MPI_Comm comm = self->communicator;
+
+ /** Find Local Index */
+ if ( Mesh_GlobalToDomain( mesh, MT_VERTEX, gNode_I, &lNode_I ) ) {
+ /** If node is on local processor, then get value of field */
+ memcpy( coord, Mesh_GetVertex( mesh, lNode_I ), self->dim * sizeof(double) );
+ MPI_Comm_rank( comm, (int*)&rootRankL );
+ }
+
+ /** Send to other processors */
+ MPI_Allreduce( &rootRankL, &rootRankG, 1, MPI_INT, MPI_MAX, comm );
+ MPI_Bcast( coord, self->dim, MPI_DOUBLE, rootRankG, comm );
+}
+
+
+void FeVariable_ZeroField( void* feVariable ) {
+ FeVariable* self = (FeVariable*) feVariable;
+ double* values = Memory_Alloc_Array( double, self->fieldComponentCount, "tempValues" );
+ Index lNode_I, lNodeCount;
+
+ lNodeCount = FeMesh_GetNodeLocalSize( self->feMesh );
+
+ memset( values, 0, self->fieldComponentCount * sizeof(double) );
+
+ for( lNode_I = 0 ; lNode_I < lNodeCount; lNode_I++ ) {
+ FeVariable_SetValueAtNode( self, lNode_I, values );
+ }
+
+ Memory_Free( values );
+}
+
+/** --- Public Functions --- */
+
+InterpolationResult FeVariable_GetElementLocalCoordAtGlobalCoord( void* feVariable, double* globalCoord, double* elLocalCoord,
+ Element_DomainIndex* elementCoordInPtr )
+{
+ FeVariable* self = (FeVariable*)feVariable;
+ InterpolationResult retValue;
+ unsigned elInd;
+
+ /** locate which mesh element given coord is in : use inclusive upper boundaries to save
+ the need to use shadow space if possible */
+ if( !Mesh_SearchElements( self->feMesh, globalCoord, &elInd ) ) {
+ Bool outsideGlobal = False;
+ double min[3], max[3];
+ Dimension_Index dim_I=0;
+
+ FieldVariable_GetMinAndMaxGlobalCoords( self, min, max );
+ for ( dim_I = 0; dim_I < self->dim; dim_I++ ) {
+ if ( ( globalCoord[dim_I] < min[dim_I] ) || (globalCoord[dim_I] > max[dim_I] ) ) {
+ outsideGlobal = True;
+ }
+ }
+
+ if ( outsideGlobal == True ) {
+ return OUTSIDE_GLOBAL;
+ }
+ else {
+ return OTHER_PROC;
+ }
+ }
+ else /** We found the coord is within a local or shadow element */ {
+ ElementType* elementType = NULL;
+
+ *elementCoordInPtr = elInd;
+ if ( elInd < FeMesh_GetElementLocalSize( self->feMesh ) ) {
+ retValue = LOCAL;
+ }
+ else {
+ retValue = SHADOW;
+ }
+
+ /** convert global coordinate to local co-ordinates of element the coord is in */
+ elementType = FeMesh_GetElementType( self->feMesh, (*elementCoordInPtr) );
+ ElementType_ConvertGlobalCoordToElLocal( elementType, self->feMesh, *elementCoordInPtr,
+ globalCoord, elLocalCoord );
+ }
+
+ return retValue;
+}
+
+
+void FeVariable_SetValueAtNode( void* feVariable, Node_DomainIndex dNode_I, double* componentValues ) {
+ FeVariable* self = (FeVariable*)feVariable;
+ Dof_Index dofCountThisNode = 0;
+ Dof_Index nodeLocalDof_I = 0;
+
+ dofCountThisNode = self->dofLayout->dofCounts[dNode_I];
+
+ for ( nodeLocalDof_I=0; nodeLocalDof_I < dofCountThisNode; nodeLocalDof_I++ ) {
+ DofLayout_SetValueDouble( (self)->dofLayout, dNode_I, nodeLocalDof_I, componentValues[nodeLocalDof_I] );
+ }
+}
+
+
+void FeVariable_PrintLocalDiscreteValues_2dBox( void* variable, Stream* stream ) {
+ FeVariable* self = (FeVariable*)variable;
+ Node_LocalIndex node_lI=0;
+ Index x_I, y_I;
+ Index ii;
+ Dof_Index dof_I=0;
+ Dof_Index currNodeNumDofs=0;
+ Index nx = 0;
+ Index ny = 0;
+ double dx = 0;
+ double dy = 0;
+ DofLayout* dofLayout = self->dofLayout;
+ Stream* eStream = Journal_Register( Error_Type, (Name)self->type );
+ Index minLocalNodeX;
+ Index minLocalNodeY;
+ Index maxLocalNodeX;
+ Index maxLocalNodeY;
+ Grid* vertGrid;
+ unsigned inds[2];
+ unsigned vertInd;
+ double* verts[2];
+ unsigned *localOrigin, *localRange;
+ double min[2], max[2];
+
+ if( ExtensionManager_GetHandle( self->feMesh->info, (Name)"vertexGrid" ) == (unsigned)-1 ||
+ Mesh_GetDimSize( self->feMesh ) != 2 )
+ {
+ Journal_Printf( eStream, "Warning: %s called on variable \"%s\", but this isn't stored on a "
+ "regular 2D mesh - so just returning.\n", __func__, self->name );
+ return;
+ }
+
+ vertGrid = *(Grid**)ExtensionManager_Get( self->feMesh->info, self->feMesh,
+ ExtensionManager_GetHandle( self->feMesh->info, (Name)"vertexGrid" ) );
+ localOrigin = (unsigned* )ExtensionManager_Get( self->feMesh->info, self->feMesh,
+ ExtensionManager_GetHandle( self->feMesh->info, (Name)"localOrigin" ) );
+ localRange = (unsigned* )ExtensionManager_Get( self->feMesh->info, self->feMesh,
+ ExtensionManager_GetHandle( self->feMesh->info, (Name)"localRange" ) );
+
+ memcpy( inds, localOrigin, Mesh_GetDimSize( self->feMesh ) * sizeof(unsigned) );
+ insist( Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, Grid_Project( vertGrid, inds ), &vertInd ), == True );
+ verts[0] = Mesh_GetVertex( self->feMesh, vertInd );
+ inds[0]++;
+ inds[1]++;
+ insist( Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, Grid_Project( vertGrid, inds ), &vertInd ), == True );
+ verts[1] = Mesh_GetVertex( self->feMesh, vertInd );
+
+ nx = vertGrid->sizes[0];
+ ny = vertGrid->sizes[1];
+ dx = verts[1][0] - verts[0][0];
+ dy = verts[1][1] - verts[0][1];
+
+
+
+ minLocalNodeX = localOrigin[0];
+ minLocalNodeY = localOrigin[1];
+ maxLocalNodeX = minLocalNodeX + localRange[0] + 1;
+ maxLocalNodeY = minLocalNodeY + localRange[1] + 1;
+
+ Mesh_GetGlobalCoordRange( self->feMesh, min, max );
+
+ Journal_Printf( stream, "display of Values in 2D box X:{%5.2f-%5.2f}, Y:{%5.2f-%5.2f}\n",
+ min[I_AXIS], max[I_AXIS],
+ min[J_AXIS], max[J_AXIS] );
+ Journal_Printf( stream, "\twith %d elements in X (dx=%5.2f) and %d elements in Y (dy=%5.2f)\n\n",
+ nx-1, dx, ny-1, dy );
+
+ /**Header*/
+ for (ii=0;ii<10;ii++) Journal_Printf( stream, " " );
+ for ( x_I=0; x_I < nx; x_I++ ) {
+ Journal_Printf( stream, "| xNode=%3d ", x_I );
+ }
+ Journal_Printf( stream, "|\n", x_I );
+
+ for ( y_I= ny-1; y_I != (unsigned)-1; y_I-- ) {
+ /**Blocks */
+ for (ii=0;ii<10;ii++) Journal_Printf( stream, " " );
+ for ( x_I=0; x_I < nx; x_I++ ) {
+ if (y_I == ny-1) {
+ Journal_Printf( stream, "-" );
+ }
+ else if (x_I==0) {
+ Journal_Printf( stream, "|" );
+ }
+ else {
+ Journal_Printf( stream, "*" );
+ }
+ for (ii=0;ii<14;ii++) Journal_Printf( stream, "-" );
+ }
+ if (y_I == ny-1) {
+ Journal_Printf( stream, "-\n" );
+ }
+ else {
+ Journal_Printf( stream, "|\n" );
+ }
+
+
+ /** Now a row of y values */
+ Journal_Printf( stream, "yNode=%3d |", y_I );
+ for ( x_I=0; x_I < nx; x_I++ ) {
+
+ if ( ( y_I >= minLocalNodeY ) && ( y_I < maxLocalNodeY )
+ && ( x_I >= minLocalNodeX ) && ( x_I < maxLocalNodeX ) ) {
+
+ inds[0] = x_I;
+ inds[1] = y_I;
+ node_lI = RegularMeshUtils_Node_3DTo1D( self->feMesh, inds );
+ insist( Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, node_lI, &node_lI ), == True );
+ currNodeNumDofs = dofLayout->dofCounts[node_lI];
+
+ if ( currNodeNumDofs == 1 ) {
+ Journal_Printf( stream, " " );
+ }
+ Journal_Printf( stream, "(" );
+ for ( dof_I=0; dof_I < currNodeNumDofs - 1 ; dof_I++ ) {
+ Journal_Printf( stream, "%5.2f,", DofLayout_GetValueDouble( dofLayout, node_lI, dof_I ) );
+ }
+ Journal_Printf( stream, "%5.2f )", DofLayout_GetValueDouble( dofLayout, node_lI, dof_I ) );
+
+ if ( currNodeNumDofs == 1 ) {
+ Journal_Printf( stream, " " );
+ }
+ Journal_Printf( stream, "|" );
+ }
+ else {
+ for (ii=0;ii<14;ii++) Journal_Printf( stream, "X" );
+ Journal_Printf( stream, "|" );
+ }
+ }
+ Journal_Printf( stream, "\n" );
+ }
+
+ /**Blocks */
+ for (ii=0;ii<10;ii++) Journal_Printf( stream, " " );
+ for ( x_I=0; x_I < nx; x_I++ ) {
+ Journal_Printf( stream, "-" );
+ for (ii=0;ii<14;ii++) Journal_Printf( stream, "-" );
+ }
+ Journal_Printf( stream, "-\n", x_I );
+}
+
+
+Bool FeVariable_InterpolateDerivativesAt( void* variable, double* globalCoord, double* value ) {
+ FeVariable* self = (FeVariable*)variable;
+ Element_DomainIndex elementCoordIn = (unsigned)-1;
+ Coord elLocalCoord = {0,0,0};
+
+ /** Need a special rule for points on this processor's boundary: instead of the normal
+ rule, "round" the point to lie inside the local space, rather than shadow */
+
+ /** locate which mesh element given coord is in : use inclusive upper boundaries to save
+ the need to use shadow space if possible */
+ if ( !Mesh_Algorithms_SearchElements( self->feMesh->algorithms, globalCoord,
+ &elementCoordIn ) )
+ {
+ /** If coord isn't inside domain elements list, bail out */
+ return False;
+ }
+ else /** We found the coord is within a local or shadow element */ {
+ if ( elementCoordIn >= FeMesh_GetElementLocalSize( self->feMesh ) ) {
+ if ( False == self->shadowValuesSynchronised ) {
+ Stream* warningStr = Journal_Register( Error_Type, (Name)self->type );
+ Journal_Printf( warningStr, "Warning - in %s: user asking to interpolate derivatives "
+ "to coord (%g,%g,%g), which is in shadow space, but "
+ "FeVariable_SyncShadowValues() hasn't been called yet.\n",
+ __func__, globalCoord[0], globalCoord[1], globalCoord[2] );
+ return False;
+ }
+ }
+
+ /** convert global coordinate to local co-ordinates of element the coord is in */
+ FeMesh_CoordGlobalToLocal( self->feMesh, elementCoordIn, globalCoord, elLocalCoord );
+
+ /** Now interpolate the value at that coordinate, using shape functions */
+ FeVariable_InterpolateDerivativesToElLocalCoord( self, elementCoordIn, elLocalCoord, value );
+ }
+
+ return True;
+}
+
+void FeVariable_InterpolateDerivativesToElLocalCoord( void* _feVariable, Element_DomainIndex lElement_I, Coord elLocalCoord, double* value ) {
+ FeVariable* self = (FeVariable*) _feVariable;
+ ElementType* elementType = FeMesh_GetElementType( self->feMesh, lElement_I );
+ double** GNx;
+ double detJac;
+ Dimension_Index dim = self->dim;
+
+ GNx = self->GNx;
+
+ /** Evaluate Global Shape Functions */
+ ElementType_ShapeFunctionsGlobalDerivs(
+ elementType,
+ self->feMesh, lElement_I,
+ elLocalCoord, dim, &detJac, GNx );
+
+ /** Do Interpolation */
+ FeVariable_InterpolateDerivatives_WithGNx( self, lElement_I, GNx, value );
+}
+
+void FeVariable_InterpolateDerivatives_WithGNx( void* _feVariable, Element_LocalIndex lElement_I, double** GNx, double* value ) {
+ FeVariable* self = (FeVariable*) _feVariable;
+ Node_ElementLocalIndex elLocalNode_I;
+ Node_LocalIndex lNode_I;
+ Dof_Index dof_I;
+ Dof_Index dofCount;
+ /* Variable* dofVariable; */
+ double nodeValue;
+ unsigned nInc, *inc;
+ Dimension_Index dim = self->dim;
+ double* tmpVal;
+
+ /** Gets number of degrees of freedom - assuming it is the same throughout the mesh */
+ dofCount = self->dofLayout->dofCounts[0];
+
+ /** Initialise */
+ memset( value, 0, sizeof( double ) * dofCount * dim );
+ tmpVal = (double*)malloc( dim*dofCount*sizeof(double) );
+
+ FeMesh_GetElementNodes( self->feMesh, lElement_I, self->inc );
+ nInc = IArray_GetSize( self->inc );
+ inc = (unsigned*)IArray_GetPtr( self->inc );
+
+ /** Interpolate derivative from nodes */
+ for ( elLocalNode_I = 0 ; elLocalNode_I < nInc ; elLocalNode_I++) {
+
+ lNode_I = inc[ elLocalNode_I ];
+ FeVariable_GetValueAtNode( self, lNode_I, tmpVal );
+ /*dofVariable = DofLayout_GetVariable( self->dofLayout, lNode_I, dof_I );*/
+ /*nodeValue = Variable_GetValueDouble( dofVariable, lNode_I );*/
+
+ for ( dof_I = 0 ; dof_I < dofCount ; dof_I++ ) {
+ nodeValue = tmpVal[dof_I];
+
+ value[dof_I*dim + 0] += GNx[0][elLocalNode_I] * nodeValue;
+ value[dof_I*dim + 1] += GNx[1][elLocalNode_I] * nodeValue;
+ if( dim == 3 )
+ value[dof_I*dim + 2] += GNx[2][elLocalNode_I] * nodeValue;
+ }
+ }
+
+ free( tmpVal );
+}
+
+void FeVariable_InterpolateValue_WithNi( void* _feVariable, Element_LocalIndex lElement_I, double* Ni, double* value ) {
+ FeVariable* self = (FeVariable*) _feVariable;
+ Node_ElementLocalIndex elLocalNode_I;
+ Node_LocalIndex lNode_I;
+ Dof_Index dof_I;
+ Dof_Index dofCount;
+ Variable* dofVariable;
+ double nodeValue;
+ unsigned nInc, *inc;
+
+ /** Gets number of degrees of freedom - assuming it is the same throughout the mesh */
+ dofCount = self->dofLayout->dofCounts[0];
+
+ /** Initialise */
+ memset( value, 0, sizeof( double ) * dofCount );
+
+ FeMesh_GetElementNodes( self->feMesh, lElement_I, self->inc );
+ nInc = IArray_GetSize( self->inc );
+ inc = (unsigned*)IArray_GetPtr( self->inc );
+
+ for ( dof_I = 0 ; dof_I < dofCount ; dof_I++ ) {
+ /** Interpolate derivative from nodes */
+ for ( elLocalNode_I = 0 ; elLocalNode_I < nInc ; elLocalNode_I++) {
+ lNode_I = inc[ elLocalNode_I ];
+ dofVariable = DofLayout_GetVariable( self->dofLayout, lNode_I, dof_I );
+ nodeValue = Variable_GetValueDouble( dofVariable, lNode_I );
+
+ value[dof_I] += Ni[elLocalNode_I] * nodeValue;
+ }
+ }
+}
+
+void FeVariable_GetMinimumSeparation( void* feVariable, double* minSeparationPtr, double minSeparationEachDim[3] ) {
+ FeVariable* self = (FeVariable*)feVariable;
+
+ assert( self && Stg_CheckType( self, FeVariable ) );
+
+ Mesh_GetMinimumSeparation( self->feMesh, minSeparationPtr, minSeparationEachDim );
+}
+
+
+void _FeVariable_SyncShadowValues( void* feVariable ) {
+ FeVariable* self = (FeVariable*)feVariable;
+ DofLayout* dofLayout;
+ Sync* vertSync;
+ unsigned var_i;
+
+ assert( self );
+
+ /** Shortcuts. */
+ dofLayout = self->dofLayout;
+ if( !dofLayout ) {
+ self->shadowValuesSynchronised = True;
+ return;
+ }
+
+ /** Create a distributed array based on the mesh's vertices. */
+ vertSync = Mesh_GetSync( self->feMesh, MT_VERTEX );
+
+ /**
+ ** For each variable in the dof layout, we need to create a distributed array and update
+ ** shadow values.
+ */
+
+ for( var_i = 0; var_i < dofLayout->_totalVarCount; var_i++ ) {
+ unsigned varInd;
+ Variable* var;
+ unsigned field_i;
+
+ /** Get the variable. */
+ varInd = dofLayout->_varIndicesMapping[var_i];
+ var = Variable_Register_GetByIndex( dofLayout->_variableRegister, varInd );
+
+ /** Each field of the variable will need to be handled individually. */
+ for( field_i = 0; field_i < var->offsetCount; field_i++ ) {
+ unsigned offs, size;
+ Stg_Byte *arrayStart, *arrayEnd;
+
+ offs = var->offsets[field_i];
+ size = var->dataSizes[field_i];
+
+ arrayStart = (Stg_Byte*)var->arrayPtr + offs;
+ arrayEnd = arrayStart + var->structSize * FeMesh_GetNodeLocalSize( self->feMesh );
+ Sync_SyncArray( vertSync, arrayStart, var->structSize,
+ arrayEnd, var->structSize,
+ size );
+ }
+ }
+
+ self->shadowValuesSynchronised = True;
+
+#if 0
+ Neighbour_Index nbr_I = 0;
+ Node_Index node_stI = 0;
+ Node_DomainIndex node_dI = 0;
+ Node_LocalIndex node_lI = 0;
+ Dof_Index nodalDof_I = 0;
+ Processor_Index nbrRank = 0;
+ Index* incomingDofTotals = NULL;
+ double** incomingDofValues = NULL;
+ MPI_Request** incomingDofValRequests = NULL;
+ Node_Index myShadowNodesOnThisNbrCount = 0;
+ Dof_Index incomingDof_I;
+ Index* outgoingDofTotals = NULL;
+ double** outgoingDofValues = NULL;
+ MPI_Request** outgoingDofValRequests = NULL;
+ Node_Index nbrShadowNodesOnMeCount = 0;
+ Dof_Index outgoingDof_I;
+ MPI_Status status;
+ int incomingDofValueSetsYetToReceive;
+ Bool* incomingDofValueSetsReceived;
+
+ Journal_DPrintf( self->debug, "In %s- for feVariable \"%s\":\n", __func__, self->name );
+ Stream_Indent( self->debug );
+
+ if ( ( 1 == mesh->layout->decomp->procsInUse ) || ( 0 == mesh->layout->decomp->shadowDepth ) ) {
+ Journal_DPrintf( self->debug, "No shadow nodes: nothing to do - returning.\n" );
+ Stream_UnIndent( self->debug );
+ return;
+ }
+
+ self->shadowValuesSynchronised = True;
+
+ /** allocate memory for incoming info */
+ incomingDofTotals = Memory_Alloc_Array( Index, mesh->procNbrInfo->procNbrCnt, "incomingDofTotals" );
+ incomingDofValues = Memory_Alloc_Array( double*, mesh->procNbrInfo->procNbrCnt, "incomingDofValues" );
+ incomingDofValRequests = Memory_Alloc_Array( MPI_Request*, mesh->procNbrInfo->procNbrCnt, "incomingDofValRequests" );
+ incomingDofValueSetsReceived = Memory_Alloc_Array( Bool, mesh->procNbrInfo->procNbrCnt, "incomingDofValueSets" );
+ incomingDofValueSetsYetToReceive = 0;
+ for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
+ myShadowNodesOnThisNbrCount = mesh->nodeShadowInfo->procShadowCnt[nbr_I];
+ incomingDofTotals[nbr_I] = 0;
+ incomingDofValues[nbr_I] = NULL;
+ incomingDofValRequests[nbr_I] = NULL;
+ incomingDofValueSetsReceived[nbr_I] = False;
+
+ if ( myShadowNodesOnThisNbrCount > 0 ) {
+ for( node_stI = 0; node_stI < myShadowNodesOnThisNbrCount; node_stI++ ) {
+ node_dI = mesh->nodeShadowInfo->procShadowTbl[nbr_I][node_stI];
+ incomingDofTotals[nbr_I] += self->dofLayout->dofCounts[node_dI];
+ }
+ incomingDofValues[nbr_I] = Memory_Alloc_Array( double, incomingDofTotals[nbr_I],
+ "incomingDofValues[]" );
+ incomingDofValRequests[nbr_I] = Memory_Alloc( MPI_Request, "incomingDofValRequest" );
+ incomingDofValueSetsYetToReceive++;
+ }
+ }
+ /** allocate memory for outgoing info */
+ outgoingDofTotals = Memory_Alloc_Array( Index, mesh->procNbrInfo->procNbrCnt, "outgoingDofTotals" );
+ outgoingDofValues = Memory_Alloc_Array( double*, mesh->procNbrInfo->procNbrCnt, "outgoingDofValues" );
+ outgoingDofValRequests = Memory_Alloc_Array( MPI_Request*, mesh->procNbrInfo->procNbrCnt, "outgoingDofValRequests" );
+ for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
+ nbrShadowNodesOnMeCount = mesh->nodeShadowInfo->procShadowedCnt[nbr_I];
+ outgoingDofTotals[nbr_I] = 0;
+ outgoingDofValues[nbr_I] = NULL;
+ outgoingDofValRequests[nbr_I] = NULL;
+
+ if ( nbrShadowNodesOnMeCount > 0 ) {
+ for( node_stI = 0; node_stI < nbrShadowNodesOnMeCount; node_stI++ ) {
+ node_lI = mesh->nodeShadowInfo->procShadowedTbl[nbr_I][node_stI];
+ outgoingDofTotals[nbr_I] += self->dofLayout->dofCounts[node_lI];
+ }
+ outgoingDofValues[nbr_I] = Memory_Alloc_Array( double, outgoingDofTotals[nbr_I],
+ "outgoingDofValues[]" );
+ outgoingDofValRequests[nbr_I] = Memory_Alloc( MPI_Request, "outgoingDofValRequest" );
+ }
+ }
+
+ Journal_DPrintfL( self->debug, 2, "Starting non-blocking recv's of incoming values\n" );
+ Stream_Indent( self->debug );
+ for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
+ myShadowNodesOnThisNbrCount = mesh->nodeShadowInfo->procShadowCnt[nbr_I];
+ if ( myShadowNodesOnThisNbrCount > 0 ) {
+ nbrRank = mesh->procNbrInfo->procNbrTbl[nbr_I];
+ Journal_DPrintfL( self->debug, 2, "Start recv from proc %u - %u values\n", nbrRank, incomingDofTotals[nbr_I] );
+ MPI_Irecv( incomingDofValues[nbr_I], incomingDofTotals[nbr_I], MPI_DOUBLE, nbrRank,
+ DOF_VALUES_TAG, self->communicator, incomingDofValRequests[nbr_I] );
+ }
+ }
+ Stream_UnIndent( self->debug );
+
+ Journal_DPrintfL( self->debug, 2, "Non-blocking send out required shadow values to neighbours\n" );
+ Stream_Indent( self->debug );
+ for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
+ if ( mesh->nodeShadowInfo->procShadowedCnt[nbr_I] > 0 ) {
+ nbrRank = mesh->procNbrInfo->procNbrTbl[nbr_I];
+
+ outgoingDof_I = 0;
+ for( node_stI = 0; node_stI < mesh->nodeShadowInfo->procShadowedCnt[nbr_I]; node_stI++ ) {
+ node_lI = mesh->nodeShadowInfo->procShadowedTbl[nbr_I][node_stI];
+ for ( nodalDof_I=0; nodalDof_I < self->dofLayout->dofCounts[node_lI]; nodalDof_I++ ) {
+ outgoingDofValues[nbr_I][outgoingDof_I] =
+ DofLayout_GetValueDouble( self->dofLayout, node_lI, nodalDof_I );
+ outgoingDof_I++;
+ }
+ }
+ Journal_DPrintfL( self->debug, 2, "Start send to proc %u - %u values\n", nbrRank, outgoingDofTotals[nbr_I] );
+ MPI_Isend( outgoingDofValues[nbr_I], outgoingDofTotals[nbr_I], MPI_DOUBLE, nbrRank,
+ DOF_VALUES_TAG, self->communicator, outgoingDofValRequests[nbr_I] );
+ }
+ }
+ Stream_UnIndent( self->debug );
+
+ Journal_DPrintfL( self->debug, 2, "Receiving and updating shadow values I need from neighbours:\n" );
+ Stream_Indent( self->debug );
+ while ( incomingDofValueSetsYetToReceive > 0 ) {
+ int testFlag = 0;
+
+ for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
+
+ if ( ( mesh->nodeShadowInfo->procShadowCnt[nbr_I] > 0 )
+ && ( False == incomingDofValueSetsReceived[nbr_I] ) )
+ {
+ MPI_Test( incomingDofValRequests[nbr_I], &testFlag, &status );
+ if ( False == testFlag ) {
+ continue;
+ }
+ else {
+ Journal_DPrintfL( self->debug, 2, "Recv'd a batch of values from proc %u: updating...\n",
+ nbrRank );
+ /** update the appropriate values from recv'd set */
+ incomingDof_I = 0;
+ for( node_stI = 0; node_stI < mesh->nodeShadowInfo->procShadowCnt[nbr_I]; node_stI++ ) {
+ node_dI = mesh->nodeShadowInfo->procShadowTbl[nbr_I][node_stI];
+ for ( nodalDof_I=0; nodalDof_I < self->dofLayout->dofCounts[node_dI]; nodalDof_I++ ) {
+ DofLayout_SetValueDouble( self->dofLayout, node_dI, nodalDof_I,
+ incomingDofValues[nbr_I][incomingDof_I] );
+ incomingDof_I++;
+ }
+ }
+ incomingDofValueSetsReceived[nbr_I] = True;
+ incomingDofValueSetsYetToReceive--;
+ }
+ }
+ }
+ }
+ Journal_DPrintfL( self->debug, 2, "Done.\n" );
+ Stream_UnIndent( self->debug );
+
+ Journal_DPrintfL( self->debug, 2, "Making sure outgoing sends have completed...\n" );
+ for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
+ if ( mesh->nodeShadowInfo->procShadowCnt[nbr_I] > 0 ) {
+ MPI_Wait( outgoingDofValRequests[nbr_I], &status );
+ }
+ }
+ Journal_DPrintfL( self->debug, 2, "Done.\n" );
+
+ /** clean up temporary memory */
+ for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
+ myShadowNodesOnThisNbrCount = mesh->nodeShadowInfo->procShadowCnt[nbr_I];
+ if ( myShadowNodesOnThisNbrCount > 0 ) {
+ Memory_Free( incomingDofValues[nbr_I] );
+ Memory_Free( incomingDofValRequests[nbr_I] );
+ }
+ }
+ Memory_Free( incomingDofTotals );
+ Memory_Free( incomingDofValues );
+ Memory_Free( incomingDofValRequests );
+ for ( nbr_I=0; nbr_I < mesh->procNbrInfo->procNbrCnt; nbr_I++ ) {
+ nbrShadowNodesOnMeCount = mesh->nodeShadowInfo->procShadowedCnt[nbr_I];
+ if ( nbrShadowNodesOnMeCount > 0 ) {
+ Memory_Free( outgoingDofValues[nbr_I] );
+ Memory_Free( outgoingDofValRequests[nbr_I] );
+ }
+ }
+ Memory_Free( outgoingDofTotals );
+ Memory_Free( outgoingDofValues );
+ Memory_Free( outgoingDofValRequests );
+
+ Stream_UnIndent( self->debug );
+#endif
+}
+
+
+void FeVariable_PrintDomainDiscreteValues( void* variable, Stream* stream ) {
+ FeVariable* self = (FeVariable*)variable;
+
+ Journal_Printf( stream, "In %s: for FeVariable \"%s\":\n", __func__, self->name );
+
+ _FeVariable_PrintLocalOrDomainValues( variable, FeMesh_GetNodeDomainSize( self->feMesh ), stream );
+}
+
+void FeVariable_PrintCoordsAndValues( void* _feVariable, Stream* stream ) {
+ FeVariable* self = (FeVariable*) _feVariable;
+ Node_LocalIndex node_I = 0;
+ Node_LocalIndex nodeLocalCount = FeMesh_GetNodeLocalSize( self->feMesh );
+ Dof_Index currNodeNumDofs;
+ Dof_Index nodeLocalDof_I;
+ Variable* currVariable;
+ double* nodeCoord;
+
+ /** Print Header of stream */
+ Journal_Printf( stream, "# FeVariable - %s\n", self->name );
+ Journal_Printf( stream, "# x coord | y coord | z coord" );
+ currNodeNumDofs = self->dofLayout->dofCounts[ 0 ];
+ for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
+ currVariable = DofLayout_GetVariable( self->dofLayout, node_I, nodeLocalDof_I );
+ Journal_Printf( stream, " | %s", currVariable->name );
+ }
+ Journal_Printf(stream, "\n");
+
+ /** Loop over local nodes */
+ for( node_I=0; node_I < nodeLocalCount ; node_I++ ) {
+ currNodeNumDofs = self->dofLayout->dofCounts[ node_I ];
+
+ /** Get Coordinate of Node */
+ nodeCoord = Mesh_GetVertex( self->feMesh, node_I );
+ Journal_Printf( stream, "%12.6g %12.6g %12.6g ",
+ nodeCoord[ I_AXIS ], nodeCoord[ J_AXIS ], nodeCoord[ K_AXIS ] );
+
+ /** Print each dof */
+ for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
+ currVariable = DofLayout_GetVariable( self->dofLayout, node_I, nodeLocalDof_I );
+ Journal_Printf( stream, "%12.6g ", Variable_GetValueDouble( currVariable, node_I ) );
+ }
+ Journal_Printf( stream, "\n" );
+ }
+}
+
+
+/** --- Private Functions --- */
+
+void _FeVariable_InterpolateNodeValuesToElLocalCoord( void* feVariable, Element_DomainIndex element_lI, Coord elLocalCoord, double* value ) {
+ FeVariable* self = (FeVariable*) feVariable;
+ ElementType* elementType=NULL;
+ Dof_Index nodeLocalDof_I=0;
+ Dof_Index dofCountThisNode=0;
+ Node_ElementLocalIndex elLocalNode_I=0;
+ double* shapeFuncsEvaluatedAtCoord=NULL;
+ Node_LocalIndex lNode_I=0;
+ Variable* currVariable=NULL;
+ double dofValueAtCurrNode=0;
+ unsigned nInc, *inc;
+
+ FeMesh_GetElementNodes( self->feMesh, element_lI, self->inc );
+ nInc = IArray_GetSize( self->inc );
+ inc = (unsigned*)IArray_GetPtr( self->inc );
+
+ /** Gets number of degrees of freedom - assuming it is the same throughout the mesh */
+ dofCountThisNode = self->dofLayout->dofCounts[lNode_I];
+
+ /** evaluate shape function values of current element at elLocalCoords */
+ elementType = FeMesh_GetElementType( self->feMesh, element_lI );
+ shapeFuncsEvaluatedAtCoord = AllocArray( double, nInc );
+ ElementType_EvaluateShapeFunctionsAt( elementType, elLocalCoord, shapeFuncsEvaluatedAtCoord );
+
+ for ( nodeLocalDof_I=0; nodeLocalDof_I < dofCountThisNode; nodeLocalDof_I++ ) {
+ value[nodeLocalDof_I] = 0;
+ }
+
+ /** Now for each node, add that node's contribution at point */
+ for ( elLocalNode_I=0; elLocalNode_I < nInc; elLocalNode_I++ ) {
+ lNode_I = inc[elLocalNode_I];
+
+ for ( nodeLocalDof_I=0; nodeLocalDof_I < dofCountThisNode; nodeLocalDof_I++ ) {
+ currVariable = DofLayout_GetVariable( self->dofLayout, lNode_I, nodeLocalDof_I );
+ dofValueAtCurrNode = Variable_GetValueDouble( currVariable, lNode_I );
+ value[nodeLocalDof_I] += dofValueAtCurrNode * shapeFuncsEvaluatedAtCoord[elLocalNode_I];
+ }
+ }
+ FreeArray( shapeFuncsEvaluatedAtCoord );
+}
+
+void _FeVariable_PrintLocalOrDomainValues( void* variable, Index localOrDomainCount, Stream* stream ) {
+ FeVariable* self = (FeVariable*)variable;
+ Node_Index node_I = 0;
+ Node_GlobalIndex gNode_I = 0;
+ Dof_Index currNodeNumDofs;
+ Dof_Index nodeLocalDof_I;
+ Dof_EquationNumber currEqNum;
+ Variable* currVariable;
+
+ for( node_I=0; node_I < localOrDomainCount; node_I++ ) {
+ gNode_I = FeMesh_NodeDomainToGlobal( self->feMesh, node_I );
+ Journal_Printf( stream, "node %d (global index %d):\n", node_I, gNode_I );
+
+ currNodeNumDofs = self->fieldComponentCount;
+
+
+ /** Print each dof */
+ for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
+ currVariable = DofLayout_GetVariable( self->dofLayout, node_I, nodeLocalDof_I );
+ Journal_Printf( stream, "\tdof %d \"%s\": %6g - ", nodeLocalDof_I, currVariable->name,
+ Variable_GetValueDouble( currVariable, node_I ) );
+ currEqNum = self->eqNum->destinationArray[node_I][nodeLocalDof_I];
+ if ( currEqNum == -1 ) {
+ Journal_Printf( stream, "(from BC)", currEqNum );
+ }
+ else {
+ Journal_Printf( stream, "(eq num %d)", currEqNum );
+ }
+ Journal_Printf( stream, "\n", currEqNum );
+ }
+ }
+}
+
+InterpolationResult FeVariable_InterpolateFromMeshLocalCoord( void* feVariable, FeMesh* mesh, Element_DomainIndex dElement_I, double* localCoord, double* value ) {
+ FeVariable* self = (FeVariable*) feVariable;
+
+ if ( mesh == self->feMesh ) {
+ /** If the meshes are identical - then we can just interpolate within the elements because the elements are the same */
+ FeVariable_InterpolateWithinElement( self, dElement_I, localCoord, value );
+ return LOCAL;
+ }
+ else {
+ Coord globalCoord;
+
+ /** If the meshes are different - then we must find the global coordinates and interpolate to that */
+ FeMesh_CoordLocalToGlobal( mesh, dElement_I, localCoord, globalCoord );
+ return FieldVariable_InterpolateValueAt( feVariable, globalCoord, value );
+ }
+
+}
+
+/** TODO: can't assume all swarms have particles of type integrationPoint anymore.
+ should check that the given swarm does have I.P for the rest of these functions.*/
+double FeVariable_IntegrateElement_AxisIndependent(
+ void* feVariable, void* _swarm,
+ Element_DomainIndex dElement_I, Dimension_Index dim,
+ Axis axis0, Axis axis1, Axis axis2 )
+{
+ FeVariable* self = (FeVariable*) feVariable;
+ Swarm* swarm = (Swarm*) _swarm;
+ FeMesh* feMesh = self->feMesh;
+ FeMesh* mesh;
+ ElementType* elementType;
+ Cell_LocalIndex cell_I;
+ Particle_InCellIndex cParticle_I;
+ Particle_InCellIndex cellParticleCount;
+ IntegrationPoint* particle;
+ double detJac;
+ double integral;
+ double value;
+
+ /** Initialise Summation of Integral */
+ integral = 0.0;
+
+ /** Use feVariable's mesh as geometry mesh if one isn't passed in */
+ if( Stg_Class_IsInstance( feMesh->algorithms, Mesh_CentroidAlgorithms_Type ) )
+ mesh = (FeMesh*)((Mesh_CentroidAlgorithms*)feMesh->algorithms)->elMesh;
+ else
+ mesh = feMesh;
+ elementType = FeMesh_GetElementType( mesh, dElement_I );
+
+ /** Determine number of particles in element */
+ cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, dElement_I );
+ cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
+
+ /** Loop over all particles in element */
+ for( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
+ /** Get Pointer to particle */
+ particle = (IntegrationPoint*) Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
+
+ /** Interpolate Value of Field at Particle */
+ FeVariable_InterpolateWithinElement( feVariable, dElement_I, particle->xi, &value );
+
+ Journal_DPrintfL( self->debug, 3, "%s: Integrating element %d - particle %d - Value = %g\n", self->name, dElement_I, cParticle_I, value );
+
+ /** Calculate Determinant of Jacobian */
+ detJac = ElementType_JacobianDeterminant_AxisIndependent(
+ elementType, mesh, dElement_I, particle->xi, dim, axis0, axis1, axis2 );
+
+ /** Sum Integral */
+ integral += detJac * particle->weight * value;
+ }
+
+ return integral;
+}
+
+double FeVariable_Integrate( void* feVariable, void* _swarm ) {
+ FeVariable* self = (FeVariable*) feVariable;
+ Swarm* swarm = (Swarm*) _swarm;
+ FeMesh* feMesh = self->feMesh;
+ Element_LocalIndex lElement_I;
+ Element_LocalIndex elementLocalCount = FeMesh_GetElementLocalSize( feMesh );
+ double integral, integralGlobal;
+
+ /** Initialise Summation of Integral */
+ integral = 0.0;
+
+ /** Loop over all local elements */
+ for ( lElement_I = 0 ; lElement_I < elementLocalCount ; lElement_I++ ) {
+ integral += FeVariable_IntegrateElement( self, swarm, lElement_I );
+ Journal_DPrintfL( self->debug, 3, "%s: Integrating element %d - Accumulated Integral = %g\n", self->name, lElement_I, integral );
+ }
+
+ /** Gather and sum integrals from other processors */
+ MPI_Allreduce( &integral, &integralGlobal, 1, MPI_DOUBLE, MPI_SUM, self->communicator );
+
+ return integralGlobal;
+}
+
+double FeVariable_AverageTopLayer( void* feVariable, void* swarm, Axis layerAxis ) {
+ FeVariable* self = (FeVariable*) feVariable;
+ Grid* elGrid;
+
+ elGrid = *(Grid**)ExtensionManager_Get( self->feMesh->info, self->feMesh,
+ ExtensionManager_GetHandle( self->feMesh->info, (Name)"elementGrid" ) );
+
+ return FeVariable_AverageLayer( self, swarm, layerAxis, elGrid->sizes[1] - 1 );
+}
+
+double FeVariable_AverageBottomLayer( void* feVariable, void* swarm, Axis layerAxis ) {
+ FeVariable* self = (FeVariable*) feVariable;
+
+ return FeVariable_AverageLayer( self, swarm, layerAxis, 0 );
+}
+
+double FeVariable_AverageLayer( void* feVariable, void* swarm, Axis layerAxis, Index layerIndex ) {
+ FeVariable* self = (FeVariable*) feVariable;
+ Axis aAxis = ( layerAxis == I_AXIS ? J_AXIS : I_AXIS );
+ Axis bAxis = ( layerAxis == K_AXIS ? J_AXIS : K_AXIS );
+ Dimension_Index dim = self->dim;
+ double integral;
+ double layerThickness = 0.0;
+ double sendThickness;
+ Grid* vertGrid;
+ unsigned* inds;
+ double heights[2];
+ unsigned localInd[2], globalInd[2];
+ double *min, *max;
+ int d_i;
+
+ integral = FeVariable_IntegrateLayer( self, swarm, layerAxis, layerIndex );
+
+ /** Calculate layer thickness. This assumes the mesh is regular. */
+ vertGrid = *(Grid**)ExtensionManager_Get( self->feMesh->info, self->feMesh,
+ ExtensionManager_GetHandle( self->feMesh->info, (Name)"vertexGrid" ) );
+ inds = Memory_Alloc_Array_Unnamed( unsigned, Mesh_GetDimSize( self->feMesh ) );
+ for( d_i = 0; d_i < Mesh_GetDimSize( self->feMesh ); d_i++ ) {
+ if( d_i != layerAxis )
+ inds[d_i] = 0;
+ else
+ inds[d_i] = layerIndex;
+ }
+ globalInd[0] = Grid_Project( vertGrid, inds );
+ inds[layerAxis]++;
+ globalInd[1] = Grid_Project( vertGrid, inds );
+ if( Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, globalInd[0], &localInd[0] ) &&
+ Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, globalInd[1], &localInd[1] ) )
+ {
+ heights[0] = Mesh_GetVertex( self->feMesh, localInd[0] )[layerAxis];
+ heights[1] = Mesh_GetVertex( self->feMesh, localInd[1] )[layerAxis];
+ sendThickness = heights[1] - heights[0];
+ }
+ else {
+ sendThickness = 0.0;
+ }
+ MPI_Allreduce( &sendThickness, &layerThickness, 1, MPI_DOUBLE, MPI_MAX, self->communicator );
+ FreeArray( inds );
+
+ min = Memory_Alloc_Array_Unnamed( double, Mesh_GetDimSize( self->feMesh ) );
+ max = Memory_Alloc_Array_Unnamed( double, Mesh_GetDimSize( self->feMesh ) );
+ Mesh_GetGlobalCoordRange( self->feMesh, min, max );
+ integral /= layerThickness * (max[aAxis] - min[aAxis]);
+ if ( dim == 3 )
+ integral /= max[ bAxis ] - min[ bAxis ];
+ FreeArray( min );
+ FreeArray( max );
+
+ return integral;
+}
+
+
+double FeVariable_IntegrateLayer_AxisIndependent(
+ void* feVariable, void* _swarm,
+ Axis layerAxis, Index layerIndex, Dimension_Index dim,
+ Axis axis0, Axis axis1, Axis axis2 )
+{
+ FeVariable* self = (FeVariable*) feVariable;
+ Swarm* swarm = (Swarm*) _swarm;
+ Element_LocalIndex lElement_I;
+ Element_GlobalIndex gElement_I;
+ IJK elementIJK;
+ double elementIntegral;
+ double integral;
+ double integralGlobal;
+
+ Journal_DPrintf( self->debug, "In %s() for FeVariable \"%s\":\n", __func__, self->name );
+
+ /** Initialise Sumation of Integral */
+ integral = 0.0;
+
+ Stream_Indent( self->debug );
+ for ( gElement_I = 0 ; gElement_I < FeMesh_GetElementGlobalSize( self->feMesh ); gElement_I++ ) {
+ RegularMeshUtils_Element_1DTo3D( self->feMesh, gElement_I, elementIJK );
+
+ /** Check if element is in layer plane */
+ if ( elementIJK[ layerAxis ] != layerIndex )
+ continue;
+
+ /** Check if element is local */
+ if( !FeMesh_ElementGlobalToDomain( self->feMesh, gElement_I, &lElement_I ) ||
+ lElement_I >= FeMesh_GetElementLocalSize( self->feMesh ) )
+ {
+ continue;
+ }
+
+ elementIntegral = FeVariable_IntegrateElement_AxisIndependent( self, swarm, lElement_I, dim, axis0, axis1, axis2 );
+ Journal_DPrintfL( self->debug, 2, "Integral of element %d was %f\n", lElement_I, elementIntegral );
+ integral += elementIntegral;
+ }
+ Stream_UnIndent( self->debug );
+
+
+ /** Gather and sum integrals from other processors */
+ MPI_Allreduce( &integral, &integralGlobal, 1, MPI_DOUBLE, MPI_SUM, self->communicator );
+
+ Journal_DPrintf( self->debug, "Calculated global integral of layer %d in Axis %d was %f\n", layerIndex, layerAxis, integralGlobal );
+ return integralGlobal;
+}
+
+
+double FeVariable_AveragePlane( void* feVariable, Axis planeAxis, double planeHeight ) {
+ FeVariable* self = (FeVariable*) feVariable;
+ double integral;
+ Axis aAxis = ( planeAxis == I_AXIS ? J_AXIS : I_AXIS );
+ Axis bAxis = ( planeAxis == K_AXIS ? J_AXIS : K_AXIS );
+ Dimension_Index dim = self->dim;
+ double min[3], max[3];
+
+ integral = FeVariable_IntegratePlane( self, planeAxis, planeHeight );
+
+ Mesh_GetGlobalCoordRange( self->feMesh, min, max );
+
+ integral /= max[ aAxis ] - min[ aAxis ];
+ if ( dim == 3 )
+ integral /= max[ bAxis ] - min[ bAxis ];
+
+ return integral;
+}
+
+double FeVariable_IntegratePlane( void* feVariable, Axis planeAxis, double planeHeight ) {
+ FeVariable* self = (FeVariable*) feVariable;
+ IJK planeIJK;
+ Element_LocalIndex lElement_I;
+ Element_GlobalIndex gElement_I;
+ Element_LocalIndex elementLocalCount = FeMesh_GetElementLocalSize( self->feMesh );
+ Axis aAxis = ( planeAxis == I_AXIS ? J_AXIS : I_AXIS );
+ Axis bAxis = ( planeAxis == K_AXIS ? J_AXIS : K_AXIS );
+ double integral;
+ /** Swarm Stuff */
+ Swarm* tmpSwarm;
+ Bool dimExists[] = { False, False, False };
+ ExtensionManager_Register* extensionMgr_Register;
+ SingleCellLayout* singleCellLayout;
+ GaussParticleLayout* gaussParticleLayout;
+ Particle_Index lParticle_I;
+ IntegrationPoint* particle;
+ /** Plane location stuff */
+ double storedXi_J_AXIS;
+ Coord planeCoord;
+ double planeXi = -1;
+ double planeXiGlobal;
+ Index planeLayer = 0;
+ Index planeLayerGlobal;
+ Particle_InCellIndex particlesPerDim[] = {2,2,2};
+
+ /** Find Elements which plane cuts through */
+ memcpy( planeCoord, Mesh_GetVertex( self->feMesh, 0 ), sizeof( Coord ) );
+ planeCoord[ planeAxis ] = planeHeight;
+
+ if( Mesh_Algorithms_SearchElements( self->feMesh->algorithms, planeCoord, &lElement_I ) &&
+ lElement_I < elementLocalCount )
+ {
+ Coord planeXiCoord;
+
+ gElement_I = FeMesh_ElementDomainToGlobal( self->feMesh, lElement_I );
+ RegularMeshUtils_Element_1DTo3D( self->feMesh, gElement_I, planeIJK );
+ planeLayer = planeIJK[ planeAxis ];
+
+ /** Find Local Coordinate of plane */
+ FeMesh_CoordGlobalToLocal( self->feMesh, lElement_I, planeCoord, planeXiCoord );
+ planeXi = planeXiCoord[ planeAxis ];
+ }
+
+ /** Should be broadcast */
+ MPI_Allreduce( &planeXi, &planeXiGlobal, 1, MPI_DOUBLE, MPI_MAX, self->communicator );
+ MPI_Allreduce( &planeLayer, &planeLayerGlobal, 1, MPI_UNSIGNED, MPI_MAX, self->communicator );
+
+ /** Create Swarm in plane */
+ extensionMgr_Register = ExtensionManager_Register_New();
+ dimExists[ aAxis ] = True;
+ if (self->dim == 3)
+ dimExists[ bAxis ] = True;
+
+ singleCellLayout = SingleCellLayout_New( "cellLayout", (AbstractContext*)self->context, dimExists, NULL, NULL );
+ particlesPerDim[ planeAxis ] = 1;
+ gaussParticleLayout = GaussParticleLayout_New( "particleLayout", NULL, LocalCoordSystem, True, self->dim - 1, particlesPerDim );
+ tmpSwarm = Swarm_New(
+ "tmpgaussSwarm", NULL,
+ singleCellLayout,
+ gaussParticleLayout,
+ self->dim,
+ sizeof(IntegrationPoint),
+ extensionMgr_Register,
+ NULL,
+ self->communicator,
+ NULL );
+ Stg_Component_Build( tmpSwarm, NULL, False );
+
+ /** Change Positions of the particles */
+ Stg_Component_Initialise( tmpSwarm, NULL, False );
+ for ( lParticle_I = 0 ; lParticle_I < tmpSwarm->particleLocalCount ; lParticle_I++ ) {
+ particle = (IntegrationPoint*) Swarm_ParticleAt( tmpSwarm, lParticle_I );
+
+ storedXi_J_AXIS = particle->xi[ J_AXIS ];
+ particle->xi[ aAxis ] = particle->xi[ I_AXIS ];
+ particle->xi[ bAxis ] = storedXi_J_AXIS;
+ particle->xi[ planeAxis ] = planeXiGlobal;
+ }
+
+ integral = FeVariable_IntegrateLayer_AxisIndependent( self, tmpSwarm, planeAxis, planeLayerGlobal,
+ self->dim - 1, aAxis, bAxis, planeAxis );
+
+ /** Delete */
+ Stg_Class_Delete( tmpSwarm );
+ Stg_Class_Delete( gaussParticleLayout );
+ Stg_Class_Delete( singleCellLayout );
+ Stg_Class_Delete( extensionMgr_Register );
+
+ return integral;
+}
+
+
+void FeVariable_ImportExportInfo_Delete( void* ptr ) {
+ /** Nothing to do - the ObjectAdaptor will take care of deleting the actual struct itself */
+}
+
+void FeVariable_SaveToFile( void* feVariable, Name filename, Bool saveCoords ) {
+ FeVariable* self = (FeVariable*)feVariable;
+ Node_LocalIndex lNode_I;
+ Node_GlobalIndex gNode_I;
+ double* coord;
+ Dof_Index dof_I;
+ Dof_Index dofAtEachNodeCount;
+ double variableValues[MAX_FIELD_COMPONENTS];
+ MPI_Comm comm = Comm_GetMPIComm( Mesh_GetCommTopology( self->feMesh, MT_VERTEX ) );
+ int myRank;
+ int nProcs;
+ MPI_Status status;
+ Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
+ const int FINISHED_WRITING_TAG = 100;
+ int confirmation = 0;
+ MeshGenerator* theGenerator;
+
+#ifdef WRITE_HDF5
+ hid_t file, fileSpace, fileData;
+ hid_t memSpace;
+ hsize_t start[2], count[2], size[2];
+ double* buf;
+#else
+ FILE* outputFile;
+#endif
+
+ lNode_I = 0; gNode_I = 0;
+
+ MPI_Comm_size( comm, (int*)&nProcs );
+ MPI_Comm_rank( comm, (int*)&myRank );
+
+ /** Note: assumes same number of dofs at each node */
+ dofAtEachNodeCount = self->fieldComponentCount;
+
+#ifdef WRITE_HDF5
+ /** wait for go-ahead from process ranked lower than me, to avoid competition writing to file */
+ if ( myRank != 0 ) {
+ MPI_Recv( &confirmation, 1, MPI_INT, myRank - 1, FINISHED_WRITING_TAG, comm, &status );
+ }
+
+ /** Open the file */
+ if ( myRank == 0 ) {
+ hid_t attribData_id, attrib_id, group_id;
+ hsize_t a_dims;
+ int attribData;
+ Grid** grid;
+ unsigned* sizes;
+
+ /** Open the HDF5 output file. */
+ file = H5Fcreate( filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT );
+ Journal_Firewall( file >= 0, errorStr,
+ "Error in %s for %s '%s' - Cannot create file %s.\n",
+ __func__, self->type, self->name, filename );
+
+ /** create file attribute */
+ /** first store the fevariable checkpointing version */
+ a_dims = 1;
+ attribData = FeCHECKPOINT_V2;
+ attribData_id = H5Screate_simple(1, &a_dims, NULL);
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ group_id = H5Gopen(file, "/");
+ attrib_id = H5Acreate(group_id, "checkpoint file version", H5T_STD_I32BE, attribData_id, H5P_DEFAULT);
+ #else
+ group_id = H5Gopen2(file, "/", H5P_DEFAULT);
+ attrib_id = H5Acreate2(group_id, "checkpoint file version", H5T_STD_I32BE, attribData_id, H5P_DEFAULT, H5P_DEFAULT);
+ #endif
+ H5Awrite(attrib_id, H5T_NATIVE_INT, &attribData);
+ H5Aclose(attrib_id);
+ H5Gclose(group_id);
+ H5Sclose(attribData_id);
+
+ /** store the fevariable dimensionality */
+ a_dims = 1;
+ attribData = self->dim;
+ attribData_id = H5Screate_simple(1, &a_dims, NULL);
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ group_id = H5Gopen(file, "/");
+ attrib_id = H5Acreate(group_id, "dimensions", H5T_STD_I32BE, attribData_id, H5P_DEFAULT);
+ #else
+ group_id = H5Gopen2(file, "/", H5P_DEFAULT);
+ attrib_id = H5Acreate2(group_id, "dimensions", H5T_STD_I32BE, attribData_id, H5P_DEFAULT, H5P_DEFAULT);
+ #endif
+ H5Awrite(attrib_id, H5T_NATIVE_INT, &attribData);
+ H5Aclose(attrib_id);
+ H5Gclose(group_id);
+ H5Sclose(attribData_id);
+
+ /** get the generator */
+ if( Stg_Class_IsInstance( self->feMesh->generator, MeshAdaptor_Type ))
+ theGenerator = ((MeshAdaptor*)self->feMesh->generator)->generator;
+ else
+ theGenerator = self->feMesh->generator;
+
+ /** store the mesh resolution if mesh is cartesian */
+ if ( Stg_Class_IsInstance( theGenerator, CartesianGenerator_Type ) ) {
+ a_dims = self->dim;
+ grid = (Grid**) Mesh_GetExtension( self->feMesh, Grid*, "elementGrid" );
+ sizes = Grid_GetSizes( *grid ); /** global no. of elements in each dim */
+
+ attribData_id = H5Screate_simple(1, &a_dims, NULL);
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ group_id = H5Gopen(file, "/");
+ attrib_id = H5Acreate(group_id, "mesh resolution", H5T_STD_I32BE, attribData_id, H5P_DEFAULT);
+ #else
+ group_id = H5Gopen2(file, "/", H5P_DEFAULT);
+ attrib_id = H5Acreate2(group_id, "mesh resolution", H5T_STD_I32BE, attribData_id, H5P_DEFAULT, H5P_DEFAULT);
+ #endif
+ H5Awrite(attrib_id, H5T_NATIVE_INT, sizes);
+ H5Aclose(attrib_id);
+ H5Gclose(group_id);
+ H5Sclose(attribData_id);
+ }
+ size[0] = Mesh_GetGlobalSize( self->feMesh, (MeshTopology_Dim)0 );;
+ size[1] = dofAtEachNodeCount;
+ if( saveCoords )
+ size[1] += self->dim;
+
+ /** Create filespace */
+ fileSpace = H5Screate_simple( 2, size, NULL );
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ fileData = H5Dcreate( file, "/data", H5T_NATIVE_DOUBLE, fileSpace, H5P_DEFAULT );
+ #else
+ fileData = H5Dcreate2( file, "/data", H5T_NATIVE_DOUBLE, fileSpace,
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
+ #endif
+ } else {
+ /** Open the HDF5 output file. */
+ file = H5Fopen( filename, H5F_ACC_RDWR, H5P_DEFAULT );
+ Journal_Firewall( file >= 0, errorStr,
+ "Error in %s for %s '%s' - Cannot open file %s.\n",
+ __func__, self->type, self->name, filename );
+
+ /** get the filespace */
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ fileData = H5Dopen( file, "/data" );
+ #else
+ fileData = H5Dopen2( file, "/data", H5P_DEFAULT );
+ #endif
+ /** get the filespace handle */
+ fileSpace = H5Dget_space(fileData);
+ }
+
+ /** get the section of fileSpace to write to... set start point to be the
+ global index of first local node */
+ count[0] = 1;
+ count[1] = dofAtEachNodeCount;
+ if( saveCoords )
+ count[1] += self->dim;
+
+ /** create memSpace */
+ memSpace = H5Screate_simple( 2, count, NULL );
+ H5Sselect_all( memSpace );
+
+ buf = Memory_Alloc_Array( double, count[1], "fileBuffer" );
+
+ for ( lNode_I = 0; lNode_I < FeMesh_GetNodeLocalSize( self->feMesh ); lNode_I++ ) {
+
+ /** If required, add coords to array */
+ if( saveCoords ) {
+ coord = Mesh_GetVertex( self->feMesh, lNode_I );
+ buf[0] = coord[0];
+ buf[1] = coord[1];
+ if( self->dim == 3 )
+ buf[2] = coord[2];
+ }
+
+ /** Add field value at current node to array */
+ FeVariable_GetValueAtNode( self, lNode_I, variableValues );
+ for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
+ if( saveCoords )
+ buf[dof_I + self->dim] = variableValues[dof_I];
+ else
+ buf[dof_I] = variableValues[dof_I];
+ }
+
+ /** select the region of dataspace to write to */
+ start[0] = FeMesh_NodeDomainToGlobal( self->feMesh, lNode_I );
+ start[1] = 0;
+ H5Sselect_hyperslab( fileSpace, H5S_SELECT_SET, start, NULL, count, NULL );
+ /** Write the array to file */
+ H5Dwrite( fileData, H5T_NATIVE_DOUBLE, memSpace, fileSpace, H5P_DEFAULT, buf );
+ }
+ /** free memory! */
+ Memory_Free( buf );
+
+ /** Close all handles */
+ H5Dclose( fileData );
+ H5Sclose( memSpace );
+ H5Sclose( fileSpace );
+ H5Fclose( file );
+
+ /** send go-ahead to process ranked above me, to avoid competition writing to file */
+ if ( myRank != nProcs - 1 ) {
+ MPI_Ssend( &confirmation, 1, MPI_INT, myRank + 1, FINISHED_WRITING_TAG, comm );
+ }
+
+#else
+ /** wait for go-ahead from process ranked lower than me, to avoid competition writing to file */
+ if ( myRank != 0 ) {
+ MPI_Recv( &confirmation, 1, MPI_INT, myRank - 1, FINISHED_WRITING_TAG, comm, &status );
+ }
+
+ /** Open the file */
+ if ( myRank == 0 ) {
+ outputFile = fopen( filename, "w" );
+ }
+ else {
+ outputFile = fopen( filename, "a" );
+ }
+
+ Journal_Firewall( outputFile != NULL, errorStr,
+ "Error in %s for %s '%s' - Cannot create file %s.\n",
+ __func__, self->type, self->name, filename );
+
+ for ( lNode_I = 0; lNode_I < FeMesh_GetNodeLocalSize( self->feMesh ); lNode_I++ ) {
+ gNode_I = FeMesh_NodeDomainToGlobal( self->feMesh, lNode_I );
+ fprintf( outputFile, "%u ", gNode_I );
+
+ /** If required, write the node coords to file */
+ if( saveCoords ) {
+ coord = Mesh_GetVertex( self->feMesh, lNode_I );
+ if(self->dim == 2)
+ fprintf( outputFile, "%.15g %.15g 0 ", coord[0], coord[1]);
+ else
+ fprintf( outputFile, "%.15g %.15g %.15g ", coord[0], coord[1], coord[2] );
+ }
+
+ /** Add field value at current node to the file */
+ FeVariable_GetValueAtNode( self, lNode_I, variableValues );
+ for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
+ fprintf( outputFile, "%.15g ", variableValues[dof_I] );
+ }
+ fprintf( outputFile, "\n" );
+ }
+
+ /** Close the file */
+ fclose( outputFile );
+
+ /** send go-ahead to process ranked above me, to avoid competition writing to file */
+ if ( myRank != nProcs - 1 ) {
+ MPI_Ssend( &confirmation, 1, MPI_INT, myRank + 1, FINISHED_WRITING_TAG, comm );
+ }
+
+#endif
+}
+
+
+#define MAX_LINE_LENGTH_DEFINE 1024
+
+void FeVariable_ReadFromFile( void* feVariable, Name filename ) {
+ FeVariable* self = (FeVariable*)feVariable;
+ Node_LocalIndex lNode_I = 0;
+ Node_GlobalIndex gNode_I = 0;
+ Dof_Index dof_I;
+ Dof_Index dofAtEachNodeCount;
+#ifndef READ_HDF5
+ FILE* inputFile;
+#endif
+ double variableVal;
+ Processor_Index proc_I;
+ MPI_Comm comm = Comm_GetMPIComm( Mesh_GetCommTopology( self->feMesh, MT_VERTEX ) );
+ unsigned rank;
+ unsigned nRanks;
+ int nDims;
+ Bool savedCoords = False;
+ Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
+ MeshGenerator* theGenerator;
+
+#ifdef READ_HDF5
+ hid_t file, fileSpace, fileData, error;
+ unsigned totalNodes, ii, noffset;
+ hid_t memSpace;
+ hsize_t start[2], count[2], size[2], maxSize[2];
+ double* buf;
+ FeCheckpointFileVersion ver;
+ hid_t attrib_id, group_id;
+ herr_t status;
+#else
+ unsigned uTemp;
+ double temp[3];
+ int count = 0;
+ char lineString[MAX_LINE_LENGTH_DEFINE];
+ const unsigned int MAX_LINE_LENGTH = MAX_LINE_LENGTH_DEFINE;
+ int offset, n;
+#endif
+
+ MPI_Comm_rank( comm, (int*)&rank );
+ MPI_Comm_size( comm, (int*)&nRanks );
+
+ dofAtEachNodeCount = self->fieldComponentCount;
+ proc_I = 0;
+ nDims = 0;
+
+#ifdef READ_HDF5
+
+ /** Open the file and data set. */
+ file = H5Fopen( filename, H5F_ACC_RDONLY, H5P_DEFAULT );
+
+ Journal_Firewall( file >= 0, errorStr,
+ "Error in %s for %s '%s' - Cannot open file %s.\n",
+ __func__, self->type, self->name, filename );
+
+ /** get the file attributes to sanity and version checks */
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ group_id = H5Gopen(file, "/");
+ attrib_id = H5Aopen_name(group_id, "checkpoint file version");
+ #else
+ group_id = H5Gopen2(file, "/", H5P_DEFAULT);
+ attrib_id = H5Aopen(group_id, "checkpoint file version", H5P_DEFAULT);
+ #endif
+ /** if this attribute does not exist (attrib_id < 0) then we assume FeCHECKPOINT_V1 and continue without checking attributes */
+ if(attrib_id < 0)
+ ver = FeCHECKPOINT_V1;
+ else {
+ int checkVer;
+ int ndims;
+ int res[self->dim];
+ Grid** grid;
+ unsigned* sizes;
+
+ /** check for known checkpointing version type */
+
+ status = H5Aread(attrib_id, H5T_NATIVE_INT, &checkVer);
+ H5Aclose(attrib_id);
+ if(checkVer == 2)
+ ver = FeCHECKPOINT_V2;
+ else
+ Journal_Firewall( (0), errorStr,
+ "\n\nError in %s for %s '%s'\n"
+ "Unknown checkpoint version (%u) for checkpoint file (%s).\n",
+ __func__, self->type, self->name, (unsigned int) checkVer, filename);
+
+ /** check for correct number of dimensions */
+
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ attrib_id = H5Aopen_name(group_id, "dimensions");
+ #else
+ attrib_id = H5Aopen(group_id, "dimensions", H5P_DEFAULT);
+ #endif
+ status = H5Aread(attrib_id, H5T_NATIVE_INT, &ndims);
+ H5Aclose(attrib_id);
+ Journal_Firewall( (ndims == self->dim), errorStr,
+ "\n\nError in %s for %s '%s'\n"
+ "Number of dimensions (%u) for checkpoint file (%s) does not correspond to simulation dimensions (%u).\n",
+ __func__, self->type, self->name, (unsigned int) ndims, filename,
+ self->dim);
+
+ /** get the generator */
+ if( Stg_Class_IsInstance( self->feMesh->generator, MeshAdaptor_Type ))
+ theGenerator = ((MeshAdaptor*)self->feMesh->generator)->generator;
+ else
+ theGenerator = self->feMesh->generator;
+
+ /** check for correct mesh size if expecting a cartesian mesh*/
+ if ( Stg_Class_IsInstance( theGenerator, CartesianGenerator_Type ) ) {
+
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ attrib_id = H5Aopen_name(group_id, "mesh resolution");
+ #else
+ attrib_id = H5Aopen(group_id, "mesh resolution", H5P_DEFAULT);
+ #endif
+ status = H5Aread(attrib_id, H5T_NATIVE_INT, &res);
+ H5Aclose(attrib_id);
+
+ grid = (Grid**) Mesh_GetExtension( self->feMesh, Grid*, "elementGrid" );
+ sizes = Grid_GetSizes( *grid ); /** global no. of elements in each dim */
+ if(self->dim == 2)
+ Journal_Firewall(
+ ( (sizes[0] == res[0]) && (sizes[1] == res[1]) ),
+ errorStr,
+ "\n\nError in %s for %s '%s'\n"
+ "Size of mesh (%u,%u) for checkpoint file (%s) does not correspond to simulation mesh size (%u,%u).\n\n"
+ "If you would like to interpolate checkpoint data to simulation mesh size\n"
+ " please re-launch using '--interpolateRestart=1' flag\n\n",
+ __func__, self->type, self->name,
+ (unsigned int) res[0], (unsigned int) res[1],
+ filename,
+ (unsigned int) sizes[0], (unsigned int) sizes[1]);
+ else
+ Journal_Firewall(
+ ( (sizes[0] == res[0]) && (sizes[1] == res[1]) && (sizes[2] == res[2]) ),
+ errorStr,
+ "\n\nError in %s for %s '%s'\n"
+ "Size of mesh (%u,%u,%u) for checkpoint file (%s) does not correspond to simulation mesh size (%u,%u,%u).\n\n"
+ "If you would like to interpolate checkpoint data to simulation mesh size\n"
+ " please re-launch using '--interpolateRestart=1' flag\n\n",
+ __func__, self->type, self->name,
+ (unsigned int) res[0], (unsigned int) res[1], (unsigned int) res[2],
+ filename,
+ (unsigned int) sizes[0], (unsigned int) sizes[1], (unsigned int) sizes[2]);
+ }
+ }
+ H5Gclose(group_id);
+
+ /** account for different versions of checkpointing */
+ switch ( ver ) {
+ case FeCHECKPOINT_V1:
+ noffset = 1;
+ break;
+ case FeCHECKPOINT_V2:
+ noffset = 0;
+ break;
+ default:
+ Journal_Firewall( 0, errorStr,
+ "Error: in %s: unknown checkpoint file version.\n",
+ __func__ );
+ }
+
+ /** Prepare to read vertices from file */
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ fileData = H5Dopen( file, "/data" );
+ #else
+ fileData = H5Dopen2( file, "/data", H5P_DEFAULT );
+ #endif
+ fileSpace = H5Dget_space( fileData );
+
+ /** Get size of dataspace to determine if coords are in file */
+ H5Sget_simple_extent_dims( fileSpace, size, maxSize );
+
+ if( maxSize[1] > dofAtEachNodeCount + noffset )
+ savedCoords = True;
+
+ start[1] = 0;
+ count[0] = 1;
+ count[1] = dofAtEachNodeCount + noffset ;
+ if( savedCoords )
+ count[1] += self->dim;
+
+ memSpace = H5Screate_simple( 2, count, NULL );
+ totalNodes = Mesh_GetGlobalSize( self->feMesh, (MeshTopology_Dim)0 );
+ buf = Memory_Alloc_Array( double, count[1], "fileBuffer" );
+
+ Journal_Firewall( (maxSize[0] == totalNodes), errorStr,
+ "\n\nError in %s for %s '%s'\n"
+ "Number of node values (%u) stored in %s does not correspond to total number of requested mesh nodes (%u).\n",
+ __func__, self->type, self->name, (unsigned int)maxSize[0], filename, totalNodes);
+
+
+ /** Read from HDF5 checkpint file */
+ for( ii=0; ii<totalNodes; ii++ ) {
+ start[0] = ii;
+
+ H5Sselect_hyperslab( fileSpace, H5S_SELECT_SET, start, NULL, count, NULL );
+ H5Sselect_all( memSpace );
+
+ error = H5Dread( fileData, H5T_NATIVE_DOUBLE, memSpace, fileSpace, H5P_DEFAULT, buf );
+ gNode_I = ii;
+
+ Journal_Firewall( error >= 0, errorStr,
+ "\n\nError in %s for %s '%s' - Cannot read data in %s.\n",
+ __func__, self->type, self->name, filename );
+
+ if( Mesh_GlobalToDomain( self->feMesh, MT_VERTEX, gNode_I, &lNode_I ) &&
+ lNode_I < Mesh_GetLocalSize( self->feMesh, MT_VERTEX ) )
+ {
+ for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
+ if( savedCoords )
+ variableVal = buf[dof_I + self->dim + noffset ];
+ else
+ variableVal = buf[dof_I + noffset ];
+ DofLayout_SetValueDouble( self->dofLayout, lNode_I, dof_I, variableVal );
+ }
+ }
+ }
+ Memory_Free( buf );
+
+ /** Close all handles */
+ H5Dclose( fileData );
+ H5Sclose( memSpace );
+ H5Sclose( fileSpace );
+ H5Fclose( file );
+
+#else
+
+ /** This loop used to stop 2 processors trying to open the file at the same time, which
+ * seems to cause problems */
+ for ( proc_I = 0; proc_I < nRanks; proc_I++ ) {
+ MPI_Barrier( comm );
+ if ( proc_I == rank ) {
+ /** Do the following since in parallel on some systems, the file
+ * doesn't get re-opened at the start automatically. */
+ inputFile = fopen( filename, "r" );
+
+ if ( False == inputFile ) {
+ Journal_Firewall( 0, errorStr, "Error- in %s(), for feVariable \"%s\": Couldn't import from file: "
+ "\"%s\" - aborting.\n", __func__, self->name, filename );
+
+ }
+ rewind( inputFile );
+
+ }
+ }
+
+ /** Need to determine whether checkpoint file contains coordinates */
+ fgets( lineString, MAX_LINE_LENGTH, inputFile );
+
+ sscanf( lineString, "%u%n ", &uTemp, &offset );
+ while( sscanf( lineString + offset, "%lf%n ", &temp[0], &n ) )
+ {
+ offset += n;
+ count ++;
+ if( offset >= strlen( lineString ) - 2 )
+ break;
+ }
+
+ if( count > dofAtEachNodeCount + 1 )
+ savedCoords = True;
+
+ rewind( inputFile );
+
+ /** Need to re-set the geometry here, in case we're loading from a checkpoint that had compression/squashing BCs,
+ and hence ended up with a smaller mesh than the original */
+ nDims = Mesh_GetDimSize( self->feMesh );
+ while ( !feof(inputFile) ) {
+ fscanf( inputFile, "%u ", &gNode_I );
+
+ if( savedCoords )
+ fscanf( inputFile, "%lg %lg %lg ", &temp[0], &temp[1], &temp[2] );
+
+ if( FeMesh_NodeGlobalToDomain( self->feMesh, gNode_I, &lNode_I ) &&
+ lNode_I < FeMesh_GetNodeLocalSize( self->feMesh ) )
+ {
+ for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
+ fscanf( inputFile, "%lg ", &variableVal );
+ DofLayout_SetValueDouble( self->dofLayout, lNode_I, dof_I, variableVal );
+ }
+ }
+ else {
+ fgets( lineString, MAX_LINE_LENGTH, inputFile );
+ }
+ }
+ fclose( inputFile );
+#endif
+
+ Mesh_DeformationUpdate( self->feMesh );
+
+ /** Sync shadow values now, as all procs should have required input */
+ FeVariable_SyncShadowValues( self );
+}
+
+void FeVariable_InterpolateFromFile( void* feVariable, DomainContext* context, Name feVarFilename, const char* meshFilename ){
+ FeVariable* self = (FeVariable*)feVariable;
+ Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
+#ifdef READ_HDF5
+ CartesianGenerator* gen;
+ C0Generator* C0gen;
+ FeMesh *feMesh, *C0feMesh, *elementMesh;
+ DofLayout* dofs;
+ Variable_Register* varReg;
+ Variable* var;
+ FeVariable* feVar;
+ hid_t file, fileData;
+ unsigned totalNodes, ii;
+ hid_t attrib_id, group_id;
+ herr_t status;
+ int res[3];
+ int checkVer;
+ int ndims;
+ double crdMin[3], crdMax[3];
+ double* value;
+ unsigned nDomainVerts;
+ static double* arrayPtr;
+ char* varName[9];
+
+ /** Open the file and data set. */
+ file = H5Fopen( meshFilename, H5F_ACC_RDONLY, H5P_DEFAULT );
+
+ Journal_Firewall( file >= 0, errorStr, "Error in %s for %s '%s' - Cannot open file %s.\n", __func__, self->type, self->name, meshFilename );
+
+ /** get the file attributes to sanity and version checks */
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ group_id = H5Gopen(file, "/");
+ attrib_id = H5Aopen_name(group_id, "checkpoint file version");
+ #else
+ group_id = H5Gopen2(file, "/", H5P_DEFAULT);
+ attrib_id = H5Aopen(group_id, "checkpoint file version", H5P_DEFAULT);
+ #endif
+ /** if this attribute does not exist (attrib_id < 0) then we assume MeshCHECKPOINT_V1 which is not supported */
+ if(attrib_id < 0)
+ Journal_Firewall( 0, errorStr,"\nError in %s for %s '%s' \n\n Interpolation restart not supported for Version 1 Checkpoint files \n\n", __func__, self->type, self->name );
+
+ /** check for known checkpointing version type */
+
+ status = H5Aread(attrib_id, H5T_NATIVE_INT, &checkVer);
+ H5Aclose(attrib_id);
+ if(checkVer != 2)
+ Journal_Firewall( (0), errorStr, "\n\nError in %s for %s '%s'\n" "Unknown checkpoint version (%u) for checkpoint file (%s).\n", __func__,
+ self->type, self->name, (unsigned int) checkVer, meshFilename);
+
+ /** check for correct number of dimensions */
+
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ attrib_id = H5Aopen_name(group_id, "dimensions");
+ #else
+ attrib_id = H5Aopen(group_id, "dimensions", H5P_DEFAULT);
+ #endif
+ status = H5Aread(attrib_id, H5T_NATIVE_INT, &ndims);
+ H5Aclose(attrib_id);
+ Journal_Firewall( (ndims == self->dim), errorStr,
+ "\n\nError in %s for %s '%s'\n"
+ "Number of dimensions (%u) for checkpoint file (%s) does not correspond to simulation dimensions (%u).\n",
+ __func__, self->type, self->name, (unsigned int) ndims, meshFilename,
+ self->dim);
+
+ /** check for correct mesh size if expecting a cartesian mesh*/
+
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ attrib_id = H5Aopen_name(group_id, "mesh resolution");
+ #else
+ attrib_id = H5Aopen(group_id, "mesh resolution", H5P_DEFAULT);
+ #endif
+ status = H5Aread(attrib_id, H5T_NATIVE_INT, &res);
+ H5Aclose(attrib_id);
+
+ /** Read in minimum coord. */
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ fileData = H5Dopen( file, "/min" );
+ #else
+ fileData = H5Dopen2( file, "/min", H5P_DEFAULT );
+ #endif
+ H5Dread( fileData, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &crdMin );
+ H5Dclose( fileData );
+
+ /** Read in maximum coord. */
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ fileData = H5Dopen( file, "/max" );
+ #else
+ fileData = H5Dopen2( file, "/max", H5P_DEFAULT );
+ #endif
+ H5Dread( fileData, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, &crdMax );
+ H5Dclose( fileData );
+
+ /** Close all handles */
+ H5Gclose(group_id);
+ H5Fclose( file );
+
+ /** create a cartesian mesh generator which will be required for the fevariable creation */
+ gen = CartesianGenerator_New( "", NULL );
+ /** use the feVariable dimension size for mesh generator */
+ CartesianGenerator_SetDimSize( gen, self->dim );
+ /** use the element size read in from the checkpoint file for the new mesh generator */
+ CartesianGenerator_SetTopologyParams( gen, (unsigned*)res, 0, NULL, NULL );
+ /** use the feVariable's mesh's generator's crdMin and crdMax (which have been previously read in from checkpointed mesh file */
+ CartesianGenerator_SetGeometryParams( gen, crdMin, crdMax );
+ /** set it so that the generator does not read in the mesh from a file - we will
+ explicitly do this after we build the feMesh using the provided mesh checkpoint file */
+ gen->readFromFile = False;
+ /** create a feMesh */
+ feMesh = FeMesh_New( "", NULL );
+ /** set feMesh to use generator we just created */
+ Mesh_SetGenerator( feMesh, gen );
+ /** set the feMesh family to be the same as that of the feVariable we are initialising/interpolating ie constant, linear, etc
+ unless we are initialising a constant mesh, in which case we set the element family to linear, and the mesh will be used
+ as the elementMesh for the C0 generator */
+ if (!strcmp(self->feMesh->generator->type, CartesianGenerator_Type)){
+ FeMesh_SetElementFamily( feMesh, self->feMesh->feElFamily );
+ /** set periodicity according to current simulation */
+ gen->periodic[0] = ((CartesianGenerator*)self->feMesh->generator)->periodic[0];
+ gen->periodic[1] = ((CartesianGenerator*)self->feMesh->generator)->periodic[1];
+ gen->periodic[2] = ((CartesianGenerator*)self->feMesh->generator)->periodic[2];
+ } else if (!strcmp(self->feMesh->generator->type, C0Generator_Type)){
+ FeMesh_SetElementFamily( feMesh, "linear" );
+ /** set periodicity according to current simulation */
+ gen->periodic[0] = ((CartesianGenerator*)((C0Generator*)self->feMesh->generator)->elMesh)->periodic[0];
+ gen->periodic[1] = ((CartesianGenerator*)((C0Generator*)self->feMesh->generator)->elMesh)->periodic[1];
+ gen->periodic[2] = ((CartesianGenerator*)((C0Generator*)self->feMesh->generator)->elMesh)->periodic[2];
+ } else
+ Journal_Firewall( 0, errorStr,"\nError in %s for %s '%s' \n\n Interpolation restart not supported for this mesh type \n\n", __func__, self->type, self->name );
+
+ /** now build the mesh, then read in the required coordinates from the given file */
+ Stg_Component_Build( feMesh, NULL, False );
+ CartesianGenerator_ReadFromHDF5( gen, (Mesh*) feMesh, meshFilename );
+
+ /** where we are dealing with a constant mesh feVariable, we have to build a new C0 mesh */
+ if (!strcmp(self->feMesh->generator->type, C0Generator_Type)){
+ elementMesh = feMesh;
+ /** create the C0 generator */
+ C0gen = C0Generator_New( "", (AbstractContext*)self->context );
+ /** set it's element mesh to the feMesh create just above */
+ C0Generator_SetElementMesh( C0gen, (void*) elementMesh );
+ /** create a new feMesh */
+ C0feMesh = FeMesh_New( "", NULL );
+ /** set feMesh to use generator we just created, and set its type to constant mesh */
+ Mesh_SetGenerator( C0feMesh, C0gen );
+ FeMesh_SetElementFamily( C0feMesh, self->feMesh->feElFamily );
+ /** now build the mesh, which will generate the mesh using the provided generator */
+ Stg_Component_Build( C0feMesh, NULL, False );
+ /** reset the feMesh pointer to point to this C0 mesh */
+ feMesh = C0feMesh;
+ }
+ Stg_Component_Initialise( feMesh, NULL, False );
+ /** get the number of mesh vertices stored locally */
+ nDomainVerts = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+
+ varReg = Variable_Register_New();
+ if (self->fieldComponentCount == 1){
+ var = Variable_NewScalar( "interpolation_temp_scalar", (AbstractContext*)self->context, Variable_DataType_Double, (Index*)&nDomainVerts, NULL, (void **)(&arrayPtr), varReg );
+ } else {
+ unsigned var_I;
+ for( var_I = 0; var_I < self->fieldComponentCount; var_I++ )
+ Stg_asprintf( &varName[var_I], "%s-loaded-Component-%d", self->name, var_I );
+ var = Variable_NewVector( "interpolation_temp_vector",
+ (AbstractContext*)self->context,
+ Variable_DataType_Double,
+ self->fieldComponentCount,
+ &nDomainVerts,
+ NULL,
+ (void**)&arrayPtr,
+ varReg,
+ varName[0], varName[1], varName[2], varName[3], varName[4],
+ varName[5], varName[6], varName[7], varName[8] );
+ }
+ Variable_Register_Add( varReg, var);
+ var->allocateSelf = True;
+ Stg_Component_Build( var, NULL, False );
+
+ dofs = DofLayout_New( "interpolation_temp_dof", self->context, varReg, nDomainVerts, feMesh );
+ if( self->fieldComponentCount == 1 )
+ DofLayout_AddAllFromVariableArray( dofs, 1, &var );
+ else {
+ unsigned var_I, node_I;
+ Variable* variable;
+ for( var_I = 0; var_I < self->fieldComponentCount; var_I++ ) {
+ variable = Variable_Register_GetByName( varReg, varName[var_I] );
+ variable->arrayPtrPtr = &var->arrayPtr;
+
+ for( node_I = 0; node_I < nDomainVerts; node_I++ )
+ DofLayout_AddDof_ByVarName( dofs, varName[var_I], node_I );
+
+ Memory_Free( varName[var_I] );
+ }
+ }
+ Stg_Component_Build( dofs, NULL, False );
+ Stg_Component_Initialise( dofs, NULL, False );
+
+ feVar = FeVariable_New(
+ "interpolation_temp_fevar",
+ self->context,
+ feMesh,
+ NULL,
+ dofs,
+ NULL,
+ NULL,
+ NULL,
+ self->fieldComponentCount,
+ False,
+ True,
+ False,
+ NULL );
+
+ Stg_Component_Build( feVar, context, False );
+ /** not sure why these aren't being set correctly, so a little (tri/ha)ckery */
+ feVar->fieldComponentCount = self->fieldComponentCount;
+ feVar->dim = self->dim;
+ FeVariable_ReadFromFile( feVar, feVarFilename );
+ feVar->_syncShadowValues( feVar );
+
+ totalNodes = Mesh_GetLocalSize( self->feMesh, MT_VERTEX );
+ value = Memory_Alloc_Array( double, self->fieldComponentCount, "interValue" );
+
+ /** step through nodes, interpolating the required values from our newly created feVariable */
+ for( ii=0; ii<totalNodes; ii++ ) {
+ feVar->_interpolateValueAt( feVar, Mesh_GetVertex( self->feMesh, ii ), value);
+ FeVariable_SetValueAtNode( self, ii, value);
+ }
+ Memory_Free( value );
+
+ /** our work is done, so we clean up after ourselves */
+ _FeVariable_Delete(feVar);
+ _DofLayout_Delete(dofs);
+ _Variable_Delete(var);
+ _Variable_Register_Delete(varReg);
+ _FeMesh_Delete(feMesh);
+
+ if (!strcmp(self->feMesh->generator->type, C0Generator_Type)){
+ _C0Generator_Delete(C0gen);
+ _FeMesh_Delete(elementMesh);
+ }
+ _CartesianGenerator_Delete(gen);
+
+#else
+ Journal_Firewall(!context->interpolateRestart,
+ errorStr,"\n\n Interpolation restart not supported for ASCII checkpoint files \n\n");
+#endif
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FieldTest.c
--- a/Discretisation/src/FieldTest.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1166 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: FieldTest.c 1095 2008-04-03 06:29:29Z JulianGiordani $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "types.h"
-#include "FieldTest.h"
-#include "FeVariable.h"
-#include "ElementType.h"
-#include "FeMesh.h"
-#include "OperatorFeVariable.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-const Type FieldTest_Type = "FieldTest";
-
-FieldTest* fieldTestSingleton = NULL;
-
-void* _FieldTest_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(FieldTest);
- Type type = FieldTest_Type;
- Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
- Stg_Class_PrintFunction* _print = _FieldTest_Print;
- Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _FieldTest_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _FieldTest_AssignFromXML;
- Stg_Component_BuildFunction* _build = _FieldTest_Build;
- Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
- Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _FieldTest_New( FIELDTEST_PASSARGS );
-}
-
-FieldTest* _FieldTest_New( FIELDTEST_DEFARGS )
-{
- FieldTest* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(FieldTest) );
- /* Construct using parent */
- /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
- /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
- and so should be set to ZERO in any children of this class. */
- nameAllocationType = NON_GLOBAL;
-
- self = (FieldTest*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- self->normalise = False;
- self->epsilon = 0.0001;
- self->referenceSolnFromFile = False;
-
- /* Assign singleton ptr */
- fieldTestSingleton = self;
- return self;
-}
-
-void _FieldTest_Delete( void* fieldTest ) {
- FieldTest* self = (FieldTest*)fieldTest;
-
- /*if( self->integrationSwarm ) Stg_Class_Delete( self->integrationSwarm );*/
- /*
- if( self->fieldCount ) {
- Memory_Free( self->gAnalyticSq );
- Memory_Free( self->gErrorSq );
- Memory_Free( self->gError );
- Memory_Free( self->gErrorNorm );
-
- Memory_Free( self->analyticSolnForFeVarKey );
- Memory_Free( self->_analyticSolutionList );
- }
-
- if( self->swarmVarCount ) {
- Index swarmVar_I;
- for( swarmVar_I = 0; swarmVar_I < self->swarmVarCount; swarmVar_I++ )
- Memory_Free(self->swarmVarNameList[swarmVar_I]);
- Memory_Free( self->swarmVarNameList );
- }
-
- Memory_Free( self->referenceSolnPath );
- Memory_Free( self->expectedFileName );
- Memory_Free( self->expectedFilePath );
- Memory_Free( self->dumpExpectedFileName );
- */
-
- /* Stg_Class_Delete parent*/
- _Stg_Component_Delete( self );
-}
-
-void _FieldTest_Print( void* fieldTest, Stream* stream ) {
- FieldTest* self = (FieldTest*)fieldTest;
-
- /* Print parent */
- _Stg_Component_Print( self, stream );
-
-}
-
-void* _FieldTest_Copy( const void* fieldTest, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- abort();
- return NULL;
-}
-
-void _FieldTest_AssignFromXML( void* fieldTest, Stg_ComponentFactory* cf, void* data ) {
- FieldTest* self = (FieldTest*)fieldTest;
- Dictionary* dict = cf->rootDict;
- Dictionary_Entry_Value* dictEntryVal = Dictionary_Get( dict, (Dictionary_Entry_Key)"pluginData" );
- Dictionary* pluginDict = Dictionary_Entry_Value_AsDictionary( dictEntryVal );
- /* get the pluginDict from the xml, needed for rejig */
- Dictionary* pluginDict2 = Codelet_GetPluginDictionary( self, cf->rootDict );
- Dictionary_Entry_Value* fieldList;
- Dictionary_Entry_Value* swarmVarList = Dictionary_Get( dict, (Dictionary_Entry_Key)"NumericSwarmVariableNames" );
- FieldVariable_Register* fV_Register;
- Index feVariable_I/*, referenceFieldCount*/;
- Index swarmVar_I;
- char* fieldName;
- Hook* generateErrorFields;
- Hook* physicsTestHook;
- Stream* errStream = Journal_Register( Error_Type, (Name)"FieldTests" );
-
- Journal_Firewall( pluginDict != NULL , errStream, "\nError in %s: No pluginData xml was defined ... aborting\n", __func__ );
-
- self->context = Stg_ComponentFactory_ConstructByName( cf, Dictionary_GetString( pluginDict2, (Dictionary_Entry_Key)"Context" ), DomainContext, False, data );
- if( !self->context )
- self->context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", DomainContext, True, data );
-
- fV_Register = self->context->fieldVariable_Register;
-
- fieldList = Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"NumericFields" );
- self->fieldCount = fieldList ? Dictionary_Entry_Value_GetCount( fieldList ) / 2 : 0;
-
- if( self->fieldCount ) {
- self->numericFieldList = Memory_Alloc_Array( FeVariable*, self->fieldCount, "numeric fields" );
- self->referenceFieldList = Memory_Alloc_Array( FeVariable*, self->fieldCount, "reference fields" );
- self->errorFieldList = Memory_Alloc_Array( FeVariable*, self->fieldCount, "error fields" );
- self->referenceMagFieldList = Memory_Alloc_Array( OperatorFeVariable*, self->fieldCount, "reference field magnitudes" );
- self->errorMagFieldList = Memory_Alloc_Array( OperatorFeVariable*, self->fieldCount, "error field magnitudes" );
-
- if( !self->referenceSolnFromFile ) {
- self->analyticSolnForFeVarKey = Memory_Alloc_Array( unsigned, self->fieldCount,
- "analytic solution index for ith feVariable" );
- }
-#if 0
- else {
- fieldList = Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"ReferenceFields" );
- referenceFieldCount = fieldList ? Dictionary_Entry_Value_GetCount( fieldList ) : assert(0);
-
- for( feVariable_I = 0; feVariable_I < referenceFieldCount; feVariable_I++ ) {
- referenceSolnFileList
- }
- }
-#endif
-
- for( feVariable_I = 0; feVariable_I < self->fieldCount; feVariable_I++ ) {
- /* read in the FeVariable from the tuple */
- fieldName = ( fieldList ) ?
- StG_Strdup( Dictionary_Entry_Value_AsString( Dictionary_Entry_Value_GetElement( fieldList, 2 * feVariable_I ) ) ):
- StG_Strdup( Dictionary_GetString( pluginDict, (Dictionary_Entry_Key)"FeVariable" ) );
-
- self->numericFieldList[feVariable_I] = (FeVariable* ) FieldVariable_Register_GetByName( fV_Register, fieldName );
-
- if( !self->numericFieldList[feVariable_I] ) {
- /* if the numericFieldList[x] can't be found in register
- and can't be constructed through the factory then
- skip this entry and take one off self->fieldCount
- needed for simple regression test
- */
- self->numericFieldList[feVariable_I] = Stg_ComponentFactory_ConstructByName( cf, (Name)fieldName, FeVariable, False, data );
- if( self->numericFieldList[feVariable_I]==NULL ) {
- self->fieldCount--;
- continue;
- }
- }
-
- /* ...and the corresponding analytic function ptr index - these have to be consistent with how they're ordered in the plugin */
- self->analyticSolnForFeVarKey[feVariable_I] = Dictionary_Entry_Value_AsUnsignedInt(
- Dictionary_Entry_Value_GetElement( fieldList, 2 * feVariable_I + 1 ) );
- Memory_Free( fieldName );
- }
- }
-
- self->integrationSwarm = (Swarm*)LiveComponentRegister_Get( cf->LCRegister, Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"IntegrationSwarm" ) ) );
- self->constantMesh = (FeMesh* )LiveComponentRegister_Get( cf->LCRegister, Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"ConstantMesh" ) ) );
- self->elementMesh = (FeMesh* )LiveComponentRegister_Get( cf->LCRegister, Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"ElementMesh" ) ) );
-
- self->swarmVarCount = swarmVarList ? Dictionary_Entry_Value_GetCount( swarmVarList ) : 0;
- if( self->swarmVarCount ) {
- self->swarmVarNameList = Memory_Alloc_Array( Name, self->swarmVarCount, "numeric swarm variable names" );
-
- for( swarmVar_I = 0; swarmVar_I < self->swarmVarCount; swarmVar_I++ ) {
- self->swarmVarNameList[swarmVar_I] = ( swarmVarList ) ?
- StG_Strdup( Dictionary_Entry_Value_AsString( Dictionary_Entry_Value_GetElement( swarmVarList, swarmVar_I ) ) ):
- StG_Strdup( Dictionary_GetString( pluginDict, (Dictionary_Entry_Key)"SwarmVariable" ) );
- }
- }
-
- self->referenceSolnPath = StG_Strdup( Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"referenceSolutionFilePath" ) ) );
- self->normalise = Dictionary_Entry_Value_AsBool( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"normaliseByAnalyticSolution" ) );
- self->epsilon = Dictionary_Entry_Value_AsDouble( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"epsilon" ) );
- self->testTimestep = Dictionary_GetInt_WithDefault( pluginDict, (Dictionary_Entry_Key)"testTimestep", 0 );
- self->referenceSolnFromFile = Dictionary_Entry_Value_AsBool( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"useReferenceSolutionFromFile" ) );
- self->appendToAnalysisFile = Dictionary_GetBool_WithDefault( pluginDict, (Dictionary_Entry_Key)"appendToAnalysisFile", False ) ;
-
- /* for the physics test */
- self->expectedFileName = StG_Strdup( Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"expectedFileName" ) ) );
- self->expectedFilePath = StG_Strdup( Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"expectedFilePath" ) ) );
- self->dumpExpectedFileName = StG_Strdup( Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"expectedOutputFileName" ) ) );
- self->expectedPass = False;
-
- /* set up the entry point */
- generateErrorFields = Hook_New( "Generate error fields hook", (void*)FieldTest_GenerateErrFields, self->name );
- _EntryPoint_AppendHook( Context_GetEntryPoint( self->context, AbstractContext_EP_FrequentOutput ), generateErrorFields );
-
- /* entry point for the fisix test func */
- if( strlen(self->expectedFileName) > 1 ) {
- physicsTestHook = Hook_New( "Physics test hook", (void*)FieldTest_EvaluatePhysicsTest, self->name );
- _EntryPoint_AppendHook( Context_GetEntryPoint( self->context, AbstractContext_EP_FrequentOutput ), physicsTestHook );
- }
-
- self->LCRegister = cf->LCRegister;
-}
-
-void _FieldTest_Build( void* fieldTest, void* data ) {
- FieldTest* self = (FieldTest*) fieldTest;
- Index field_I;
- //Index swarm_I;
-
- if( self->constantMesh ) Stg_Component_Build( self->constantMesh, data, False );
-
- for( field_I = 0; field_I < self->fieldCount; field_I++ ) {
- FieldTest_BuildAnalyticField( self, field_I );
- FieldTest_BuildErrField( self, field_I );
-
- Stg_Component_Build( self->numericFieldList[field_I], data, False );
- Stg_Component_Build( self->errorFieldList[field_I], data, False );
-
- Stg_Component_Build( self->referenceFieldList[field_I], data, False );
- Stg_Component_Build( self->errorFieldList[field_I], data, False );
- }
-
- /*for( swarm_I = 0; swarm_I < self->swarmCount; swarm_I++ ) {
- FieldTest_BuildAnalyticSwarm( self->referenceMesh, self->numericSwarmList[swarm_I],
- self->context, &self->referenceSwarmList[swarm_I] );
- FieldTest_BuildErrSwarm( self->constantMesh, self->numericSwarmList[swarm_I],
- self->context, &self->referenceSwarmList[swarm_I] );
- }*/
-
- if( self->fieldCount ) {
- self->gAnalyticSq = Memory_Alloc_2DArray( double, self->fieldCount, 9, (Name)"global reference solution squared" );
- self->gErrorSq = Memory_Alloc_2DArray( double, self->fieldCount, 9, (Name)"global L2 error squared" );
- self->gError = Memory_Alloc_2DArray( double, self->fieldCount, 9, (Name)"global L2 error" );
- self->gErrorNorm = Memory_Alloc_2DArray( double, self->fieldCount, 9, (Name)"global L2 error normalised" );
- }
-}
-
-void _FieldTest_Initialise( void* fieldTest, void* data ) {
- FieldTest* self = (FieldTest*) fieldTest;
- Index field_I;
- FILE* expected_fp;
- char* expectedFilename;
- int num_time_steps;
- int dof_i, dim_i;
- int expected_i = 0;
-
- for( field_I = 0; field_I < self->fieldCount; field_I++ ) {
- Stg_Component_Initialise( self->numericFieldList[field_I], data, False );
- Stg_Component_Initialise( self->errorFieldList[field_I], data, False );
- Stg_Component_Initialise( self->referenceFieldList[field_I], data, False );
- if( self->referenceMagFieldList[field_I] )
- Stg_Component_Initialise( self->referenceMagFieldList[field_I], data, False );
- if( self->errorMagFieldList[field_I] )
- Stg_Component_Initialise( self->errorMagFieldList[field_I], data, False );
- }
-
- /* load the reference solution from file if req'd */
- if( self->referenceSolnFromFile ) {
- char *referenceSolnFileName;
- for( field_I = 0; field_I < self->fieldCount; field_I++ ) {
- /* create the name of the reference file, the apprendix is handled by FieldTest_LoadReferenceSolutionFromFile */
- referenceSolnFileName = Memory_Alloc_Array_Unnamed( char, strlen((char*)self->referenceSolnPath) + 1 + strlen((char*)self->numericFieldList[field_I]->name) + 1 + 5 + strlen(".h5x\0") );
-#ifdef READ_HDF5
- sprintf( referenceSolnFileName, "%s/%s.%.5d.h5", self->referenceSolnPath, self->numericFieldList[field_I]->name, self->testTimestep );
-#else
- sprintf( referenceSolnFileName, "%s/%s.%.5d.dat", self->referenceSolnPath, self->numericFieldList[field_I]->name, self->testTimestep );
-#endif
- FeVariable_ReadFromFile( self->referenceFieldList[field_I], referenceSolnFileName );
-
- /* FieldTest_LoadReferenceSolutionFromFile( self->referenceFieldList[field_I],
- referenceSolnFileName,
- self->referenceSolnPath, self->context ); */
- Memory_Free( referenceSolnFileName );
- }
- }
- /* calculate the analytic solutions */
- else {
- for( field_I = 0; field_I < self->fieldCount; field_I++ ) {
- FieldTest_CalculateAnalyticSolutionForField( self, field_I );
- FeVariable_ZeroField( self->errorFieldList[field_I] );
- }
- }
-
- if( strlen(self->expectedFileName) > 1 && strcmp( self->expectedFileName, "false" ) ) {
- /* if the self->expectedFileName == False then don't go here */
- expectedFilename = Memory_Alloc_Array_Unnamed( char, strlen(self->expectedFilePath) + strlen(self->expectedFileName) + 1 );
- sprintf( expectedFilename, "%s%s", self->expectedFilePath, self->expectedFileName );
-
- expected_fp = fopen( expectedFilename, "r" );
-
- fscanf( expected_fp, "%d %d", &self->expectedDofs, &num_time_steps );
-
- self->expected = Memory_Alloc_Array_Unnamed( Event, num_time_steps + 1 );
- self->numeric = Memory_Alloc_Array_Unnamed( Event, self->context->maxTimeSteps + 1 );
- self->tolerance = Memory_Alloc_Array_Unnamed( Event, num_time_steps + 1 );
-
- while ( !feof( expected_fp ) ) {
- fscanf( expected_fp, "%lf ", &self->expected[expected_i].time );
-
- for( dim_i = 0; dim_i < self->context->dim; dim_i++ )
- fscanf( expected_fp, "%lf ", &self->expected[expected_i].place[dim_i] );
-
- for( dof_i = 0; dof_i < self->expectedDofs; dof_i++ )
- fscanf( expected_fp, "%lf ", &self->expected[expected_i].value[dof_i] );
-
- fscanf( expected_fp, "%lf ", &self->tolerance[expected_i].time );
-
- for( dim_i = 0; dim_i < self->context->dim; dim_i++ )
- fscanf( expected_fp, "%lf ", &self->tolerance[expected_i].place[dim_i] );
-
- for( dof_i = 0; dof_i < self->expectedDofs; dof_i++ )
- fscanf( expected_fp, "%lf ", &self->tolerance[expected_i].value[dof_i] );
-
- expected_i++;
- }
- fclose( expected_fp );
-
- Memory_Free( expectedFilename );
- }
-}
-
-void FieldTest_CalculateAnalyticSolutionForField( void* fieldTest, Index field_I ) {
- FieldTest* self = (FieldTest*) fieldTest;
- FeVariable* analyticField = self->referenceFieldList[field_I];
- FeMesh* analyticMesh = analyticField->feMesh;
- FieldTest_AnalyticSolutionFunc* analyticSolution;
- Index lNode_I;
- Index lMeshSize = Mesh_GetLocalSize( analyticMesh, MT_VERTEX );
- double* coord;
- double* value;
-
- analyticSolution = self->_analyticSolutionList[self->analyticSolnForFeVarKey[field_I]];
- value = Memory_Alloc_Array_Unnamed( double, analyticField->fieldComponentCount );
- memset( value, 0, analyticField->fieldComponentCount * sizeof(double) );
-
- for( lNode_I = 0; lNode_I < lMeshSize; lNode_I++ ) {
- coord = Mesh_GetVertex( analyticMesh, lNode_I );
- analyticSolution( self, coord, value );
- FeVariable_SetValueAtNode( analyticField, lNode_I, value );
- }
-
- Memory_Free( value );
-}
-
-void _FieldTest_Execute( void* fieldTest, void* data ) {
-}
-
-void _FieldTest_Destroy( void* fieldTest, void* data ) {
- FieldTest* self = (FieldTest*) fieldTest;
-
- if( self->fieldCount ) {
- Memory_Free( self->numericFieldList );
- Memory_Free( self->referenceFieldList );
- Memory_Free( self->errorFieldList );
- Memory_Free( self->referenceMagFieldList );
- Memory_Free( self->errorMagFieldList );
-
- Memory_Free( self->gAnalyticSq );
- Memory_Free( self->gErrorSq );
- Memory_Free( self->gError );
- Memory_Free( self->gErrorNorm );
- }
-
- if( strlen(self->expectedFileName) > 1 ) {
- Memory_Free( self->expected );
- Memory_Free( self->numeric );
- Memory_Free( self->tolerance );
- }
- if( !self->referenceSolnFromFile ) {
- Memory_Free( self->analyticSolnForFeVarKey );
- Memory_Free( self->_analyticSolutionList );
- }
-
- Stg_Component_Destroy( self, data, False );
-}
-
-void FieldTest_BuildAnalyticField( void* fieldTest, Index field_I ) {
- FieldTest* self = (FieldTest*) fieldTest;
- FeVariable* numericField = self->numericFieldList[field_I];
- FeMesh* referenceMesh = numericField->feMesh;
- DomainContext* context = self->context;
- Variable_Register* variable_Register = context->variable_Register;
- char* tmpName;
- Dof_Index componentsCount = numericField->fieldComponentCount;
- char* varName[9];
- unsigned var_I;
- unsigned node_I;
- Variable* variable;
- Variable* baseVariable = NULL;
- DofLayout* referenceDofLayout = NULL;
-
- unsigned nDomainVerts = Mesh_GetDomainSize( referenceMesh, MT_VERTEX );
- static double* arrayPtr;
-
- tmpName = Stg_Object_AppendSuffix( numericField, (Name)"AnalyticVariable" );
-
- if( componentsCount == 1 ) {
- arrayPtr = Memory_Alloc_Array_Unnamed( double, nDomainVerts );
- baseVariable = Variable_NewScalar( tmpName, (AbstractContext*)self->context, Variable_DataType_Double, (Index*)&nDomainVerts, NULL, (void**)&arrayPtr, variable_Register );
- }
- else {
- for( var_I = 0; var_I < componentsCount; var_I++ )
- Stg_asprintf( &varName[var_I], "%s-Component-%d", tmpName, var_I );
-
- arrayPtr = Memory_Alloc_Array_Unnamed( double, nDomainVerts * componentsCount );
- baseVariable = Variable_NewVector( tmpName,
- (AbstractContext*)self->context,
- Variable_DataType_Double,
- componentsCount,
- &nDomainVerts,
- NULL,
- (void**)&arrayPtr,
- variable_Register,
- varName[0], varName[1], varName[2],
- varName[3], varName[4], varName[5],
- varName[6], varName[7], varName[8] );
- }
- Memory_Free( tmpName );
-
- tmpName = Stg_Object_AppendSuffix( numericField, (Name)"AnalyticDofLayout" );
-
- referenceDofLayout = DofLayout_New( tmpName, self->context, variable_Register, Mesh_GetDomainSize( referenceMesh, MT_VERTEX ), referenceMesh );
-
- if( componentsCount == 1 )
- DofLayout_AddAllFromVariableArray( referenceDofLayout, 1, &baseVariable );
- else {
- for( var_I = 0; var_I < componentsCount; var_I++ ) {
- variable = Variable_Register_GetByName( variable_Register, varName[var_I] );
- variable->arrayPtrPtr = &baseVariable->arrayPtr;
-
- for( node_I = 0; node_I < Mesh_GetDomainSize( referenceMesh, MT_VERTEX ); node_I++ )
- DofLayout_AddDof_ByVarName( referenceDofLayout, varName[var_I], node_I );
-
- Memory_Free( varName[var_I] );
- }
-
- }
-
- Stg_Component_Build( referenceDofLayout, NULL, False );
- Stg_Component_Initialise( referenceDofLayout, NULL, False );
-
- Memory_Free( tmpName );
-
- tmpName = Stg_Object_AppendSuffix( numericField, (Name)"Analytic" );
-
- self->referenceFieldList[field_I] = FeVariable_New( tmpName, self->context, referenceMesh, referenceMesh, referenceDofLayout, NULL, NULL, NULL,
- Mesh_GetDimSize( referenceMesh ), False, False, False, context->fieldVariable_Register );
- self->referenceFieldList[field_I]->context = context;
- /* so that the eqnation numbers don't get built for this guy */
- self->referenceFieldList[field_I]->buildEqNums = False;
-
- if( componentsCount > Mesh_GetDimSize( referenceMesh ) ) {
- /* we're dealing with a tensor, so use invariant */
- tmpName = Stg_Object_AppendSuffix( self->referenceFieldList[field_I], (Name)"Invariant" );
- self->referenceMagFieldList[field_I] = OperatorFeVariable_NewUnary( tmpName, self->context, self->referenceFieldList[field_I], "SymmetricTensor_Invariant" );
- self->referenceMagFieldList[field_I]->context = context;
- } else {
- /* we're dealing with a vector, so use magnitude */
- tmpName = Stg_Object_AppendSuffix( self->referenceFieldList[field_I], (Name)"Magnitude" );
- self->referenceMagFieldList[field_I] = OperatorFeVariable_NewUnary( tmpName, self->context, self->referenceFieldList[field_I], "Magnitude" );
- self->referenceMagFieldList[field_I]->context = context;
- }
-
- Memory_Free( tmpName );
- Stg_Component_Build( self->referenceMagFieldList[field_I], context, False );
- self->referenceMagFieldList[field_I]->_operator = Operator_NewFromName( self->referenceMagFieldList[field_I]->operatorName,
- self->referenceFieldList[field_I]->fieldComponentCount, context->dim );
- self->referenceMagFieldList[field_I]->fieldComponentCount = self->referenceMagFieldList[field_I]->_operator->resultDofs;
- _OperatorFeVariable_SetFunctions( self->referenceMagFieldList[field_I] );
-
- LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) baseVariable );
- LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) referenceDofLayout );
- LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) self->referenceFieldList[field_I] );
- LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) self->referenceMagFieldList[field_I] );
-}
-
-void FieldTest_BuildErrField( void* fieldTest, Index field_I ) {
- FieldTest* self = (FieldTest*) fieldTest;
- FeMesh* constantMesh = self->constantMesh;
- FeVariable* numericField = self->numericFieldList[field_I];
- DomainContext* context = self->context;
- Variable_Register* variable_Register = context->variable_Register;
- char* tmpName;
- Dof_Index componentsCount = numericField->fieldComponentCount;
- char* varName[9];
- unsigned var_I;
- unsigned node_I;
- Variable* variable;
- Variable* baseVariable = NULL;
- DofLayout* errorDofLayout = NULL;
- unsigned nDomainVerts = Mesh_GetDomainSize( constantMesh, MT_VERTEX );
- static void* arrayPtr;
-
- tmpName = Stg_Object_AppendSuffix( numericField, (Name)"ErrorVariable" );
-
- if( componentsCount == 1 ) {
- arrayPtr = Memory_Alloc_Array_Unnamed( double, nDomainVerts );
- baseVariable = Variable_NewScalar( tmpName, (AbstractContext*)self->context, Variable_DataType_Double, (Index*)&nDomainVerts, NULL, &arrayPtr, variable_Register );
- }
- else {
- for( var_I = 0; var_I < componentsCount; var_I++ )
- Stg_asprintf( &varName[var_I], "%s-Component-%d", tmpName, var_I );
-
- arrayPtr = Memory_Alloc_Array_Unnamed( double, nDomainVerts * componentsCount );
- baseVariable = Variable_NewVector( tmpName, (AbstractContext*)self->context, Variable_DataType_Double, componentsCount, &nDomainVerts,
- NULL, (void**)&arrayPtr, variable_Register,
- varName[0], varName[1], varName[2], varName[3], varName[4],
- varName[5], varName[6], varName[7], varName[8] );
- }
- Memory_Free( tmpName );
-
- tmpName = Stg_Object_AppendSuffix( numericField, (Name)"ErrorDofLayout" );
-
- errorDofLayout = DofLayout_New( tmpName, self->context, variable_Register, Mesh_GetDomainSize( constantMesh, MT_VERTEX ), constantMesh );
-
- if( componentsCount == 1 )
- DofLayout_AddAllFromVariableArray( errorDofLayout, 1, &baseVariable );
- else {
- for( var_I = 0; var_I < componentsCount; var_I++ ) {
- variable = Variable_Register_GetByName( variable_Register, varName[var_I] );
- variable->arrayPtrPtr = &baseVariable->arrayPtr;
-
- for( node_I = 0; node_I < Mesh_GetDomainSize( constantMesh, MT_VERTEX ); node_I++ )
- DofLayout_AddDof_ByVarName( errorDofLayout, varName[var_I], node_I );
-
- Memory_Free( varName[var_I] );
- }
-
- //errorDofLayout->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, componentsCount );
- //errorDofLayout->baseVariables[0] = baseVariable;
- }
-
- Stg_Component_Build( errorDofLayout, NULL, False );
- Stg_Component_Initialise( errorDofLayout, NULL, False );
-
- Memory_Free( tmpName );
-
- tmpName = Stg_Object_AppendSuffix( numericField, (Name)"Error" );
-
- self->errorFieldList[field_I] = FeVariable_New( tmpName, self->context, constantMesh, constantMesh, errorDofLayout, NULL, NULL, NULL,
- Mesh_GetDimSize( constantMesh ), False, False, False, context->fieldVariable_Register );
- /* so that the eqnation numbers don't get built for this guy */
- self->errorFieldList[field_I]->buildEqNums = False;
-
- if( componentsCount > Mesh_GetDimSize( constantMesh ) ) {
- /* we're dealing with a tensor, so use invariant */
- tmpName = Stg_Object_AppendSuffix( self->errorFieldList[field_I], (Name)"Invariant" );
- self->errorMagFieldList[field_I] = OperatorFeVariable_NewUnary( tmpName, self->context, self->errorFieldList[field_I], "SymmetricTensor_Invariant" );
- self->errorMagFieldList[field_I]->context = context;
- } else {
- /* we're dealing with a vector, so use magnitude */
- tmpName = Stg_Object_AppendSuffix( self->errorFieldList[field_I], (Name)"Magnitude" );
- self->errorMagFieldList[field_I] = OperatorFeVariable_NewUnary( tmpName, self->context, self->errorFieldList[field_I], "Magnitude" );
- self->errorMagFieldList[field_I]->context = context;
- }
- Memory_Free( tmpName );
- Stg_Component_Build( self->errorMagFieldList[field_I], context, False );
- self->errorMagFieldList[field_I]->_operator = Operator_NewFromName( self->errorMagFieldList[field_I]->operatorName,
- self->errorFieldList[field_I]->fieldComponentCount, context->dim );
- self->errorMagFieldList[field_I]->fieldComponentCount = self->errorMagFieldList[field_I]->_operator->resultDofs;
- _OperatorFeVariable_SetFunctions( self->errorMagFieldList[field_I] );
-
- LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) baseVariable );
- LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) errorDofLayout );
- LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) self->errorFieldList[field_I] );
- LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) self->errorMagFieldList[field_I] );
-}
-
-void FieldTest_LoadReferenceSolutionFromFile( FeVariable* feVariable, Name referenceSolnName, Name referenceSolnPath, DomainContext* context ) {
- FeMesh* feMesh = feVariable->feMesh;
- char* filename;
- unsigned nx = 0, ny = 0, nz = 0, total;
- unsigned lineNum = 0;
- double resolution[3];
- double* coord;
- Index node_I, dim_I;
- unsigned increments[3];
- double value[3];
- unsigned lineNum0;
- unsigned dofAtEachNodeCount, dof_I;
- unsigned meshSize = Mesh_GetLocalSize( feMesh, MT_VERTEX );
- unsigned nDims = Mesh_GetDimSize( feMesh );
- double vertex0[3], coordPrime[3];
- double Ni[27], values[27][3];
- unsigned shapeFunc_I;
- double *posx, *posy, *posz;
- double **variables;
- unsigned numShapeFuncs = ( nDims == 3 ) ? 27 : 9;
- double xi, eta, zeta;
- double a0, b0, c0;
- double a1, b1, c1;
- double a2, b2, c2;
- double m0, m1, m2, m3, m4, m5, m6;
-#ifdef READ_HDF5
- hid_t inputFile;
- hid_t dataSet, memSpace, dataSpace;
- hsize_t start[2], count[2], hSize;
-#endif
- int sizes[3];
- double* data;
- int dataPos = 0;
- double nodeDummy;
-
- Stg_Component_Initialise( feMesh, context, False );
- Stg_Component_Initialise( feVariable, context, False );
-
- dofAtEachNodeCount = feVariable->fieldComponentCount;
- /* . h5 \0 */
- filename = Memory_Alloc_Array_Unnamed( char, strlen(referenceSolnPath) + strlen(referenceSolnName) + 1 + 2 + 1 );
- sprintf( filename, "%s%s.h5", referenceSolnPath, referenceSolnName );
-#ifdef READ_HDF5
- inputFile = H5Fopen( filename, H5F_ACC_RDONLY, H5P_DEFAULT );
-#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- dataSet = H5Dopen( inputFile, "/size" );
-#else
- dataSet = H5Dopen2( inputFile, "/size", H5P_DEFAULT );
-#endif
- H5Dread( dataSet, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, sizes );
- nx = sizes[0];
- ny = sizes[1];
- total = nx * ny;
- if( nDims == 3 ) {
- nz = sizes[2];
- total *= nz;
- }
- H5Dclose( dataSet );
-
- posx = Memory_Alloc_Array_Unnamed( double, total );
- posy = Memory_Alloc_Array_Unnamed( double, total );
- if( nDims == 3 ) posz = Memory_Alloc_Array_Unnamed( double, total );
- variables = Memory_Alloc_2DArray_Unnamed( double, total, dofAtEachNodeCount );
- data = Memory_Alloc_Array_Unnamed( double, nDims + dofAtEachNodeCount );
-
- hSize = nDims + dofAtEachNodeCount;
- memSpace = H5Screate_simple( 1, &hSize, NULL );
- H5Sselect_all( memSpace );
-#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- dataSet = H5Dopen( inputFile, "/data" );
-#else
- dataSet = H5Dopen2( inputFile, "/data", H5P_DEFAULT );
-#endif
- dataSpace = H5Dget_space( dataSet );
- start[0] = 0;
- start[1] = 0;
- count[0] = 1;
- count[1] = nDims + dofAtEachNodeCount;
- H5Sselect_hyperslab( dataSpace, H5S_SELECT_SET, start, NULL, count, NULL );
- for( lineNum = 0; lineNum < total; lineNum++ ) {
- start[0] = lineNum;
- H5Sselect_hyperslab( dataSpace, H5S_SELECT_SET, start, NULL, count, NULL );
- H5Dread( dataSet, H5T_NATIVE_DOUBLE, memSpace, dataSpace, H5P_DEFAULT, data );
-
- dataPos = 0;
- nodeDummy = data[dataPos++];
- posx[lineNum] = data[dataPos++];
- posy[lineNum] = data[dataPos++];
- if( nDims == 3 ) posz[lineNum] = data[dataPos++];
-
- for( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ )
- variables[lineNum][dof_I] = data[dataPos++];
- }
-
- H5Sclose( memSpace );
- H5Sclose( dataSpace );
- H5Dclose( dataSet );
-#endif
- Memory_Free( data );
-
- resolution[0] = posx[1] - posx[0];
- resolution[1] = posy[nx] - posy[0];
- if( nDims == 3 ) resolution[2] = posz[nx*ny] - posz[0];
-
- for( node_I = 0; node_I < meshSize; node_I++ ) {
- coord = Mesh_GetVertex( feMesh, node_I );
- increments[0] = (unsigned)( ( coord[0] - posx[0] ) / resolution[0] );
- increments[1] = (unsigned)( ( coord[1] - posy[0] ) / resolution[1] );
- if( nDims == 3 ) increments[2] = (unsigned)( ( coord[2] - posz[0] ) / resolution[2] );
-
- for( dim_I = 0; dim_I < nDims; dim_I++ )
- if( increments[dim_I] % 2 == 1 )
- increments[dim_I]--;
- if( increments[0] >= nx - 2 )
- increments[0] = nx - 3;
- if( increments[1] >= ny - 2 )
- increments[1] = ny - 3;
- if( nDims == 3 && increments[2] >= nz - 2 )
- increments[2] = nz - 3;
-
- lineNum0 = increments[0] + nx * increments[1];
- if( nDims == 3 ) lineNum0 += nx * ny * increments[2];
- if( lineNum0 >= total )
- Journal_Printf( context->info, "interpolation error: node value: %d resolution size: %d\n", lineNum0, total );
-
- vertex0[0] = posx[lineNum0];
- vertex0[1] = posy[lineNum0];
- if( nDims == 3 ) vertex0[2] = posz[lineNum0];
-
- /* for quadratic elements the resolution is twice the distance between the nodes */
- for( dim_I = 0; dim_I < nDims; dim_I++ )
- coordPrime[dim_I] = ( coord[dim_I] - vertex0[dim_I] ) / resolution[dim_I] - 1.0;
-
- /* assign the shape functions & interpolate quadratically */
- if( nDims == 2 ) {
- xi = coordPrime[0]; eta = coordPrime[1];
- a0 = xi - 1.0; b0 = eta - 1.0;
- a1 = 1.0 - xi * xi; b1 = 1.0 - eta * eta;
- a2 = xi + 1.0; b2 = eta + 1.0;
- m0 = 0.5 * xi; m1 = 0.5 * eta; m2 = 0.25 * xi * eta;
-
- Ni[0] = m2 * a0 * b0; Ni[1] = m1 * a1 * b0; Ni[2] = m2 * a2 * b0;
- Ni[3] = m0 * a0 * b1; Ni[4] = a1 * b1; Ni[5] = m0 * a2 * b1;
- Ni[6] = m2 * a0 * b2; Ni[7] = m1 * a1 * b2; Ni[8] = m2 * a2 * b2;
-
- for( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
- values[0][dof_I] = variables[lineNum0][dof_I];
- values[1][dof_I] = variables[lineNum0+1][dof_I];
- values[2][dof_I] = variables[lineNum0+2][dof_I];
- values[3][dof_I] = variables[lineNum0+nx][dof_I];
- values[4][dof_I] = variables[lineNum0+nx+1][dof_I];
- values[5][dof_I] = variables[lineNum0+nx+2][dof_I];
- values[6][dof_I] = variables[lineNum0+(2*nx)][dof_I];
- values[7][dof_I] = variables[lineNum0+(2*nx)+1][dof_I];
- values[8][dof_I] = variables[lineNum0+(2*nx)+2][dof_I];
-
- value[dof_I] = 0.0;
- for( shapeFunc_I = 0; shapeFunc_I < numShapeFuncs; shapeFunc_I++ )
- value[dof_I] += Ni[shapeFunc_I] * values[shapeFunc_I][dof_I];
- }
- }
- else {
- xi = coordPrime[0]; eta = coordPrime[1]; zeta = coordPrime[2];
- a0 = xi - 1.0; b0 = eta - 1.0; c0 = zeta - 1.0;
- a1 = 1.0 - xi * xi; b1 = 1.0 - eta * eta; c1 = 1.0 - zeta * zeta;
- a2 = xi + 1.0; b2 = eta + 1.0; c2 = zeta + 1.0;
- m0 = 0.5 * xi; m1 = 0.5 * eta; m2 = 0.5 * zeta;
- m3 = 0.25 * xi * eta; m4 = 0.25 * xi * zeta; m5 = 0.25 * eta * zeta;
- m6 = 0.125 * xi * eta * zeta;
-
- Ni[0] = m6 * a0 * b0 * c0; Ni[1] = m5 * a1 * b0 * c0; Ni[2] = m6 * a2 * b0 * c0;
- Ni[3] = m4 * a0 * b1 * c0; Ni[4] = m2 * a1 * b1 * c0; Ni[5] = m4 * a2 * b1 * c0;
- Ni[6] = m6 * a0 * b2 * c0; Ni[7] = m5 * a1 * b2 * c0; Ni[8] = m6 * a2 * b2 * c0;
-
- Ni[9] = m3 * a0 * b0 * c1; Ni[10] = m1 * a1 * b0 * c1; Ni[11] = m3 * a2 * b0 * c1;
- Ni[12] = m0 * a0 * b1 * c1; Ni[13] = a1 * b1 * c1; Ni[14] = m0 * a2 * b1 * c1;
- Ni[15] = m3 * a0 * b2 * c1; Ni[16] = m1 * a1 * b2 * c1; Ni[17] = m3 * a2 * b2 * c1;
-
- Ni[18] = m6 * a0 * b0 * c2; Ni[19] = m5 * a1 * b0 * c2; Ni[20] = m6 * a2 * b0 * c2;
- Ni[21] = m4 * a0 * b1 * c2; Ni[22] = m2 * a1 * b1 * c2; Ni[23] = m4 * a2 * b1 * c2;
- Ni[24] = m6 * a0 * b2 * c2; Ni[25] = m5 * a1 * b2 * c2; Ni[26] = m6 * a2 * b2 * c2;
-
- for( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
- values[0][dof_I] = variables[lineNum0][dof_I];
- values[1][dof_I] = variables[lineNum0+1][dof_I];
- values[2][dof_I] = variables[lineNum0+2][dof_I];
- values[3][dof_I] = variables[lineNum0+nx][dof_I];
- values[4][dof_I] = variables[lineNum0+nx+1][dof_I];
- values[5][dof_I] = variables[lineNum0+nx+2][dof_I];
- values[6][dof_I] = variables[lineNum0+(2*nx)][dof_I];
- values[7][dof_I] = variables[lineNum0+(2*nx)+1][dof_I];
- values[8][dof_I] = variables[lineNum0+(2*nx)+2][dof_I];
-
- values[9][dof_I] = variables[lineNum0+(nx*ny)][dof_I];
- values[10][dof_I] = variables[lineNum0+(nx*ny)+1][dof_I];
- values[11][dof_I] = variables[lineNum0+(nx*ny)+2][dof_I];
- values[12][dof_I] = variables[lineNum0+(nx*ny)+nx][dof_I];
- values[13][dof_I] = variables[lineNum0+(nx*ny)+nx+1][dof_I];
- values[14][dof_I] = variables[lineNum0+(nx*ny)+nx+2][dof_I];
- values[15][dof_I] = variables[lineNum0+(nx*ny)+(2*nx)][dof_I];
- values[16][dof_I] = variables[lineNum0+(nx*ny)+(2*nx)+1][dof_I];
- values[17][dof_I] = variables[lineNum0+(nx*ny)+(2*nx)+2][dof_I];
-
- values[18][dof_I] = variables[lineNum0+(2*nx*ny)][dof_I];
- values[19][dof_I] = variables[lineNum0+(2*nx*ny)+1][dof_I];
- values[20][dof_I] = variables[lineNum0+(2*nx*ny)+2][dof_I];
- values[21][dof_I] = variables[lineNum0+(2*nx*ny)+nx][dof_I];
- values[22][dof_I] = variables[lineNum0+(2*nx*ny)+nx+1][dof_I];
- values[23][dof_I] = variables[lineNum0+(2*nx*ny)+nx+2][dof_I];
- values[24][dof_I] = variables[lineNum0+(2*nx*ny)+(2*nx)][dof_I];
- values[25][dof_I] = variables[lineNum0+(2*nx*ny)+(2*nx)+1][dof_I];
- values[26][dof_I] = variables[lineNum0+(2*nx*ny)+(2*nx)+2][dof_I];
-
- value[dof_I] = 0.0;
- for( shapeFunc_I = 0; shapeFunc_I < numShapeFuncs; shapeFunc_I++ )
- value[dof_I] += Ni[shapeFunc_I] * values[shapeFunc_I][dof_I];
- }
- }
-
- FeVariable_SetValueAtNode( feVariable, node_I, value );
- }
-
- Memory_Free( filename );
- Memory_Free( posx );
- Memory_Free( posy );
- if( nDims == 3 ) Memory_Free( posz );
- Memory_Free( variables );
-
-#ifdef READ_HDF5
- H5Fclose( inputFile );
-#endif
-}
-
-void _FieldTest_DumpToAnalysisFile( FieldTest* self, Stream* analysisStream ) {
- int field_I, numDofs, dim, dof_I;
- /* double error; */
- FeVariable* errorField;
-
- for( field_I = 0; field_I < self->fieldCount; field_I++ ) {
- /* should be using MT_VOLUME for the reference field mesh, but seems to have a bug */
- errorField = self->errorFieldList[field_I];
- numDofs = self->numericFieldList[field_I]->fieldComponentCount;
- dim = self->numericFieldList[field_I]->dim;
-
-#if 0
- /* Fancy error measurements of magnitudes and 2ndInvars, no needed
- * but I'm leaving it in incase */
- if( dim == numDofs ) {
- /* It's a vector */
- error = StGermain_VectorMagnitude( self->gErrorNorm[field_I], dim );
- } else if ( numDofs > self->numericFieldList[field_I]->dim ) {
- /* Assume it's a symmetric tensor */
- error = SymmetricTensor_2ndInvariant( self->gErrorNorm[field_I], dim );
- } else {
- /* It's a scalar */
- error = self->gErrorNorm[field_I][0];
- }
- Journal_Printf( analysisStream, "%.8e ", error );
-#endif
- for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
- if(self->normalise)
- Journal_RPrintf( analysisStream, "%.8e ", self->gErrorNorm[field_I][dof_I] );
- else
- Journal_RPrintf( analysisStream, "%.8e ", self->gErrorSq[field_I][dof_I] );
- }
-
- }
-}
-
-/* by default, success of the physics test is set to false. this is reset if the test passes */
-void FieldTest_EvaluatePhysicsTest( void* _context, void* data ) {
- DomainContext* context = (DomainContext*)_context;
- /* dodgy!!! - not sure how else to pass the self reference at an entry point */
- FieldTest* self = fieldTestSingleton;
- FieldTest_ExpectedResultFunc* expectedFunc = self->expectedFunc;
- FILE* dumpExpectedFilePtr;
- char* dumpExpectedFileName;
- int dim_i, dof_i;
-
- if( expectedFunc( self->expectedData, context, self->expected, self->numeric, self->tolerance ) )
- self->expectedPass = True;
-
- if( strlen(self->dumpExpectedFileName) > 1 ) {
- dumpExpectedFileName = Memory_Alloc_Array_Unnamed( char, strlen(self->expectedFilePath) +
- strlen(self->dumpExpectedFileName) + 5 );
- sprintf( dumpExpectedFileName, "%s%s.out", self->expectedFilePath, self->dumpExpectedFileName );
- dumpExpectedFilePtr = fopen( dumpExpectedFileName, "a" );
-
- fprintf( dumpExpectedFilePtr, "%.8e ", self->numeric[context->timeStep].time );
- for( dim_i = 0; dim_i < context->dim; dim_i++ )
- fprintf( dumpExpectedFilePtr, "%.8e ", self->numeric[context->timeStep].place[dim_i] );
- for( dof_i = 0; dof_i < self->expectedDofs; dof_i++ )
- fprintf( dumpExpectedFilePtr, "%.8e ", self->numeric[context->timeStep].value[dof_i] );
-
- fprintf( dumpExpectedFilePtr, "\n" );
-
- if( context->timeStep == context->maxTimeSteps ) {
- if( self->expectedPass )
- fprintf( dumpExpectedFilePtr, "test result: PASS\n" );
- else
- fprintf( dumpExpectedFilePtr, "test result: FAIL\n" );
- }
-
- Memory_Free( dumpExpectedFileName );
- fclose( dumpExpectedFilePtr );
- }
-}
-
-void FieldTest_GenerateErrFields( void* _context, void* data ) {
- DomainContext* context = (DomainContext*)_context;
- /* this a really dodgy way to get the self ptr, as will only work if the textual name is consistent with that in
- * the XML - need to find a way to add an entry point which allows the self ptr to be passed as a void * */
- //FieldTest* self = LiveComponentRegister_Get( context->CF->LCRegister, (Name)"NumericFields" );
- /* this is also a dodgy way to get the self ptr, as its obtained from a global variable */
- FieldTest* self = fieldTestSingleton;
- FeVariable* errorField;
- Index lMeshSize, lElement_I;
- double elErrorSq[9], elNormSq[9], elError[9];
- double lAnalyticSq[9], gAnalyticSq[9];
- double lErrorSq[9], gErrorSq[9];
- Bool normalise = self->normalise;
- Index numDofs, dof_I, fieldCount;
- Index field_I;
- Stream* analysisStream;
- /* double eps = self->epsilon; */
-
- /* if testTimestep is NOT initialise and NOT equal to the current timestep
- * we skip this function */
- if( self->testTimestep != context->timeStep && self->testTimestep != 0 )
- return;
-
- fieldCount = self->fieldCount;
-
- if( self->appendToAnalysisFile ) {
- /* append (or create if not found ) a file to report results */
- double length, elementResI;
- char* filename;
- analysisStream = Journal_Register( Info_Type, (Name)self->type );
- Stg_asprintf( &filename, "%s-analysis.cvg", self->name );
- Stream_AppendFile( analysisStream, filename );
- Memory_Free( filename );
-
- /* write heading names in file */
- Journal_RPrintf( analysisStream, "#Res ");
- for(field_I = 0 ; field_I < fieldCount ; field_I++ ) {
- numDofs = self->numericFieldList[field_I]->fieldComponentCount;
- for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
- Journal_RPrintf( analysisStream, "%s%d ", self->numericFieldList[field_I]->name, dof_I+1 );
- }
- }
- length = Dictionary_GetDouble( context->CF->rootDict, "maxX" ) - Dictionary_GetDouble( context->CF->rootDict, "minX" ) ;
- elementResI = Dictionary_GetInt( context->CF->rootDict, (Dictionary_Entry_Key)"elementResI" );
- /* assume square resolution */
- Journal_RPrintf( analysisStream, "\n%e ", length/elementResI );
- }
-
- for( field_I = 0; field_I < fieldCount; field_I++ ) {
- /* should be using MT_VOLUME for the reference field mesh, but seems to have a bug */
- lMeshSize = Mesh_GetLocalSize( self->constantMesh, MT_VERTEX );
- errorField = self->errorFieldList[field_I];
- numDofs = self->numericFieldList[field_I]->fieldComponentCount;
-
- assert( !strcmp( errorField->feMesh->name, "constantMesh" ) );
-
- for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
- lAnalyticSq[dof_I] = 0.0;
- lErrorSq[dof_I] = 0.0;
- }
-
- for( lElement_I = 0; lElement_I < lMeshSize; lElement_I++ ) {
- for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
- elErrorSq[dof_I] = 0.0;
- elNormSq[dof_I] = 0.0;
- }
-
- if( self->referenceSolnFromFile )
- FieldTest_ElementErrReferenceFromField( self, field_I, lElement_I, elErrorSq, elNormSq );
- else
- FieldTest_ElementErrAnalyticFromField( self, field_I, lElement_I, elErrorSq, elNormSq );
-
- for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
- lAnalyticSq[dof_I] += elNormSq[dof_I];
- lErrorSq[dof_I] += elErrorSq[dof_I];
- //elError[dof_I] = normalise ? sqrt( elErrorSq[dof_I] / ( elNormSq[dof_I] + eps ) ) : sqrt( elErrorSq[dof_I] );
- elError[dof_I] = normalise ? sqrt( elErrorSq[dof_I] / ( elNormSq[dof_I] ) ) : sqrt( elErrorSq[dof_I] );
- }
-
- /* constant mesh, so node and element indices map 1:1 */
- FeVariable_SetValueAtNode( errorField, lElement_I, elError );
- }
-
- MPI_Allreduce( lAnalyticSq, gAnalyticSq, numDofs, MPI_DOUBLE, MPI_SUM, self->referenceFieldList[field_I]->communicator );
- MPI_Allreduce( lErrorSq, gErrorSq, numDofs, MPI_DOUBLE, MPI_SUM, self->referenceFieldList[field_I]->communicator );
-
- for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
- self->gAnalyticSq[field_I][dof_I] = gAnalyticSq[dof_I];
- self->gErrorSq[field_I][dof_I] = gErrorSq[dof_I];
- self->gErrorNorm[field_I][dof_I] = sqrt( gErrorSq[dof_I] / gAnalyticSq[dof_I] );
-
- if( normalise ) {
- Journal_RPrintf( context->info, "%s - dof %d normalised global error: %.8e\n",
- self->numericFieldList[field_I]->name, dof_I, self->gErrorNorm[field_I][dof_I] );
- }
- else {
- Journal_RPrintf( context->info, "%s - dof %d global error: %.8e\n",
- self->numericFieldList[field_I]->name, dof_I, sqrt( self->gErrorSq[field_I][dof_I] ) );
- }
- }
- }
-
- if( self->appendToAnalysisFile ) {
- _FieldTest_DumpToAnalysisFile( self, analysisStream );
- Journal_RPrintf( analysisStream, "\n" );
- Stream_CloseAndFreeFile( analysisStream );
- }
-}
-
-void FieldTest_ElementErrReferenceFromField( void* fieldTest, Index field_I, Index lElement_I, double* elErrorSq, double* elNormSq ) {
- FieldTest* self = (FieldTest*) fieldTest;
- FeVariable* referenceField = self->referenceFieldList[field_I];
- FeVariable* numericField = self->numericFieldList[field_I];
- FeMesh* referenceMesh = referenceField->feMesh;
- FeMesh* elementMesh = self->elementMesh;
- Index constantElNode = lElement_I;
- double* coord = Mesh_GetVertex( self->constantMesh, constantElNode );
- unsigned nDims = Mesh_GetDimSize( referenceMesh );
- Index el_I, elementMeshElem;
- ElementType* elType;
- Swarm* intSwarm = self->integrationSwarm;
- Index cell_I;
- unsigned cellParticleCount;
- Index cParticle_I;
- IntegrationPoint* cParticle;
- double *xi, weight;
- double globalCoord[3];
- double detJac;
- double reference[9], numeric[9];
- Index numDofs = numericField->fieldComponentCount;
- Index dof_I;
-
- /* don't assume that the constant error field mesh & reference field mesh necessarily map 1:1 */
- Mesh_SearchElements( referenceMesh, coord, &el_I );
- Mesh_SearchElements( elementMesh, coord, &elementMeshElem );
- elType = FeMesh_GetElementType( elementMesh, elementMeshElem );
-
- cell_I = CellLayout_MapElementIdToCellId( intSwarm->cellLayout, el_I );
- cellParticleCount = intSwarm->cellParticleCountTbl[cell_I];
-
- for( cParticle_I = 0; cParticle_I < cellParticleCount; cParticle_I++ ) {
- cParticle = (IntegrationPoint*) Swarm_ParticleInCellAt( intSwarm, cell_I, cParticle_I );
- xi = cParticle->xi;
- weight = cParticle->weight;
-
- FeMesh_CoordLocalToGlobal( referenceMesh, el_I, xi, globalCoord );
- FieldVariable_InterpolateValueAt( referenceField, globalCoord, reference );
- FieldVariable_InterpolateValueAt( numericField, globalCoord, numeric );
-
- detJac = ElementType_JacobianDeterminant( elType, elementMesh, elementMeshElem, xi, nDims );
-
- for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
- elErrorSq[dof_I] += ( numeric[dof_I] - reference[dof_I] ) * ( numeric[dof_I] - reference[dof_I] )
- * weight * detJac;
- elNormSq[dof_I] += reference[dof_I] * reference[dof_I] * weight * detJac;
- }
- }
-}
-
-void FieldTest_ElementErrAnalyticFromField( void* fieldTest, Index field_I, Index lElement_I, double* elErrorSq, double* elNormSq ) {
- FieldTest* self = (FieldTest*) fieldTest;
- FeVariable* numericField = self->numericFieldList[field_I];
- FeMesh* elementMesh = self->elementMesh;
- Index constantElNode = lElement_I;
- double* coord = Mesh_GetVertex( self->constantMesh, constantElNode );
- unsigned nDims = Mesh_GetDimSize( elementMesh );
- Index el_I;
- ElementType* elType;
- Swarm* intSwarm = self->integrationSwarm;
- Index cell_I;
- unsigned cellParticleCount;
- Index cParticle_I;
- IntegrationPoint* cParticle;
- double *xi, weight;
- double globalCoord[3];
- double detJac;
- double analytic[9], numeric[9];
- Index numDofs = numericField->fieldComponentCount;
- Index dof_I;
- /* corresponding analytic solution function for this feVariable, as assigned in the plugin */
- FieldTest_AnalyticSolutionFunc* analyticSolution = self->_analyticSolutionList[self->analyticSolnForFeVarKey[field_I]];
-
- /* don't assume that the constant error field mesh & reference field mesh necessarily map 1:1 */
- Mesh_SearchElements( elementMesh, coord, &el_I );
- elType = FeMesh_GetElementType( elementMesh, el_I );
-
- cell_I = CellLayout_MapElementIdToCellId( intSwarm->cellLayout, el_I );
- cellParticleCount = intSwarm->cellParticleCountTbl[cell_I];
-
- for( cParticle_I = 0; cParticle_I < cellParticleCount; cParticle_I++ ) {
- cParticle = (IntegrationPoint*) Swarm_ParticleInCellAt( intSwarm, cell_I, cParticle_I );
- xi = cParticle->xi;
- weight = cParticle->weight;
-
- detJac = ElementType_JacobianDeterminant( elType, elementMesh, el_I, xi, nDims );
-
- FeMesh_CoordLocalToGlobal( elementMesh, el_I, xi, globalCoord );
- analyticSolution( self, globalCoord, analytic );
- FieldVariable_InterpolateValueAt( numericField, globalCoord, numeric );
-
- for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
- elErrorSq[dof_I] += ( numeric[dof_I] - analytic[dof_I] ) * ( numeric[dof_I] - analytic[dof_I] ) * weight * detJac;
- elNormSq[dof_I] += analytic[dof_I] * analytic[dof_I] * weight * detJac;
- }
- }
-}
-
-void FieldTest_ElementErrAnalyticFromSwarm( void* fieldTest, Index var_I, Index lElement_I, double* elErrorSq, double* elNormSq ) {
-}
-
-void FieldTest_ElementErrReferenceFromSwarm( void* fieldTest, Index var_I, Index lElement_I, double* elErrorSq, double* elNormSq ) {
-}
-
-/* the first index 'func_I' denotes the index of the function in the analytic solution list to be applied to calculate
- * the analytic field at index 'field_I' in the analytic field list.
- *
- * the analytic fields are in the same order as their numeric counterparts are read in from the XML */
-void FieldTest_AddAnalyticSolutionFuncToListAtIndex( void* fieldTest, Index func_I, FieldTest_AnalyticSolutionFunc* func, Index field_I ) {
- FieldTest* self = (FieldTest*) fieldTest;
-
- self->_analyticSolutionList[func_I] = func;
- self->analyticSolnForFeVarKey[field_I] = func_I;
-}
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FieldTest.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/FieldTest.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,1166 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: FieldTest.c 1095 2008-04-03 06:29:29Z JulianGiordani $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "types.h"
+#include "FieldTest.h"
+#include "FeVariable.h"
+#include "ElementType.h"
+#include "FeMesh.h"
+#include "OperatorFeVariable.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+const Type FieldTest_Type = "FieldTest";
+
+FieldTest* fieldTestSingleton = NULL;
+
+void* _FieldTest_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(FieldTest);
+ Type type = FieldTest_Type;
+ Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
+ Stg_Class_PrintFunction* _print = _FieldTest_Print;
+ Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _FieldTest_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _FieldTest_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _FieldTest_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _FieldTest_New( FIELDTEST_PASSARGS );
+}
+
+FieldTest* _FieldTest_New( FIELDTEST_DEFARGS )
+{
+ FieldTest* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(FieldTest) );
+ /* Construct using parent */
+ /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
+ /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
+ and so should be set to ZERO in any children of this class. */
+ nameAllocationType = NON_GLOBAL;
+
+ self = (FieldTest*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ self->normalise = False;
+ self->epsilon = 0.0001;
+ self->referenceSolnFromFile = False;
+
+ /* Assign singleton ptr */
+ fieldTestSingleton = self;
+ return self;
+}
+
+void _FieldTest_Delete( void* fieldTest ) {
+ FieldTest* self = (FieldTest*)fieldTest;
+
+ /*if( self->integrationSwarm ) Stg_Class_Delete( self->integrationSwarm );*/
+ /*
+ if( self->fieldCount ) {
+ Memory_Free( self->gAnalyticSq );
+ Memory_Free( self->gErrorSq );
+ Memory_Free( self->gError );
+ Memory_Free( self->gErrorNorm );
+
+ Memory_Free( self->analyticSolnForFeVarKey );
+ Memory_Free( self->_analyticSolutionList );
+ }
+
+ if( self->swarmVarCount ) {
+ Index swarmVar_I;
+ for( swarmVar_I = 0; swarmVar_I < self->swarmVarCount; swarmVar_I++ )
+ Memory_Free(self->swarmVarNameList[swarmVar_I]);
+ Memory_Free( self->swarmVarNameList );
+ }
+
+ Memory_Free( self->referenceSolnPath );
+ Memory_Free( self->expectedFileName );
+ Memory_Free( self->expectedFilePath );
+ Memory_Free( self->dumpExpectedFileName );
+ */
+
+ /* Stg_Class_Delete parent*/
+ _Stg_Component_Delete( self );
+}
+
+void _FieldTest_Print( void* fieldTest, Stream* stream ) {
+ FieldTest* self = (FieldTest*)fieldTest;
+
+ /* Print parent */
+ _Stg_Component_Print( self, stream );
+
+}
+
+void* _FieldTest_Copy( const void* fieldTest, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ abort();
+ return NULL;
+}
+
+void _FieldTest_AssignFromXML( void* fieldTest, Stg_ComponentFactory* cf, void* data ) {
+ FieldTest* self = (FieldTest*)fieldTest;
+ Dictionary* dict = cf->rootDict;
+ Dictionary_Entry_Value* dictEntryVal = Dictionary_Get( dict, (Dictionary_Entry_Key)"pluginData" );
+ Dictionary* pluginDict = Dictionary_Entry_Value_AsDictionary( dictEntryVal );
+ /* get the pluginDict from the xml, needed for rejig */
+ Dictionary* pluginDict2 = Codelet_GetPluginDictionary( self, cf->rootDict );
+ Dictionary_Entry_Value* fieldList;
+ Dictionary_Entry_Value* swarmVarList = Dictionary_Get( dict, (Dictionary_Entry_Key)"NumericSwarmVariableNames" );
+ FieldVariable_Register* fV_Register;
+ Index feVariable_I/*, referenceFieldCount*/;
+ Index swarmVar_I;
+ char* fieldName;
+ Hook* generateErrorFields;
+ Hook* physicsTestHook;
+ Stream* errStream = Journal_Register( Error_Type, (Name)"FieldTests" );
+
+ Journal_Firewall( pluginDict != NULL , errStream, "\nError in %s: No pluginData xml was defined ... aborting\n", __func__ );
+
+ self->context = Stg_ComponentFactory_ConstructByName( cf, Dictionary_GetString( pluginDict2, (Dictionary_Entry_Key)"Context" ), DomainContext, False, data );
+ if( !self->context )
+ self->context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", DomainContext, True, data );
+
+ fV_Register = self->context->fieldVariable_Register;
+
+ fieldList = Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"NumericFields" );
+ self->fieldCount = fieldList ? Dictionary_Entry_Value_GetCount( fieldList ) / 2 : 0;
+
+ if( self->fieldCount ) {
+ self->numericFieldList = Memory_Alloc_Array( FeVariable*, self->fieldCount, "numeric fields" );
+ self->referenceFieldList = Memory_Alloc_Array( FeVariable*, self->fieldCount, "reference fields" );
+ self->errorFieldList = Memory_Alloc_Array( FeVariable*, self->fieldCount, "error fields" );
+ self->referenceMagFieldList = Memory_Alloc_Array( OperatorFeVariable*, self->fieldCount, "reference field magnitudes" );
+ self->errorMagFieldList = Memory_Alloc_Array( OperatorFeVariable*, self->fieldCount, "error field magnitudes" );
+
+ if( !self->referenceSolnFromFile ) {
+ self->analyticSolnForFeVarKey = Memory_Alloc_Array( unsigned, self->fieldCount,
+ "analytic solution index for ith feVariable" );
+ }
+#if 0
+ else {
+ fieldList = Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"ReferenceFields" );
+ referenceFieldCount = fieldList ? Dictionary_Entry_Value_GetCount( fieldList ) : assert(0);
+
+ for( feVariable_I = 0; feVariable_I < referenceFieldCount; feVariable_I++ ) {
+ referenceSolnFileList
+ }
+ }
+#endif
+
+ for( feVariable_I = 0; feVariable_I < self->fieldCount; feVariable_I++ ) {
+ /* read in the FeVariable from the tuple */
+ fieldName = ( fieldList ) ?
+ StG_Strdup( Dictionary_Entry_Value_AsString( Dictionary_Entry_Value_GetElement( fieldList, 2 * feVariable_I ) ) ):
+ StG_Strdup( Dictionary_GetString( pluginDict, (Dictionary_Entry_Key)"FeVariable" ) );
+
+ self->numericFieldList[feVariable_I] = (FeVariable* ) FieldVariable_Register_GetByName( fV_Register, fieldName );
+
+ if( !self->numericFieldList[feVariable_I] ) {
+ /* if the numericFieldList[x] can't be found in register
+ and can't be constructed through the factory then
+ skip this entry and take one off self->fieldCount
+ needed for simple regression test
+ */
+ self->numericFieldList[feVariable_I] = Stg_ComponentFactory_ConstructByName( cf, (Name)fieldName, FeVariable, False, data );
+ if( self->numericFieldList[feVariable_I]==NULL ) {
+ self->fieldCount--;
+ continue;
+ }
+ }
+
+ /* ...and the corresponding analytic function ptr index - these have to be consistent with how they're ordered in the plugin */
+ self->analyticSolnForFeVarKey[feVariable_I] = Dictionary_Entry_Value_AsUnsignedInt(
+ Dictionary_Entry_Value_GetElement( fieldList, 2 * feVariable_I + 1 ) );
+ Memory_Free( fieldName );
+ }
+ }
+
+ self->integrationSwarm = (Swarm*)LiveComponentRegister_Get( cf->LCRegister, Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"IntegrationSwarm" ) ) );
+ self->constantMesh = (FeMesh* )LiveComponentRegister_Get( cf->LCRegister, Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"ConstantMesh" ) ) );
+ self->elementMesh = (FeMesh* )LiveComponentRegister_Get( cf->LCRegister, Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"ElementMesh" ) ) );
+
+ self->swarmVarCount = swarmVarList ? Dictionary_Entry_Value_GetCount( swarmVarList ) : 0;
+ if( self->swarmVarCount ) {
+ self->swarmVarNameList = Memory_Alloc_Array( Name, self->swarmVarCount, "numeric swarm variable names" );
+
+ for( swarmVar_I = 0; swarmVar_I < self->swarmVarCount; swarmVar_I++ ) {
+ self->swarmVarNameList[swarmVar_I] = ( swarmVarList ) ?
+ StG_Strdup( Dictionary_Entry_Value_AsString( Dictionary_Entry_Value_GetElement( swarmVarList, swarmVar_I ) ) ):
+ StG_Strdup( Dictionary_GetString( pluginDict, (Dictionary_Entry_Key)"SwarmVariable" ) );
+ }
+ }
+
+ self->referenceSolnPath = StG_Strdup( Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"referenceSolutionFilePath" ) ) );
+ self->normalise = Dictionary_Entry_Value_AsBool( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"normaliseByAnalyticSolution" ) );
+ self->epsilon = Dictionary_Entry_Value_AsDouble( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"epsilon" ) );
+ self->testTimestep = Dictionary_GetInt_WithDefault( pluginDict, (Dictionary_Entry_Key)"testTimestep", 0 );
+ self->referenceSolnFromFile = Dictionary_Entry_Value_AsBool( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"useReferenceSolutionFromFile" ) );
+ self->appendToAnalysisFile = Dictionary_GetBool_WithDefault( pluginDict, (Dictionary_Entry_Key)"appendToAnalysisFile", False ) ;
+
+ /* for the physics test */
+ self->expectedFileName = StG_Strdup( Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"expectedFileName" ) ) );
+ self->expectedFilePath = StG_Strdup( Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"expectedFilePath" ) ) );
+ self->dumpExpectedFileName = StG_Strdup( Dictionary_Entry_Value_AsString( Dictionary_Get( pluginDict, (Dictionary_Entry_Key)"expectedOutputFileName" ) ) );
+ self->expectedPass = False;
+
+ /* set up the entry point */
+ generateErrorFields = Hook_New( "Generate error fields hook", (void*)FieldTest_GenerateErrFields, self->name );
+ _EntryPoint_AppendHook( Context_GetEntryPoint( self->context, AbstractContext_EP_FrequentOutput ), generateErrorFields );
+
+ /* entry point for the fisix test func */
+ if( strlen(self->expectedFileName) > 1 ) {
+ physicsTestHook = Hook_New( "Physics test hook", (void*)FieldTest_EvaluatePhysicsTest, self->name );
+ _EntryPoint_AppendHook( Context_GetEntryPoint( self->context, AbstractContext_EP_FrequentOutput ), physicsTestHook );
+ }
+
+ self->LCRegister = cf->LCRegister;
+}
+
+void _FieldTest_Build( void* fieldTest, void* data ) {
+ FieldTest* self = (FieldTest*) fieldTest;
+ Index field_I;
+ //Index swarm_I;
+
+ if( self->constantMesh ) Stg_Component_Build( self->constantMesh, data, False );
+
+ for( field_I = 0; field_I < self->fieldCount; field_I++ ) {
+ FieldTest_BuildAnalyticField( self, field_I );
+ FieldTest_BuildErrField( self, field_I );
+
+ Stg_Component_Build( self->numericFieldList[field_I], data, False );
+ Stg_Component_Build( self->errorFieldList[field_I], data, False );
+
+ Stg_Component_Build( self->referenceFieldList[field_I], data, False );
+ Stg_Component_Build( self->errorFieldList[field_I], data, False );
+ }
+
+ /*for( swarm_I = 0; swarm_I < self->swarmCount; swarm_I++ ) {
+ FieldTest_BuildAnalyticSwarm( self->referenceMesh, self->numericSwarmList[swarm_I],
+ self->context, &self->referenceSwarmList[swarm_I] );
+ FieldTest_BuildErrSwarm( self->constantMesh, self->numericSwarmList[swarm_I],
+ self->context, &self->referenceSwarmList[swarm_I] );
+ }*/
+
+ if( self->fieldCount ) {
+ self->gAnalyticSq = Memory_Alloc_2DArray( double, self->fieldCount, 9, (Name)"global reference solution squared" );
+ self->gErrorSq = Memory_Alloc_2DArray( double, self->fieldCount, 9, (Name)"global L2 error squared" );
+ self->gError = Memory_Alloc_2DArray( double, self->fieldCount, 9, (Name)"global L2 error" );
+ self->gErrorNorm = Memory_Alloc_2DArray( double, self->fieldCount, 9, (Name)"global L2 error normalised" );
+ }
+}
+
+void _FieldTest_Initialise( void* fieldTest, void* data ) {
+ FieldTest* self = (FieldTest*) fieldTest;
+ Index field_I;
+ FILE* expected_fp;
+ char* expectedFilename;
+ int num_time_steps;
+ int dof_i, dim_i;
+ int expected_i = 0;
+
+ for( field_I = 0; field_I < self->fieldCount; field_I++ ) {
+ Stg_Component_Initialise( self->numericFieldList[field_I], data, False );
+ Stg_Component_Initialise( self->errorFieldList[field_I], data, False );
+ Stg_Component_Initialise( self->referenceFieldList[field_I], data, False );
+ if( self->referenceMagFieldList[field_I] )
+ Stg_Component_Initialise( self->referenceMagFieldList[field_I], data, False );
+ if( self->errorMagFieldList[field_I] )
+ Stg_Component_Initialise( self->errorMagFieldList[field_I], data, False );
+ }
+
+ /* load the reference solution from file if req'd */
+ if( self->referenceSolnFromFile ) {
+ char *referenceSolnFileName;
+ for( field_I = 0; field_I < self->fieldCount; field_I++ ) {
+ /* create the name of the reference file, the apprendix is handled by FieldTest_LoadReferenceSolutionFromFile */
+ referenceSolnFileName = Memory_Alloc_Array_Unnamed( char, strlen((char*)self->referenceSolnPath) + 1 + strlen((char*)self->numericFieldList[field_I]->name) + 1 + 5 + strlen(".h5x\0") );
+#ifdef READ_HDF5
+ sprintf( referenceSolnFileName, "%s/%s.%.5d.h5", self->referenceSolnPath, self->numericFieldList[field_I]->name, self->testTimestep );
+#else
+ sprintf( referenceSolnFileName, "%s/%s.%.5d.dat", self->referenceSolnPath, self->numericFieldList[field_I]->name, self->testTimestep );
+#endif
+ FeVariable_ReadFromFile( self->referenceFieldList[field_I], referenceSolnFileName );
+
+ /* FieldTest_LoadReferenceSolutionFromFile( self->referenceFieldList[field_I],
+ referenceSolnFileName,
+ self->referenceSolnPath, self->context ); */
+ Memory_Free( referenceSolnFileName );
+ }
+ }
+ /* calculate the analytic solutions */
+ else {
+ for( field_I = 0; field_I < self->fieldCount; field_I++ ) {
+ FieldTest_CalculateAnalyticSolutionForField( self, field_I );
+ FeVariable_ZeroField( self->errorFieldList[field_I] );
+ }
+ }
+
+ if( strlen(self->expectedFileName) > 1 && strcmp( self->expectedFileName, "false" ) ) {
+ /* if the self->expectedFileName == False then don't go here */
+ expectedFilename = Memory_Alloc_Array_Unnamed( char, strlen(self->expectedFilePath) + strlen(self->expectedFileName) + 1 );
+ sprintf( expectedFilename, "%s%s", self->expectedFilePath, self->expectedFileName );
+
+ expected_fp = fopen( expectedFilename, "r" );
+
+ fscanf( expected_fp, "%d %d", &self->expectedDofs, &num_time_steps );
+
+ self->expected = Memory_Alloc_Array_Unnamed( Event, num_time_steps + 1 );
+ self->numeric = Memory_Alloc_Array_Unnamed( Event, self->context->maxTimeSteps + 1 );
+ self->tolerance = Memory_Alloc_Array_Unnamed( Event, num_time_steps + 1 );
+
+ while ( !feof( expected_fp ) ) {
+ fscanf( expected_fp, "%lf ", &self->expected[expected_i].time );
+
+ for( dim_i = 0; dim_i < self->context->dim; dim_i++ )
+ fscanf( expected_fp, "%lf ", &self->expected[expected_i].place[dim_i] );
+
+ for( dof_i = 0; dof_i < self->expectedDofs; dof_i++ )
+ fscanf( expected_fp, "%lf ", &self->expected[expected_i].value[dof_i] );
+
+ fscanf( expected_fp, "%lf ", &self->tolerance[expected_i].time );
+
+ for( dim_i = 0; dim_i < self->context->dim; dim_i++ )
+ fscanf( expected_fp, "%lf ", &self->tolerance[expected_i].place[dim_i] );
+
+ for( dof_i = 0; dof_i < self->expectedDofs; dof_i++ )
+ fscanf( expected_fp, "%lf ", &self->tolerance[expected_i].value[dof_i] );
+
+ expected_i++;
+ }
+ fclose( expected_fp );
+
+ Memory_Free( expectedFilename );
+ }
+}
+
+void FieldTest_CalculateAnalyticSolutionForField( void* fieldTest, Index field_I ) {
+ FieldTest* self = (FieldTest*) fieldTest;
+ FeVariable* analyticField = self->referenceFieldList[field_I];
+ FeMesh* analyticMesh = analyticField->feMesh;
+ FieldTest_AnalyticSolutionFunc* analyticSolution;
+ Index lNode_I;
+ Index lMeshSize = Mesh_GetLocalSize( analyticMesh, MT_VERTEX );
+ double* coord;
+ double* value;
+
+ analyticSolution = self->_analyticSolutionList[self->analyticSolnForFeVarKey[field_I]];
+ value = Memory_Alloc_Array_Unnamed( double, analyticField->fieldComponentCount );
+ memset( value, 0, analyticField->fieldComponentCount * sizeof(double) );
+
+ for( lNode_I = 0; lNode_I < lMeshSize; lNode_I++ ) {
+ coord = Mesh_GetVertex( analyticMesh, lNode_I );
+ analyticSolution( self, coord, value );
+ FeVariable_SetValueAtNode( analyticField, lNode_I, value );
+ }
+
+ Memory_Free( value );
+}
+
+void _FieldTest_Execute( void* fieldTest, void* data ) {
+}
+
+void _FieldTest_Destroy( void* fieldTest, void* data ) {
+ FieldTest* self = (FieldTest*) fieldTest;
+
+ if( self->fieldCount ) {
+ Memory_Free( self->numericFieldList );
+ Memory_Free( self->referenceFieldList );
+ Memory_Free( self->errorFieldList );
+ Memory_Free( self->referenceMagFieldList );
+ Memory_Free( self->errorMagFieldList );
+
+ Memory_Free( self->gAnalyticSq );
+ Memory_Free( self->gErrorSq );
+ Memory_Free( self->gError );
+ Memory_Free( self->gErrorNorm );
+ }
+
+ if( strlen(self->expectedFileName) > 1 ) {
+ Memory_Free( self->expected );
+ Memory_Free( self->numeric );
+ Memory_Free( self->tolerance );
+ }
+ if( !self->referenceSolnFromFile ) {
+ Memory_Free( self->analyticSolnForFeVarKey );
+ Memory_Free( self->_analyticSolutionList );
+ }
+
+ Stg_Component_Destroy( self, data, False );
+}
+
+void FieldTest_BuildAnalyticField( void* fieldTest, Index field_I ) {
+ FieldTest* self = (FieldTest*) fieldTest;
+ FeVariable* numericField = self->numericFieldList[field_I];
+ FeMesh* referenceMesh = numericField->feMesh;
+ DomainContext* context = self->context;
+ Variable_Register* variable_Register = context->variable_Register;
+ char* tmpName;
+ Dof_Index componentsCount = numericField->fieldComponentCount;
+ char* varName[9];
+ unsigned var_I;
+ unsigned node_I;
+ Variable* variable;
+ Variable* baseVariable = NULL;
+ DofLayout* referenceDofLayout = NULL;
+
+ unsigned nDomainVerts = Mesh_GetDomainSize( referenceMesh, MT_VERTEX );
+ static double* arrayPtr;
+
+ tmpName = Stg_Object_AppendSuffix( numericField, (Name)"AnalyticVariable" );
+
+ if( componentsCount == 1 ) {
+ arrayPtr = Memory_Alloc_Array_Unnamed( double, nDomainVerts );
+ baseVariable = Variable_NewScalar( tmpName, (AbstractContext*)self->context, Variable_DataType_Double, (Index*)&nDomainVerts, NULL, (void**)&arrayPtr, variable_Register );
+ }
+ else {
+ for( var_I = 0; var_I < componentsCount; var_I++ )
+ Stg_asprintf( &varName[var_I], "%s-Component-%d", tmpName, var_I );
+
+ arrayPtr = Memory_Alloc_Array_Unnamed( double, nDomainVerts * componentsCount );
+ baseVariable = Variable_NewVector( tmpName,
+ (AbstractContext*)self->context,
+ Variable_DataType_Double,
+ componentsCount,
+ &nDomainVerts,
+ NULL,
+ (void**)&arrayPtr,
+ variable_Register,
+ varName[0], varName[1], varName[2],
+ varName[3], varName[4], varName[5],
+ varName[6], varName[7], varName[8] );
+ }
+ Memory_Free( tmpName );
+
+ tmpName = Stg_Object_AppendSuffix( numericField, (Name)"AnalyticDofLayout" );
+
+ referenceDofLayout = DofLayout_New( tmpName, self->context, variable_Register, Mesh_GetDomainSize( referenceMesh, MT_VERTEX ), referenceMesh );
+
+ if( componentsCount == 1 )
+ DofLayout_AddAllFromVariableArray( referenceDofLayout, 1, &baseVariable );
+ else {
+ for( var_I = 0; var_I < componentsCount; var_I++ ) {
+ variable = Variable_Register_GetByName( variable_Register, varName[var_I] );
+ variable->arrayPtrPtr = &baseVariable->arrayPtr;
+
+ for( node_I = 0; node_I < Mesh_GetDomainSize( referenceMesh, MT_VERTEX ); node_I++ )
+ DofLayout_AddDof_ByVarName( referenceDofLayout, varName[var_I], node_I );
+
+ Memory_Free( varName[var_I] );
+ }
+
+ }
+
+ Stg_Component_Build( referenceDofLayout, NULL, False );
+ Stg_Component_Initialise( referenceDofLayout, NULL, False );
+
+ Memory_Free( tmpName );
+
+ tmpName = Stg_Object_AppendSuffix( numericField, (Name)"Analytic" );
+
+ self->referenceFieldList[field_I] = FeVariable_New( tmpName, self->context, referenceMesh, referenceMesh, referenceDofLayout, NULL, NULL, NULL,
+ Mesh_GetDimSize( referenceMesh ), False, False, False, context->fieldVariable_Register );
+ self->referenceFieldList[field_I]->context = context;
+ /* so that the eqnation numbers don't get built for this guy */
+ self->referenceFieldList[field_I]->buildEqNums = False;
+
+ if( componentsCount > Mesh_GetDimSize( referenceMesh ) ) {
+ /* we're dealing with a tensor, so use invariant */
+ tmpName = Stg_Object_AppendSuffix( self->referenceFieldList[field_I], (Name)"Invariant" );
+ self->referenceMagFieldList[field_I] = OperatorFeVariable_NewUnary( tmpName, self->context, self->referenceFieldList[field_I], "SymmetricTensor_Invariant" );
+ self->referenceMagFieldList[field_I]->context = context;
+ } else {
+ /* we're dealing with a vector, so use magnitude */
+ tmpName = Stg_Object_AppendSuffix( self->referenceFieldList[field_I], (Name)"Magnitude" );
+ self->referenceMagFieldList[field_I] = OperatorFeVariable_NewUnary( tmpName, self->context, self->referenceFieldList[field_I], "Magnitude" );
+ self->referenceMagFieldList[field_I]->context = context;
+ }
+
+ Memory_Free( tmpName );
+ Stg_Component_Build( self->referenceMagFieldList[field_I], context, False );
+ self->referenceMagFieldList[field_I]->_operator = Operator_NewFromName( self->referenceMagFieldList[field_I]->operatorName,
+ self->referenceFieldList[field_I]->fieldComponentCount, context->dim );
+ self->referenceMagFieldList[field_I]->fieldComponentCount = self->referenceMagFieldList[field_I]->_operator->resultDofs;
+ _OperatorFeVariable_SetFunctions( self->referenceMagFieldList[field_I] );
+
+ LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) baseVariable );
+ LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) referenceDofLayout );
+ LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) self->referenceFieldList[field_I] );
+ LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) self->referenceMagFieldList[field_I] );
+}
+
+void FieldTest_BuildErrField( void* fieldTest, Index field_I ) {
+ FieldTest* self = (FieldTest*) fieldTest;
+ FeMesh* constantMesh = self->constantMesh;
+ FeVariable* numericField = self->numericFieldList[field_I];
+ DomainContext* context = self->context;
+ Variable_Register* variable_Register = context->variable_Register;
+ char* tmpName;
+ Dof_Index componentsCount = numericField->fieldComponentCount;
+ char* varName[9];
+ unsigned var_I;
+ unsigned node_I;
+ Variable* variable;
+ Variable* baseVariable = NULL;
+ DofLayout* errorDofLayout = NULL;
+ unsigned nDomainVerts = Mesh_GetDomainSize( constantMesh, MT_VERTEX );
+ static void* arrayPtr;
+
+ tmpName = Stg_Object_AppendSuffix( numericField, (Name)"ErrorVariable" );
+
+ if( componentsCount == 1 ) {
+ arrayPtr = Memory_Alloc_Array_Unnamed( double, nDomainVerts );
+ baseVariable = Variable_NewScalar( tmpName, (AbstractContext*)self->context, Variable_DataType_Double, (Index*)&nDomainVerts, NULL, &arrayPtr, variable_Register );
+ }
+ else {
+ for( var_I = 0; var_I < componentsCount; var_I++ )
+ Stg_asprintf( &varName[var_I], "%s-Component-%d", tmpName, var_I );
+
+ arrayPtr = Memory_Alloc_Array_Unnamed( double, nDomainVerts * componentsCount );
+ baseVariable = Variable_NewVector( tmpName, (AbstractContext*)self->context, Variable_DataType_Double, componentsCount, &nDomainVerts,
+ NULL, (void**)&arrayPtr, variable_Register,
+ varName[0], varName[1], varName[2], varName[3], varName[4],
+ varName[5], varName[6], varName[7], varName[8] );
+ }
+ Memory_Free( tmpName );
+
+ tmpName = Stg_Object_AppendSuffix( numericField, (Name)"ErrorDofLayout" );
+
+ errorDofLayout = DofLayout_New( tmpName, self->context, variable_Register, Mesh_GetDomainSize( constantMesh, MT_VERTEX ), constantMesh );
+
+ if( componentsCount == 1 )
+ DofLayout_AddAllFromVariableArray( errorDofLayout, 1, &baseVariable );
+ else {
+ for( var_I = 0; var_I < componentsCount; var_I++ ) {
+ variable = Variable_Register_GetByName( variable_Register, varName[var_I] );
+ variable->arrayPtrPtr = &baseVariable->arrayPtr;
+
+ for( node_I = 0; node_I < Mesh_GetDomainSize( constantMesh, MT_VERTEX ); node_I++ )
+ DofLayout_AddDof_ByVarName( errorDofLayout, varName[var_I], node_I );
+
+ Memory_Free( varName[var_I] );
+ }
+
+ //errorDofLayout->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, componentsCount );
+ //errorDofLayout->baseVariables[0] = baseVariable;
+ }
+
+ Stg_Component_Build( errorDofLayout, NULL, False );
+ Stg_Component_Initialise( errorDofLayout, NULL, False );
+
+ Memory_Free( tmpName );
+
+ tmpName = Stg_Object_AppendSuffix( numericField, (Name)"Error" );
+
+ self->errorFieldList[field_I] = FeVariable_New( tmpName, self->context, constantMesh, constantMesh, errorDofLayout, NULL, NULL, NULL,
+ Mesh_GetDimSize( constantMesh ), False, False, False, context->fieldVariable_Register );
+ /* so that the eqnation numbers don't get built for this guy */
+ self->errorFieldList[field_I]->buildEqNums = False;
+
+ if( componentsCount > Mesh_GetDimSize( constantMesh ) ) {
+ /* we're dealing with a tensor, so use invariant */
+ tmpName = Stg_Object_AppendSuffix( self->errorFieldList[field_I], (Name)"Invariant" );
+ self->errorMagFieldList[field_I] = OperatorFeVariable_NewUnary( tmpName, self->context, self->errorFieldList[field_I], "SymmetricTensor_Invariant" );
+ self->errorMagFieldList[field_I]->context = context;
+ } else {
+ /* we're dealing with a vector, so use magnitude */
+ tmpName = Stg_Object_AppendSuffix( self->errorFieldList[field_I], (Name)"Magnitude" );
+ self->errorMagFieldList[field_I] = OperatorFeVariable_NewUnary( tmpName, self->context, self->errorFieldList[field_I], "Magnitude" );
+ self->errorMagFieldList[field_I]->context = context;
+ }
+ Memory_Free( tmpName );
+ Stg_Component_Build( self->errorMagFieldList[field_I], context, False );
+ self->errorMagFieldList[field_I]->_operator = Operator_NewFromName( self->errorMagFieldList[field_I]->operatorName,
+ self->errorFieldList[field_I]->fieldComponentCount, context->dim );
+ self->errorMagFieldList[field_I]->fieldComponentCount = self->errorMagFieldList[field_I]->_operator->resultDofs;
+ _OperatorFeVariable_SetFunctions( self->errorMagFieldList[field_I] );
+
+ LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) baseVariable );
+ LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) errorDofLayout );
+ LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) self->errorFieldList[field_I] );
+ LiveComponentRegister_Add( context->CF->LCRegister, (Stg_Component*) self->errorMagFieldList[field_I] );
+}
+
+void FieldTest_LoadReferenceSolutionFromFile( FeVariable* feVariable, Name referenceSolnName, Name referenceSolnPath, DomainContext* context ) {
+ FeMesh* feMesh = feVariable->feMesh;
+ char* filename;
+ unsigned nx = 0, ny = 0, nz = 0, total;
+ unsigned lineNum = 0;
+ double resolution[3];
+ double* coord;
+ Index node_I, dim_I;
+ unsigned increments[3];
+ double value[3];
+ unsigned lineNum0;
+ unsigned dofAtEachNodeCount, dof_I;
+ unsigned meshSize = Mesh_GetLocalSize( feMesh, MT_VERTEX );
+ unsigned nDims = Mesh_GetDimSize( feMesh );
+ double vertex0[3], coordPrime[3];
+ double Ni[27], values[27][3];
+ unsigned shapeFunc_I;
+ double *posx, *posy, *posz;
+ double **variables;
+ unsigned numShapeFuncs = ( nDims == 3 ) ? 27 : 9;
+ double xi, eta, zeta;
+ double a0, b0, c0;
+ double a1, b1, c1;
+ double a2, b2, c2;
+ double m0, m1, m2, m3, m4, m5, m6;
+#ifdef READ_HDF5
+ hid_t inputFile;
+ hid_t dataSet, memSpace, dataSpace;
+ hsize_t start[2], count[2], hSize;
+#endif
+ int sizes[3];
+ double* data;
+ int dataPos = 0;
+ double nodeDummy;
+
+ Stg_Component_Initialise( feMesh, context, False );
+ Stg_Component_Initialise( feVariable, context, False );
+
+ dofAtEachNodeCount = feVariable->fieldComponentCount;
+ /* . h5 \0 */
+ filename = Memory_Alloc_Array_Unnamed( char, strlen(referenceSolnPath) + strlen(referenceSolnName) + 1 + 2 + 1 );
+ sprintf( filename, "%s%s.h5", referenceSolnPath, referenceSolnName );
+#ifdef READ_HDF5
+ inputFile = H5Fopen( filename, H5F_ACC_RDONLY, H5P_DEFAULT );
+#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ dataSet = H5Dopen( inputFile, "/size" );
+#else
+ dataSet = H5Dopen2( inputFile, "/size", H5P_DEFAULT );
+#endif
+ H5Dread( dataSet, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, sizes );
+ nx = sizes[0];
+ ny = sizes[1];
+ total = nx * ny;
+ if( nDims == 3 ) {
+ nz = sizes[2];
+ total *= nz;
+ }
+ H5Dclose( dataSet );
+
+ posx = Memory_Alloc_Array_Unnamed( double, total );
+ posy = Memory_Alloc_Array_Unnamed( double, total );
+ if( nDims == 3 ) posz = Memory_Alloc_Array_Unnamed( double, total );
+ variables = Memory_Alloc_2DArray_Unnamed( double, total, dofAtEachNodeCount );
+ data = Memory_Alloc_Array_Unnamed( double, nDims + dofAtEachNodeCount );
+
+ hSize = nDims + dofAtEachNodeCount;
+ memSpace = H5Screate_simple( 1, &hSize, NULL );
+ H5Sselect_all( memSpace );
+#if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ dataSet = H5Dopen( inputFile, "/data" );
+#else
+ dataSet = H5Dopen2( inputFile, "/data", H5P_DEFAULT );
+#endif
+ dataSpace = H5Dget_space( dataSet );
+ start[0] = 0;
+ start[1] = 0;
+ count[0] = 1;
+ count[1] = nDims + dofAtEachNodeCount;
+ H5Sselect_hyperslab( dataSpace, H5S_SELECT_SET, start, NULL, count, NULL );
+ for( lineNum = 0; lineNum < total; lineNum++ ) {
+ start[0] = lineNum;
+ H5Sselect_hyperslab( dataSpace, H5S_SELECT_SET, start, NULL, count, NULL );
+ H5Dread( dataSet, H5T_NATIVE_DOUBLE, memSpace, dataSpace, H5P_DEFAULT, data );
+
+ dataPos = 0;
+ nodeDummy = data[dataPos++];
+ posx[lineNum] = data[dataPos++];
+ posy[lineNum] = data[dataPos++];
+ if( nDims == 3 ) posz[lineNum] = data[dataPos++];
+
+ for( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ )
+ variables[lineNum][dof_I] = data[dataPos++];
+ }
+
+ H5Sclose( memSpace );
+ H5Sclose( dataSpace );
+ H5Dclose( dataSet );
+#endif
+ Memory_Free( data );
+
+ resolution[0] = posx[1] - posx[0];
+ resolution[1] = posy[nx] - posy[0];
+ if( nDims == 3 ) resolution[2] = posz[nx*ny] - posz[0];
+
+ for( node_I = 0; node_I < meshSize; node_I++ ) {
+ coord = Mesh_GetVertex( feMesh, node_I );
+ increments[0] = (unsigned)( ( coord[0] - posx[0] ) / resolution[0] );
+ increments[1] = (unsigned)( ( coord[1] - posy[0] ) / resolution[1] );
+ if( nDims == 3 ) increments[2] = (unsigned)( ( coord[2] - posz[0] ) / resolution[2] );
+
+ for( dim_I = 0; dim_I < nDims; dim_I++ )
+ if( increments[dim_I] % 2 == 1 )
+ increments[dim_I]--;
+ if( increments[0] >= nx - 2 )
+ increments[0] = nx - 3;
+ if( increments[1] >= ny - 2 )
+ increments[1] = ny - 3;
+ if( nDims == 3 && increments[2] >= nz - 2 )
+ increments[2] = nz - 3;
+
+ lineNum0 = increments[0] + nx * increments[1];
+ if( nDims == 3 ) lineNum0 += nx * ny * increments[2];
+ if( lineNum0 >= total )
+ Journal_Printf( context->info, "interpolation error: node value: %d resolution size: %d\n", lineNum0, total );
+
+ vertex0[0] = posx[lineNum0];
+ vertex0[1] = posy[lineNum0];
+ if( nDims == 3 ) vertex0[2] = posz[lineNum0];
+
+ /* for quadratic elements the resolution is twice the distance between the nodes */
+ for( dim_I = 0; dim_I < nDims; dim_I++ )
+ coordPrime[dim_I] = ( coord[dim_I] - vertex0[dim_I] ) / resolution[dim_I] - 1.0;
+
+ /* assign the shape functions & interpolate quadratically */
+ if( nDims == 2 ) {
+ xi = coordPrime[0]; eta = coordPrime[1];
+ a0 = xi - 1.0; b0 = eta - 1.0;
+ a1 = 1.0 - xi * xi; b1 = 1.0 - eta * eta;
+ a2 = xi + 1.0; b2 = eta + 1.0;
+ m0 = 0.5 * xi; m1 = 0.5 * eta; m2 = 0.25 * xi * eta;
+
+ Ni[0] = m2 * a0 * b0; Ni[1] = m1 * a1 * b0; Ni[2] = m2 * a2 * b0;
+ Ni[3] = m0 * a0 * b1; Ni[4] = a1 * b1; Ni[5] = m0 * a2 * b1;
+ Ni[6] = m2 * a0 * b2; Ni[7] = m1 * a1 * b2; Ni[8] = m2 * a2 * b2;
+
+ for( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
+ values[0][dof_I] = variables[lineNum0][dof_I];
+ values[1][dof_I] = variables[lineNum0+1][dof_I];
+ values[2][dof_I] = variables[lineNum0+2][dof_I];
+ values[3][dof_I] = variables[lineNum0+nx][dof_I];
+ values[4][dof_I] = variables[lineNum0+nx+1][dof_I];
+ values[5][dof_I] = variables[lineNum0+nx+2][dof_I];
+ values[6][dof_I] = variables[lineNum0+(2*nx)][dof_I];
+ values[7][dof_I] = variables[lineNum0+(2*nx)+1][dof_I];
+ values[8][dof_I] = variables[lineNum0+(2*nx)+2][dof_I];
+
+ value[dof_I] = 0.0;
+ for( shapeFunc_I = 0; shapeFunc_I < numShapeFuncs; shapeFunc_I++ )
+ value[dof_I] += Ni[shapeFunc_I] * values[shapeFunc_I][dof_I];
+ }
+ }
+ else {
+ xi = coordPrime[0]; eta = coordPrime[1]; zeta = coordPrime[2];
+ a0 = xi - 1.0; b0 = eta - 1.0; c0 = zeta - 1.0;
+ a1 = 1.0 - xi * xi; b1 = 1.0 - eta * eta; c1 = 1.0 - zeta * zeta;
+ a2 = xi + 1.0; b2 = eta + 1.0; c2 = zeta + 1.0;
+ m0 = 0.5 * xi; m1 = 0.5 * eta; m2 = 0.5 * zeta;
+ m3 = 0.25 * xi * eta; m4 = 0.25 * xi * zeta; m5 = 0.25 * eta * zeta;
+ m6 = 0.125 * xi * eta * zeta;
+
+ Ni[0] = m6 * a0 * b0 * c0; Ni[1] = m5 * a1 * b0 * c0; Ni[2] = m6 * a2 * b0 * c0;
+ Ni[3] = m4 * a0 * b1 * c0; Ni[4] = m2 * a1 * b1 * c0; Ni[5] = m4 * a2 * b1 * c0;
+ Ni[6] = m6 * a0 * b2 * c0; Ni[7] = m5 * a1 * b2 * c0; Ni[8] = m6 * a2 * b2 * c0;
+
+ Ni[9] = m3 * a0 * b0 * c1; Ni[10] = m1 * a1 * b0 * c1; Ni[11] = m3 * a2 * b0 * c1;
+ Ni[12] = m0 * a0 * b1 * c1; Ni[13] = a1 * b1 * c1; Ni[14] = m0 * a2 * b1 * c1;
+ Ni[15] = m3 * a0 * b2 * c1; Ni[16] = m1 * a1 * b2 * c1; Ni[17] = m3 * a2 * b2 * c1;
+
+ Ni[18] = m6 * a0 * b0 * c2; Ni[19] = m5 * a1 * b0 * c2; Ni[20] = m6 * a2 * b0 * c2;
+ Ni[21] = m4 * a0 * b1 * c2; Ni[22] = m2 * a1 * b1 * c2; Ni[23] = m4 * a2 * b1 * c2;
+ Ni[24] = m6 * a0 * b2 * c2; Ni[25] = m5 * a1 * b2 * c2; Ni[26] = m6 * a2 * b2 * c2;
+
+ for( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
+ values[0][dof_I] = variables[lineNum0][dof_I];
+ values[1][dof_I] = variables[lineNum0+1][dof_I];
+ values[2][dof_I] = variables[lineNum0+2][dof_I];
+ values[3][dof_I] = variables[lineNum0+nx][dof_I];
+ values[4][dof_I] = variables[lineNum0+nx+1][dof_I];
+ values[5][dof_I] = variables[lineNum0+nx+2][dof_I];
+ values[6][dof_I] = variables[lineNum0+(2*nx)][dof_I];
+ values[7][dof_I] = variables[lineNum0+(2*nx)+1][dof_I];
+ values[8][dof_I] = variables[lineNum0+(2*nx)+2][dof_I];
+
+ values[9][dof_I] = variables[lineNum0+(nx*ny)][dof_I];
+ values[10][dof_I] = variables[lineNum0+(nx*ny)+1][dof_I];
+ values[11][dof_I] = variables[lineNum0+(nx*ny)+2][dof_I];
+ values[12][dof_I] = variables[lineNum0+(nx*ny)+nx][dof_I];
+ values[13][dof_I] = variables[lineNum0+(nx*ny)+nx+1][dof_I];
+ values[14][dof_I] = variables[lineNum0+(nx*ny)+nx+2][dof_I];
+ values[15][dof_I] = variables[lineNum0+(nx*ny)+(2*nx)][dof_I];
+ values[16][dof_I] = variables[lineNum0+(nx*ny)+(2*nx)+1][dof_I];
+ values[17][dof_I] = variables[lineNum0+(nx*ny)+(2*nx)+2][dof_I];
+
+ values[18][dof_I] = variables[lineNum0+(2*nx*ny)][dof_I];
+ values[19][dof_I] = variables[lineNum0+(2*nx*ny)+1][dof_I];
+ values[20][dof_I] = variables[lineNum0+(2*nx*ny)+2][dof_I];
+ values[21][dof_I] = variables[lineNum0+(2*nx*ny)+nx][dof_I];
+ values[22][dof_I] = variables[lineNum0+(2*nx*ny)+nx+1][dof_I];
+ values[23][dof_I] = variables[lineNum0+(2*nx*ny)+nx+2][dof_I];
+ values[24][dof_I] = variables[lineNum0+(2*nx*ny)+(2*nx)][dof_I];
+ values[25][dof_I] = variables[lineNum0+(2*nx*ny)+(2*nx)+1][dof_I];
+ values[26][dof_I] = variables[lineNum0+(2*nx*ny)+(2*nx)+2][dof_I];
+
+ value[dof_I] = 0.0;
+ for( shapeFunc_I = 0; shapeFunc_I < numShapeFuncs; shapeFunc_I++ )
+ value[dof_I] += Ni[shapeFunc_I] * values[shapeFunc_I][dof_I];
+ }
+ }
+
+ FeVariable_SetValueAtNode( feVariable, node_I, value );
+ }
+
+ Memory_Free( filename );
+ Memory_Free( posx );
+ Memory_Free( posy );
+ if( nDims == 3 ) Memory_Free( posz );
+ Memory_Free( variables );
+
+#ifdef READ_HDF5
+ H5Fclose( inputFile );
+#endif
+}
+
+void _FieldTest_DumpToAnalysisFile( FieldTest* self, Stream* analysisStream ) {
+ int field_I, numDofs, dim, dof_I;
+ /* double error; */
+ FeVariable* errorField;
+
+ for( field_I = 0; field_I < self->fieldCount; field_I++ ) {
+ /* should be using MT_VOLUME for the reference field mesh, but seems to have a bug */
+ errorField = self->errorFieldList[field_I];
+ numDofs = self->numericFieldList[field_I]->fieldComponentCount;
+ dim = self->numericFieldList[field_I]->dim;
+
+#if 0
+ /* Fancy error measurements of magnitudes and 2ndInvars, no needed
+ * but I'm leaving it in incase */
+ if( dim == numDofs ) {
+ /* It's a vector */
+ error = StGermain_VectorMagnitude( self->gErrorNorm[field_I], dim );
+ } else if ( numDofs > self->numericFieldList[field_I]->dim ) {
+ /* Assume it's a symmetric tensor */
+ error = SymmetricTensor_2ndInvariant( self->gErrorNorm[field_I], dim );
+ } else {
+ /* It's a scalar */
+ error = self->gErrorNorm[field_I][0];
+ }
+ Journal_Printf( analysisStream, "%.8e ", error );
+#endif
+ for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
+ if(self->normalise)
+ Journal_RPrintf( analysisStream, "%.8e ", self->gErrorNorm[field_I][dof_I] );
+ else
+ Journal_RPrintf( analysisStream, "%.8e ", self->gErrorSq[field_I][dof_I] );
+ }
+
+ }
+}
+
+/* by default, success of the physics test is set to false. this is reset if the test passes */
+void FieldTest_EvaluatePhysicsTest( void* _context, void* data ) {
+ DomainContext* context = (DomainContext*)_context;
+ /* dodgy!!! - not sure how else to pass the self reference at an entry point */
+ FieldTest* self = fieldTestSingleton;
+ FieldTest_ExpectedResultFunc* expectedFunc = self->expectedFunc;
+ FILE* dumpExpectedFilePtr;
+ char* dumpExpectedFileName;
+ int dim_i, dof_i;
+
+ if( expectedFunc( self->expectedData, context, self->expected, self->numeric, self->tolerance ) )
+ self->expectedPass = True;
+
+ if( strlen(self->dumpExpectedFileName) > 1 ) {
+ dumpExpectedFileName = Memory_Alloc_Array_Unnamed( char, strlen(self->expectedFilePath) +
+ strlen(self->dumpExpectedFileName) + 5 );
+ sprintf( dumpExpectedFileName, "%s%s.out", self->expectedFilePath, self->dumpExpectedFileName );
+ dumpExpectedFilePtr = fopen( dumpExpectedFileName, "a" );
+
+ fprintf( dumpExpectedFilePtr, "%.8e ", self->numeric[context->timeStep].time );
+ for( dim_i = 0; dim_i < context->dim; dim_i++ )
+ fprintf( dumpExpectedFilePtr, "%.8e ", self->numeric[context->timeStep].place[dim_i] );
+ for( dof_i = 0; dof_i < self->expectedDofs; dof_i++ )
+ fprintf( dumpExpectedFilePtr, "%.8e ", self->numeric[context->timeStep].value[dof_i] );
+
+ fprintf( dumpExpectedFilePtr, "\n" );
+
+ if( context->timeStep == context->maxTimeSteps ) {
+ if( self->expectedPass )
+ fprintf( dumpExpectedFilePtr, "test result: PASS\n" );
+ else
+ fprintf( dumpExpectedFilePtr, "test result: FAIL\n" );
+ }
+
+ Memory_Free( dumpExpectedFileName );
+ fclose( dumpExpectedFilePtr );
+ }
+}
+
+void FieldTest_GenerateErrFields( void* _context, void* data ) {
+ DomainContext* context = (DomainContext*)_context;
+ /* this a really dodgy way to get the self ptr, as will only work if the textual name is consistent with that in
+ * the XML - need to find a way to add an entry point which allows the self ptr to be passed as a void * */
+ //FieldTest* self = LiveComponentRegister_Get( context->CF->LCRegister, (Name)"NumericFields" );
+ /* this is also a dodgy way to get the self ptr, as its obtained from a global variable */
+ FieldTest* self = fieldTestSingleton;
+ FeVariable* errorField;
+ Index lMeshSize, lElement_I;
+ double elErrorSq[9], elNormSq[9], elError[9];
+ double lAnalyticSq[9], gAnalyticSq[9];
+ double lErrorSq[9], gErrorSq[9];
+ Bool normalise = self->normalise;
+ Index numDofs, dof_I, fieldCount;
+ Index field_I;
+ Stream* analysisStream;
+ /* double eps = self->epsilon; */
+
+ /* if testTimestep is NOT initialise and NOT equal to the current timestep
+ * we skip this function */
+ if( self->testTimestep != context->timeStep && self->testTimestep != 0 )
+ return;
+
+ fieldCount = self->fieldCount;
+
+ if( self->appendToAnalysisFile ) {
+ /* append (or create if not found ) a file to report results */
+ double length, elementResI;
+ char* filename;
+ analysisStream = Journal_Register( Info_Type, (Name)self->type );
+ Stg_asprintf( &filename, "%s-analysis.cvg", self->name );
+ Stream_AppendFile( analysisStream, filename );
+ Memory_Free( filename );
+
+ /* write heading names in file */
+ Journal_RPrintf( analysisStream, "#Res ");
+ for(field_I = 0 ; field_I < fieldCount ; field_I++ ) {
+ numDofs = self->numericFieldList[field_I]->fieldComponentCount;
+ for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
+ Journal_RPrintf( analysisStream, "%s%d ", self->numericFieldList[field_I]->name, dof_I+1 );
+ }
+ }
+ length = Dictionary_GetDouble( context->CF->rootDict, "maxX" ) - Dictionary_GetDouble( context->CF->rootDict, "minX" ) ;
+ elementResI = Dictionary_GetInt( context->CF->rootDict, (Dictionary_Entry_Key)"elementResI" );
+ /* assume square resolution */
+ Journal_RPrintf( analysisStream, "\n%e ", length/elementResI );
+ }
+
+ for( field_I = 0; field_I < fieldCount; field_I++ ) {
+ /* should be using MT_VOLUME for the reference field mesh, but seems to have a bug */
+ lMeshSize = Mesh_GetLocalSize( self->constantMesh, MT_VERTEX );
+ errorField = self->errorFieldList[field_I];
+ numDofs = self->numericFieldList[field_I]->fieldComponentCount;
+
+ assert( !strcmp( errorField->feMesh->name, "constantMesh" ) );
+
+ for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
+ lAnalyticSq[dof_I] = 0.0;
+ lErrorSq[dof_I] = 0.0;
+ }
+
+ for( lElement_I = 0; lElement_I < lMeshSize; lElement_I++ ) {
+ for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
+ elErrorSq[dof_I] = 0.0;
+ elNormSq[dof_I] = 0.0;
+ }
+
+ if( self->referenceSolnFromFile )
+ FieldTest_ElementErrReferenceFromField( self, field_I, lElement_I, elErrorSq, elNormSq );
+ else
+ FieldTest_ElementErrAnalyticFromField( self, field_I, lElement_I, elErrorSq, elNormSq );
+
+ for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
+ lAnalyticSq[dof_I] += elNormSq[dof_I];
+ lErrorSq[dof_I] += elErrorSq[dof_I];
+ //elError[dof_I] = normalise ? sqrt( elErrorSq[dof_I] / ( elNormSq[dof_I] + eps ) ) : sqrt( elErrorSq[dof_I] );
+ elError[dof_I] = normalise ? sqrt( elErrorSq[dof_I] / ( elNormSq[dof_I] ) ) : sqrt( elErrorSq[dof_I] );
+ }
+
+ /* constant mesh, so node and element indices map 1:1 */
+ FeVariable_SetValueAtNode( errorField, lElement_I, elError );
+ }
+
+ MPI_Allreduce( lAnalyticSq, gAnalyticSq, numDofs, MPI_DOUBLE, MPI_SUM, self->referenceFieldList[field_I]->communicator );
+ MPI_Allreduce( lErrorSq, gErrorSq, numDofs, MPI_DOUBLE, MPI_SUM, self->referenceFieldList[field_I]->communicator );
+
+ for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
+ self->gAnalyticSq[field_I][dof_I] = gAnalyticSq[dof_I];
+ self->gErrorSq[field_I][dof_I] = gErrorSq[dof_I];
+ self->gErrorNorm[field_I][dof_I] = sqrt( gErrorSq[dof_I] / gAnalyticSq[dof_I] );
+
+ if( normalise ) {
+ Journal_RPrintf( context->info, "%s - dof %d normalised global error: %.8e\n",
+ self->numericFieldList[field_I]->name, dof_I, self->gErrorNorm[field_I][dof_I] );
+ }
+ else {
+ Journal_RPrintf( context->info, "%s - dof %d global error: %.8e\n",
+ self->numericFieldList[field_I]->name, dof_I, sqrt( self->gErrorSq[field_I][dof_I] ) );
+ }
+ }
+ }
+
+ if( self->appendToAnalysisFile ) {
+ _FieldTest_DumpToAnalysisFile( self, analysisStream );
+ Journal_RPrintf( analysisStream, "\n" );
+ Stream_CloseAndFreeFile( analysisStream );
+ }
+}
+
+void FieldTest_ElementErrReferenceFromField( void* fieldTest, Index field_I, Index lElement_I, double* elErrorSq, double* elNormSq ) {
+ FieldTest* self = (FieldTest*) fieldTest;
+ FeVariable* referenceField = self->referenceFieldList[field_I];
+ FeVariable* numericField = self->numericFieldList[field_I];
+ FeMesh* referenceMesh = referenceField->feMesh;
+ FeMesh* elementMesh = self->elementMesh;
+ Index constantElNode = lElement_I;
+ double* coord = Mesh_GetVertex( self->constantMesh, constantElNode );
+ unsigned nDims = Mesh_GetDimSize( referenceMesh );
+ Index el_I, elementMeshElem;
+ ElementType* elType;
+ Swarm* intSwarm = self->integrationSwarm;
+ Index cell_I;
+ unsigned cellParticleCount;
+ Index cParticle_I;
+ IntegrationPoint* cParticle;
+ double *xi, weight;
+ double globalCoord[3];
+ double detJac;
+ double reference[9], numeric[9];
+ Index numDofs = numericField->fieldComponentCount;
+ Index dof_I;
+
+ /* don't assume that the constant error field mesh & reference field mesh necessarily map 1:1 */
+ Mesh_SearchElements( referenceMesh, coord, &el_I );
+ Mesh_SearchElements( elementMesh, coord, &elementMeshElem );
+ elType = FeMesh_GetElementType( elementMesh, elementMeshElem );
+
+ cell_I = CellLayout_MapElementIdToCellId( intSwarm->cellLayout, el_I );
+ cellParticleCount = intSwarm->cellParticleCountTbl[cell_I];
+
+ for( cParticle_I = 0; cParticle_I < cellParticleCount; cParticle_I++ ) {
+ cParticle = (IntegrationPoint*) Swarm_ParticleInCellAt( intSwarm, cell_I, cParticle_I );
+ xi = cParticle->xi;
+ weight = cParticle->weight;
+
+ FeMesh_CoordLocalToGlobal( referenceMesh, el_I, xi, globalCoord );
+ FieldVariable_InterpolateValueAt( referenceField, globalCoord, reference );
+ FieldVariable_InterpolateValueAt( numericField, globalCoord, numeric );
+
+ detJac = ElementType_JacobianDeterminant( elType, elementMesh, elementMeshElem, xi, nDims );
+
+ for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
+ elErrorSq[dof_I] += ( numeric[dof_I] - reference[dof_I] ) * ( numeric[dof_I] - reference[dof_I] )
+ * weight * detJac;
+ elNormSq[dof_I] += reference[dof_I] * reference[dof_I] * weight * detJac;
+ }
+ }
+}
+
+void FieldTest_ElementErrAnalyticFromField( void* fieldTest, Index field_I, Index lElement_I, double* elErrorSq, double* elNormSq ) {
+ FieldTest* self = (FieldTest*) fieldTest;
+ FeVariable* numericField = self->numericFieldList[field_I];
+ FeMesh* elementMesh = self->elementMesh;
+ Index constantElNode = lElement_I;
+ double* coord = Mesh_GetVertex( self->constantMesh, constantElNode );
+ unsigned nDims = Mesh_GetDimSize( elementMesh );
+ Index el_I;
+ ElementType* elType;
+ Swarm* intSwarm = self->integrationSwarm;
+ Index cell_I;
+ unsigned cellParticleCount;
+ Index cParticle_I;
+ IntegrationPoint* cParticle;
+ double *xi, weight;
+ double globalCoord[3];
+ double detJac;
+ double analytic[9], numeric[9];
+ Index numDofs = numericField->fieldComponentCount;
+ Index dof_I;
+ /* corresponding analytic solution function for this feVariable, as assigned in the plugin */
+ FieldTest_AnalyticSolutionFunc* analyticSolution = self->_analyticSolutionList[self->analyticSolnForFeVarKey[field_I]];
+
+ /* don't assume that the constant error field mesh & reference field mesh necessarily map 1:1 */
+ Mesh_SearchElements( elementMesh, coord, &el_I );
+ elType = FeMesh_GetElementType( elementMesh, el_I );
+
+ cell_I = CellLayout_MapElementIdToCellId( intSwarm->cellLayout, el_I );
+ cellParticleCount = intSwarm->cellParticleCountTbl[cell_I];
+
+ for( cParticle_I = 0; cParticle_I < cellParticleCount; cParticle_I++ ) {
+ cParticle = (IntegrationPoint*) Swarm_ParticleInCellAt( intSwarm, cell_I, cParticle_I );
+ xi = cParticle->xi;
+ weight = cParticle->weight;
+
+ detJac = ElementType_JacobianDeterminant( elType, elementMesh, el_I, xi, nDims );
+
+ FeMesh_CoordLocalToGlobal( elementMesh, el_I, xi, globalCoord );
+ analyticSolution( self, globalCoord, analytic );
+ FieldVariable_InterpolateValueAt( numericField, globalCoord, numeric );
+
+ for( dof_I = 0; dof_I < numDofs; dof_I++ ) {
+ elErrorSq[dof_I] += ( numeric[dof_I] - analytic[dof_I] ) * ( numeric[dof_I] - analytic[dof_I] ) * weight * detJac;
+ elNormSq[dof_I] += analytic[dof_I] * analytic[dof_I] * weight * detJac;
+ }
+ }
+}
+
+void FieldTest_ElementErrAnalyticFromSwarm( void* fieldTest, Index var_I, Index lElement_I, double* elErrorSq, double* elNormSq ) {
+}
+
+void FieldTest_ElementErrReferenceFromSwarm( void* fieldTest, Index var_I, Index lElement_I, double* elErrorSq, double* elNormSq ) {
+}
+
+/* the first index 'func_I' denotes the index of the function in the analytic solution list to be applied to calculate
+ * the analytic field at index 'field_I' in the analytic field list.
+ *
+ * the analytic fields are in the same order as their numeric counterparts are read in from the XML */
+void FieldTest_AddAnalyticSolutionFuncToListAtIndex( void* fieldTest, Index func_I, FieldTest_AnalyticSolutionFunc* func, Index field_I ) {
+ FieldTest* self = (FieldTest*) fieldTest;
+
+ self->_analyticSolutionList[func_I] = func;
+ self->analyticSolnForFeVarKey[field_I] = func_I;
+}
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/Finalise.c
--- a/Discretisation/src/Finalise.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "ElementType_Register.h"
-#include "Finalise.h"
-
-#include "FeVariable.h"
-#include <petsc.h>
-
-#include <stdio.h>
-
-Bool StgFEM_Discretisation_Finalise( void ) {
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- Stream_IndentBranch( StgFEM_Debug );
-
- _ElementType_Register_Delete( elementType_Register );
-
- PetscFinalize();
-
- Stream_UnIndentBranch( StgFEM_Debug );
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/Finalise.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/Finalise.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,69 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "ElementType_Register.h"
+#include "Finalise.h"
+
+#include "FeVariable.h"
+#include <petsc.h>
+
+#include <stdio.h>
+
+Bool StgFEM_Discretisation_Finalise( void ) {
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ Stream_IndentBranch( StgFEM_Debug );
+
+ _ElementType_Register_Delete( elementType_Register );
+
+ PetscFinalize();
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FunctionSuite.c
--- a/Discretisation/src/FunctionSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/* Suite of functions for evaluating diagnostic properties from StG.
- * components (ie: Swarms, FeVariables, OperatorFeVariables)
- *
- * */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <string.h>
-#include <math.h>
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "types.h"
-#include "FeMesh.h"
-#include "FeVariable.h"
-#include "FunctionSuite.h"
-
-/* root mean squared velocity, takes in a velocity squared
- * OperatorFeVariable and an integration Swarm */
-double StgFEM_Vrms( FeVariable* velsq, Swarm* swarm ) {
- Mesh* mesh = (Mesh*) velsq->feMesh;
- double max[3], min[3];
- double volume;
- double integral;
- double vrms;
- unsigned dim = Mesh_GetDimSize( mesh );
-
- Mesh_GetGlobalCoordRange( mesh, min, max );
-
- integral = FeVariable_Integrate( velsq, swarm );
-
- volume = ( max[I_AXIS] - min[I_AXIS] ) * ( max[J_AXIS] - min[J_AXIS] );
- if( dim == 3 )
- volume *= ( max[K_AXIS] - min[K_AXIS] );
-
- vrms = sqrt( integral / volume );
-
- return vrms;
-}
-
-/* optimised version of the feVariable interpolation function. assumes constant number of dofs for each node */
-void StgFEM_InterpolateValue_WithNi( void* _feVariable, Element_LocalIndex lElement_I, double* Ni, double* value ) {
- FeVariable* self = (FeVariable*) _feVariable;
- Node_ElementLocalIndex elLocalNode_I;
- Node_LocalIndex lNode_I;
- Dof_Index dof_I;
- Dof_Index dofCount;
- Variable* dofVariable;
- double nodeValue;
- unsigned nInc, *inc;
-
- /* Gets number of degrees of freedom - assuming it is the same throughout the mesh */
- dofCount = self->dofLayout->dofCounts[0];
-
- /* Initialise */
- memset( value, 0, sizeof( double )*dofCount );
-
- FeMesh_GetElementNodes( self->feMesh, lElement_I, self->inc );
- nInc = IArray_GetSize( self->inc );
- inc = (unsigned*)IArray_GetPtr( self->inc );
-
- for ( dof_I = 0; dof_I < dofCount; dof_I++ ) {
- dofVariable = DofLayout_GetVariable( self->dofLayout, 0, dof_I );
- for ( elLocalNode_I = 0 ; elLocalNode_I < nInc ; elLocalNode_I++) {
- lNode_I = inc[ elLocalNode_I ];
- nodeValue = Variable_GetValueDouble( dofVariable, lNode_I );
- value[dof_I] += Ni[elLocalNode_I] * nodeValue;
- }
- }
-}
-
-/* optimised version of the feVariable interpolate derivatives function. assumes constant number of dofs for each node */
-void StgFEM_InterpolateDerivatives_WithGNx( void* _feVariable, Element_LocalIndex lElement_I, double** GNx, double* value ) {
- FeVariable* self = (FeVariable*) _feVariable;
- Node_ElementLocalIndex elLocalNode_I;
- Node_LocalIndex lNode_I;
- Dof_Index dof_I, dim_I;
- Dof_Index dofCount;
- Variable* dofVariable;
- double nodeValue;
- unsigned nInc, *inc;
- Dimension_Index dim = self->dim;
-
- /* Gets number of degrees of freedom - assuming it is the same throughout the mesh */
- dofCount = self->dofLayout->dofCounts[0];
-
- /* Initialise */
- memset( value, 0, sizeof( double )*dofCount*dim );
-
- FeMesh_GetElementNodes( self->feMesh, lElement_I, self->inc );
- nInc = IArray_GetSize( self->inc );
- inc = (unsigned*)IArray_GetPtr( self->inc );
-
- for ( dof_I = 0 ; dof_I < dofCount ; dof_I++ ) {
- dofVariable = DofLayout_GetVariable( self->dofLayout, 0, dof_I );
- /* Interpolate derivative from nodes */
- for ( elLocalNode_I = 0; elLocalNode_I < nInc; elLocalNode_I++) {
- lNode_I = inc[ elLocalNode_I ];
- nodeValue = Variable_GetValueDouble( dofVariable, lNode_I );
-
- for( dim_I = 0; dim_I < dim; dim_I++ )
- value[dof_I*dim + dim_I] += GNx[dim_I][elLocalNode_I] * nodeValue;
- }
- }
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/FunctionSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/FunctionSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,109 @@
+/* Suite of functions for evaluating diagnostic properties from StG.
+ * components (ie: Swarms, FeVariables, OperatorFeVariables)
+ *
+ * */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "types.h"
+#include "FeMesh.h"
+#include "FeVariable.h"
+#include "FunctionSuite.h"
+
+/* root mean squared velocity, takes in a velocity squared
+ * OperatorFeVariable and an integration Swarm */
+double StgFEM_Vrms( FeVariable* velsq, Swarm* swarm ) {
+ Mesh* mesh = (Mesh*) velsq->feMesh;
+ double max[3], min[3];
+ double volume;
+ double integral;
+ double vrms;
+ unsigned dim = Mesh_GetDimSize( mesh );
+
+ Mesh_GetGlobalCoordRange( mesh, min, max );
+
+ integral = FeVariable_Integrate( velsq, swarm );
+
+ volume = ( max[I_AXIS] - min[I_AXIS] ) * ( max[J_AXIS] - min[J_AXIS] );
+ if( dim == 3 )
+ volume *= ( max[K_AXIS] - min[K_AXIS] );
+
+ vrms = sqrt( integral / volume );
+
+ return vrms;
+}
+
+/* optimised version of the feVariable interpolation function. assumes constant number of dofs for each node */
+void StgFEM_InterpolateValue_WithNi( void* _feVariable, Element_LocalIndex lElement_I, double* Ni, double* value ) {
+ FeVariable* self = (FeVariable*) _feVariable;
+ Node_ElementLocalIndex elLocalNode_I;
+ Node_LocalIndex lNode_I;
+ Dof_Index dof_I;
+ Dof_Index dofCount;
+ Variable* dofVariable;
+ double nodeValue;
+ unsigned nInc, *inc;
+
+ /* Gets number of degrees of freedom - assuming it is the same throughout the mesh */
+ dofCount = self->dofLayout->dofCounts[0];
+
+ /* Initialise */
+ memset( value, 0, sizeof( double )*dofCount );
+
+ FeMesh_GetElementNodes( self->feMesh, lElement_I, self->inc );
+ nInc = IArray_GetSize( self->inc );
+ inc = (unsigned*)IArray_GetPtr( self->inc );
+
+ for ( dof_I = 0; dof_I < dofCount; dof_I++ ) {
+ dofVariable = DofLayout_GetVariable( self->dofLayout, 0, dof_I );
+ for ( elLocalNode_I = 0 ; elLocalNode_I < nInc ; elLocalNode_I++) {
+ lNode_I = inc[ elLocalNode_I ];
+ nodeValue = Variable_GetValueDouble( dofVariable, lNode_I );
+ value[dof_I] += Ni[elLocalNode_I] * nodeValue;
+ }
+ }
+}
+
+/* optimised version of the feVariable interpolate derivatives function. assumes constant number of dofs for each node */
+void StgFEM_InterpolateDerivatives_WithGNx( void* _feVariable, Element_LocalIndex lElement_I, double** GNx, double* value ) {
+ FeVariable* self = (FeVariable*) _feVariable;
+ Node_ElementLocalIndex elLocalNode_I;
+ Node_LocalIndex lNode_I;
+ Dof_Index dof_I, dim_I;
+ Dof_Index dofCount;
+ Variable* dofVariable;
+ double nodeValue;
+ unsigned nInc, *inc;
+ Dimension_Index dim = self->dim;
+
+ /* Gets number of degrees of freedom - assuming it is the same throughout the mesh */
+ dofCount = self->dofLayout->dofCounts[0];
+
+ /* Initialise */
+ memset( value, 0, sizeof( double )*dofCount*dim );
+
+ FeMesh_GetElementNodes( self->feMesh, lElement_I, self->inc );
+ nInc = IArray_GetSize( self->inc );
+ inc = (unsigned*)IArray_GetPtr( self->inc );
+
+ for ( dof_I = 0 ; dof_I < dofCount ; dof_I++ ) {
+ dofVariable = DofLayout_GetVariable( self->dofLayout, 0, dof_I );
+ /* Interpolate derivative from nodes */
+ for ( elLocalNode_I = 0; elLocalNode_I < nInc; elLocalNode_I++) {
+ lNode_I = inc[ elLocalNode_I ];
+ nodeValue = Variable_GetValueDouble( dofVariable, lNode_I );
+
+ for( dim_I = 0; dim_I < dim; dim_I++ )
+ value[dof_I*dim + dim_I] += GNx[dim_I][elLocalNode_I] * nodeValue;
+ }
+ }
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/Init.c
--- a/Discretisation/src/Init.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,139 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Init.c 1218 2008-09-04 06:18:44Z DavidLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <stdio.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "Discretisation.h"
-
-
-Stream* StgFEM_Debug = NULL;
-Stream* StgFEM_Warning = NULL;
-Stream* StgFEM_Discretisation_Debug = NULL;
-
-
-/** Initialises the Linear Algebra package, then any init for this package
-such as streams etc */
-Bool StgFEM_Discretisation_Init( int* argc, char** argv[] ) {
- Stg_ComponentRegister* componentRegister = Stg_ComponentRegister_Get_ComponentRegister();
- int tmp;
-
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
- tmp = Stream_GetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ) );
- Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), 0 );
- Journal_Printf( /* DO NOT CHANGE OR REMOVE */ Journal_Register( InfoStream_Type, (Name)"Context" ),
- "StGermain FEM Discretisation Framework revision %s. Copyright (C) 2003-2005 VPAC.\n", VERSION );
- Stream_Flush( Journal_Register( InfoStream_Type, (Name)"Context" ) );
- Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), tmp );
-
- /* initialise this level's streams */
- StgFEM_Debug = Journal_Register( DebugStream_Type, (Name)"StgFEM" );
- StgFEM_Discretisation_Debug = Stream_RegisterChild( StgFEM_Debug, "Discretisation" );
- StgFEM_Warning = Journal_Register( ErrorStream_Type, (Name)"StgFEM" );
-
- elementType_Register = ElementType_Register_New( "elementType_Register" );
- ElementType_Register_Add( elementType_Register, (ElementType*)ConstantElementType_New( "constantElementType" ) );
- ElementType_Register_Add( elementType_Register, (ElementType*)BilinearElementType_New( "bilinearElementType" ) );
- ElementType_Register_Add( elementType_Register, (ElementType*)TrilinearElementType_New( "trilinearElementType" ) );
- ElementType_Register_Add( elementType_Register, (ElementType*)LinearTriangleElementType_New( "linearElementType" ) );
- ElementType_Register_Add( elementType_Register, (ElementType*)Biquadratic_New( "biquadraticElementType" ) );
- ElementType_Register_Add( elementType_Register, (ElementType*)Triquadratic_New( "triquadraticElementType" ) );
-
- Stg_ComponentRegister_Add( componentRegister, FeVariable_Type, (Name)"0", _FeVariable_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, LinkedDofInfo_Type, (Name)"0", _LinkedDofInfo_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, OperatorFeVariable_Type, (Name)"0", _OperatorFeVariable_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, ShapeFeVariable_Type, (Name)"0", ShapeFeVariable_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, FeSwarmVariable_Type, (Name)"0", _FeSwarmVariable_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, FeMesh_Type, (Name)"0",
- (Stg_Component_DefaultConstructorFunction*)_FeMesh_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, C0Generator_Type, (Name)"0",
- (Stg_Component_DefaultConstructorFunction*)C0Generator_New );
- Stg_ComponentRegister_Add( componentRegister, C2Generator_Type, (Name)"0",
- (Stg_Component_DefaultConstructorFunction*)C2Generator_New );
-/*
- Stg_ComponentRegister_Add( componentRegister, P1Generator_Type, (Name)"0", P1Generator_New );
-*/
- Stg_ComponentRegister_Add( componentRegister, Inner2DGenerator_Type, (Name)"0", (Stg_Component_DefaultConstructorFunction*)Inner2DGenerator_New );
- Stg_ComponentRegister_Add( componentRegister, FieldTest_Type, (Name)"0", _FieldTest_DefaultNew );
-
- /** Register Parents for type checking */
- RegisterParent( FeMesh_Algorithms_Type, Mesh_Algorithms_Type );
- RegisterParent( FeMesh_ElementType_Type, Mesh_HexType_Type );
- RegisterParent( ElementType_Type, Stg_Component_Type );
- RegisterParent( BilinearElementType_Type, ElementType_Type );
- RegisterParent( TrilinearElementType_Type, ElementType_Type );
- RegisterParent( Biquadratic_Type, ElementType_Type );
- RegisterParent( Triquadratic_Type, ElementType_Type );
- RegisterParent( P1_Type, ElementType_Type );
- RegisterParent( RegularTrilinear_Type, TrilinearElementType_Type );
- RegisterParent( ConstantElementType_Type, ElementType_Type );
- RegisterParent( LinearTriangleElementType_Type, ElementType_Type );
- RegisterParent( ElementType_Register_Type, Stg_Component_Type );
-
- RegisterParent( FeEquationNumber_Type, Stg_Component_Type );
- RegisterParent( LinkedDofInfo_Type, Stg_Component_Type );
- RegisterParent( FeMesh_Type, Mesh_Type );
- RegisterParent( C0Generator_Type, MeshGenerator_Type );
- RegisterParent( C2Generator_Type, CartesianGenerator_Type );
-/*
- RegisterParent( P1Generator_Type, MeshGenerator_Type );
-*/
- RegisterParent( Inner2DGenerator_Type, MeshGenerator_Type );
-
- RegisterParent( FeVariable_Type, FieldVariable_Type );
- RegisterParent( OperatorFeVariable_Type, FeVariable_Type );
- RegisterParent( ShapeFeVariable_Type, FeVariable_Type );
- RegisterParent( FeSwarmVariable_Type, SwarmVariable_Type );
-
- RegisterParent( FieldTest_Type, Stg_Component_Type );
-
- {
- PetscErrorCode ec;
- ec = PetscInitialize( argc, argv, (char*)0, NULL );
- CheckPETScError( ec );
- }
-
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/Init.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/Init.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,139 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Init.c 1218 2008-09-04 06:18:44Z DavidLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <stdio.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "Discretisation.h"
+
+
+Stream* StgFEM_Debug = NULL;
+Stream* StgFEM_Warning = NULL;
+Stream* StgFEM_Discretisation_Debug = NULL;
+
+
+/** Initialises the Linear Algebra package, then any init for this package
+such as streams etc */
+Bool StgFEM_Discretisation_Init( int* argc, char** argv[] ) {
+ Stg_ComponentRegister* componentRegister = Stg_ComponentRegister_Get_ComponentRegister();
+ int tmp;
+
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+ tmp = Stream_GetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ) );
+ Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), 0 );
+ Journal_Printf( /* DO NOT CHANGE OR REMOVE */ Journal_Register( InfoStream_Type, (Name)"Context" ),
+ "StGermain FEM Discretisation Framework revision %s. Copyright (C) 2003-2005 VPAC.\n", VERSION );
+ Stream_Flush( Journal_Register( InfoStream_Type, (Name)"Context" ) );
+ Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), tmp );
+
+ /* initialise this level's streams */
+ StgFEM_Debug = Journal_Register( DebugStream_Type, (Name)"StgFEM" );
+ StgFEM_Discretisation_Debug = Stream_RegisterChild( StgFEM_Debug, "Discretisation" );
+ StgFEM_Warning = Journal_Register( ErrorStream_Type, (Name)"StgFEM" );
+
+ elementType_Register = ElementType_Register_New( "elementType_Register" );
+ ElementType_Register_Add( elementType_Register, (ElementType*)ConstantElementType_New( "constantElementType" ) );
+ ElementType_Register_Add( elementType_Register, (ElementType*)BilinearElementType_New( "bilinearElementType" ) );
+ ElementType_Register_Add( elementType_Register, (ElementType*)TrilinearElementType_New( "trilinearElementType" ) );
+ ElementType_Register_Add( elementType_Register, (ElementType*)LinearTriangleElementType_New( "linearElementType" ) );
+ ElementType_Register_Add( elementType_Register, (ElementType*)Biquadratic_New( "biquadraticElementType" ) );
+ ElementType_Register_Add( elementType_Register, (ElementType*)Triquadratic_New( "triquadraticElementType" ) );
+
+ Stg_ComponentRegister_Add( componentRegister, FeVariable_Type, (Name)"0", _FeVariable_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, LinkedDofInfo_Type, (Name)"0", _LinkedDofInfo_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, OperatorFeVariable_Type, (Name)"0", _OperatorFeVariable_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, ShapeFeVariable_Type, (Name)"0", ShapeFeVariable_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, FeSwarmVariable_Type, (Name)"0", _FeSwarmVariable_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, FeMesh_Type, (Name)"0",
+ (Stg_Component_DefaultConstructorFunction*)_FeMesh_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, C0Generator_Type, (Name)"0",
+ (Stg_Component_DefaultConstructorFunction*)C0Generator_New );
+ Stg_ComponentRegister_Add( componentRegister, C2Generator_Type, (Name)"0",
+ (Stg_Component_DefaultConstructorFunction*)C2Generator_New );
+/*
+ Stg_ComponentRegister_Add( componentRegister, P1Generator_Type, (Name)"0", P1Generator_New );
+*/
+ Stg_ComponentRegister_Add( componentRegister, Inner2DGenerator_Type, (Name)"0", (Stg_Component_DefaultConstructorFunction*)Inner2DGenerator_New );
+ Stg_ComponentRegister_Add( componentRegister, FieldTest_Type, (Name)"0", _FieldTest_DefaultNew );
+
+ /** Register Parents for type checking */
+ RegisterParent( FeMesh_Algorithms_Type, Mesh_Algorithms_Type );
+ RegisterParent( FeMesh_ElementType_Type, Mesh_HexType_Type );
+ RegisterParent( ElementType_Type, Stg_Component_Type );
+ RegisterParent( BilinearElementType_Type, ElementType_Type );
+ RegisterParent( TrilinearElementType_Type, ElementType_Type );
+ RegisterParent( Biquadratic_Type, ElementType_Type );
+ RegisterParent( Triquadratic_Type, ElementType_Type );
+ RegisterParent( P1_Type, ElementType_Type );
+ RegisterParent( RegularTrilinear_Type, TrilinearElementType_Type );
+ RegisterParent( ConstantElementType_Type, ElementType_Type );
+ RegisterParent( LinearTriangleElementType_Type, ElementType_Type );
+ RegisterParent( ElementType_Register_Type, Stg_Component_Type );
+
+ RegisterParent( FeEquationNumber_Type, Stg_Component_Type );
+ RegisterParent( LinkedDofInfo_Type, Stg_Component_Type );
+ RegisterParent( FeMesh_Type, Mesh_Type );
+ RegisterParent( C0Generator_Type, MeshGenerator_Type );
+ RegisterParent( C2Generator_Type, CartesianGenerator_Type );
+/*
+ RegisterParent( P1Generator_Type, MeshGenerator_Type );
+*/
+ RegisterParent( Inner2DGenerator_Type, MeshGenerator_Type );
+
+ RegisterParent( FeVariable_Type, FieldVariable_Type );
+ RegisterParent( OperatorFeVariable_Type, FeVariable_Type );
+ RegisterParent( ShapeFeVariable_Type, FeVariable_Type );
+ RegisterParent( FeSwarmVariable_Type, SwarmVariable_Type );
+
+ RegisterParent( FieldTest_Type, Stg_Component_Type );
+
+ {
+ PetscErrorCode ec;
+ ec = PetscInitialize( argc, argv, (char*)0, NULL );
+ CheckPETScError( ec );
+ }
+
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/Inner2DGenerator.c
--- a/Discretisation/src/Inner2DGenerator.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,392 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Inner2DGenerator.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <mpi.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "Discretisation.h"
-
-
-/* Textual name of this class */
-const Type Inner2DGenerator_Type = "Inner2DGenerator";
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-Inner2DGenerator* Inner2DGenerator_New( Name name, AbstractContext* context ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(Inner2DGenerator);
- Type type = Inner2DGenerator_Type;
- Stg_Class_DeleteFunction* _delete = _Inner2DGenerator_Delete;
- Stg_Class_PrintFunction* _print = _Inner2DGenerator_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_Inner2DGenerator_New;
- Stg_Component_ConstructFunction* _construct = _Inner2DGenerator_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Inner2DGenerator_Build;
- Stg_Component_InitialiseFunction* _initialise = _Inner2DGenerator_Initialise;
- Stg_Component_ExecuteFunction* _execute = _Inner2DGenerator_Execute;
- Stg_Component_DestroyFunction* _destroy = NULL;
- AllocationType nameAllocationType = NON_GLOBAL;
- MeshGenerator_SetDimSizeFunc* setDimSizeFunc = _MeshGenerator_SetDimSize;
- MeshGenerator_GenerateFunc* generateFunc = (MeshGenerator_GenerateFunc*)Inner2DGenerator_Generate;
-
- Inner2DGenerator* self = _Inner2DGenerator_New( INNER2DGENERATOR_PASSARGS );
-
- _MeshGenerator_Init( (MeshGenerator*)self, context );
- _Inner2DGenerator_Init( self );
-
- return self;
-}
-
-Inner2DGenerator* _Inner2DGenerator_New( INNER2DGENERATOR_DEFARGS ) {
- Inner2DGenerator* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(Inner2DGenerator) );
- self = (Inner2DGenerator*)_MeshGenerator_New( MESHGENERATOR_PASSARGS );
-
- return self;
-}
-
-void _Inner2DGenerator_Init( Inner2DGenerator* self ) {
- assert( self && Stg_CheckType( self, Inner2DGenerator ) );
-
- self->elMesh = NULL;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _Inner2DGenerator_Delete( void* generator ) {
- Inner2DGenerator* self = (Inner2DGenerator*)generator;
-
- /* Delete the parent. */
- _MeshGenerator_Delete( self );
-}
-
-void _Inner2DGenerator_Print( void* generator, Stream* stream ) {
- Inner2DGenerator* self = (Inner2DGenerator*)generator;
-
- /* Set the Journal for printing informations */
- Stream* generatorStream;
- generatorStream = Journal_Register( InfoStream_Type, (Name)"Inner2DGeneratorStream" );
-
- /* Print parent */
- Journal_Printf( stream, "Inner2DGenerator (ptr): (%p)\n", self );
- _MeshGenerator_Print( self, stream );
-}
-
-void _Inner2DGenerator_AssignFromXML( void* generator, Stg_ComponentFactory* cf, void* data ) {
- Inner2DGenerator* self = (Inner2DGenerator*)generator;
- Mesh* elMesh;
-
- assert( self );
- assert( cf );
-
- _MeshGenerator_AssignFromXML( self, cf, data );
-
- elMesh = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"elementMesh", Mesh, True, data );
- Inner2DGenerator_SetElementMesh( self, elMesh );
-}
-
-void _Inner2DGenerator_Build( void* generator, void* data ) {
- _MeshGenerator_Build( generator, data );
-}
-
-void _Inner2DGenerator_Initialise( void* generator, void* data ) {
- _MeshGenerator_Initialise( generator, data );
-}
-
-void _Inner2DGenerator_Execute( void* generator, void* data ) {
-}
-
-void _Inner2DGenerator_Destroy( void* generator, void* data ) {
- Inner2DGenerator* self = (Inner2DGenerator*)generator;
-
- Stg_Component_Destroy( self->elMesh, data, False );
- _MeshGenerator_Destroy( self, data );
-}
-
-void Inner2DGenerator_Generate( void* generator, void* _mesh ) {
- Inner2DGenerator* self = (Inner2DGenerator*)generator;
- FeMesh* mesh = (FeMesh*)_mesh;
- Grid** grid;
- Grid* elGrid;
-
- assert( self && Stg_CheckType( self, Inner2DGenerator ) );
- assert( mesh && Stg_CheckType( mesh, FeMesh ) );
-
- Inner2DGenerator_BuildTopology( self, mesh );
- Inner2DGenerator_BuildGeometry( self, mesh );
- Inner2DGenerator_BuildElementTypes( self, mesh );
-
- elGrid = *(Grid**)ExtensionManager_Get( self->elMesh->info, self->elMesh,
- ExtensionManager_GetHandle( self->elMesh->info, (Name)"elementGrid" ) );
- ExtensionManager_Add( mesh->info, (Name)"elementGrid", sizeof(Grid*) );
- grid = (Grid** )ExtensionManager_Get( mesh->info, mesh,
- ExtensionManager_GetHandle( mesh->info, (Name)"elementGrid" ) );
- *grid = Grid_New( );
- Grid_SetNumDims( *grid, elGrid->nDims );
- Grid_SetSizes( *grid, elGrid->sizes );
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-void Inner2DGenerator_SetElementMesh( void* generator, void* mesh ) {
- Inner2DGenerator* self = (Inner2DGenerator*)generator;
-
- assert( self && Stg_CheckType( self, Inner2DGenerator ) );
-
- self->elMesh = (Mesh*)mesh;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-void Inner2DGenerator_BuildTopology( Inner2DGenerator* self, FeMesh* mesh ) {
- Mesh* elMesh;
- MeshTopology *topo, *elTopo;
- unsigned nDims;
- unsigned nIncEls, *incEls;
- unsigned nDomainEls;
- Decomp *elDecomp, *nodeDecomp;
- Sync *elSync, *nodeSync;
- int nLocals, *locals;
- int nRemotes, *remotes;
- unsigned global;
- unsigned e_i, l_i, r_i;
-
- assert( self );
- assert( mesh );
-
- elMesh = self->elMesh;
- nDims = Mesh_GetDimSize( elMesh );
- elTopo = Mesh_GetTopology( elMesh );
- elSync = Mesh_GetSync( elMesh, (MeshTopology_Dim)nDims );
-
- topo = Mesh_GetTopology( mesh );
- MeshTopology_SetComm( topo, MeshTopology_GetComm( elTopo ) );
- MeshTopology_SetNumDims( topo, nDims );
- IGraph_SetDomain( topo, nDims, elSync );
-
- /* Need to redefine the nodes, nDims + 1 per parent element. */
- elDecomp = (Decomp*)Sync_GetDecomp( elSync );
- nodeDecomp = Decomp_New();
-
- if( nDims == 2 ) {
- nLocals = Decomp_GetNumLocals( elDecomp ) * 3;
- locals = MemArray( int, nLocals, Inner2DGenerator_Type );
- for( l_i = 0; l_i < Decomp_GetNumLocals( elDecomp ); l_i++ ) {
- global = Decomp_LocalToGlobal( elDecomp, l_i );
- locals[l_i * 3 + 0] = global * 3;
- locals[l_i * 3 + 1] = global * 3 + 1;
- locals[l_i * 3 + 2] = global * 3 + 2;
- }
- }
- else if( nDims == 3 ) {
- nLocals = Decomp_GetNumLocals( elDecomp ) * 4;
- locals = MemArray( int, nLocals, Inner2DGenerator_Type );
- for( l_i = 0; l_i < Decomp_GetNumLocals( elDecomp ); l_i++ ) {
- global = Decomp_LocalToGlobal( elDecomp, l_i );
- locals[l_i * 4 + 0] = global * 4;
- locals[l_i * 4 + 1] = global * 4 + 1;
- locals[l_i * 4 + 2] = global * 4 + 2;
- locals[l_i * 4 + 3] = global * 4 + 3;
- }
- }
- Decomp_SetLocals( nodeDecomp, nLocals, locals );
- MemFree( locals );
-
- nodeSync = Sync_New();
- Sync_SetComm( nodeSync, Sync_GetComm( elSync ) );
- Sync_SetDecomp( nodeSync, nodeDecomp );
-
- if( nDims == 2 ) {
- nRemotes = Sync_GetNumRemotes( elSync ) * 3;
- remotes = MemArray( int, nRemotes, Inner2DGenerator_Type );
- for( r_i = 0; r_i < Sync_GetNumRemotes( elSync ); r_i++ ) {
- global = Sync_RemoteToGlobal( elSync, r_i );
- remotes[r_i * 3 + 0] = global * 3;
- remotes[r_i * 3 + 1] = global * 3 + 1;
- remotes[r_i * 3 + 2] = global * 3 + 2;
- }
- }
- else if( nDims == 3 ) {
- nRemotes = Sync_GetNumRemotes( elSync ) * 4;
- remotes = MemArray( int, nRemotes, Inner2DGenerator_Type );
- for( r_i = 0; r_i < Sync_GetNumRemotes( elSync ); r_i++ ) {
- global = Sync_RemoteToGlobal( elSync, r_i );
- remotes[r_i * 4 + 0] = global * 4;
- remotes[r_i * 4 + 1] = global * 4 + 1;
- remotes[r_i * 4 + 2] = global * 4 + 2;
- remotes[r_i * 4 + 3] = global * 4 + 3;
- }
- }
- Sync_SetRemotes( nodeSync, nRemotes, remotes );
- MemFree( remotes );
-
- IGraph_SetDomain( topo, 0, nodeSync );
-
- /* Same shadow depth. */
- topo->shadDepth = elTopo->shadDepth;
-
- /* Build the incidence. */
- nDomainEls = Mesh_GetDomainSize( elMesh, (MeshTopology_Dim)nDims );
- if( nDims == 2 ) {
- nIncEls = 3;
- incEls = MemArray( unsigned, 3, Inner2DGenerator_Type );
- for( e_i = 0; e_i < nDomainEls; e_i++ ) {
- incEls[0] = e_i * 3;
- incEls[1] = e_i * 3 + 1;
- incEls[2] = e_i * 3 + 2;
- IGraph_SetIncidence( topo, nDims, e_i, 0, nIncEls, (int*)incEls );
- }
- }
- else if( nDims == 3 ) {
- nIncEls = 4;
- incEls = MemArray( unsigned, 4, Inner2DGenerator_Type );
- for( e_i = 0; e_i < nDomainEls; e_i++ ) {
- incEls[0] = e_i * 4;
- incEls[1] = e_i * 4 + 1;
- incEls[2] = e_i * 4 + 2;
- incEls[3] = e_i * 4 + 3;
- IGraph_SetIncidence( topo, nDims, e_i, 0, nIncEls, (int*)incEls );
- }
- }
- FreeArray( incEls );
-
- IGraph_InvertIncidence( topo, MT_VERTEX, nDims );
-}
-
-void Inner2DGenerator_BuildGeometry( Inner2DGenerator* self, FeMesh* mesh ) {
- Mesh* elMesh;
- double localCrds[3][2] = {{-0.5, -0.5},
- {0.5, -0.5},
- {0, 0.5}};
- double globalCrd[2];
- double *vert;
- unsigned nDims;
- unsigned nDomainEls;
- unsigned e_i;
-
- assert( self );
- assert( mesh );
-
- elMesh = self->elMesh;
- nDims = Mesh_GetDimSize( elMesh );
- nDomainEls = Mesh_GetDomainSize( elMesh, (MeshTopology_Dim)nDims );
-
- if( nDims == 2 ) {
- mesh->verts = AllocArray2D( double, nDomainEls * 3, nDims );
- for( e_i = 0; e_i < nDomainEls; e_i++ ) {
- unsigned elInd = e_i * 3;
-
- FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds[0], globalCrd );
- vert = Mesh_GetVertex( mesh, elInd );
- memcpy( vert, globalCrd, nDims * sizeof(double) );
-
- FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds[1], globalCrd );
- vert = Mesh_GetVertex( mesh, elInd + 1 );
- memcpy( vert, globalCrd, nDims * sizeof(double) );
-
- FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds[2], globalCrd );
- vert = Mesh_GetVertex( mesh, elInd + 2 );
- memcpy( vert, globalCrd, nDims * sizeof(double) );
- }
- }
-
- else if( nDims == 3 ) {
- double localCrds3D[4][3] = { {-0.5, -0.5, -0.5},
- {0.25, 0.25, 0.25},
- {0.5, -0.25, -0.5},
- {-0.25, 0.5, 0.5} };
- double globalCrd3D[3];
-
- mesh->verts = AllocArray2D( double, nDomainEls * 4, nDims );
- for( e_i = 0; e_i < nDomainEls; e_i++ ) {
- unsigned elInd = e_i * 4;
-
- FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds3D[0], globalCrd3D );
- vert = Mesh_GetVertex( mesh, elInd );
- memcpy( vert, globalCrd3D, nDims * sizeof(double) );
-
- FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds3D[1], globalCrd3D );
- vert = Mesh_GetVertex( mesh, elInd + 1 );
- memcpy( vert, globalCrd3D, nDims * sizeof(double) );
-
- FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds3D[2], globalCrd3D );
- vert = Mesh_GetVertex( mesh, elInd + 2 );
- memcpy( vert, globalCrd3D, nDims * sizeof(double) );
-
- FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds3D[3], globalCrd3D );
- vert = Mesh_GetVertex( mesh, elInd + 3 );
- memcpy( vert, globalCrd3D, nDims * sizeof(double) );
- }
- }
-}
-
-void Inner2DGenerator_BuildElementTypes( Inner2DGenerator* self, FeMesh* mesh ) {
- unsigned nDomainEls;
- Mesh_Algorithms* algs;
- unsigned e_i;
-
- assert( self );
- assert( mesh );
-
- mesh->nElTypes = 1;
- mesh->elTypes = AllocNamedArray( Mesh_ElementType*, mesh->nElTypes, "Mesh::elTypes" );
- mesh->elTypes[0] = (Mesh_ElementType*)Mesh_CentroidType_New();
- Mesh_ElementType_SetMesh( mesh->elTypes[0], mesh );
- Mesh_CentroidType_SetElementMesh( mesh->elTypes[0], self->elMesh );
- nDomainEls = Mesh_GetDomainSize( mesh, Mesh_GetDimSize( mesh ) );
- mesh->elTypeMap = AllocNamedArray( unsigned, nDomainEls, "Mesh::elTypeMap" );
- for( e_i = 0; e_i < nDomainEls; e_i++ )
- mesh->elTypeMap[e_i] = 0;
-
- algs = (Mesh_Algorithms*)Mesh_CentroidAlgorithms_New( "", NULL );
- Mesh_CentroidAlgorithms_SetElementMesh( algs, self->elMesh );
- Mesh_SetAlgorithms( mesh, algs );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/Inner2DGenerator.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/Inner2DGenerator.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,392 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Inner2DGenerator.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type Inner2DGenerator_Type = "Inner2DGenerator";
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+Inner2DGenerator* Inner2DGenerator_New( Name name, AbstractContext* context ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(Inner2DGenerator);
+ Type type = Inner2DGenerator_Type;
+ Stg_Class_DeleteFunction* _delete = _Inner2DGenerator_Delete;
+ Stg_Class_PrintFunction* _print = _Inner2DGenerator_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_Inner2DGenerator_New;
+ Stg_Component_ConstructFunction* _construct = _Inner2DGenerator_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Inner2DGenerator_Build;
+ Stg_Component_InitialiseFunction* _initialise = _Inner2DGenerator_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _Inner2DGenerator_Execute;
+ Stg_Component_DestroyFunction* _destroy = NULL;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ MeshGenerator_SetDimSizeFunc* setDimSizeFunc = _MeshGenerator_SetDimSize;
+ MeshGenerator_GenerateFunc* generateFunc = (MeshGenerator_GenerateFunc*)Inner2DGenerator_Generate;
+
+ Inner2DGenerator* self = _Inner2DGenerator_New( INNER2DGENERATOR_PASSARGS );
+
+ _MeshGenerator_Init( (MeshGenerator*)self, context );
+ _Inner2DGenerator_Init( self );
+
+ return self;
+}
+
+Inner2DGenerator* _Inner2DGenerator_New( INNER2DGENERATOR_DEFARGS ) {
+ Inner2DGenerator* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(Inner2DGenerator) );
+ self = (Inner2DGenerator*)_MeshGenerator_New( MESHGENERATOR_PASSARGS );
+
+ return self;
+}
+
+void _Inner2DGenerator_Init( Inner2DGenerator* self ) {
+ assert( self && Stg_CheckType( self, Inner2DGenerator ) );
+
+ self->elMesh = NULL;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _Inner2DGenerator_Delete( void* generator ) {
+ Inner2DGenerator* self = (Inner2DGenerator*)generator;
+
+ /* Delete the parent. */
+ _MeshGenerator_Delete( self );
+}
+
+void _Inner2DGenerator_Print( void* generator, Stream* stream ) {
+ Inner2DGenerator* self = (Inner2DGenerator*)generator;
+
+ /* Set the Journal for printing informations */
+ Stream* generatorStream;
+ generatorStream = Journal_Register( InfoStream_Type, (Name)"Inner2DGeneratorStream" );
+
+ /* Print parent */
+ Journal_Printf( stream, "Inner2DGenerator (ptr): (%p)\n", self );
+ _MeshGenerator_Print( self, stream );
+}
+
+void _Inner2DGenerator_AssignFromXML( void* generator, Stg_ComponentFactory* cf, void* data ) {
+ Inner2DGenerator* self = (Inner2DGenerator*)generator;
+ Mesh* elMesh;
+
+ assert( self );
+ assert( cf );
+
+ _MeshGenerator_AssignFromXML( self, cf, data );
+
+ elMesh = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"elementMesh", Mesh, True, data );
+ Inner2DGenerator_SetElementMesh( self, elMesh );
+}
+
+void _Inner2DGenerator_Build( void* generator, void* data ) {
+ _MeshGenerator_Build( generator, data );
+}
+
+void _Inner2DGenerator_Initialise( void* generator, void* data ) {
+ _MeshGenerator_Initialise( generator, data );
+}
+
+void _Inner2DGenerator_Execute( void* generator, void* data ) {
+}
+
+void _Inner2DGenerator_Destroy( void* generator, void* data ) {
+ Inner2DGenerator* self = (Inner2DGenerator*)generator;
+
+ Stg_Component_Destroy( self->elMesh, data, False );
+ _MeshGenerator_Destroy( self, data );
+}
+
+void Inner2DGenerator_Generate( void* generator, void* _mesh ) {
+ Inner2DGenerator* self = (Inner2DGenerator*)generator;
+ FeMesh* mesh = (FeMesh*)_mesh;
+ Grid** grid;
+ Grid* elGrid;
+
+ assert( self && Stg_CheckType( self, Inner2DGenerator ) );
+ assert( mesh && Stg_CheckType( mesh, FeMesh ) );
+
+ Inner2DGenerator_BuildTopology( self, mesh );
+ Inner2DGenerator_BuildGeometry( self, mesh );
+ Inner2DGenerator_BuildElementTypes( self, mesh );
+
+ elGrid = *(Grid**)ExtensionManager_Get( self->elMesh->info, self->elMesh,
+ ExtensionManager_GetHandle( self->elMesh->info, (Name)"elementGrid" ) );
+ ExtensionManager_Add( mesh->info, (Name)"elementGrid", sizeof(Grid*) );
+ grid = (Grid** )ExtensionManager_Get( mesh->info, mesh,
+ ExtensionManager_GetHandle( mesh->info, (Name)"elementGrid" ) );
+ *grid = Grid_New( );
+ Grid_SetNumDims( *grid, elGrid->nDims );
+ Grid_SetSizes( *grid, elGrid->sizes );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+void Inner2DGenerator_SetElementMesh( void* generator, void* mesh ) {
+ Inner2DGenerator* self = (Inner2DGenerator*)generator;
+
+ assert( self && Stg_CheckType( self, Inner2DGenerator ) );
+
+ self->elMesh = (Mesh*)mesh;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+void Inner2DGenerator_BuildTopology( Inner2DGenerator* self, FeMesh* mesh ) {
+ Mesh* elMesh;
+ MeshTopology *topo, *elTopo;
+ unsigned nDims;
+ unsigned nIncEls, *incEls;
+ unsigned nDomainEls;
+ Decomp *elDecomp, *nodeDecomp;
+ Sync *elSync, *nodeSync;
+ int nLocals, *locals;
+ int nRemotes, *remotes;
+ unsigned global;
+ unsigned e_i, l_i, r_i;
+
+ assert( self );
+ assert( mesh );
+
+ elMesh = self->elMesh;
+ nDims = Mesh_GetDimSize( elMesh );
+ elTopo = Mesh_GetTopology( elMesh );
+ elSync = Mesh_GetSync( elMesh, (MeshTopology_Dim)nDims );
+
+ topo = Mesh_GetTopology( mesh );
+ MeshTopology_SetComm( topo, MeshTopology_GetComm( elTopo ) );
+ MeshTopology_SetNumDims( topo, nDims );
+ IGraph_SetDomain( topo, nDims, elSync );
+
+ /* Need to redefine the nodes, nDims + 1 per parent element. */
+ elDecomp = (Decomp*)Sync_GetDecomp( elSync );
+ nodeDecomp = Decomp_New();
+
+ if( nDims == 2 ) {
+ nLocals = Decomp_GetNumLocals( elDecomp ) * 3;
+ locals = MemArray( int, nLocals, Inner2DGenerator_Type );
+ for( l_i = 0; l_i < Decomp_GetNumLocals( elDecomp ); l_i++ ) {
+ global = Decomp_LocalToGlobal( elDecomp, l_i );
+ locals[l_i * 3 + 0] = global * 3;
+ locals[l_i * 3 + 1] = global * 3 + 1;
+ locals[l_i * 3 + 2] = global * 3 + 2;
+ }
+ }
+ else if( nDims == 3 ) {
+ nLocals = Decomp_GetNumLocals( elDecomp ) * 4;
+ locals = MemArray( int, nLocals, Inner2DGenerator_Type );
+ for( l_i = 0; l_i < Decomp_GetNumLocals( elDecomp ); l_i++ ) {
+ global = Decomp_LocalToGlobal( elDecomp, l_i );
+ locals[l_i * 4 + 0] = global * 4;
+ locals[l_i * 4 + 1] = global * 4 + 1;
+ locals[l_i * 4 + 2] = global * 4 + 2;
+ locals[l_i * 4 + 3] = global * 4 + 3;
+ }
+ }
+ Decomp_SetLocals( nodeDecomp, nLocals, locals );
+ MemFree( locals );
+
+ nodeSync = Sync_New();
+ Sync_SetComm( nodeSync, Sync_GetComm( elSync ) );
+ Sync_SetDecomp( nodeSync, nodeDecomp );
+
+ if( nDims == 2 ) {
+ nRemotes = Sync_GetNumRemotes( elSync ) * 3;
+ remotes = MemArray( int, nRemotes, Inner2DGenerator_Type );
+ for( r_i = 0; r_i < Sync_GetNumRemotes( elSync ); r_i++ ) {
+ global = Sync_RemoteToGlobal( elSync, r_i );
+ remotes[r_i * 3 + 0] = global * 3;
+ remotes[r_i * 3 + 1] = global * 3 + 1;
+ remotes[r_i * 3 + 2] = global * 3 + 2;
+ }
+ }
+ else if( nDims == 3 ) {
+ nRemotes = Sync_GetNumRemotes( elSync ) * 4;
+ remotes = MemArray( int, nRemotes, Inner2DGenerator_Type );
+ for( r_i = 0; r_i < Sync_GetNumRemotes( elSync ); r_i++ ) {
+ global = Sync_RemoteToGlobal( elSync, r_i );
+ remotes[r_i * 4 + 0] = global * 4;
+ remotes[r_i * 4 + 1] = global * 4 + 1;
+ remotes[r_i * 4 + 2] = global * 4 + 2;
+ remotes[r_i * 4 + 3] = global * 4 + 3;
+ }
+ }
+ Sync_SetRemotes( nodeSync, nRemotes, remotes );
+ MemFree( remotes );
+
+ IGraph_SetDomain( topo, 0, nodeSync );
+
+ /* Same shadow depth. */
+ topo->shadDepth = elTopo->shadDepth;
+
+ /* Build the incidence. */
+ nDomainEls = Mesh_GetDomainSize( elMesh, (MeshTopology_Dim)nDims );
+ if( nDims == 2 ) {
+ nIncEls = 3;
+ incEls = MemArray( unsigned, 3, Inner2DGenerator_Type );
+ for( e_i = 0; e_i < nDomainEls; e_i++ ) {
+ incEls[0] = e_i * 3;
+ incEls[1] = e_i * 3 + 1;
+ incEls[2] = e_i * 3 + 2;
+ IGraph_SetIncidence( topo, nDims, e_i, 0, nIncEls, (int*)incEls );
+ }
+ }
+ else if( nDims == 3 ) {
+ nIncEls = 4;
+ incEls = MemArray( unsigned, 4, Inner2DGenerator_Type );
+ for( e_i = 0; e_i < nDomainEls; e_i++ ) {
+ incEls[0] = e_i * 4;
+ incEls[1] = e_i * 4 + 1;
+ incEls[2] = e_i * 4 + 2;
+ incEls[3] = e_i * 4 + 3;
+ IGraph_SetIncidence( topo, nDims, e_i, 0, nIncEls, (int*)incEls );
+ }
+ }
+ FreeArray( incEls );
+
+ IGraph_InvertIncidence( topo, MT_VERTEX, nDims );
+}
+
+void Inner2DGenerator_BuildGeometry( Inner2DGenerator* self, FeMesh* mesh ) {
+ Mesh* elMesh;
+ double localCrds[3][2] = {{-0.5, -0.5},
+ {0.5, -0.5},
+ {0, 0.5}};
+ double globalCrd[2];
+ double *vert;
+ unsigned nDims;
+ unsigned nDomainEls;
+ unsigned e_i;
+
+ assert( self );
+ assert( mesh );
+
+ elMesh = self->elMesh;
+ nDims = Mesh_GetDimSize( elMesh );
+ nDomainEls = Mesh_GetDomainSize( elMesh, (MeshTopology_Dim)nDims );
+
+ if( nDims == 2 ) {
+ mesh->verts = AllocArray2D( double, nDomainEls * 3, nDims );
+ for( e_i = 0; e_i < nDomainEls; e_i++ ) {
+ unsigned elInd = e_i * 3;
+
+ FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds[0], globalCrd );
+ vert = Mesh_GetVertex( mesh, elInd );
+ memcpy( vert, globalCrd, nDims * sizeof(double) );
+
+ FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds[1], globalCrd );
+ vert = Mesh_GetVertex( mesh, elInd + 1 );
+ memcpy( vert, globalCrd, nDims * sizeof(double) );
+
+ FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds[2], globalCrd );
+ vert = Mesh_GetVertex( mesh, elInd + 2 );
+ memcpy( vert, globalCrd, nDims * sizeof(double) );
+ }
+ }
+
+ else if( nDims == 3 ) {
+ double localCrds3D[4][3] = { {-0.5, -0.5, -0.5},
+ {0.25, 0.25, 0.25},
+ {0.5, -0.25, -0.5},
+ {-0.25, 0.5, 0.5} };
+ double globalCrd3D[3];
+
+ mesh->verts = AllocArray2D( double, nDomainEls * 4, nDims );
+ for( e_i = 0; e_i < nDomainEls; e_i++ ) {
+ unsigned elInd = e_i * 4;
+
+ FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds3D[0], globalCrd3D );
+ vert = Mesh_GetVertex( mesh, elInd );
+ memcpy( vert, globalCrd3D, nDims * sizeof(double) );
+
+ FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds3D[1], globalCrd3D );
+ vert = Mesh_GetVertex( mesh, elInd + 1 );
+ memcpy( vert, globalCrd3D, nDims * sizeof(double) );
+
+ FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds3D[2], globalCrd3D );
+ vert = Mesh_GetVertex( mesh, elInd + 2 );
+ memcpy( vert, globalCrd3D, nDims * sizeof(double) );
+
+ FeMesh_CoordLocalToGlobal( elMesh, e_i, localCrds3D[3], globalCrd3D );
+ vert = Mesh_GetVertex( mesh, elInd + 3 );
+ memcpy( vert, globalCrd3D, nDims * sizeof(double) );
+ }
+ }
+}
+
+void Inner2DGenerator_BuildElementTypes( Inner2DGenerator* self, FeMesh* mesh ) {
+ unsigned nDomainEls;
+ Mesh_Algorithms* algs;
+ unsigned e_i;
+
+ assert( self );
+ assert( mesh );
+
+ mesh->nElTypes = 1;
+ mesh->elTypes = AllocNamedArray( Mesh_ElementType*, mesh->nElTypes, "Mesh::elTypes" );
+ mesh->elTypes[0] = (Mesh_ElementType*)Mesh_CentroidType_New();
+ Mesh_ElementType_SetMesh( mesh->elTypes[0], mesh );
+ Mesh_CentroidType_SetElementMesh( mesh->elTypes[0], self->elMesh );
+ nDomainEls = Mesh_GetDomainSize( mesh, Mesh_GetDimSize( mesh ) );
+ mesh->elTypeMap = AllocNamedArray( unsigned, nDomainEls, "Mesh::elTypeMap" );
+ for( e_i = 0; e_i < nDomainEls; e_i++ )
+ mesh->elTypeMap[e_i] = 0;
+
+ algs = (Mesh_Algorithms*)Mesh_CentroidAlgorithms_New( "", NULL );
+ Mesh_CentroidAlgorithms_SetElementMesh( algs, self->elMesh );
+ Mesh_SetAlgorithms( mesh, algs );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/LinearTriangleElementType.c
--- a/Discretisation/src/LinearTriangleElementType.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: LinearTriangleElementType.c 1177 2008-07-15 01:29:58Z DavidLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "ElementType.h"
-#include "LinearTriangleElementType.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-
-const Type LinearTriangleElementType_Type = "LinearTriangleElementType";
-
-#define _LinearTriangleElementType_NodeCount 3
-
-LinearTriangleElementType* LinearTriangleElementType_New( Name name ) {
- LinearTriangleElementType* self = (LinearTriangleElementType*)_LinearTriangleElementType_DefaultNew( name );
-
- self->isConstructed = True;
- _ElementType_Init( (ElementType*)self, _LinearTriangleElementType_NodeCount );
- _LinearTriangleElementType_Init( self );
-
- return self;
-}
-
-void* _LinearTriangleElementType_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(LinearTriangleElementType);
- Type type = LinearTriangleElementType_Type;
- Stg_Class_DeleteFunction* _delete = _LinearTriangleElementType_Delete;
- Stg_Class_PrintFunction* _print = _LinearTriangleElementType_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LinearTriangleElementType_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _LinearTriangleElementType_AssignFromXML;
- Stg_Component_BuildFunction* _build = _LinearTriangleElementType_Build;
- Stg_Component_InitialiseFunction* _initialise = _LinearTriangleElementType_Initialise;
- Stg_Component_ExecuteFunction* _execute = _LinearTriangleElementType_Execute;
- Stg_Component_DestroyFunction* _destroy = _LinearTriangleElementType_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _LinearTriangleElementType_SF_allNodes;
- ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _LinearTriangleElementType_SF_allLocalDerivs_allNodes;
- ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
- ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _ElementType_JacobianDeterminantSurface;
- ElementType_SurfaceNormalFunction* _surfaceNormal = _LinearTriangularElementType_SurfaceNormal;
-
- return _LinearTriangleElementType_New( LINEARTRIANGLEELEMENTTYPE_PASSARGS );
-}
-
-LinearTriangleElementType* _LinearTriangleElementType_New( LINEARTRIANGLEELEMENTTYPE_DEFARGS ) {
- LinearTriangleElementType* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(LinearTriangleElementType) );
- self = (LinearTriangleElementType*)_ElementType_New( ELEMENTTYPE_PASSARGS );
-
- /* General info */
-
- /* Virtual functions */
-
- /* LinearTriangleElementType info */
-
- return self;
-}
-
-void _LinearTriangleElementType_Init( LinearTriangleElementType* self ) {
- self->dim = 1;
-}
-
-void _LinearTriangleElementType_Delete( void* elementType ) {
- LinearTriangleElementType* self = (LinearTriangleElementType*)elementType;
-
- /* Stg_Class_Delete parent*/
- _ElementType_Delete( self );
-}
-
-void _LinearTriangleElementType_Print( void* elementType, Stream* stream ) {
- LinearTriangleElementType* self = (LinearTriangleElementType*)elementType;
-
- /* Set the Journal for printing informations */
- Stream* linearTriangleElementTypeStream = stream;
-
- /* General info */
- Journal_Printf( linearTriangleElementTypeStream, "LinearTriangleElementType (ptr): %p\n", self );
-
- /* Print parent */
- _ElementType_Print( self, linearTriangleElementTypeStream );
-
- /* Virtual info */
-
- /* LinearTriangleElementType info */
-}
-
-void _LinearTriangleElementType_AssignFromXML( void* elementType, Stg_ComponentFactory *cf, void* data ){
- LinearTriangleElementType* self = (LinearTriangleElementType*)elementType;
-
- _LinearTriangleElementType_Init( self );
-}
-
-void _LinearTriangleElementType_Build( void* elementType, void *data ){
-}
-
-void _LinearTriangleElementType_Initialise( void* elementType, void *data ){
-}
-
-void _LinearTriangleElementType_Execute( void* elementType, void *data ){
-}
-
-void _LinearTriangleElementType_Destroy( void* elementType, void *data ){
- LinearTriangleElementType* self = (LinearTriangleElementType*)elementType;
-
- _ElementType_Destroy( self, data );
-}
-
-/*
-
- - Shape function definitions
- - Local node numbering convention for linearTriangle element (xi, eta)
- - Local coordinate domain spans 0 <= xi,eta <= 1
-
- eta
- |
- |____ xi
-
- eta
- |
- |
-2 \
-| \
-| \_____xi
-| \
-0-----\1
-
-
-*/
-void _LinearTriangleElementType_SF_allNodes( void* elementType, const double localCoord[], double* const evaluatedValues) {
- double xi, eta, zeta;
-
- xi = localCoord[0];
- eta = localCoord[1];
- zeta = localCoord[2];
-
- evaluatedValues[0] = 1.0 - xi - eta;
- evaluatedValues[1] = xi;
- evaluatedValues[2] = eta;
-}
-
-
-void _LinearTriangleElementType_SF_allLocalDerivs_allNodes( void* elementType, const double localCoord[],
- double** const evaluatedDerivatives )
-{
- double xi, eta, zeta;
-
- xi = localCoord[0];
- eta = localCoord[1];
- zeta = localCoord[2];
-
- /* derivatives wrt xi */
- evaluatedDerivatives[0][0] = -1.0;
- evaluatedDerivatives[0][1] = 1.0;
- evaluatedDerivatives[0][2] = 0.0;
-
- /* derivatives wrt eta */
- evaluatedDerivatives[1][0] = - 1.0;
- evaluatedDerivatives[1][1] = 0.0;
- evaluatedDerivatives[1][2] = 1.0;
-}
-
-int _LinearTriangularElementType_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* norm ) {
- Stream* errStream = Journal_Register( ErrorStream_Type, (Name)ElementType_Type );
-
- Journal_Printf( errStream, "surface normal function not yet implemented for this element type.\n" );
- assert( 0 );
-
- norm = NULL;
-
- return -1;
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/LinearTriangleElementType.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/LinearTriangleElementType.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,222 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: LinearTriangleElementType.c 1177 2008-07-15 01:29:58Z DavidLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "ElementType.h"
+#include "LinearTriangleElementType.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+const Type LinearTriangleElementType_Type = "LinearTriangleElementType";
+
+#define _LinearTriangleElementType_NodeCount 3
+
+LinearTriangleElementType* LinearTriangleElementType_New( Name name ) {
+ LinearTriangleElementType* self = (LinearTriangleElementType*)_LinearTriangleElementType_DefaultNew( name );
+
+ self->isConstructed = True;
+ _ElementType_Init( (ElementType*)self, _LinearTriangleElementType_NodeCount );
+ _LinearTriangleElementType_Init( self );
+
+ return self;
+}
+
+void* _LinearTriangleElementType_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(LinearTriangleElementType);
+ Type type = LinearTriangleElementType_Type;
+ Stg_Class_DeleteFunction* _delete = _LinearTriangleElementType_Delete;
+ Stg_Class_PrintFunction* _print = _LinearTriangleElementType_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LinearTriangleElementType_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _LinearTriangleElementType_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _LinearTriangleElementType_Build;
+ Stg_Component_InitialiseFunction* _initialise = _LinearTriangleElementType_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _LinearTriangleElementType_Execute;
+ Stg_Component_DestroyFunction* _destroy = _LinearTriangleElementType_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _LinearTriangleElementType_SF_allNodes;
+ ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _LinearTriangleElementType_SF_allLocalDerivs_allNodes;
+ ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
+ ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _ElementType_JacobianDeterminantSurface;
+ ElementType_SurfaceNormalFunction* _surfaceNormal = _LinearTriangularElementType_SurfaceNormal;
+
+ return _LinearTriangleElementType_New( LINEARTRIANGLEELEMENTTYPE_PASSARGS );
+}
+
+LinearTriangleElementType* _LinearTriangleElementType_New( LINEARTRIANGLEELEMENTTYPE_DEFARGS ) {
+ LinearTriangleElementType* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(LinearTriangleElementType) );
+ self = (LinearTriangleElementType*)_ElementType_New( ELEMENTTYPE_PASSARGS );
+
+ /* General info */
+
+ /* Virtual functions */
+
+ /* LinearTriangleElementType info */
+
+ return self;
+}
+
+void _LinearTriangleElementType_Init( LinearTriangleElementType* self ) {
+ self->dim = 1;
+}
+
+void _LinearTriangleElementType_Delete( void* elementType ) {
+ LinearTriangleElementType* self = (LinearTriangleElementType*)elementType;
+
+ /* Stg_Class_Delete parent*/
+ _ElementType_Delete( self );
+}
+
+void _LinearTriangleElementType_Print( void* elementType, Stream* stream ) {
+ LinearTriangleElementType* self = (LinearTriangleElementType*)elementType;
+
+ /* Set the Journal for printing informations */
+ Stream* linearTriangleElementTypeStream = stream;
+
+ /* General info */
+ Journal_Printf( linearTriangleElementTypeStream, "LinearTriangleElementType (ptr): %p\n", self );
+
+ /* Print parent */
+ _ElementType_Print( self, linearTriangleElementTypeStream );
+
+ /* Virtual info */
+
+ /* LinearTriangleElementType info */
+}
+
+void _LinearTriangleElementType_AssignFromXML( void* elementType, Stg_ComponentFactory *cf, void* data ){
+ LinearTriangleElementType* self = (LinearTriangleElementType*)elementType;
+
+ _LinearTriangleElementType_Init( self );
+}
+
+void _LinearTriangleElementType_Build( void* elementType, void *data ){
+}
+
+void _LinearTriangleElementType_Initialise( void* elementType, void *data ){
+}
+
+void _LinearTriangleElementType_Execute( void* elementType, void *data ){
+}
+
+void _LinearTriangleElementType_Destroy( void* elementType, void *data ){
+ LinearTriangleElementType* self = (LinearTriangleElementType*)elementType;
+
+ _ElementType_Destroy( self, data );
+}
+
+/*
+
+ - Shape function definitions
+ - Local node numbering convention for linearTriangle element (xi, eta)
+ - Local coordinate domain spans 0 <= xi,eta <= 1
+
+ eta
+ |
+ |____ xi
+
+ eta
+ |
+ |
+2 \
+| \
+| \_____xi
+| \
+0-----\1
+
+
+*/
+void _LinearTriangleElementType_SF_allNodes( void* elementType, const double localCoord[], double* const evaluatedValues) {
+ double xi, eta, zeta;
+
+ xi = localCoord[0];
+ eta = localCoord[1];
+ zeta = localCoord[2];
+
+ evaluatedValues[0] = 1.0 - xi - eta;
+ evaluatedValues[1] = xi;
+ evaluatedValues[2] = eta;
+}
+
+
+void _LinearTriangleElementType_SF_allLocalDerivs_allNodes( void* elementType, const double localCoord[],
+ double** const evaluatedDerivatives )
+{
+ double xi, eta, zeta;
+
+ xi = localCoord[0];
+ eta = localCoord[1];
+ zeta = localCoord[2];
+
+ /* derivatives wrt xi */
+ evaluatedDerivatives[0][0] = -1.0;
+ evaluatedDerivatives[0][1] = 1.0;
+ evaluatedDerivatives[0][2] = 0.0;
+
+ /* derivatives wrt eta */
+ evaluatedDerivatives[1][0] = - 1.0;
+ evaluatedDerivatives[1][1] = 0.0;
+ evaluatedDerivatives[1][2] = 1.0;
+}
+
+int _LinearTriangularElementType_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* norm ) {
+ Stream* errStream = Journal_Register( ErrorStream_Type, (Name)ElementType_Type );
+
+ Journal_Printf( errStream, "surface normal function not yet implemented for this element type.\n" );
+ assert( 0 );
+
+ norm = NULL;
+
+ return -1;
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/LinkedDofInfo.c
--- a/Discretisation/src/LinkedDofInfo.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,474 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: LinkedDofInfo.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "LinkedDofInfo.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <assert.h>
-
-/** Textual name of this class */
-const Type LinkedDofInfo_Type = "LinkedDofInfo";
-
-LinkedDofInfo* LinkedDofInfo_New( Name name, DomainContext* context, void* mesh, DofLayout* dofLayout, Dictionary* dictionary ) {
- LinkedDofInfo* self = (LinkedDofInfo*)_LinkedDofInfo_DefaultNew( name );
-
- self->isConstructed = True;
- _LinkedDofInfo_Init( self, context, mesh, dofLayout, dictionary );
-
- return self;
-}
-
-void* _LinkedDofInfo_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(LinkedDofInfo);
- Type type = LinkedDofInfo_Type;
- Stg_Class_DeleteFunction* _delete = _LinkedDofInfo_Delete;
- Stg_Class_PrintFunction* _print = _LinkedDofInfo_Print;
- Stg_Class_CopyFunction* _copy = _LinkedDofInfo_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LinkedDofInfo_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _LinkedDofInfo_AssignFromXML;
- Stg_Component_BuildFunction* _build = _LinkedDofInfo_Build;
- Stg_Component_InitialiseFunction* _initialise = _LinkedDofInfo_Initialise;
- Stg_Component_ExecuteFunction* _execute = _LinkedDofInfo_Execute;
- Stg_Component_DestroyFunction* _destroy = _LinkedDofInfo_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
-
- return (void*)
- _LinkedDofInfo_New( LINKEDDOFINFO_PASSARGS );
-}
-
-LinkedDofInfo* _LinkedDofInfo_New( LINKEDDOFINFO_DEFARGS ) {
- LinkedDofInfo* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(LinkedDofInfo) );
- self = (LinkedDofInfo*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- /* General info */
-
- /* Virtual info */
- self->_build = _build;
- self->_initialise = _initialise;
-
- /* member info */
-
- return self;
-}
-
-void _LinkedDofInfo_Init( void* linkedDofInfo, DomainContext* context, void* mesh, DofLayout* dofLayout, Dictionary* dictionary ) {
- LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
-
- self->context = context;
- self->dofLayout = dofLayout;
- self->mesh = (Mesh*)mesh;
- self->dictionary = dictionary;
-
- /* Initially no sets */
- self->linkedDofSetsCount = 0;
- self->linkedDofSetsDelta = 4;
- self->linkedDofSetsSize = self->linkedDofSetsDelta;
- self->eqNumsOfLinkedDofs = Memory_Alloc_Array( int, self->linkedDofSetsSize, "linkedDofInfo->eqNumsOfLinkedDofs" );
-}
-
-void _LinkedDofInfo_Delete( void* linkedDofInfo ) {
- LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
-
- _Stg_Component_Delete( self );
-}
-
-void _LinkedDofInfo_Print( void* linkedDofInfo, Stream* stream ) {
- LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
- Index dofSet_I = 0;
- Node_Index node_I = 0;
- Dof_Index nodeLocalDof_I = 0;
-
- /* General info */
- Journal_Printf( stream, "LinkedDofInfo (ptr): %p\n", self );
-
- /* Print parent */
- _Stg_Class_Print( self, stream );
-
- Journal_Printf( stream, "%d Linked dof sets active:\n", self->linkedDofSetsCount );
- Stream_Indent( stream );
-
- for ( dofSet_I = 0; dofSet_I < self->linkedDofSetsCount; dofSet_I++ ) {
- Journal_Printf( stream, "Set %u: has eqNum %d\n", dofSet_I, self->eqNumsOfLinkedDofs[dofSet_I] );
- }
- Stream_UnIndent( stream );
-
- Journal_Printf( stream, "Linked dof sets table:\n", self->linkedDofSetsCount );
- Stream_Indent( stream );
-
- for ( node_I = 0; node_I < self->dofLayout->_numItemsInLayout; node_I++ ) {
- Journal_Printf( stream, "Node %d: ", node_I );
- for ( nodeLocalDof_I = 0; nodeLocalDof_I < self->dofLayout->dofCounts[node_I]; nodeLocalDof_I++ ) {
- Journal_Printf( stream, "%d, ", self->linkedDofTbl[node_I][nodeLocalDof_I] );
- }
- Journal_Printf( stream, "\n" );
- }
- Stream_UnIndent( stream );
-}
-
-void _LinkedDofInfo_AssignFromXML( void* linkedDofInfo, Stg_ComponentFactory *cf, void* data ){
- LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
- Dictionary* dictionary;
- Mesh* mesh = NULL;
- DofLayout* dofLayout = NULL;
- DomainContext* context;
-
- dictionary = Dictionary_GetDictionary( cf->componentDict, self->name );
-
- context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", DomainContext, False, data );
- if( !context )
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", DomainContext, True, data );
-
- mesh = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Mesh", Mesh, True, data );
- dofLayout = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)DofLayout_Type, DofLayout, True, data );
-
- _LinkedDofInfo_Init( self, context, mesh, dofLayout, dictionary );
-}
-
-void _LinkedDofInfo_Execute( void* linkedDofInfo, void *data ){
-}
-
-void _LinkedDofInfo_Destroy( void* linkedDofInfo, void *data ){
- LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
-
- Memory_Free( self->linkedDofTbl );
- Memory_Free( self->eqNumsOfLinkedDofs );
-}
-
-void* _LinkedDofInfo_Copy( const void* linkedDofInfo, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
- LinkedDofInfo* newLinkedDofInfo;
- PtrMap* map = ptrMap;
- Bool ownMap = False;
-
- if( !map ) {
- map = PtrMap_New( 10 );
- ownMap = True;
- }
-
- newLinkedDofInfo = (LinkedDofInfo*)_Stg_Class_Copy( self, dest, deep, nameExt, map );
-
- /* Virtual methods */
- newLinkedDofInfo->linkedDofSetsCount = self->linkedDofSetsCount;
- newLinkedDofInfo->linkedDofSetsSize = self->linkedDofSetsSize;
- newLinkedDofInfo->linkedDofSetsDelta = self->linkedDofSetsDelta;
-
- if ( deep ) {
- newLinkedDofInfo->dofLayout = (DofLayout*)Stg_Class_Copy( self->dofLayout, NULL, deep, nameExt, map );
- newLinkedDofInfo->mesh = (Mesh*)Stg_Class_Copy( self->mesh, NULL, deep, nameExt, map );
-
- if ( (newLinkedDofInfo->linkedDofTbl = (int**)PtrMap_Find( map, self->linkedDofTbl )) == NULL && self->linkedDofTbl ) {
- Node_Index node_I;
- Dof_Index dof_I;
- newLinkedDofInfo->linkedDofTbl = Memory_Alloc_2DComplex( int, self->dofLayout->_numItemsInLayout, self->dofLayout->dofCounts, "linkedDofInfo->linkedDofTbl" );
- for ( node_I = 0; node_I < self->dofLayout->_numItemsInLayout; node_I++ ) {
- for ( dof_I = 0; dof_I < self->dofLayout->dofCounts[node_I]; dof_I++ ) {
- newLinkedDofInfo->linkedDofTbl[node_I][dof_I] =
- self->linkedDofTbl[node_I][dof_I];
- }
- }
- PtrMap_Append( map, self->linkedDofTbl, newLinkedDofInfo->linkedDofTbl );
- }
- if ( (newLinkedDofInfo->eqNumsOfLinkedDofs = (int*)PtrMap_Find( map, self->eqNumsOfLinkedDofs )) == NULL && self->eqNumsOfLinkedDofs ) {
- newLinkedDofInfo->eqNumsOfLinkedDofs = Memory_Alloc_Array( int, self->linkedDofSetsCount, "linkedDofInfo->eqNumsOfLinkedDofs" );
- memcpy( newLinkedDofInfo->eqNumsOfLinkedDofs, self->eqNumsOfLinkedDofs, self->linkedDofSetsCount * sizeof(int) );
- PtrMap_Append( map, self->eqNumsOfLinkedDofs, newLinkedDofInfo->eqNumsOfLinkedDofs );
- }
- }
- else {
- newLinkedDofInfo->dofLayout = self->dofLayout;
- newLinkedDofInfo->mesh = self->mesh;
- newLinkedDofInfo->linkedDofTbl = self->linkedDofTbl;
- newLinkedDofInfo->eqNumsOfLinkedDofs = self->eqNumsOfLinkedDofs;
- }
-
- if( ownMap ) {
- Stg_Class_Delete( map );
- }
-
- return (void*)newLinkedDofInfo;
-}
-
-void _LinkedDofInfo_Build( void* linkedDofInfo, void* data ) {
- LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
- Dictionary_Entry_Value* linkSpecs = NULL;
- Node_Index node_I;
- Node_Index nodeLocalDof_I;
- DofLayout* dofLayout;
-
- dofLayout = self->dofLayout;
- Stg_Component_Build( self->dofLayout, data, False );
-
- self->linkedDofTbl = Memory_Alloc_2DComplex( int, dofLayout->_numItemsInLayout,
- dofLayout->dofCounts, "linkedDofInfo->linkedDofTbl" );
-
- /* Initially, set all dofs as not belonging to a set */
- for ( node_I = 0 ; node_I < dofLayout->_numItemsInLayout; node_I++ ) {
- for ( nodeLocalDof_I = 0; nodeLocalDof_I < dofLayout->dofCounts[node_I]; nodeLocalDof_I++ ) {
- self->linkedDofTbl[node_I][nodeLocalDof_I] = -1;
- }
- }
-
- linkSpecs = Dictionary_Get( self->dictionary, (Dictionary_Entry_Key)"linkSpecifications" );
-
- /* Note that the dictionary entry is optional - user may prefer to specify the sets
- using the AddDofToSet and AddDofsToSet_FromIndexSet functions */
-
- if ( linkSpecs ) {
- Index numSpecs = 0;
- Index linkSpec_I;
- Dictionary_Entry_Value* linkSpec = NULL;
- Dictionary* linkSpecDict;
- Index dofSet = 0;
- Dictionary_Entry_Value* wallVal;
- Dictionary_Entry_Value* shapeVal;
- Dictionary_Entry_Value* wallPairVal;
- Index nodalDof;
-
- numSpecs = Dictionary_Entry_Value_GetCount( linkSpecs );
-
- for ( linkSpec_I = 0; linkSpec_I < numSpecs; linkSpec_I++ ) {
- linkSpec = Dictionary_Entry_Value_GetElement( linkSpecs, linkSpec_I );
- linkSpecDict = Dictionary_Entry_Value_AsDictionary( linkSpec );
- nodalDof = Dictionary_Entry_Value_AsUnsignedInt( Dictionary_Get( linkSpecDict, (Dictionary_Entry_Key)"dof" ) );
-
- if ( nodalDof >= self->dofLayout->dofCounts[0] ) {
- Stream* warningStr = Journal_Register( Error_Type, (Name)self->type );
-
- Journal_DPrintf( warningStr, "Warning- in %s: User requested a periodic BC on "
- "dof %d, but only %d dofs are active. Ignoring.\n", __func__, nodalDof,
- self->dofLayout->dofCounts[0] );
-
- continue;
- }
-
- if ( ( wallVal = Dictionary_Get( linkSpecDict, (Dictionary_Entry_Key)"wall" ) ) ) {
- IndexSet* indexSet = NULL;
- char* wallStr = Dictionary_Entry_Value_AsString( wallVal );
-
- dofSet = Dictionary_Entry_Value_AsUnsignedInt( Dictionary_Get( linkSpecDict, (Dictionary_Entry_Key)"dofSet" ) );
-
- if ( 0 == strcmp( wallStr, "left" ) ) {
- indexSet = RegularMeshUtils_CreateGlobalLeftSet( self->mesh );
- }
- else if ( 0 == strcmp( wallStr, "right" ) ) {
- indexSet = RegularMeshUtils_CreateGlobalRightSet( self->mesh );
- }
- else if ( 0 == strcmp( wallStr, "bottom" ) ) {
- indexSet = RegularMeshUtils_CreateGlobalBottomSet( self->mesh );
- }
- else if ( 0 == strcmp( wallStr, "top" ) ) {
- indexSet = RegularMeshUtils_CreateGlobalTopSet( self->mesh );
- }
- else if ( 0 == strcmp( wallStr, "front" ) ) {
- indexSet = RegularMeshUtils_CreateGlobalFrontSet( self->mesh );
- }
- else if ( 0 == strcmp( wallStr, "back" ) ) {
- indexSet = RegularMeshUtils_CreateGlobalBackSet( self->mesh );
- }
- else {
- Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
- Journal_Printf( errorStr, "Error in %s: unknown wall string \"%s\" given. "
- "Exiting.\n", __func__, wallStr );
- exit(EXIT_FAILURE);
- }
-
- while ( dofSet >= self->linkedDofSetsCount ) {
- LinkedDofInfo_AddDofSet( linkedDofInfo );
- }
-
- LinkedDofInfo_AddDofsToSet_FromIndexSet( self, dofSet, indexSet, nodalDof );
- }
- else if ( ( shapeVal = Dictionary_Get( linkSpecDict, (Dictionary_Entry_Key)"shape" ) ) ) {
- char* shapeStr = Dictionary_Entry_Value_AsString( shapeVal );
- Stg_Shape* shape = NULL;
- Node_LocalIndex lNode_I = 0;
- AbstractContext* context = (AbstractContext* ) data;
- Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
-
- Journal_Firewall( context && Stg_Class_IsInstance( context, AbstractContext_Type ),
- errorStr, "Error - in %s(): you've asked to create a Shape linked dof "
- "specification, but haven't passed in the context as the \"data\" parameter "
- "to %s - hence the shape can't be found in the component factory.\n",
- __func__, __func__ );
-
- Journal_Firewall( context->CF != NULL, errorStr,
- "Error - in %s(): you've asked to create a Shape linked dof "
- "specification, but the context passed as the \"data\" parameter "
- "doesn't have a valid component factory to find the shape in.\n",
- __func__, __func__ );
-
- dofSet = Dictionary_Entry_Value_AsUnsignedInt( Dictionary_Get( linkSpecDict, (Dictionary_Entry_Key)"dofSet" ) );
- while ( dofSet >= self->linkedDofSetsCount ) {
- LinkedDofInfo_AddDofSet( linkedDofInfo );
- }
-
- shape = Stg_ComponentFactory_ConstructByName( context->CF, (Name)shapeStr, Stg_Shape, True, data );
-
- for ( lNode_I = 0; lNode_I < Mesh_GetLocalSize( self->mesh, MT_VERTEX ); lNode_I++ ) {
- if ( Stg_Shape_IsCoordInside( shape, Mesh_GetVertex( self->mesh, lNode_I ) ) ) {
- LinkedDofInfo_AddDofToSet( self, dofSet, lNode_I, nodalDof );
- }
- }
- }
- else if ( ( wallPairVal = Dictionary_Get( linkSpecDict, (Dictionary_Entry_Key)"wallPair" ) ) ) {
- char* wallPairStr = Dictionary_Entry_Value_AsString( wallPairVal );
- Index dofSetStart_I = self->linkedDofSetsCount;
- Index dofSet_I = 0;
- Index numWallNodes;
- Index wallSetNode_I = 0;
- Index firstSetNode_I = 0;
- Index secondSetNode_I = 0;
- IndexSet* firstSet = NULL;
- IndexSet* secondSet = NULL;
- Index numExtraDofSetsNeeded = 0;
- Index globallyKnownExtraDofSetsNeeded = 0;
-
- if ( 0 == strcmp( wallPairStr, "left-right" ) ) {
- firstSet = RegularMeshUtils_CreateGlobalLeftSet( self->mesh );
- secondSet = RegularMeshUtils_CreateGlobalRightSet( self->mesh );
- }
- else if ( 0 == strcmp( wallPairStr, "back-front" ) ) {
- firstSet = RegularMeshUtils_CreateGlobalBackSet( self->mesh );
- secondSet = RegularMeshUtils_CreateGlobalFrontSet( self->mesh );
- }
- else if ( 0 == strcmp( wallPairStr, "bottom-top" ) ) {
- firstSet = RegularMeshUtils_CreateGlobalBottomSet( self->mesh );
- secondSet = RegularMeshUtils_CreateGlobalTopSet( self->mesh );
- }
- else {
- Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
- Journal_Printf( errorStr, "Error in %s: unknown wall pair string \"%s\" given. "
- "Exiting.\n", __func__, wallPairStr );
- exit(EXIT_FAILURE);
- }
-
- numExtraDofSetsNeeded = IndexSet_UpdateMembersCount( firstSet );
- numWallNodes = IndexSet_UpdateMembersCount( secondSet );
- if ( numWallNodes > numExtraDofSetsNeeded ) {
- numExtraDofSetsNeeded = numWallNodes;
- }
- /* In parallel, there may be several processors in the middle who aren't holding the
- * walls, but need to know they exist. Hence use an MPI_Allreduce to get the count */
- MPI_Allreduce( &numExtraDofSetsNeeded, &globallyKnownExtraDofSetsNeeded, 1, MPI_UNSIGNED,
- MPI_MAX, Mesh_GetCommTopology( self->mesh, MT_VERTEX )->mpiComm );
-
- for( dofSet_I = 0; dofSet_I < globallyKnownExtraDofSetsNeeded; dofSet_I++ ) {
- LinkedDofInfo_AddDofSet( linkedDofInfo );
- }
-
- /* The below for loops are 2 separate ones, since in the parallel case we don't
- know that the current proc contains both walls */
- numWallNodes = IndexSet_UpdateMembersCount( firstSet );
- dofSet_I = dofSetStart_I;
- for ( wallSetNode_I = 0; wallSetNode_I < numWallNodes; wallSetNode_I++ ) {
- firstSetNode_I = IndexSet_GetIndexOfNthMember( firstSet, wallSetNode_I );
- LinkedDofInfo_AddDofToSet( linkedDofInfo, dofSet_I, firstSetNode_I, nodalDof );
- dofSet_I++;
- }
-
- numWallNodes = IndexSet_UpdateMembersCount( secondSet );
- dofSet_I = dofSetStart_I;
- for ( wallSetNode_I = 0; wallSetNode_I < numWallNodes; wallSetNode_I++ ) {
- secondSetNode_I = IndexSet_GetIndexOfNthMember( secondSet, wallSetNode_I );
- LinkedDofInfo_AddDofToSet( linkedDofInfo, dofSet_I, secondSetNode_I, nodalDof );
- dofSet_I++;
- }
- }
- }
- }
-}
-
-void _LinkedDofInfo_Initialise( void* linkedDofInfo, void* data ) {
-}
-
-Index LinkedDofInfo_AddDofSet( void* linkedDofInfo ) {
- LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
- Index indexIntoArray;
-
- if ( self->linkedDofSetsCount == self->linkedDofSetsSize ) {
- self->linkedDofSetsSize += self->linkedDofSetsDelta;
- self->eqNumsOfLinkedDofs = Memory_Realloc_Array( self->eqNumsOfLinkedDofs, int, self->linkedDofSetsSize );
- }
- /* Set the eq num to -1 since uninitialised */
- self->eqNumsOfLinkedDofs[self->linkedDofSetsCount] = -1;
- indexIntoArray = self->linkedDofSetsCount++;
-
- return indexIntoArray;
-}
-
-void LinkedDofInfo_AddDofToSet( void* linkedDofInfo, Index linkedDofSet_I, Node_Index node_I, Dof_Index nodeLocalDof_I ) {
- LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
- Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
-
- Journal_Firewall( node_I < self->dofLayout->_numItemsInLayout, errorStr, "Error- in %s: tried to add a dof at a "
- "node that doesn't exist.\n", __func__ );
- Journal_Firewall( nodeLocalDof_I < self->dofLayout->dofCounts[node_I], errorStr, "Error- in %s: tried to add a "
- "dof %d that doesn't exist at current node %d (max index is %d).\n", __func__, nodeLocalDof_I, node_I,
- self->dofLayout->dofCounts[node_I]-1 );
-
- self->linkedDofTbl[node_I][nodeLocalDof_I] = linkedDofSet_I;
-}
-
-void LinkedDofInfo_AddDofsToSet_FromIndexSet( void* linkedDofInfo, Index linkedDofSet_I, IndexSet* nodeSet, Dof_Index nodeLocalDof_I ) {
- LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
- Node_DomainIndex node_I;
-
- for ( node_I = 0; node_I < nodeSet->size; node_I++ ) {
- if ( IndexSet_IsMember( nodeSet, node_I ) ) {
- self->linkedDofTbl[node_I][nodeLocalDof_I] = linkedDofSet_I;
- }
- }
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/LinkedDofInfo.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/LinkedDofInfo.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,474 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: LinkedDofInfo.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "LinkedDofInfo.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+/** Textual name of this class */
+const Type LinkedDofInfo_Type = "LinkedDofInfo";
+
+LinkedDofInfo* LinkedDofInfo_New( Name name, DomainContext* context, void* mesh, DofLayout* dofLayout, Dictionary* dictionary ) {
+ LinkedDofInfo* self = (LinkedDofInfo*)_LinkedDofInfo_DefaultNew( name );
+
+ self->isConstructed = True;
+ _LinkedDofInfo_Init( self, context, mesh, dofLayout, dictionary );
+
+ return self;
+}
+
+void* _LinkedDofInfo_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(LinkedDofInfo);
+ Type type = LinkedDofInfo_Type;
+ Stg_Class_DeleteFunction* _delete = _LinkedDofInfo_Delete;
+ Stg_Class_PrintFunction* _print = _LinkedDofInfo_Print;
+ Stg_Class_CopyFunction* _copy = _LinkedDofInfo_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LinkedDofInfo_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _LinkedDofInfo_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _LinkedDofInfo_Build;
+ Stg_Component_InitialiseFunction* _initialise = _LinkedDofInfo_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _LinkedDofInfo_Execute;
+ Stg_Component_DestroyFunction* _destroy = _LinkedDofInfo_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+
+ return (void*)
+ _LinkedDofInfo_New( LINKEDDOFINFO_PASSARGS );
+}
+
+LinkedDofInfo* _LinkedDofInfo_New( LINKEDDOFINFO_DEFARGS ) {
+ LinkedDofInfo* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(LinkedDofInfo) );
+ self = (LinkedDofInfo*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ /* General info */
+
+ /* Virtual info */
+ self->_build = _build;
+ self->_initialise = _initialise;
+
+ /* member info */
+
+ return self;
+}
+
+void _LinkedDofInfo_Init( void* linkedDofInfo, DomainContext* context, void* mesh, DofLayout* dofLayout, Dictionary* dictionary ) {
+ LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
+
+ self->context = context;
+ self->dofLayout = dofLayout;
+ self->mesh = (Mesh*)mesh;
+ self->dictionary = dictionary;
+
+ /* Initially no sets */
+ self->linkedDofSetsCount = 0;
+ self->linkedDofSetsDelta = 4;
+ self->linkedDofSetsSize = self->linkedDofSetsDelta;
+ self->eqNumsOfLinkedDofs = Memory_Alloc_Array( int, self->linkedDofSetsSize, "linkedDofInfo->eqNumsOfLinkedDofs" );
+}
+
+void _LinkedDofInfo_Delete( void* linkedDofInfo ) {
+ LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
+
+ _Stg_Component_Delete( self );
+}
+
+void _LinkedDofInfo_Print( void* linkedDofInfo, Stream* stream ) {
+ LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
+ Index dofSet_I = 0;
+ Node_Index node_I = 0;
+ Dof_Index nodeLocalDof_I = 0;
+
+ /* General info */
+ Journal_Printf( stream, "LinkedDofInfo (ptr): %p\n", self );
+
+ /* Print parent */
+ _Stg_Class_Print( self, stream );
+
+ Journal_Printf( stream, "%d Linked dof sets active:\n", self->linkedDofSetsCount );
+ Stream_Indent( stream );
+
+ for ( dofSet_I = 0; dofSet_I < self->linkedDofSetsCount; dofSet_I++ ) {
+ Journal_Printf( stream, "Set %u: has eqNum %d\n", dofSet_I, self->eqNumsOfLinkedDofs[dofSet_I] );
+ }
+ Stream_UnIndent( stream );
+
+ Journal_Printf( stream, "Linked dof sets table:\n", self->linkedDofSetsCount );
+ Stream_Indent( stream );
+
+ for ( node_I = 0; node_I < self->dofLayout->_numItemsInLayout; node_I++ ) {
+ Journal_Printf( stream, "Node %d: ", node_I );
+ for ( nodeLocalDof_I = 0; nodeLocalDof_I < self->dofLayout->dofCounts[node_I]; nodeLocalDof_I++ ) {
+ Journal_Printf( stream, "%d, ", self->linkedDofTbl[node_I][nodeLocalDof_I] );
+ }
+ Journal_Printf( stream, "\n" );
+ }
+ Stream_UnIndent( stream );
+}
+
+void _LinkedDofInfo_AssignFromXML( void* linkedDofInfo, Stg_ComponentFactory *cf, void* data ){
+ LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
+ Dictionary* dictionary;
+ Mesh* mesh = NULL;
+ DofLayout* dofLayout = NULL;
+ DomainContext* context;
+
+ dictionary = Dictionary_GetDictionary( cf->componentDict, self->name );
+
+ context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", DomainContext, False, data );
+ if( !context )
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", DomainContext, True, data );
+
+ mesh = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Mesh", Mesh, True, data );
+ dofLayout = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)DofLayout_Type, DofLayout, True, data );
+
+ _LinkedDofInfo_Init( self, context, mesh, dofLayout, dictionary );
+}
+
+void _LinkedDofInfo_Execute( void* linkedDofInfo, void *data ){
+}
+
+void _LinkedDofInfo_Destroy( void* linkedDofInfo, void *data ){
+ LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
+
+ Memory_Free( self->linkedDofTbl );
+ Memory_Free( self->eqNumsOfLinkedDofs );
+}
+
+void* _LinkedDofInfo_Copy( const void* linkedDofInfo, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
+ LinkedDofInfo* newLinkedDofInfo;
+ PtrMap* map = ptrMap;
+ Bool ownMap = False;
+
+ if( !map ) {
+ map = PtrMap_New( 10 );
+ ownMap = True;
+ }
+
+ newLinkedDofInfo = (LinkedDofInfo*)_Stg_Class_Copy( self, dest, deep, nameExt, map );
+
+ /* Virtual methods */
+ newLinkedDofInfo->linkedDofSetsCount = self->linkedDofSetsCount;
+ newLinkedDofInfo->linkedDofSetsSize = self->linkedDofSetsSize;
+ newLinkedDofInfo->linkedDofSetsDelta = self->linkedDofSetsDelta;
+
+ if ( deep ) {
+ newLinkedDofInfo->dofLayout = (DofLayout*)Stg_Class_Copy( self->dofLayout, NULL, deep, nameExt, map );
+ newLinkedDofInfo->mesh = (Mesh*)Stg_Class_Copy( self->mesh, NULL, deep, nameExt, map );
+
+ if ( (newLinkedDofInfo->linkedDofTbl = (int**)PtrMap_Find( map, self->linkedDofTbl )) == NULL && self->linkedDofTbl ) {
+ Node_Index node_I;
+ Dof_Index dof_I;
+ newLinkedDofInfo->linkedDofTbl = Memory_Alloc_2DComplex( int, self->dofLayout->_numItemsInLayout, self->dofLayout->dofCounts, "linkedDofInfo->linkedDofTbl" );
+ for ( node_I = 0; node_I < self->dofLayout->_numItemsInLayout; node_I++ ) {
+ for ( dof_I = 0; dof_I < self->dofLayout->dofCounts[node_I]; dof_I++ ) {
+ newLinkedDofInfo->linkedDofTbl[node_I][dof_I] =
+ self->linkedDofTbl[node_I][dof_I];
+ }
+ }
+ PtrMap_Append( map, self->linkedDofTbl, newLinkedDofInfo->linkedDofTbl );
+ }
+ if ( (newLinkedDofInfo->eqNumsOfLinkedDofs = (int*)PtrMap_Find( map, self->eqNumsOfLinkedDofs )) == NULL && self->eqNumsOfLinkedDofs ) {
+ newLinkedDofInfo->eqNumsOfLinkedDofs = Memory_Alloc_Array( int, self->linkedDofSetsCount, "linkedDofInfo->eqNumsOfLinkedDofs" );
+ memcpy( newLinkedDofInfo->eqNumsOfLinkedDofs, self->eqNumsOfLinkedDofs, self->linkedDofSetsCount * sizeof(int) );
+ PtrMap_Append( map, self->eqNumsOfLinkedDofs, newLinkedDofInfo->eqNumsOfLinkedDofs );
+ }
+ }
+ else {
+ newLinkedDofInfo->dofLayout = self->dofLayout;
+ newLinkedDofInfo->mesh = self->mesh;
+ newLinkedDofInfo->linkedDofTbl = self->linkedDofTbl;
+ newLinkedDofInfo->eqNumsOfLinkedDofs = self->eqNumsOfLinkedDofs;
+ }
+
+ if( ownMap ) {
+ Stg_Class_Delete( map );
+ }
+
+ return (void*)newLinkedDofInfo;
+}
+
+void _LinkedDofInfo_Build( void* linkedDofInfo, void* data ) {
+ LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
+ Dictionary_Entry_Value* linkSpecs = NULL;
+ Node_Index node_I;
+ Node_Index nodeLocalDof_I;
+ DofLayout* dofLayout;
+
+ dofLayout = self->dofLayout;
+ Stg_Component_Build( self->dofLayout, data, False );
+
+ self->linkedDofTbl = Memory_Alloc_2DComplex( int, dofLayout->_numItemsInLayout,
+ dofLayout->dofCounts, "linkedDofInfo->linkedDofTbl" );
+
+ /* Initially, set all dofs as not belonging to a set */
+ for ( node_I = 0 ; node_I < dofLayout->_numItemsInLayout; node_I++ ) {
+ for ( nodeLocalDof_I = 0; nodeLocalDof_I < dofLayout->dofCounts[node_I]; nodeLocalDof_I++ ) {
+ self->linkedDofTbl[node_I][nodeLocalDof_I] = -1;
+ }
+ }
+
+ linkSpecs = Dictionary_Get( self->dictionary, (Dictionary_Entry_Key)"linkSpecifications" );
+
+ /* Note that the dictionary entry is optional - user may prefer to specify the sets
+ using the AddDofToSet and AddDofsToSet_FromIndexSet functions */
+
+ if ( linkSpecs ) {
+ Index numSpecs = 0;
+ Index linkSpec_I;
+ Dictionary_Entry_Value* linkSpec = NULL;
+ Dictionary* linkSpecDict;
+ Index dofSet = 0;
+ Dictionary_Entry_Value* wallVal;
+ Dictionary_Entry_Value* shapeVal;
+ Dictionary_Entry_Value* wallPairVal;
+ Index nodalDof;
+
+ numSpecs = Dictionary_Entry_Value_GetCount( linkSpecs );
+
+ for ( linkSpec_I = 0; linkSpec_I < numSpecs; linkSpec_I++ ) {
+ linkSpec = Dictionary_Entry_Value_GetElement( linkSpecs, linkSpec_I );
+ linkSpecDict = Dictionary_Entry_Value_AsDictionary( linkSpec );
+ nodalDof = Dictionary_Entry_Value_AsUnsignedInt( Dictionary_Get( linkSpecDict, (Dictionary_Entry_Key)"dof" ) );
+
+ if ( nodalDof >= self->dofLayout->dofCounts[0] ) {
+ Stream* warningStr = Journal_Register( Error_Type, (Name)self->type );
+
+ Journal_DPrintf( warningStr, "Warning- in %s: User requested a periodic BC on "
+ "dof %d, but only %d dofs are active. Ignoring.\n", __func__, nodalDof,
+ self->dofLayout->dofCounts[0] );
+
+ continue;
+ }
+
+ if ( ( wallVal = Dictionary_Get( linkSpecDict, (Dictionary_Entry_Key)"wall" ) ) ) {
+ IndexSet* indexSet = NULL;
+ char* wallStr = Dictionary_Entry_Value_AsString( wallVal );
+
+ dofSet = Dictionary_Entry_Value_AsUnsignedInt( Dictionary_Get( linkSpecDict, (Dictionary_Entry_Key)"dofSet" ) );
+
+ if ( 0 == strcmp( wallStr, "left" ) ) {
+ indexSet = RegularMeshUtils_CreateGlobalLeftSet( self->mesh );
+ }
+ else if ( 0 == strcmp( wallStr, "right" ) ) {
+ indexSet = RegularMeshUtils_CreateGlobalRightSet( self->mesh );
+ }
+ else if ( 0 == strcmp( wallStr, "bottom" ) ) {
+ indexSet = RegularMeshUtils_CreateGlobalBottomSet( self->mesh );
+ }
+ else if ( 0 == strcmp( wallStr, "top" ) ) {
+ indexSet = RegularMeshUtils_CreateGlobalTopSet( self->mesh );
+ }
+ else if ( 0 == strcmp( wallStr, "front" ) ) {
+ indexSet = RegularMeshUtils_CreateGlobalFrontSet( self->mesh );
+ }
+ else if ( 0 == strcmp( wallStr, "back" ) ) {
+ indexSet = RegularMeshUtils_CreateGlobalBackSet( self->mesh );
+ }
+ else {
+ Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
+ Journal_Printf( errorStr, "Error in %s: unknown wall string \"%s\" given. "
+ "Exiting.\n", __func__, wallStr );
+ exit(EXIT_FAILURE);
+ }
+
+ while ( dofSet >= self->linkedDofSetsCount ) {
+ LinkedDofInfo_AddDofSet( linkedDofInfo );
+ }
+
+ LinkedDofInfo_AddDofsToSet_FromIndexSet( self, dofSet, indexSet, nodalDof );
+ }
+ else if ( ( shapeVal = Dictionary_Get( linkSpecDict, (Dictionary_Entry_Key)"shape" ) ) ) {
+ char* shapeStr = Dictionary_Entry_Value_AsString( shapeVal );
+ Stg_Shape* shape = NULL;
+ Node_LocalIndex lNode_I = 0;
+ AbstractContext* context = (AbstractContext* ) data;
+ Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
+
+ Journal_Firewall( context && Stg_Class_IsInstance( context, AbstractContext_Type ),
+ errorStr, "Error - in %s(): you've asked to create a Shape linked dof "
+ "specification, but haven't passed in the context as the \"data\" parameter "
+ "to %s - hence the shape can't be found in the component factory.\n",
+ __func__, __func__ );
+
+ Journal_Firewall( context->CF != NULL, errorStr,
+ "Error - in %s(): you've asked to create a Shape linked dof "
+ "specification, but the context passed as the \"data\" parameter "
+ "doesn't have a valid component factory to find the shape in.\n",
+ __func__, __func__ );
+
+ dofSet = Dictionary_Entry_Value_AsUnsignedInt( Dictionary_Get( linkSpecDict, (Dictionary_Entry_Key)"dofSet" ) );
+ while ( dofSet >= self->linkedDofSetsCount ) {
+ LinkedDofInfo_AddDofSet( linkedDofInfo );
+ }
+
+ shape = Stg_ComponentFactory_ConstructByName( context->CF, (Name)shapeStr, Stg_Shape, True, data );
+
+ for ( lNode_I = 0; lNode_I < Mesh_GetLocalSize( self->mesh, MT_VERTEX ); lNode_I++ ) {
+ if ( Stg_Shape_IsCoordInside( shape, Mesh_GetVertex( self->mesh, lNode_I ) ) ) {
+ LinkedDofInfo_AddDofToSet( self, dofSet, lNode_I, nodalDof );
+ }
+ }
+ }
+ else if ( ( wallPairVal = Dictionary_Get( linkSpecDict, (Dictionary_Entry_Key)"wallPair" ) ) ) {
+ char* wallPairStr = Dictionary_Entry_Value_AsString( wallPairVal );
+ Index dofSetStart_I = self->linkedDofSetsCount;
+ Index dofSet_I = 0;
+ Index numWallNodes;
+ Index wallSetNode_I = 0;
+ Index firstSetNode_I = 0;
+ Index secondSetNode_I = 0;
+ IndexSet* firstSet = NULL;
+ IndexSet* secondSet = NULL;
+ Index numExtraDofSetsNeeded = 0;
+ Index globallyKnownExtraDofSetsNeeded = 0;
+
+ if ( 0 == strcmp( wallPairStr, "left-right" ) ) {
+ firstSet = RegularMeshUtils_CreateGlobalLeftSet( self->mesh );
+ secondSet = RegularMeshUtils_CreateGlobalRightSet( self->mesh );
+ }
+ else if ( 0 == strcmp( wallPairStr, "back-front" ) ) {
+ firstSet = RegularMeshUtils_CreateGlobalBackSet( self->mesh );
+ secondSet = RegularMeshUtils_CreateGlobalFrontSet( self->mesh );
+ }
+ else if ( 0 == strcmp( wallPairStr, "bottom-top" ) ) {
+ firstSet = RegularMeshUtils_CreateGlobalBottomSet( self->mesh );
+ secondSet = RegularMeshUtils_CreateGlobalTopSet( self->mesh );
+ }
+ else {
+ Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
+ Journal_Printf( errorStr, "Error in %s: unknown wall pair string \"%s\" given. "
+ "Exiting.\n", __func__, wallPairStr );
+ exit(EXIT_FAILURE);
+ }
+
+ numExtraDofSetsNeeded = IndexSet_UpdateMembersCount( firstSet );
+ numWallNodes = IndexSet_UpdateMembersCount( secondSet );
+ if ( numWallNodes > numExtraDofSetsNeeded ) {
+ numExtraDofSetsNeeded = numWallNodes;
+ }
+ /* In parallel, there may be several processors in the middle who aren't holding the
+ * walls, but need to know they exist. Hence use an MPI_Allreduce to get the count */
+ MPI_Allreduce( &numExtraDofSetsNeeded, &globallyKnownExtraDofSetsNeeded, 1, MPI_UNSIGNED,
+ MPI_MAX, Mesh_GetCommTopology( self->mesh, MT_VERTEX )->mpiComm );
+
+ for( dofSet_I = 0; dofSet_I < globallyKnownExtraDofSetsNeeded; dofSet_I++ ) {
+ LinkedDofInfo_AddDofSet( linkedDofInfo );
+ }
+
+ /* The below for loops are 2 separate ones, since in the parallel case we don't
+ know that the current proc contains both walls */
+ numWallNodes = IndexSet_UpdateMembersCount( firstSet );
+ dofSet_I = dofSetStart_I;
+ for ( wallSetNode_I = 0; wallSetNode_I < numWallNodes; wallSetNode_I++ ) {
+ firstSetNode_I = IndexSet_GetIndexOfNthMember( firstSet, wallSetNode_I );
+ LinkedDofInfo_AddDofToSet( linkedDofInfo, dofSet_I, firstSetNode_I, nodalDof );
+ dofSet_I++;
+ }
+
+ numWallNodes = IndexSet_UpdateMembersCount( secondSet );
+ dofSet_I = dofSetStart_I;
+ for ( wallSetNode_I = 0; wallSetNode_I < numWallNodes; wallSetNode_I++ ) {
+ secondSetNode_I = IndexSet_GetIndexOfNthMember( secondSet, wallSetNode_I );
+ LinkedDofInfo_AddDofToSet( linkedDofInfo, dofSet_I, secondSetNode_I, nodalDof );
+ dofSet_I++;
+ }
+ }
+ }
+ }
+}
+
+void _LinkedDofInfo_Initialise( void* linkedDofInfo, void* data ) {
+}
+
+Index LinkedDofInfo_AddDofSet( void* linkedDofInfo ) {
+ LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
+ Index indexIntoArray;
+
+ if ( self->linkedDofSetsCount == self->linkedDofSetsSize ) {
+ self->linkedDofSetsSize += self->linkedDofSetsDelta;
+ self->eqNumsOfLinkedDofs = Memory_Realloc_Array( self->eqNumsOfLinkedDofs, int, self->linkedDofSetsSize );
+ }
+ /* Set the eq num to -1 since uninitialised */
+ self->eqNumsOfLinkedDofs[self->linkedDofSetsCount] = -1;
+ indexIntoArray = self->linkedDofSetsCount++;
+
+ return indexIntoArray;
+}
+
+void LinkedDofInfo_AddDofToSet( void* linkedDofInfo, Index linkedDofSet_I, Node_Index node_I, Dof_Index nodeLocalDof_I ) {
+ LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
+ Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
+
+ Journal_Firewall( node_I < self->dofLayout->_numItemsInLayout, errorStr, "Error- in %s: tried to add a dof at a "
+ "node that doesn't exist.\n", __func__ );
+ Journal_Firewall( nodeLocalDof_I < self->dofLayout->dofCounts[node_I], errorStr, "Error- in %s: tried to add a "
+ "dof %d that doesn't exist at current node %d (max index is %d).\n", __func__, nodeLocalDof_I, node_I,
+ self->dofLayout->dofCounts[node_I]-1 );
+
+ self->linkedDofTbl[node_I][nodeLocalDof_I] = linkedDofSet_I;
+}
+
+void LinkedDofInfo_AddDofsToSet_FromIndexSet( void* linkedDofInfo, Index linkedDofSet_I, IndexSet* nodeSet, Dof_Index nodeLocalDof_I ) {
+ LinkedDofInfo* self = (LinkedDofInfo*)linkedDofInfo;
+ Node_DomainIndex node_I;
+
+ for ( node_I = 0; node_I < nodeSet->size; node_I++ ) {
+ if ( IndexSet_IsMember( nodeSet, node_I ) ) {
+ self->linkedDofTbl[node_I][nodeLocalDof_I] = linkedDofSet_I;
+ }
+ }
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/OperatorFeVariable.c
--- a/Discretisation/src/OperatorFeVariable.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,685 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: OperatorFeVariable.c 1137 2008-05-23 05:57:48Z RobertTurnbull $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <string.h>
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "types.h"
-#include "FeVariable.h"
-#include "OperatorFeVariable.h"
-#include "FeMesh.h"
-
-#include <assert.h>
-
-const Type OperatorFeVariable_Type = "OperatorFeVariable";
-
-OperatorFeVariable* OperatorFeVariable_NewUnary(
- Name name,
- DomainContext* context,
- void* _feVariable,
- Name operatorName )
-{
- FeVariable* feVariable = (FeVariable*) _feVariable;
- Stream* errorStream = Journal_Register( Error_Type, (Name)OperatorFeVariable_Type );
-
- Journal_Firewall( feVariable != NULL, errorStream, "In func %s: Trying to operate on NULL field.\n", __func__ );
-
- return OperatorFeVariable_New(
- name,
- context,
- feVariable->feMesh,
- feVariable->geometryMesh,
- feVariable->dofLayout,
- feVariable->bcs,
- feVariable->ics,
- feVariable->linkedDofInfo,
- feVariable->templateFeVariable,
- OperatorFeVariable_UnaryInterpolationFunc,
- OperatorFeVariable_UnaryValueAtNodeFunc,
- operatorName,
- NULL,
- 1,
- &feVariable,
- feVariable->dim,
- feVariable->isCheckpointedAndReloaded,
- feVariable->communicator,
- feVariable->fieldVariable_Register );
-}
-
-OperatorFeVariable* OperatorFeVariable_NewUnary_OwnOperator(
- Name name,
- DomainContext* context,
- void* _feVariable,
- Operator* ownOperator )
-{
- FeVariable* feVariable = (FeVariable*) _feVariable;
- Stream* errorStream = Journal_Register( Error_Type, (Name)OperatorFeVariable_Type );
-
- Journal_Firewall( feVariable != NULL, errorStream, "In func %s: Trying to operate on NULL field.\n", __func__ );
-
- return OperatorFeVariable_New(
- name,
- context,
- feVariable->feMesh,
- feVariable->geometryMesh,
- feVariable->dofLayout,
- feVariable->bcs,
- feVariable->ics,
- feVariable->linkedDofInfo,
- feVariable->templateFeVariable,
- OperatorFeVariable_UnaryInterpolationFunc,
- OperatorFeVariable_UnaryValueAtNodeFunc,
- ownOperator->name,
- ownOperator,
- 1,
- &feVariable,
- feVariable->dim,
- feVariable->isCheckpointedAndReloaded,
- feVariable->communicator,
- feVariable->fieldVariable_Register );
-}
-
-OperatorFeVariable* OperatorFeVariable_NewBinary(
- Name name,
- DomainContext* context,
- void* _feVariable1,
- void* _feVariable2,
- Name operatorName )
-{
- FeVariable* feVariableList[2];
- Stream* errorStream = Journal_Register( Error_Type, (Name)OperatorFeVariable_Type );
-
- Journal_Firewall( _feVariable1 != NULL, errorStream, "In func %s: First field to operate on is NULL.\n", __func__ );
- Journal_Firewall( _feVariable2 != NULL, errorStream, "In func %s: Second field to operate on is NULL.\n", __func__ );
-
- feVariableList[0] = (FeVariable*) _feVariable1;
- feVariableList[1] = (FeVariable*) _feVariable2;
-
- return OperatorFeVariable_New(
- name,
- context,
- feVariableList[0]->feMesh,
- feVariableList[0]->geometryMesh,
- feVariableList[0]->dofLayout,
- feVariableList[0]->bcs,
- feVariableList[0]->ics,
- feVariableList[0]->linkedDofInfo,
- feVariableList[0]->templateFeVariable,
- OperatorFeVariable_BinaryInterpolationFunc,
- OperatorFeVariable_BinaryValueAtNodeFunc,
- operatorName,
- NULL,
- 2,
- feVariableList,
- feVariableList[0]->dim,
- feVariableList[0]->isCheckpointedAndReloaded,
- feVariableList[0]->communicator,
- feVariableList[0]->fieldVariable_Register );
-}
-
-OperatorFeVariable* OperatorFeVariable_New(
- Name name,
- DomainContext* context,
- void* feMesh,
- void* geometryMesh,
- DofLayout* dofLayout,
- void* bcs,
- void* ics,
- void* linkedDofInfo,
- void* templateFeVariable,
- FeVariable_InterpolateWithinElementFunction* interpolateWithinElement,
- FeVariable_GetValueAtNodeFunction* getValueAtNode,
- Name operatorName,
- Operator* ownOperator,
- Index feVariableCount,
- FeVariable** feVariableList,
- Dimension_Index dim,
- Bool isCheckpointedAndReloaded,
- MPI_Comm communicator,
- FieldVariable_Register* fieldVariable_Register )
-{
- OperatorFeVariable* self = (OperatorFeVariable*)_OperatorFeVariable_DefaultNew( name );
-
- self->isConstructed = True;
- _FieldVariable_Init( (FieldVariable*)self, context, feVariableCount, dim, isCheckpointedAndReloaded, communicator, fieldVariable_Register );
- _FeVariable_Init( (FeVariable*)self, feMesh, geometryMesh, dofLayout, bcs, ics, linkedDofInfo, templateFeVariable, True, False );
- _OperatorFeVariable_Init( self, operatorName, feVariableCount, feVariableList, ownOperator );
-
- return self;
-}
-
-void* _OperatorFeVariable_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(OperatorFeVariable);
- Type type = OperatorFeVariable_Type;
- Stg_Class_DeleteFunction* _delete = _OperatorFeVariable_Delete;
- Stg_Class_PrintFunction* _print = _OperatorFeVariable_Print;
- Stg_Class_CopyFunction* _copy = _OperatorFeVariable_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (Stg_Component_DefaultConstructorFunction*)_OperatorFeVariable_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _OperatorFeVariable_AssignFromXML;
- Stg_Component_BuildFunction* _build = _OperatorFeVariable_Build;
- Stg_Component_InitialiseFunction* _initialise = _OperatorFeVariable_Initialise;
- Stg_Component_ExecuteFunction* _execute = _OperatorFeVariable_Execute;
- Stg_Component_DestroyFunction* _destroy = _OperatorFeVariable_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- FieldVariable_InterpolateValueAtFunction* _interpolateValueAt = _OperatorFeVariable_InterpolateValueAt;
- FieldVariable_GetValueFunction* _getMinGlobalFieldMagnitude = _FeVariable_GetMinGlobalFieldMagnitude;
- FieldVariable_GetValueFunction* _getMaxGlobalFieldMagnitude = _FeVariable_GetMaxGlobalFieldMagnitude;
- FieldVariable_GetCoordFunction* _getMinAndMaxLocalCoords = _FeVariable_GetMinAndMaxLocalCoords;
- FieldVariable_GetCoordFunction* _getMinAndMaxGlobalCoords = _FeVariable_GetMinAndMaxGlobalCoords;
- FeVariable_InterpolateWithinElementFunction* _interpolateWithinElement = _OperatorFeVariable_InterpolateWithinElement;
- FeVariable_GetValueAtNodeFunction* _getValueAtNode = _OperatorFeVariable_GetValueAtNode;
- FeVariable_SyncShadowValuesFunc* _syncShadowValues = _OperatorFeVariable_SyncShadowValues;
-
- return _OperatorFeVariable_New( OPERATORFEVARIABLE_PASSARGS ); /* feVariableList_renamed */
-}
-
-OperatorFeVariable* _OperatorFeVariable_New( OPERATORFEVARIABLE_DEFARGS ) {
- OperatorFeVariable* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(OperatorFeVariable) );
- self = (OperatorFeVariable*) _FeVariable_New( FEVARIABLE_PASSARGS );
-
- return self;
-}
-
-void _OperatorFeVariable_Init( void* oFeVar, Name operatorName, Index feVariableCount, FeVariable** feVariableList, Operator* ownOperator ) {
- OperatorFeVariable* self = (OperatorFeVariable*) oFeVar;
- FeVariable* feVariable;
- Index feVariable_I;
- Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
-
- /* Assign values to object */
- self->feVariableCount = feVariableCount;
- self->operatorName =operatorName;
- self->_operator = ownOperator;
-
- /* Copy field variable list */
- self->feVariableList = Memory_Alloc_Array( FeVariable*, feVariableCount, "Array of Field Variables" );
- memcpy( self->feVariableList, feVariableList, feVariableCount * sizeof( FeVariable* ) );
-
- for ( feVariable_I = 0 ; feVariable_I < feVariableCount ; feVariable_I++ ) {
- feVariable = feVariableList[ feVariable_I ];
- Journal_Firewall( feVariable != NULL,
- errorStream, "In func %s: Field Variable %u in list is NULL.\n", __func__, feVariable_I );
- Journal_Firewall( feVariable->fieldComponentCount <= MAX_FIELD_COMPONENTS,
- errorStream, "In func %s: Field Variable '%s' has too many components.\n", __func__, feVariable->name );
- }
-}
-
-void _OperatorFeVariable_Delete( void* _feVariable ) {
- OperatorFeVariable* self = (OperatorFeVariable*) _feVariable;
-
- _FeVariable_Delete( self );
-}
-
-void _OperatorFeVariable_Print( void* _feVariable, Stream* stream ) {
- OperatorFeVariable* self = (OperatorFeVariable*) _feVariable;
- Index feVariable_I;
-
- _FeVariable_Print( self, stream );
-
- Journal_PrintValue( stream, self->feVariableCount );
- for ( feVariable_I = 0 ; feVariable_I < self->feVariableCount ; feVariable_I++ )
- Journal_Printf( stream, "\tFeVariable %u - '%s'\n", feVariable_I, self->feVariableList[ feVariable_I ]->name );
-
-}
-
-void* _OperatorFeVariable_Copy( const void* feVariable, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- OperatorFeVariable* self = (OperatorFeVariable*)feVariable;
- OperatorFeVariable* newOperatorFeVariable;
-
- newOperatorFeVariable = (OperatorFeVariable*)_FeVariable_Copy( self, dest, deep, nameExt, ptrMap );
-
- newOperatorFeVariable->_operator = self->_operator;
- newOperatorFeVariable->feVariableCount = self->feVariableCount;
-
- if (deep) {
- newOperatorFeVariable->feVariableList = Memory_Alloc_Array( FeVariable*, self->feVariableCount, "Array of Field Variables" );
- memcpy( newOperatorFeVariable->feVariableList, self->feVariableList, self->feVariableCount * sizeof( FeVariable* ) );
- }
- else
- newOperatorFeVariable->feVariableList = self->feVariableList;
-
- return (void*)newOperatorFeVariable;
-}
-
-void _OperatorFeVariable_AssignFromXML( void* feVariable, Stg_ComponentFactory* cf, void* data ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
- Dictionary* dictionary = Dictionary_GetDictionary( cf->componentDict, self->name );
- Dictionary_Entry_Value* list;
- Index feVariableCount = 0;
- Index feVariable_I;
- FieldVariable_Register* fV_Register;
- Name feVariableName;
- Name operatorName;
- FeVariable** feVariableList;
-
- /* Construct Parent */
- _FieldVariable_AssignFromXML( self, cf, data );
-
- fV_Register = self->context->fieldVariable_Register;
-
- operatorName = Stg_ComponentFactory_GetString( cf, self->name, (Dictionary_Entry_Key)"Operator", "" );
-
- list = Dictionary_Get( dictionary, (Dictionary_Entry_Key)"FeVariables" );
-
- feVariableCount = ( list ? Dictionary_Entry_Value_GetCount(list) : 1 );
- feVariableList = Memory_Alloc_Array( FeVariable*, feVariableCount, "FeVars" );
-
- for ( feVariable_I = 0 ; feVariable_I < feVariableCount ; feVariable_I++ ) {
- feVariableName = (list ? Dictionary_Entry_Value_AsString( Dictionary_Entry_Value_GetElement( list, feVariable_I ) ) :
- Dictionary_GetString( dictionary, (Dictionary_Entry_Key)"FeVariable" ) );
-
- /* Check in fV_Register first before assuming in LiveComponentRegister */
- Journal_PrintfL( cf->infoStream, 2, "Looking for FeVariable '%s' in fieldVariable_Register.\n", feVariableName );
- feVariableList[feVariable_I] = (FeVariable*) FieldVariable_Register_GetByName( fV_Register, feVariableName );
-
- if ( !feVariableList[feVariable_I] )
- feVariableList[feVariable_I] =
- Stg_ComponentFactory_ConstructByName( cf, (Name)feVariableName, FeVariable, True, data );
- }
-
- _FeVariable_Init( (FeVariable* ) self, feVariableList[0]->feMesh, feVariableList[0]->geometryMesh, feVariableList[0]->dofLayout, NULL, NULL, NULL, NULL, True, False );
- _OperatorFeVariable_Init( self, operatorName, feVariableCount, feVariableList, NULL );
-
- Memory_Free( feVariableList );
-}
-
-void _OperatorFeVariable_Build( void* feVariable, void* data ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
- Index feVariable_I;
- Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
-
- _FeVariable_Build( self, data );
-
- for ( feVariable_I = 0 ; feVariable_I < self->feVariableCount ; feVariable_I++ )
- Stg_Component_Build( self->feVariableList[ feVariable_I ] , data, False );
-
- if ( !self->_operator){
- /* Check if we are using a gradient operator */
- if ( strcasecmp( self->operatorName, "gradient" ) == 0 ) {
- self->useGradient = True;
- assert( self->feVariableCount == 1 );
- self->fieldComponentCount = self->feVariableList[0]->fieldComponentCount * self->dim;
- }
- else {
- /* just use normal operator */
- self->useGradient = False;
- /* Added 5 May 2006 by P Sunter: in the case of VectorScale, the fieldComponentCount should be based
- on the 2nd operator. Also make sure the 2nd operator has at least as may dofs per node as the first. */
- if ( self->feVariableCount == 2 ) {
- Journal_Firewall( self->feVariableList[1]->fieldComponentCount >= self->feVariableList[0]->fieldComponentCount,
- errorStream, "Error - in %s: tried to create a %s operator from feVariables \"%s\" "
- "and \"%s\" - who have fieldCounts %d and %d - unsupported since operations "
- "such as VectorScale require the 2nd feVariable to have >= the first's field count.\n",
- __func__, self->operatorName, self->feVariableList[0]->name, self->feVariableList[1]->name,
- self->feVariableList[0]->fieldComponentCount, self->feVariableList[1]->fieldComponentCount );
- self->_operator = Operator_NewFromName( self->operatorName, self->feVariableList[1]->fieldComponentCount,
- self->dim );
- }
- else {
- self->_operator = Operator_NewFromName( self->operatorName, self->feVariableList[0]->fieldComponentCount,
- self->dim );
- }
-
- self->fieldComponentCount = self->_operator->resultDofs; /* reset this value from that which is from operator */
- }
- }
- else {
- self->useGradient = False;
- self->fieldComponentCount = self->_operator->resultDofs; /* reset this value from that which is from operator */
- }
-
- _OperatorFeVariable_SetFunctions( self );
-}
-
-void _OperatorFeVariable_Initialise( void* feVariable, void* data ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
- DomainContext* context = self->context;
- Index feVariable_I;
- Dictionary_Entry_Value* feVarsList = NULL;
-
- for ( feVariable_I = 0 ; feVariable_I < self->feVariableCount ; feVariable_I++ )
- Stg_Component_Initialise( self->feVariableList[ feVariable_I ] , data, False );
-
- /* also include check to see if this fevariable should be checkpointed, just incase it didn't go through the fieldvariable construct phase */
- feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"fieldVariablesToCheckpoint" );
- if ( NULL == feVarsList ) {
- feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"FieldVariablesToCheckpoint" );
- }
- if (feVarsList != NULL ) {
- Index listLength = Dictionary_Entry_Value_GetCount( feVarsList );
- Index var_I = 0;
- Dictionary_Entry_Value* feVarDictValue = NULL;
- char* fieldVariableName;
-
- for ( var_I = 0; var_I < listLength; var_I++ ) {
- feVarDictValue = Dictionary_Entry_Value_GetElement( feVarsList, var_I );
- fieldVariableName = Dictionary_Entry_Value_AsString( feVarDictValue );
- if ( 0 == strcmp( self->name, fieldVariableName ) ) {
- self->isCheckpointedAndReloaded = True;
- break;
- }
- }
- }
-
- feVarsList = NULL;
- /** also include check to see if this fevariable should be saved for analysis purposes */
- feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"fieldVariablesToSave" );
- if ( NULL == feVarsList ) {
- feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"FieldVariablesToSave" );
- }
- if (feVarsList != NULL ) {
- Index listLength = Dictionary_Entry_Value_GetCount( feVarsList );
- Index var_I = 0;
- Dictionary_Entry_Value* feVarDictValue = NULL;
- char* fieldVariableName;
-
- for ( var_I = 0; var_I < listLength; var_I++ ) {
- feVarDictValue = Dictionary_Entry_Value_GetElement( feVarsList, var_I );
- fieldVariableName = Dictionary_Entry_Value_AsString( feVarDictValue );
- if ( 0 == strcmp( self->name, fieldVariableName ) ) {
- self->isSavedData = True;
- break;
- }
- }
- }
-}
-
-void _OperatorFeVariable_Execute( void* feVariable, void* data ) {}
-
-void _OperatorFeVariable_Destroy( void* feVariable, void* data ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
-
- Memory_Free( self->feVariableList );
-
- _FeVariable_Destroy( self, data );
-}
-
-void _OperatorFeVariable_SetFunctions( void* feVariable ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
- Stream* error = Journal_Register( Error_Type, (Name)self->type );
-
- if ( self->useGradient ) {
- Journal_Firewall( self->feVariableCount == 1, error, "Cannot use gradient operators for multiple variables.\n" );
- self->_interpolateWithinElement = OperatorFeVariable_GradientInterpolationFunc;
- self->_getValueAtNode = OperatorFeVariable_GradientValueAtNodeFunc;
- }
- else {
- switch ( self->feVariableCount ) {
- case 1:
- self->_interpolateWithinElement = OperatorFeVariable_UnaryInterpolationFunc;
- self->_getValueAtNode = OperatorFeVariable_UnaryValueAtNodeFunc; break;
- case 2:
- self->_interpolateWithinElement = OperatorFeVariable_BinaryInterpolationFunc;
- self->_getValueAtNode = OperatorFeVariable_BinaryValueAtNodeFunc; break;
- default: {
- Journal_Firewall( False, error,
- "Cannot use '%s' with feVariableCount = %u.\n", __func__, self->feVariableCount );
- }
- }
- }
-}
-void _OperatorFeVariable_InterpolateWithinElement( void* feVariable, Element_DomainIndex dElement_I, Coord coord, double* value ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
-
- _OperatorFeVariable_SetFunctions( self );
- FeVariable_InterpolateWithinElement( self, dElement_I, coord, value );
-}
-
-void _OperatorFeVariable_GetValueAtNode( void* feVariable, Node_DomainIndex dNode_I, double* value ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
-
- _OperatorFeVariable_SetFunctions( self );
- FeVariable_GetValueAtNode( self, dNode_I, value );
-}
-
-void _OperatorFeVariable_SyncShadowValues( void* feVariable ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
- int v_i;
-
- assert( self );
- for( v_i = 0; v_i < self->feVariableCount; v_i++ )
- FeVariable_SyncShadowValues( self->feVariableList[v_i] );
- self->shadowValuesSynchronised = True;
-}
-
-
-/** Private Functions */
-Bool _OperatorFeVariable_CheckIfValidToInterpolateInShadowSpace( OperatorFeVariable* self ){
- int feVar_I;
- FeVariable* currFeVar;
- Bool parentIsValid;
-
- for ( feVar_I=0; feVar_I < self->feVariableCount; feVar_I++ ) {
- currFeVar = self->feVariableList[feVar_I];
- if( Stg_Class_IsInstance( currFeVar, FeVariable_Type ) ) {
- if ( False == currFeVar->shadowValuesSynchronised ) {
- return False;
- }
- else {
- return True;
- }
- }
- else {
- parentIsValid = _OperatorFeVariable_CheckIfValidToInterpolateInShadowSpace(
- (OperatorFeVariable*)currFeVar );
- if ( False == parentIsValid ) {
- return False;
- }
- }
- }
-
- return True;
-}
-
-
-/** Needed to over-ride the standard _FeVariable_InterpolateValueAt() since for operator fe variables, as long as the
-base fe variable has been shadowed, this operatorFeVar can be calculated in shadow space */
-InterpolationResult _OperatorFeVariable_InterpolateValueAt( void* variable, Coord globalCoord, double* value ) {
- OperatorFeVariable* self = (OperatorFeVariable*)variable;
- Element_DomainIndex elementCoordIn = (unsigned)-1;
- Coord elLocalCoord={0,0,0};
- InterpolationResult retValue;
- Bool validToInterpolateInShadowSpace;
-
-
- retValue = FeVariable_GetElementLocalCoordAtGlobalCoord( self, globalCoord, elLocalCoord, &elementCoordIn );
-
- if ( retValue == LOCAL ) {
- /* Now interpolate the value at that coordinate, using shape functions */
- self->_interpolateWithinElement( self, elementCoordIn, elLocalCoord, value );
- }
- else if ( retValue == SHADOW ) {
- validToInterpolateInShadowSpace = _OperatorFeVariable_CheckIfValidToInterpolateInShadowSpace(self);
-
- if ( False == validToInterpolateInShadowSpace ) {
- Stream* warningStr = Journal_Register( Error_Type, (Name)self->type );
- Journal_Printf( warningStr, "Warning - in %s, for OperatorFeVar \"%s\": user asking to "
- "interpolate a value at "
- "coord (%g,%g,%g), which is in shadow space, but "
- "FeVariable_SyncShadowValues() hasn't been called on FeVariables this one is "
- "derived from yet.\n",
- __func__, self->name, globalCoord[0], globalCoord[1], globalCoord[2] );
- return retValue;
- }
- /* Now interpolate the value at that coordinate, using shape functions */
- self->_interpolateWithinElement( self, elementCoordIn, elLocalCoord, value );
- }
-
- return retValue;
-}
-
-
-
-void OperatorFeVariable_UnaryInterpolationFunc( void* feVariable, Element_DomainIndex dElement_I, Coord localCoord, double* value ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
- FeVariable* field0 = self->feVariableList[0];
- double fieldValue0[ MAX_FIELD_COMPONENTS ];
-
- field0->_interpolateWithinElement( field0, dElement_I, localCoord, fieldValue0 );
- Operator_CarryOutUnaryOperation( self->_operator, fieldValue0, value );
-
-#ifdef DEBUG
- if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
- Dimension_Index dim_I;
- Dof_Index dof_I;
- Journal_DPrintf( self->debug, "%s Unary Op: El %d, xi = ( ", self->name, dElement_I );
- for ( dim_I = 0 ; dim_I < self->dim ; dim_I++ )
- Journal_DPrintf( self->debug, "%g ", localCoord[ dim_I ] );
-
- /* Field 0 */
- Journal_DPrintf( self->debug, ") - %s = [ ", field0->name );
- for ( dof_I = 0 ; dof_I < field0->fieldComponentCount ; dof_I++ )
- Journal_DPrintf( self->debug, "%g ", fieldValue0[ dof_I ] );
-
- /* Result */
- Journal_DPrintf( self->debug, "] - Result = [ " );
- for ( dof_I = 0 ; dof_I < self->fieldComponentCount ; dof_I++ )
- Journal_DPrintf( self->debug, "%g ", value[ dof_I ] );
- Journal_DPrintf( self->debug, "]\n" );
- }
-#endif
-
-}
-
-void OperatorFeVariable_BinaryInterpolationFunc( void* feVariable, Element_DomainIndex dElement_I, Coord localCoord, double* value ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
- FeVariable* field0 = self->feVariableList[0];
- FeVariable* field1 = self->feVariableList[1];
- FeMesh* mesh = self->feMesh;
- double fieldValue0[ MAX_FIELD_COMPONENTS ];
- double fieldValue1[ MAX_FIELD_COMPONENTS ];
-
- FeVariable_InterpolateFromMeshLocalCoord( field0, mesh, dElement_I, localCoord, fieldValue0 );
- FeVariable_InterpolateFromMeshLocalCoord( field1, mesh, dElement_I, localCoord, fieldValue1 );
-
- Operator_CarryOutBinaryOperation( self->_operator, fieldValue0, fieldValue1, value );
-
-#ifdef DEBUG
- if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
- Dimension_Index dim_I;
- Dof_Index dof_I;
- Journal_DPrintf( self->debug, "%s Binary Op: El %d, xi = ( ", self->name, dElement_I );
- for ( dim_I = 0 ; dim_I < self->dim ; dim_I++ )
- Journal_DPrintf( self->debug, "%g ", localCoord[ dim_I ] );
-
- /* Field 0 */
- Journal_DPrintf( self->debug, ") - %s = [ ", field0->name );
- for ( dof_I = 0 ; dof_I < field0->fieldComponentCount ; dof_I++ )
- Journal_DPrintf( self->debug, "%g ", fieldValue0[ dof_I ] );
-
- /* Field 1 */
- Journal_DPrintf( self->debug, "] - %s = [ ", field1->name );
- for ( dof_I = 0 ; dof_I < field1->fieldComponentCount ; dof_I++ )
- Journal_DPrintf( self->debug, "%g ", fieldValue1[ dof_I ] );
-
- /* Result */
- Journal_DPrintf( self->debug, "] - Result = [ " );
- for ( dof_I = 0 ; dof_I < self->fieldComponentCount ; dof_I++ )
- Journal_DPrintf( self->debug, "%g ", value[ dof_I ] );
- Journal_DPrintf( self->debug, "]\n" );
- }
-#endif
-}
-
-void OperatorFeVariable_GradientInterpolationFunc( void* feVariable, Element_DomainIndex dElement_I, Coord localCoord, double* value ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
- FeVariable* field0 = self->feVariableList[0];
-
- FeVariable_InterpolateDerivativesToElLocalCoord( field0, dElement_I, localCoord, value );
-}
-
-void OperatorFeVariable_UnaryValueAtNodeFunc( void* feVariable, Node_DomainIndex dNode_I, double* value ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
- FeVariable* field0 = self->feVariableList[0];
- double fieldValue0[ MAX_FIELD_COMPONENTS ];
-
- FeVariable_GetValueAtNode( field0, dNode_I, fieldValue0 );
- Operator_CarryOutUnaryOperation( self->_operator, fieldValue0, value );
-}
-
-void OperatorFeVariable_BinaryValueAtNodeFunc( void* feVariable, Node_DomainIndex dNode_I, double* value ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
- FeVariable* field0 = self->feVariableList[0];
- FeVariable* field1 = self->feVariableList[1];
- double fieldValue0[ MAX_FIELD_COMPONENTS ];
- double fieldValue1[ MAX_FIELD_COMPONENTS ];
- double* coord;
- Element_DomainIndex field0Element;
- Element_DomainIndex field1Element;
- Coord field0LocalCoord;
- Coord field1LocalCoord;
-
- if( field0->feMesh == self->feMesh && field1->feMesh == self->feMesh ) {
- FeVariable_GetValueAtNode( field0, dNode_I, fieldValue0 );
- FeVariable_GetValueAtNode( field1, dNode_I, fieldValue1 );
- }
- /* field variables are using different meshes, so interpolate the values of each based on the global coord */
- else {
- coord = Mesh_GetVertex( self->feMesh, dNode_I );
- assert( Mesh_SearchElements( field0->feMesh, coord, &field0Element ) );
- FeMesh_CoordGlobalToLocal( field0->feMesh, field0Element, coord, field0LocalCoord );
- FeVariable_InterpolateWithinElement( field0, field0Element, field0LocalCoord, fieldValue0 );
-
- assert( Mesh_SearchElements( field1->feMesh, coord, &field1Element ) );
- FeMesh_CoordGlobalToLocal( field1->feMesh, field1Element, coord, field1LocalCoord );
- FeVariable_InterpolateWithinElement( field1, field1Element, field1LocalCoord, fieldValue1 );
- }
- Operator_CarryOutBinaryOperation( self->_operator, fieldValue0, fieldValue1, value );
-}
-
-void OperatorFeVariable_GradientValueAtNodeFunc( void* feVariable, Node_DomainIndex dNode_I, double* value ) {
- OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
- Mesh* mesh = (Mesh*) self->feMesh;
- double* coord;
-
- coord = Mesh_GetVertex( mesh, dNode_I );
-
- memset( value, 0, self->fieldComponentCount * sizeof(double) );
- FeVariable_InterpolateDerivativesAt( self->feVariableList[0], coord, value );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/OperatorFeVariable.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/OperatorFeVariable.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,685 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: OperatorFeVariable.c 1137 2008-05-23 05:57:48Z RobertTurnbull $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <string.h>
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "types.h"
+#include "FeVariable.h"
+#include "OperatorFeVariable.h"
+#include "FeMesh.h"
+
+#include <assert.h>
+
+const Type OperatorFeVariable_Type = "OperatorFeVariable";
+
+OperatorFeVariable* OperatorFeVariable_NewUnary(
+ Name name,
+ DomainContext* context,
+ void* _feVariable,
+ Name operatorName )
+{
+ FeVariable* feVariable = (FeVariable*) _feVariable;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)OperatorFeVariable_Type );
+
+ Journal_Firewall( feVariable != NULL, errorStream, "In func %s: Trying to operate on NULL field.\n", __func__ );
+
+ return OperatorFeVariable_New(
+ name,
+ context,
+ feVariable->feMesh,
+ feVariable->geometryMesh,
+ feVariable->dofLayout,
+ feVariable->bcs,
+ feVariable->ics,
+ feVariable->linkedDofInfo,
+ feVariable->templateFeVariable,
+ OperatorFeVariable_UnaryInterpolationFunc,
+ OperatorFeVariable_UnaryValueAtNodeFunc,
+ operatorName,
+ NULL,
+ 1,
+ &feVariable,
+ feVariable->dim,
+ feVariable->isCheckpointedAndReloaded,
+ feVariable->communicator,
+ feVariable->fieldVariable_Register );
+}
+
+OperatorFeVariable* OperatorFeVariable_NewUnary_OwnOperator(
+ Name name,
+ DomainContext* context,
+ void* _feVariable,
+ Operator* ownOperator )
+{
+ FeVariable* feVariable = (FeVariable*) _feVariable;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)OperatorFeVariable_Type );
+
+ Journal_Firewall( feVariable != NULL, errorStream, "In func %s: Trying to operate on NULL field.\n", __func__ );
+
+ return OperatorFeVariable_New(
+ name,
+ context,
+ feVariable->feMesh,
+ feVariable->geometryMesh,
+ feVariable->dofLayout,
+ feVariable->bcs,
+ feVariable->ics,
+ feVariable->linkedDofInfo,
+ feVariable->templateFeVariable,
+ OperatorFeVariable_UnaryInterpolationFunc,
+ OperatorFeVariable_UnaryValueAtNodeFunc,
+ ownOperator->name,
+ ownOperator,
+ 1,
+ &feVariable,
+ feVariable->dim,
+ feVariable->isCheckpointedAndReloaded,
+ feVariable->communicator,
+ feVariable->fieldVariable_Register );
+}
+
+OperatorFeVariable* OperatorFeVariable_NewBinary(
+ Name name,
+ DomainContext* context,
+ void* _feVariable1,
+ void* _feVariable2,
+ Name operatorName )
+{
+ FeVariable* feVariableList[2];
+ Stream* errorStream = Journal_Register( Error_Type, (Name)OperatorFeVariable_Type );
+
+ Journal_Firewall( _feVariable1 != NULL, errorStream, "In func %s: First field to operate on is NULL.\n", __func__ );
+ Journal_Firewall( _feVariable2 != NULL, errorStream, "In func %s: Second field to operate on is NULL.\n", __func__ );
+
+ feVariableList[0] = (FeVariable*) _feVariable1;
+ feVariableList[1] = (FeVariable*) _feVariable2;
+
+ return OperatorFeVariable_New(
+ name,
+ context,
+ feVariableList[0]->feMesh,
+ feVariableList[0]->geometryMesh,
+ feVariableList[0]->dofLayout,
+ feVariableList[0]->bcs,
+ feVariableList[0]->ics,
+ feVariableList[0]->linkedDofInfo,
+ feVariableList[0]->templateFeVariable,
+ OperatorFeVariable_BinaryInterpolationFunc,
+ OperatorFeVariable_BinaryValueAtNodeFunc,
+ operatorName,
+ NULL,
+ 2,
+ feVariableList,
+ feVariableList[0]->dim,
+ feVariableList[0]->isCheckpointedAndReloaded,
+ feVariableList[0]->communicator,
+ feVariableList[0]->fieldVariable_Register );
+}
+
+OperatorFeVariable* OperatorFeVariable_New(
+ Name name,
+ DomainContext* context,
+ void* feMesh,
+ void* geometryMesh,
+ DofLayout* dofLayout,
+ void* bcs,
+ void* ics,
+ void* linkedDofInfo,
+ void* templateFeVariable,
+ FeVariable_InterpolateWithinElementFunction* interpolateWithinElement,
+ FeVariable_GetValueAtNodeFunction* getValueAtNode,
+ Name operatorName,
+ Operator* ownOperator,
+ Index feVariableCount,
+ FeVariable** feVariableList,
+ Dimension_Index dim,
+ Bool isCheckpointedAndReloaded,
+ MPI_Comm communicator,
+ FieldVariable_Register* fieldVariable_Register )
+{
+ OperatorFeVariable* self = (OperatorFeVariable*)_OperatorFeVariable_DefaultNew( name );
+
+ self->isConstructed = True;
+ _FieldVariable_Init( (FieldVariable*)self, context, feVariableCount, dim, isCheckpointedAndReloaded, communicator, fieldVariable_Register );
+ _FeVariable_Init( (FeVariable*)self, feMesh, geometryMesh, dofLayout, bcs, ics, linkedDofInfo, templateFeVariable, True, False );
+ _OperatorFeVariable_Init( self, operatorName, feVariableCount, feVariableList, ownOperator );
+
+ return self;
+}
+
+void* _OperatorFeVariable_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(OperatorFeVariable);
+ Type type = OperatorFeVariable_Type;
+ Stg_Class_DeleteFunction* _delete = _OperatorFeVariable_Delete;
+ Stg_Class_PrintFunction* _print = _OperatorFeVariable_Print;
+ Stg_Class_CopyFunction* _copy = _OperatorFeVariable_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (Stg_Component_DefaultConstructorFunction*)_OperatorFeVariable_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _OperatorFeVariable_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _OperatorFeVariable_Build;
+ Stg_Component_InitialiseFunction* _initialise = _OperatorFeVariable_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _OperatorFeVariable_Execute;
+ Stg_Component_DestroyFunction* _destroy = _OperatorFeVariable_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ FieldVariable_InterpolateValueAtFunction* _interpolateValueAt = _OperatorFeVariable_InterpolateValueAt;
+ FieldVariable_GetValueFunction* _getMinGlobalFieldMagnitude = _FeVariable_GetMinGlobalFieldMagnitude;
+ FieldVariable_GetValueFunction* _getMaxGlobalFieldMagnitude = _FeVariable_GetMaxGlobalFieldMagnitude;
+ FieldVariable_GetCoordFunction* _getMinAndMaxLocalCoords = _FeVariable_GetMinAndMaxLocalCoords;
+ FieldVariable_GetCoordFunction* _getMinAndMaxGlobalCoords = _FeVariable_GetMinAndMaxGlobalCoords;
+ FeVariable_InterpolateWithinElementFunction* _interpolateWithinElement = _OperatorFeVariable_InterpolateWithinElement;
+ FeVariable_GetValueAtNodeFunction* _getValueAtNode = _OperatorFeVariable_GetValueAtNode;
+ FeVariable_SyncShadowValuesFunc* _syncShadowValues = _OperatorFeVariable_SyncShadowValues;
+
+ return _OperatorFeVariable_New( OPERATORFEVARIABLE_PASSARGS ); /* feVariableList_renamed */
+}
+
+OperatorFeVariable* _OperatorFeVariable_New( OPERATORFEVARIABLE_DEFARGS ) {
+ OperatorFeVariable* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(OperatorFeVariable) );
+ self = (OperatorFeVariable*) _FeVariable_New( FEVARIABLE_PASSARGS );
+
+ return self;
+}
+
+void _OperatorFeVariable_Init( void* oFeVar, Name operatorName, Index feVariableCount, FeVariable** feVariableList, Operator* ownOperator ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) oFeVar;
+ FeVariable* feVariable;
+ Index feVariable_I;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
+
+ /* Assign values to object */
+ self->feVariableCount = feVariableCount;
+ self->operatorName =operatorName;
+ self->_operator = ownOperator;
+
+ /* Copy field variable list */
+ self->feVariableList = Memory_Alloc_Array( FeVariable*, feVariableCount, "Array of Field Variables" );
+ memcpy( self->feVariableList, feVariableList, feVariableCount * sizeof( FeVariable* ) );
+
+ for ( feVariable_I = 0 ; feVariable_I < feVariableCount ; feVariable_I++ ) {
+ feVariable = feVariableList[ feVariable_I ];
+ Journal_Firewall( feVariable != NULL,
+ errorStream, "In func %s: Field Variable %u in list is NULL.\n", __func__, feVariable_I );
+ Journal_Firewall( feVariable->fieldComponentCount <= MAX_FIELD_COMPONENTS,
+ errorStream, "In func %s: Field Variable '%s' has too many components.\n", __func__, feVariable->name );
+ }
+}
+
+void _OperatorFeVariable_Delete( void* _feVariable ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) _feVariable;
+
+ _FeVariable_Delete( self );
+}
+
+void _OperatorFeVariable_Print( void* _feVariable, Stream* stream ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) _feVariable;
+ Index feVariable_I;
+
+ _FeVariable_Print( self, stream );
+
+ Journal_PrintValue( stream, self->feVariableCount );
+ for ( feVariable_I = 0 ; feVariable_I < self->feVariableCount ; feVariable_I++ )
+ Journal_Printf( stream, "\tFeVariable %u - '%s'\n", feVariable_I, self->feVariableList[ feVariable_I ]->name );
+
+}
+
+void* _OperatorFeVariable_Copy( const void* feVariable, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ OperatorFeVariable* self = (OperatorFeVariable*)feVariable;
+ OperatorFeVariable* newOperatorFeVariable;
+
+ newOperatorFeVariable = (OperatorFeVariable*)_FeVariable_Copy( self, dest, deep, nameExt, ptrMap );
+
+ newOperatorFeVariable->_operator = self->_operator;
+ newOperatorFeVariable->feVariableCount = self->feVariableCount;
+
+ if (deep) {
+ newOperatorFeVariable->feVariableList = Memory_Alloc_Array( FeVariable*, self->feVariableCount, "Array of Field Variables" );
+ memcpy( newOperatorFeVariable->feVariableList, self->feVariableList, self->feVariableCount * sizeof( FeVariable* ) );
+ }
+ else
+ newOperatorFeVariable->feVariableList = self->feVariableList;
+
+ return (void*)newOperatorFeVariable;
+}
+
+void _OperatorFeVariable_AssignFromXML( void* feVariable, Stg_ComponentFactory* cf, void* data ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+ Dictionary* dictionary = Dictionary_GetDictionary( cf->componentDict, self->name );
+ Dictionary_Entry_Value* list;
+ Index feVariableCount = 0;
+ Index feVariable_I;
+ FieldVariable_Register* fV_Register;
+ Name feVariableName;
+ Name operatorName;
+ FeVariable** feVariableList;
+
+ /* Construct Parent */
+ _FieldVariable_AssignFromXML( self, cf, data );
+
+ fV_Register = self->context->fieldVariable_Register;
+
+ operatorName = Stg_ComponentFactory_GetString( cf, self->name, (Dictionary_Entry_Key)"Operator", "" );
+
+ list = Dictionary_Get( dictionary, (Dictionary_Entry_Key)"FeVariables" );
+
+ feVariableCount = ( list ? Dictionary_Entry_Value_GetCount(list) : 1 );
+ feVariableList = Memory_Alloc_Array( FeVariable*, feVariableCount, "FeVars" );
+
+ for ( feVariable_I = 0 ; feVariable_I < feVariableCount ; feVariable_I++ ) {
+ feVariableName = (list ? Dictionary_Entry_Value_AsString( Dictionary_Entry_Value_GetElement( list, feVariable_I ) ) :
+ Dictionary_GetString( dictionary, (Dictionary_Entry_Key)"FeVariable" ) );
+
+ /* Check in fV_Register first before assuming in LiveComponentRegister */
+ Journal_PrintfL( cf->infoStream, 2, "Looking for FeVariable '%s' in fieldVariable_Register.\n", feVariableName );
+ feVariableList[feVariable_I] = (FeVariable*) FieldVariable_Register_GetByName( fV_Register, feVariableName );
+
+ if ( !feVariableList[feVariable_I] )
+ feVariableList[feVariable_I] =
+ Stg_ComponentFactory_ConstructByName( cf, (Name)feVariableName, FeVariable, True, data );
+ }
+
+ _FeVariable_Init( (FeVariable* ) self, feVariableList[0]->feMesh, feVariableList[0]->geometryMesh, feVariableList[0]->dofLayout, NULL, NULL, NULL, NULL, True, False );
+ _OperatorFeVariable_Init( self, operatorName, feVariableCount, feVariableList, NULL );
+
+ Memory_Free( feVariableList );
+}
+
+void _OperatorFeVariable_Build( void* feVariable, void* data ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+ Index feVariable_I;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
+
+ _FeVariable_Build( self, data );
+
+ for ( feVariable_I = 0 ; feVariable_I < self->feVariableCount ; feVariable_I++ )
+ Stg_Component_Build( self->feVariableList[ feVariable_I ] , data, False );
+
+ if ( !self->_operator){
+ /* Check if we are using a gradient operator */
+ if ( strcasecmp( self->operatorName, "gradient" ) == 0 ) {
+ self->useGradient = True;
+ assert( self->feVariableCount == 1 );
+ self->fieldComponentCount = self->feVariableList[0]->fieldComponentCount * self->dim;
+ }
+ else {
+ /* just use normal operator */
+ self->useGradient = False;
+ /* Added 5 May 2006 by P Sunter: in the case of VectorScale, the fieldComponentCount should be based
+ on the 2nd operator. Also make sure the 2nd operator has at least as may dofs per node as the first. */
+ if ( self->feVariableCount == 2 ) {
+ Journal_Firewall( self->feVariableList[1]->fieldComponentCount >= self->feVariableList[0]->fieldComponentCount,
+ errorStream, "Error - in %s: tried to create a %s operator from feVariables \"%s\" "
+ "and \"%s\" - who have fieldCounts %d and %d - unsupported since operations "
+ "such as VectorScale require the 2nd feVariable to have >= the first's field count.\n",
+ __func__, self->operatorName, self->feVariableList[0]->name, self->feVariableList[1]->name,
+ self->feVariableList[0]->fieldComponentCount, self->feVariableList[1]->fieldComponentCount );
+ self->_operator = Operator_NewFromName( self->operatorName, self->feVariableList[1]->fieldComponentCount,
+ self->dim );
+ }
+ else {
+ self->_operator = Operator_NewFromName( self->operatorName, self->feVariableList[0]->fieldComponentCount,
+ self->dim );
+ }
+
+ self->fieldComponentCount = self->_operator->resultDofs; /* reset this value from that which is from operator */
+ }
+ }
+ else {
+ self->useGradient = False;
+ self->fieldComponentCount = self->_operator->resultDofs; /* reset this value from that which is from operator */
+ }
+
+ _OperatorFeVariable_SetFunctions( self );
+}
+
+void _OperatorFeVariable_Initialise( void* feVariable, void* data ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+ DomainContext* context = self->context;
+ Index feVariable_I;
+ Dictionary_Entry_Value* feVarsList = NULL;
+
+ for ( feVariable_I = 0 ; feVariable_I < self->feVariableCount ; feVariable_I++ )
+ Stg_Component_Initialise( self->feVariableList[ feVariable_I ] , data, False );
+
+ /* also include check to see if this fevariable should be checkpointed, just incase it didn't go through the fieldvariable construct phase */
+ feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"fieldVariablesToCheckpoint" );
+ if ( NULL == feVarsList ) {
+ feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"FieldVariablesToCheckpoint" );
+ }
+ if (feVarsList != NULL ) {
+ Index listLength = Dictionary_Entry_Value_GetCount( feVarsList );
+ Index var_I = 0;
+ Dictionary_Entry_Value* feVarDictValue = NULL;
+ char* fieldVariableName;
+
+ for ( var_I = 0; var_I < listLength; var_I++ ) {
+ feVarDictValue = Dictionary_Entry_Value_GetElement( feVarsList, var_I );
+ fieldVariableName = Dictionary_Entry_Value_AsString( feVarDictValue );
+ if ( 0 == strcmp( self->name, fieldVariableName ) ) {
+ self->isCheckpointedAndReloaded = True;
+ break;
+ }
+ }
+ }
+
+ feVarsList = NULL;
+ /** also include check to see if this fevariable should be saved for analysis purposes */
+ feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"fieldVariablesToSave" );
+ if ( NULL == feVarsList ) {
+ feVarsList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)"FieldVariablesToSave" );
+ }
+ if (feVarsList != NULL ) {
+ Index listLength = Dictionary_Entry_Value_GetCount( feVarsList );
+ Index var_I = 0;
+ Dictionary_Entry_Value* feVarDictValue = NULL;
+ char* fieldVariableName;
+
+ for ( var_I = 0; var_I < listLength; var_I++ ) {
+ feVarDictValue = Dictionary_Entry_Value_GetElement( feVarsList, var_I );
+ fieldVariableName = Dictionary_Entry_Value_AsString( feVarDictValue );
+ if ( 0 == strcmp( self->name, fieldVariableName ) ) {
+ self->isSavedData = True;
+ break;
+ }
+ }
+ }
+}
+
+void _OperatorFeVariable_Execute( void* feVariable, void* data ) {}
+
+void _OperatorFeVariable_Destroy( void* feVariable, void* data ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+
+ Memory_Free( self->feVariableList );
+
+ _FeVariable_Destroy( self, data );
+}
+
+void _OperatorFeVariable_SetFunctions( void* feVariable ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+ Stream* error = Journal_Register( Error_Type, (Name)self->type );
+
+ if ( self->useGradient ) {
+ Journal_Firewall( self->feVariableCount == 1, error, "Cannot use gradient operators for multiple variables.\n" );
+ self->_interpolateWithinElement = OperatorFeVariable_GradientInterpolationFunc;
+ self->_getValueAtNode = OperatorFeVariable_GradientValueAtNodeFunc;
+ }
+ else {
+ switch ( self->feVariableCount ) {
+ case 1:
+ self->_interpolateWithinElement = OperatorFeVariable_UnaryInterpolationFunc;
+ self->_getValueAtNode = OperatorFeVariable_UnaryValueAtNodeFunc; break;
+ case 2:
+ self->_interpolateWithinElement = OperatorFeVariable_BinaryInterpolationFunc;
+ self->_getValueAtNode = OperatorFeVariable_BinaryValueAtNodeFunc; break;
+ default: {
+ Journal_Firewall( False, error,
+ "Cannot use '%s' with feVariableCount = %u.\n", __func__, self->feVariableCount );
+ }
+ }
+ }
+}
+void _OperatorFeVariable_InterpolateWithinElement( void* feVariable, Element_DomainIndex dElement_I, Coord coord, double* value ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+
+ _OperatorFeVariable_SetFunctions( self );
+ FeVariable_InterpolateWithinElement( self, dElement_I, coord, value );
+}
+
+void _OperatorFeVariable_GetValueAtNode( void* feVariable, Node_DomainIndex dNode_I, double* value ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+
+ _OperatorFeVariable_SetFunctions( self );
+ FeVariable_GetValueAtNode( self, dNode_I, value );
+}
+
+void _OperatorFeVariable_SyncShadowValues( void* feVariable ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+ int v_i;
+
+ assert( self );
+ for( v_i = 0; v_i < self->feVariableCount; v_i++ )
+ FeVariable_SyncShadowValues( self->feVariableList[v_i] );
+ self->shadowValuesSynchronised = True;
+}
+
+
+/** Private Functions */
+Bool _OperatorFeVariable_CheckIfValidToInterpolateInShadowSpace( OperatorFeVariable* self ){
+ int feVar_I;
+ FeVariable* currFeVar;
+ Bool parentIsValid;
+
+ for ( feVar_I=0; feVar_I < self->feVariableCount; feVar_I++ ) {
+ currFeVar = self->feVariableList[feVar_I];
+ if( Stg_Class_IsInstance( currFeVar, FeVariable_Type ) ) {
+ if ( False == currFeVar->shadowValuesSynchronised ) {
+ return False;
+ }
+ else {
+ return True;
+ }
+ }
+ else {
+ parentIsValid = _OperatorFeVariable_CheckIfValidToInterpolateInShadowSpace(
+ (OperatorFeVariable*)currFeVar );
+ if ( False == parentIsValid ) {
+ return False;
+ }
+ }
+ }
+
+ return True;
+}
+
+
+/** Needed to over-ride the standard _FeVariable_InterpolateValueAt() since for operator fe variables, as long as the
+base fe variable has been shadowed, this operatorFeVar can be calculated in shadow space */
+InterpolationResult _OperatorFeVariable_InterpolateValueAt( void* variable, Coord globalCoord, double* value ) {
+ OperatorFeVariable* self = (OperatorFeVariable*)variable;
+ Element_DomainIndex elementCoordIn = (unsigned)-1;
+ Coord elLocalCoord={0,0,0};
+ InterpolationResult retValue;
+ Bool validToInterpolateInShadowSpace;
+
+
+ retValue = FeVariable_GetElementLocalCoordAtGlobalCoord( self, globalCoord, elLocalCoord, &elementCoordIn );
+
+ if ( retValue == LOCAL ) {
+ /* Now interpolate the value at that coordinate, using shape functions */
+ self->_interpolateWithinElement( self, elementCoordIn, elLocalCoord, value );
+ }
+ else if ( retValue == SHADOW ) {
+ validToInterpolateInShadowSpace = _OperatorFeVariable_CheckIfValidToInterpolateInShadowSpace(self);
+
+ if ( False == validToInterpolateInShadowSpace ) {
+ Stream* warningStr = Journal_Register( Error_Type, (Name)self->type );
+ Journal_Printf( warningStr, "Warning - in %s, for OperatorFeVar \"%s\": user asking to "
+ "interpolate a value at "
+ "coord (%g,%g,%g), which is in shadow space, but "
+ "FeVariable_SyncShadowValues() hasn't been called on FeVariables this one is "
+ "derived from yet.\n",
+ __func__, self->name, globalCoord[0], globalCoord[1], globalCoord[2] );
+ return retValue;
+ }
+ /* Now interpolate the value at that coordinate, using shape functions */
+ self->_interpolateWithinElement( self, elementCoordIn, elLocalCoord, value );
+ }
+
+ return retValue;
+}
+
+
+
+void OperatorFeVariable_UnaryInterpolationFunc( void* feVariable, Element_DomainIndex dElement_I, Coord localCoord, double* value ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+ FeVariable* field0 = self->feVariableList[0];
+ double fieldValue0[ MAX_FIELD_COMPONENTS ];
+
+ field0->_interpolateWithinElement( field0, dElement_I, localCoord, fieldValue0 );
+ Operator_CarryOutUnaryOperation( self->_operator, fieldValue0, value );
+
+#ifdef DEBUG
+ if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+ Dimension_Index dim_I;
+ Dof_Index dof_I;
+ Journal_DPrintf( self->debug, "%s Unary Op: El %d, xi = ( ", self->name, dElement_I );
+ for ( dim_I = 0 ; dim_I < self->dim ; dim_I++ )
+ Journal_DPrintf( self->debug, "%g ", localCoord[ dim_I ] );
+
+ /* Field 0 */
+ Journal_DPrintf( self->debug, ") - %s = [ ", field0->name );
+ for ( dof_I = 0 ; dof_I < field0->fieldComponentCount ; dof_I++ )
+ Journal_DPrintf( self->debug, "%g ", fieldValue0[ dof_I ] );
+
+ /* Result */
+ Journal_DPrintf( self->debug, "] - Result = [ " );
+ for ( dof_I = 0 ; dof_I < self->fieldComponentCount ; dof_I++ )
+ Journal_DPrintf( self->debug, "%g ", value[ dof_I ] );
+ Journal_DPrintf( self->debug, "]\n" );
+ }
+#endif
+
+}
+
+void OperatorFeVariable_BinaryInterpolationFunc( void* feVariable, Element_DomainIndex dElement_I, Coord localCoord, double* value ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+ FeVariable* field0 = self->feVariableList[0];
+ FeVariable* field1 = self->feVariableList[1];
+ FeMesh* mesh = self->feMesh;
+ double fieldValue0[ MAX_FIELD_COMPONENTS ];
+ double fieldValue1[ MAX_FIELD_COMPONENTS ];
+
+ FeVariable_InterpolateFromMeshLocalCoord( field0, mesh, dElement_I, localCoord, fieldValue0 );
+ FeVariable_InterpolateFromMeshLocalCoord( field1, mesh, dElement_I, localCoord, fieldValue1 );
+
+ Operator_CarryOutBinaryOperation( self->_operator, fieldValue0, fieldValue1, value );
+
+#ifdef DEBUG
+ if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+ Dimension_Index dim_I;
+ Dof_Index dof_I;
+ Journal_DPrintf( self->debug, "%s Binary Op: El %d, xi = ( ", self->name, dElement_I );
+ for ( dim_I = 0 ; dim_I < self->dim ; dim_I++ )
+ Journal_DPrintf( self->debug, "%g ", localCoord[ dim_I ] );
+
+ /* Field 0 */
+ Journal_DPrintf( self->debug, ") - %s = [ ", field0->name );
+ for ( dof_I = 0 ; dof_I < field0->fieldComponentCount ; dof_I++ )
+ Journal_DPrintf( self->debug, "%g ", fieldValue0[ dof_I ] );
+
+ /* Field 1 */
+ Journal_DPrintf( self->debug, "] - %s = [ ", field1->name );
+ for ( dof_I = 0 ; dof_I < field1->fieldComponentCount ; dof_I++ )
+ Journal_DPrintf( self->debug, "%g ", fieldValue1[ dof_I ] );
+
+ /* Result */
+ Journal_DPrintf( self->debug, "] - Result = [ " );
+ for ( dof_I = 0 ; dof_I < self->fieldComponentCount ; dof_I++ )
+ Journal_DPrintf( self->debug, "%g ", value[ dof_I ] );
+ Journal_DPrintf( self->debug, "]\n" );
+ }
+#endif
+}
+
+void OperatorFeVariable_GradientInterpolationFunc( void* feVariable, Element_DomainIndex dElement_I, Coord localCoord, double* value ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+ FeVariable* field0 = self->feVariableList[0];
+
+ FeVariable_InterpolateDerivativesToElLocalCoord( field0, dElement_I, localCoord, value );
+}
+
+void OperatorFeVariable_UnaryValueAtNodeFunc( void* feVariable, Node_DomainIndex dNode_I, double* value ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+ FeVariable* field0 = self->feVariableList[0];
+ double fieldValue0[ MAX_FIELD_COMPONENTS ];
+
+ FeVariable_GetValueAtNode( field0, dNode_I, fieldValue0 );
+ Operator_CarryOutUnaryOperation( self->_operator, fieldValue0, value );
+}
+
+void OperatorFeVariable_BinaryValueAtNodeFunc( void* feVariable, Node_DomainIndex dNode_I, double* value ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+ FeVariable* field0 = self->feVariableList[0];
+ FeVariable* field1 = self->feVariableList[1];
+ double fieldValue0[ MAX_FIELD_COMPONENTS ];
+ double fieldValue1[ MAX_FIELD_COMPONENTS ];
+ double* coord;
+ Element_DomainIndex field0Element;
+ Element_DomainIndex field1Element;
+ Coord field0LocalCoord;
+ Coord field1LocalCoord;
+
+ if( field0->feMesh == self->feMesh && field1->feMesh == self->feMesh ) {
+ FeVariable_GetValueAtNode( field0, dNode_I, fieldValue0 );
+ FeVariable_GetValueAtNode( field1, dNode_I, fieldValue1 );
+ }
+ /* field variables are using different meshes, so interpolate the values of each based on the global coord */
+ else {
+ coord = Mesh_GetVertex( self->feMesh, dNode_I );
+ assert( Mesh_SearchElements( field0->feMesh, coord, &field0Element ) );
+ FeMesh_CoordGlobalToLocal( field0->feMesh, field0Element, coord, field0LocalCoord );
+ FeVariable_InterpolateWithinElement( field0, field0Element, field0LocalCoord, fieldValue0 );
+
+ assert( Mesh_SearchElements( field1->feMesh, coord, &field1Element ) );
+ FeMesh_CoordGlobalToLocal( field1->feMesh, field1Element, coord, field1LocalCoord );
+ FeVariable_InterpolateWithinElement( field1, field1Element, field1LocalCoord, fieldValue1 );
+ }
+ Operator_CarryOutBinaryOperation( self->_operator, fieldValue0, fieldValue1, value );
+}
+
+void OperatorFeVariable_GradientValueAtNodeFunc( void* feVariable, Node_DomainIndex dNode_I, double* value ) {
+ OperatorFeVariable* self = (OperatorFeVariable*) feVariable;
+ Mesh* mesh = (Mesh*) self->feMesh;
+ double* coord;
+
+ coord = Mesh_GetVertex( mesh, dNode_I );
+
+ memset( value, 0, self->fieldComponentCount * sizeof(double) );
+ FeVariable_InterpolateDerivativesAt( self->feVariableList[0], coord, value );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/P1.c
--- a/Discretisation/src/P1.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: P1.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <mpi.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "Discretisation.h"
-
-
-/* Textual name of this class */
-const Type P1_Type = "P1";
-
-#define P1_NODECOUNT 3
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-P1* P1_New( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(P1);
- Type type = P1_Type;
- Stg_Class_DeleteFunction* _delete = _P1_Delete;
- Stg_Class_PrintFunction* _print = _P1_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_P1_New;
- Stg_Component_ConstructFunction* _construct = _P1_AssignFromXML;
- Stg_Component_BuildFunction* _build = _P1_Build;
- Stg_Component_InitialiseFunction* _initialise = _P1_Initialise;
- Stg_Component_ExecuteFunction* _execute = _P1_Execute;
- Stg_Component_DestroyFunction* _destroy = _P1_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = P1_EvalBasis;
- ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = P1_EvalLocalDerivs;
- ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = NULL;
- ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _ElementType_JacobianDeterminantSurface;
- ElementType_SurfaceNormalFunction* _surfaceNormal = _P1_SurfaceNormal;
-
- return _P1_New( P1_PASSARGS );
-}
-
-P1* _P1_New( P1_DEFARGS ) {
- P1* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(P1) );
- self = (P1*)_ElementType_New( ELEMENTTYPE_PASSARGS );
-
- /* Virtual info */
-
- /* P1 info */
- self->isConstructed = True;
- _ElementType_Init( (ElementType*)self, P1_NODECOUNT );
- _P1_Init( self );
-
- return self;
-}
-
-void _P1_Init( P1* self ) {
- assert( self && Stg_CheckType( self, P1 ) );
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _P1_Delete( void* elementType ) {
- P1* self = (P1*)elementType;
-
- /* Delete the parent. */
- _ElementType_Delete( self );
-}
-
-void _P1_Print( void* elementType, Stream* stream ) {
- P1* self = (P1*)elementType;
-
- /* Set the Journal for printing informations */
- Stream* elementTypeStream;
- elementTypeStream = Journal_Register( InfoStream_Type, (Name)"P1Stream" );
-
- /* Print parent */
- Journal_Printf( stream, "P1 (ptr): (%p)\n", self );
- _ElementType_Print( self, stream );
-}
-
-void _P1_AssignFromXML( void* elementType, Stg_ComponentFactory* cf, void* data ) {
-}
-
-void _P1_Build( void* elementType, void* data ) {
-}
-
-void _P1_Initialise( void* elementType, void* data ) {
-}
-
-void _P1_Execute( void* elementType, void* data ) {
-}
-
-void _P1_Destroy( void* elementType, void* data ) {
- P1* self = (P1*)elementType;
-
- _ElementType_Destroy( self, data );
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-void P1_EvalBasis( void* elementType, const double* localCoord, double* basis ) {
- double xi = localCoord[0], eta = localCoord[1];
- double a0 = xi - 1.0, b0 = eta - 1.0;
- double a1 = 1.0 - xi * xi, b1 = 1.0 - eta * eta;
- double a2 = xi + 1.0, b2 = eta + 1.0;
- double m0 = 0.5 * xi;
- double m1 = 0.5 * eta;
- double m2 = 0.25 * xi * eta;
-
- basis[0] = m2 * a0 * b0;
- basis[1] = m1 * a1 * b0;
- basis[2] = m2 * a2 * b0;
-
- basis[3] = m0 * a0 * b1;
- basis[4] = a1 * b1;
- basis[5] = m0 * a2 * b1;
-
- basis[6] = m2 * a0 * b2;
- basis[7] = m1 * a1 * b2;
- basis[8] = m2 * a2 * b2;
-}
-
-void P1_EvalLocalDerivs( void* elementType, const double* localCoord, double** derivs ) {
- double xi = localCoord[0], eta = localCoord[1];
- double a0 = xi - 1.0, b0 = eta - 1.0;
- double a1 = xi + 1.0, b1 = eta + 1.0;
- double a2 = 2.0 * xi - 1.0, b2 = 2.0 * eta - 1.0;
- double a3 = 2.0 * xi + 1.0, b3 = 2.0 * eta + 1.0;
- double a4 = 1.0 - xi * xi, b4 = 1.0 - eta * eta;
- double m0 = 0.25 * xi;
- double m1 = 0.25 * eta;
- double m2 = -xi * eta;
-
- /* Corner nodes. */
- derivs[0][0] = m1 * a2 * b0;
- derivs[0][2] = m1 * a3 * b0;
- derivs[0][6] = m1 * a2 * b1;
- derivs[0][8] = m1 * a3 * b1;
- derivs[1][0] = m0 * a0 * b2;
- derivs[1][2] = m0 * a1 * b2;
- derivs[1][6] = m0 * a0 * b3;
- derivs[1][8] = m0 * a1 * b3;
-
- /* Side nodes. */
- derivs[0][1] = m2 * b0;
- derivs[0][7] = m2 * b1;
- derivs[0][3] = 0.5 * a2 * b4;
- derivs[0][5] = 0.5 * a3 * b4;
- derivs[1][1] = 0.5 * a4 * b2;
- derivs[1][7] = 0.5 * a4 * b3;
- derivs[1][3] = m2 * a0;
- derivs[1][5] = m2 * a1;
-
- /* Center node. */
- derivs[0][4] = -2.0 * xi * b4;
- derivs[1][4] = -2.0 * eta * a4;
-}
-
-int _P1_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* normal ) {
- Stream* errStream = Journal_Register( ErrorStream_Type, (Name)ElementType_Type );
-
- Journal_Printf( errStream, "surface normal function not implemented for this element type.\n" );
- assert( 0 );
-
- normal = NULL;
-
- return -1;
-}
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/P1.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/P1.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,216 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: P1.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type P1_Type = "P1";
+
+#define P1_NODECOUNT 3
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+P1* P1_New( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(P1);
+ Type type = P1_Type;
+ Stg_Class_DeleteFunction* _delete = _P1_Delete;
+ Stg_Class_PrintFunction* _print = _P1_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_P1_New;
+ Stg_Component_ConstructFunction* _construct = _P1_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _P1_Build;
+ Stg_Component_InitialiseFunction* _initialise = _P1_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _P1_Execute;
+ Stg_Component_DestroyFunction* _destroy = _P1_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = P1_EvalBasis;
+ ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = P1_EvalLocalDerivs;
+ ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = NULL;
+ ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _ElementType_JacobianDeterminantSurface;
+ ElementType_SurfaceNormalFunction* _surfaceNormal = _P1_SurfaceNormal;
+
+ return _P1_New( P1_PASSARGS );
+}
+
+P1* _P1_New( P1_DEFARGS ) {
+ P1* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(P1) );
+ self = (P1*)_ElementType_New( ELEMENTTYPE_PASSARGS );
+
+ /* Virtual info */
+
+ /* P1 info */
+ self->isConstructed = True;
+ _ElementType_Init( (ElementType*)self, P1_NODECOUNT );
+ _P1_Init( self );
+
+ return self;
+}
+
+void _P1_Init( P1* self ) {
+ assert( self && Stg_CheckType( self, P1 ) );
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _P1_Delete( void* elementType ) {
+ P1* self = (P1*)elementType;
+
+ /* Delete the parent. */
+ _ElementType_Delete( self );
+}
+
+void _P1_Print( void* elementType, Stream* stream ) {
+ P1* self = (P1*)elementType;
+
+ /* Set the Journal for printing informations */
+ Stream* elementTypeStream;
+ elementTypeStream = Journal_Register( InfoStream_Type, (Name)"P1Stream" );
+
+ /* Print parent */
+ Journal_Printf( stream, "P1 (ptr): (%p)\n", self );
+ _ElementType_Print( self, stream );
+}
+
+void _P1_AssignFromXML( void* elementType, Stg_ComponentFactory* cf, void* data ) {
+}
+
+void _P1_Build( void* elementType, void* data ) {
+}
+
+void _P1_Initialise( void* elementType, void* data ) {
+}
+
+void _P1_Execute( void* elementType, void* data ) {
+}
+
+void _P1_Destroy( void* elementType, void* data ) {
+ P1* self = (P1*)elementType;
+
+ _ElementType_Destroy( self, data );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+void P1_EvalBasis( void* elementType, const double* localCoord, double* basis ) {
+ double xi = localCoord[0], eta = localCoord[1];
+ double a0 = xi - 1.0, b0 = eta - 1.0;
+ double a1 = 1.0 - xi * xi, b1 = 1.0 - eta * eta;
+ double a2 = xi + 1.0, b2 = eta + 1.0;
+ double m0 = 0.5 * xi;
+ double m1 = 0.5 * eta;
+ double m2 = 0.25 * xi * eta;
+
+ basis[0] = m2 * a0 * b0;
+ basis[1] = m1 * a1 * b0;
+ basis[2] = m2 * a2 * b0;
+
+ basis[3] = m0 * a0 * b1;
+ basis[4] = a1 * b1;
+ basis[5] = m0 * a2 * b1;
+
+ basis[6] = m2 * a0 * b2;
+ basis[7] = m1 * a1 * b2;
+ basis[8] = m2 * a2 * b2;
+}
+
+void P1_EvalLocalDerivs( void* elementType, const double* localCoord, double** derivs ) {
+ double xi = localCoord[0], eta = localCoord[1];
+ double a0 = xi - 1.0, b0 = eta - 1.0;
+ double a1 = xi + 1.0, b1 = eta + 1.0;
+ double a2 = 2.0 * xi - 1.0, b2 = 2.0 * eta - 1.0;
+ double a3 = 2.0 * xi + 1.0, b3 = 2.0 * eta + 1.0;
+ double a4 = 1.0 - xi * xi, b4 = 1.0 - eta * eta;
+ double m0 = 0.25 * xi;
+ double m1 = 0.25 * eta;
+ double m2 = -xi * eta;
+
+ /* Corner nodes. */
+ derivs[0][0] = m1 * a2 * b0;
+ derivs[0][2] = m1 * a3 * b0;
+ derivs[0][6] = m1 * a2 * b1;
+ derivs[0][8] = m1 * a3 * b1;
+ derivs[1][0] = m0 * a0 * b2;
+ derivs[1][2] = m0 * a1 * b2;
+ derivs[1][6] = m0 * a0 * b3;
+ derivs[1][8] = m0 * a1 * b3;
+
+ /* Side nodes. */
+ derivs[0][1] = m2 * b0;
+ derivs[0][7] = m2 * b1;
+ derivs[0][3] = 0.5 * a2 * b4;
+ derivs[0][5] = 0.5 * a3 * b4;
+ derivs[1][1] = 0.5 * a4 * b2;
+ derivs[1][7] = 0.5 * a4 * b3;
+ derivs[1][3] = m2 * a0;
+ derivs[1][5] = m2 * a1;
+
+ /* Center node. */
+ derivs[0][4] = -2.0 * xi * b4;
+ derivs[1][4] = -2.0 * eta * a4;
+}
+
+int _P1_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* normal ) {
+ Stream* errStream = Journal_Register( ErrorStream_Type, (Name)ElementType_Type );
+
+ Journal_Printf( errStream, "surface normal function not implemented for this element type.\n" );
+ assert( 0 );
+
+ normal = NULL;
+
+ return -1;
+}
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/RegularBilinear.c
--- a/Discretisation/src/RegularBilinear.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: RegularBilinear.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <mpi.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "Discretisation.h"
-
-
-/* Textual name of this class */
-const Type RegularBilinear_Type = "RegularBilinear";
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-#define REGULARBILINEAR_NODECOUNT 4
-
-RegularBilinear* RegularBilinear_New( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(RegularBilinear);
- Type type = RegularBilinear_Type;
- Stg_Class_DeleteFunction* _delete = _RegularBilinear_Delete;
- Stg_Class_PrintFunction* _print = _RegularBilinear_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_RegularBilinear_New;
- Stg_Component_ConstructFunction* _construct = _RegularBilinear_AssignFromXML;
- Stg_Component_BuildFunction* _build = _RegularBilinear_Build;
- Stg_Component_InitialiseFunction* _initialise = _RegularBilinear_Initialise;
- Stg_Component_ExecuteFunction* _execute = _RegularBilinear_Execute;
- Stg_Component_DestroyFunction* _destroy = _RegularBilinear_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _BilinearElementType_SF_allNodes;
- ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _BilinearElementType_SF_allLocalDerivs_allNodes;
- ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
- ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _BilinearElementType_JacobianDeterminantSurface;
- ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
-
- return _RegularBilinear_New( REGULARBILINEAR_PASSARGS );
-}
-
-RegularBilinear* _RegularBilinear_New( REGULARBILINEAR_DEFARGS ) {
- RegularBilinear* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(RegularBilinear) );
- self = (RegularBilinear*)_BilinearElementType_New( BILINEARELEMENTTYPE_PASSARGS );
-
- /* Virtual info */
-
- /* RegularBilinear info */
- self->isConstructed = True;
- _ElementType_Init( (ElementType*)self, REGULARBILINEAR_NODECOUNT );
- _BilinearElementType_Init( (BilinearElementType*)self );
- _RegularBilinear_Init( self );
-
- return self;
-}
-
-void _RegularBilinear_Init( RegularBilinear* self ) {
- assert( self && Stg_CheckType( self, RegularBilinear ) );
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _RegularBilinear_Delete( void* elementType ) {
- RegularBilinear* self = (RegularBilinear*)elementType;
-
- /* Delete the parent. */
- _BilinearElementType_Delete( self );
-}
-
-void _RegularBilinear_Print( void* elementType, Stream* stream ) {
- RegularBilinear* self = (RegularBilinear*)elementType;
-
- /* Set the Journal for printing informations */
- Stream* elementTypeStream;
- elementTypeStream = Journal_Register( InfoStream_Type, (Name)"RegularBilinearStream" );
-
- /* Print parent */
- Journal_Printf( stream, "RegularBilinear (ptr): (%p)\n", self );
- _BilinearElementType_Print( self, stream );
-}
-
-void _RegularBilinear_AssignFromXML( void* elementType, Stg_ComponentFactory* cf, void* data ) {
-}
-
-void _RegularBilinear_Build( void* elementType, void* data ) {
- _BilinearElementType_Build( elementType, data );
-}
-
-void _RegularBilinear_Initialise( void* elementType, void* data ) {
- _BilinearElementType_Initialise( elementType, data );
-}
-
-void _RegularBilinear_Execute( void* elementType, void* data ) {
-}
-
-void _RegularBilinear_Destroy( void* elementType, void* data ) {
- RegularBilinear* self = (RegularBilinear*)elementType;
-
- _BilinearElementType_Destroy( self, data );
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-#if 0
-void RegularBilinear_ConvertGlobalCoordToElLocal( void* elementType, void* mesh, unsigned element,
- const double* globalCoord, double* localCoord )
-{
- RegularBilinear* self = (RegularBilinear*)elementType;
- unsigned nInc, *inc;
- double* vert[2];
- double w;
-
- assert( self && Stg_CheckType( self, RegularBilinear ) );
-
- Mesh_GetIncidence( mesh, MT_VOLUME, element, MT_VERTEX, self->inc );
- nInc = IArray_GetSize( self->inc );
- inc = IArray_GetSize( self->inc );
-
- vert[0] = Mesh_GetVertex( mesh, inc[0] );
- vert[1] = Mesh_GetVertex( mesh, inc[3] );
- w = vert[1][0] - vert[0][0];
- localCoord[0] = 2.0 * (globalCoord[0] - vert[0][0]) / w - 1.0;
- w = vert[1][1] - vert[0][1];
- localCoord[1] = 2.0 * (globalCoord[1] - vert[0][1]) / w - 1.0;
-
- assert( localCoord[0] >= -1.0 && localCoord[0] <= 1.0 );
- assert( localCoord[1] >= -1.0 && localCoord[1] <= 1.0 );
-}
-#endif
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/RegularBilinear.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/RegularBilinear.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,178 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: RegularBilinear.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type RegularBilinear_Type = "RegularBilinear";
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+#define REGULARBILINEAR_NODECOUNT 4
+
+RegularBilinear* RegularBilinear_New( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(RegularBilinear);
+ Type type = RegularBilinear_Type;
+ Stg_Class_DeleteFunction* _delete = _RegularBilinear_Delete;
+ Stg_Class_PrintFunction* _print = _RegularBilinear_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_RegularBilinear_New;
+ Stg_Component_ConstructFunction* _construct = _RegularBilinear_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _RegularBilinear_Build;
+ Stg_Component_InitialiseFunction* _initialise = _RegularBilinear_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _RegularBilinear_Execute;
+ Stg_Component_DestroyFunction* _destroy = _RegularBilinear_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _BilinearElementType_SF_allNodes;
+ ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _BilinearElementType_SF_allLocalDerivs_allNodes;
+ ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
+ ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _BilinearElementType_JacobianDeterminantSurface;
+ ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
+
+ return _RegularBilinear_New( REGULARBILINEAR_PASSARGS );
+}
+
+RegularBilinear* _RegularBilinear_New( REGULARBILINEAR_DEFARGS ) {
+ RegularBilinear* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(RegularBilinear) );
+ self = (RegularBilinear*)_BilinearElementType_New( BILINEARELEMENTTYPE_PASSARGS );
+
+ /* Virtual info */
+
+ /* RegularBilinear info */
+ self->isConstructed = True;
+ _ElementType_Init( (ElementType*)self, REGULARBILINEAR_NODECOUNT );
+ _BilinearElementType_Init( (BilinearElementType*)self );
+ _RegularBilinear_Init( self );
+
+ return self;
+}
+
+void _RegularBilinear_Init( RegularBilinear* self ) {
+ assert( self && Stg_CheckType( self, RegularBilinear ) );
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _RegularBilinear_Delete( void* elementType ) {
+ RegularBilinear* self = (RegularBilinear*)elementType;
+
+ /* Delete the parent. */
+ _BilinearElementType_Delete( self );
+}
+
+void _RegularBilinear_Print( void* elementType, Stream* stream ) {
+ RegularBilinear* self = (RegularBilinear*)elementType;
+
+ /* Set the Journal for printing informations */
+ Stream* elementTypeStream;
+ elementTypeStream = Journal_Register( InfoStream_Type, (Name)"RegularBilinearStream" );
+
+ /* Print parent */
+ Journal_Printf( stream, "RegularBilinear (ptr): (%p)\n", self );
+ _BilinearElementType_Print( self, stream );
+}
+
+void _RegularBilinear_AssignFromXML( void* elementType, Stg_ComponentFactory* cf, void* data ) {
+}
+
+void _RegularBilinear_Build( void* elementType, void* data ) {
+ _BilinearElementType_Build( elementType, data );
+}
+
+void _RegularBilinear_Initialise( void* elementType, void* data ) {
+ _BilinearElementType_Initialise( elementType, data );
+}
+
+void _RegularBilinear_Execute( void* elementType, void* data ) {
+}
+
+void _RegularBilinear_Destroy( void* elementType, void* data ) {
+ RegularBilinear* self = (RegularBilinear*)elementType;
+
+ _BilinearElementType_Destroy( self, data );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+#if 0
+void RegularBilinear_ConvertGlobalCoordToElLocal( void* elementType, void* mesh, unsigned element,
+ const double* globalCoord, double* localCoord )
+{
+ RegularBilinear* self = (RegularBilinear*)elementType;
+ unsigned nInc, *inc;
+ double* vert[2];
+ double w;
+
+ assert( self && Stg_CheckType( self, RegularBilinear ) );
+
+ Mesh_GetIncidence( mesh, MT_VOLUME, element, MT_VERTEX, self->inc );
+ nInc = IArray_GetSize( self->inc );
+ inc = IArray_GetSize( self->inc );
+
+ vert[0] = Mesh_GetVertex( mesh, inc[0] );
+ vert[1] = Mesh_GetVertex( mesh, inc[3] );
+ w = vert[1][0] - vert[0][0];
+ localCoord[0] = 2.0 * (globalCoord[0] - vert[0][0]) / w - 1.0;
+ w = vert[1][1] - vert[0][1];
+ localCoord[1] = 2.0 * (globalCoord[1] - vert[0][1]) / w - 1.0;
+
+ assert( localCoord[0] >= -1.0 && localCoord[0] <= 1.0 );
+ assert( localCoord[1] >= -1.0 && localCoord[1] <= 1.0 );
+}
+#endif
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/RegularTrilinear.c
--- a/Discretisation/src/RegularTrilinear.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: RegularTrilinear.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <mpi.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "Discretisation.h"
-
-
-/* Textual name of this class */
-const Type RegularTrilinear_Type = "RegularTrilinear";
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-#define REGULARTRILINEAR_NODECOUNT 8
-
-RegularTrilinear* RegularTrilinear_New( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(RegularTrilinear);
- Type type = RegularTrilinear_Type;
- Stg_Class_DeleteFunction* _delete = _RegularTrilinear_Delete;
- Stg_Class_PrintFunction* _print = _RegularTrilinear_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_RegularTrilinear_New;
- Stg_Component_ConstructFunction* _construct = _RegularTrilinear_AssignFromXML;
- Stg_Component_BuildFunction* _build = _RegularTrilinear_Build;
- Stg_Component_InitialiseFunction* _initialise = _RegularTrilinear_Initialise;
- Stg_Component_ExecuteFunction* _execute = _RegularTrilinear_Execute;
- Stg_Component_DestroyFunction* _destroy = _RegularTrilinear_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _TrilinearElementType_SF_allNodes;
- ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _TrilinearElementType_SF_allLocalDerivs_allNodes;
- ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
- ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _TrilinearElementType_JacobianDeterminantSurface;
- ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
-
- return _RegularTrilinear_New( REGULARTRILINEAR_PASSARGS );
-}
-
-RegularTrilinear* _RegularTrilinear_New( REGULARTRILINEAR_DEFARGS ) {
- RegularTrilinear* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(RegularTrilinear) );
- self = (RegularTrilinear*)_TrilinearElementType_New( TRILINEARELEMENTTYPE_PASSARGS );
-
- /* Virtual info */
-
- /* RegularTrilinear info */
- self->isConstructed = True;
- _ElementType_Init( (ElementType*)self, REGULARTRILINEAR_NODECOUNT );
- _TrilinearElementType_Init( (TrilinearElementType*)self );
- _RegularTrilinear_Init( self );
-
- return self;
-}
-
-void _RegularTrilinear_Init( RegularTrilinear* self ) {
- assert( self && Stg_CheckType( self, RegularTrilinear ) );
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _RegularTrilinear_Delete( void* elementType ) {
- RegularTrilinear* self = (RegularTrilinear*)elementType;
-
- /* Delete the parent. */
- _TrilinearElementType_Delete( self );
-}
-
-void _RegularTrilinear_Print( void* elementType, Stream* stream ) {
- RegularTrilinear* self = (RegularTrilinear*)elementType;
-
- /* Set the Journal for printing informations */
- Stream* elementTypeStream;
- elementTypeStream = Journal_Register( InfoStream_Type, (Name)"RegularTrilinearStream" );
-
- /* Print parent */
- Journal_Printf( stream, "RegularTrilinear (ptr): (%p)\n", self );
- _TrilinearElementType_Print( self, stream );
-}
-
-void _RegularTrilinear_AssignFromXML( void* elementType, Stg_ComponentFactory* cf, void* data ) {
-}
-
-void _RegularTrilinear_Build( void* elementType, void* data ) {
- _TrilinearElementType_Build( elementType, data );
-}
-
-void _RegularTrilinear_Initialise( void* elementType, void* data ) {
- _TrilinearElementType_Initialise( elementType, data );
-}
-
-void _RegularTrilinear_Execute( void* elementType, void* data ) {
-}
-
-void _RegularTrilinear_Destroy( void* elementType, void* data ) {
- RegularTrilinear* self = (RegularTrilinear*)elementType;
-
- _TrilinearElementType_Destroy( self, data );
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-#if 0
-void RegularTrilinear_ConvertGlobalCoordToElLocal( void* elementType, void* mesh, unsigned element,
- const double* globalCoord, double* localCoord )
-{
- RegularTrilinear* self = (RegularTrilinear*)elementType;
- unsigned nInc, *inc;
- double* vert[2];
- double w;
-
- assert( self && Stg_CheckType( self, RegularTrilinear ) );
-
- Mesh_GetIncidence( mesh, MT_VOLUME, element, MT_VERTEX, self->inc );
- nInc = IArray_GetSize( self->inc );
- inc = IArray_GetSize( self->inc );
-
- vert[0] = Mesh_GetVertex( mesh, inc[0] );
- vert[1] = Mesh_GetVertex( mesh, inc[7] );
- w = vert[1][0] - vert[0][0];
- localCoord[0] = 2.0 * (globalCoord[0] - vert[0][0]) / w - 1.0;
- w = vert[1][1] - vert[0][1];
- localCoord[1] = 2.0 * (globalCoord[1] - vert[0][1]) / w - 1.0;
- w = vert[1][2] - vert[0][2];
- localCoord[2] = 2.0 * (globalCoord[2] - vert[0][2]) / w - 1.0;
-
- assert( Num_InRange( localCoord[0], -1.0, 1.0 ) );
- assert( Num_InRange( localCoord[1], -1.0, 1.0 ) );
- assert( Num_InRange( localCoord[2], -1.0, 1.0 ) );
-}
-#endif
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/RegularTrilinear.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/RegularTrilinear.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,182 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: RegularTrilinear.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "Discretisation.h"
+
+
+/* Textual name of this class */
+const Type RegularTrilinear_Type = "RegularTrilinear";
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+#define REGULARTRILINEAR_NODECOUNT 8
+
+RegularTrilinear* RegularTrilinear_New( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(RegularTrilinear);
+ Type type = RegularTrilinear_Type;
+ Stg_Class_DeleteFunction* _delete = _RegularTrilinear_Delete;
+ Stg_Class_PrintFunction* _print = _RegularTrilinear_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_RegularTrilinear_New;
+ Stg_Component_ConstructFunction* _construct = _RegularTrilinear_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _RegularTrilinear_Build;
+ Stg_Component_InitialiseFunction* _initialise = _RegularTrilinear_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _RegularTrilinear_Execute;
+ Stg_Component_DestroyFunction* _destroy = _RegularTrilinear_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _TrilinearElementType_SF_allNodes;
+ ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _TrilinearElementType_SF_allLocalDerivs_allNodes;
+ ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
+ ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _TrilinearElementType_JacobianDeterminantSurface;
+ ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
+
+ return _RegularTrilinear_New( REGULARTRILINEAR_PASSARGS );
+}
+
+RegularTrilinear* _RegularTrilinear_New( REGULARTRILINEAR_DEFARGS ) {
+ RegularTrilinear* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(RegularTrilinear) );
+ self = (RegularTrilinear*)_TrilinearElementType_New( TRILINEARELEMENTTYPE_PASSARGS );
+
+ /* Virtual info */
+
+ /* RegularTrilinear info */
+ self->isConstructed = True;
+ _ElementType_Init( (ElementType*)self, REGULARTRILINEAR_NODECOUNT );
+ _TrilinearElementType_Init( (TrilinearElementType*)self );
+ _RegularTrilinear_Init( self );
+
+ return self;
+}
+
+void _RegularTrilinear_Init( RegularTrilinear* self ) {
+ assert( self && Stg_CheckType( self, RegularTrilinear ) );
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _RegularTrilinear_Delete( void* elementType ) {
+ RegularTrilinear* self = (RegularTrilinear*)elementType;
+
+ /* Delete the parent. */
+ _TrilinearElementType_Delete( self );
+}
+
+void _RegularTrilinear_Print( void* elementType, Stream* stream ) {
+ RegularTrilinear* self = (RegularTrilinear*)elementType;
+
+ /* Set the Journal for printing informations */
+ Stream* elementTypeStream;
+ elementTypeStream = Journal_Register( InfoStream_Type, (Name)"RegularTrilinearStream" );
+
+ /* Print parent */
+ Journal_Printf( stream, "RegularTrilinear (ptr): (%p)\n", self );
+ _TrilinearElementType_Print( self, stream );
+}
+
+void _RegularTrilinear_AssignFromXML( void* elementType, Stg_ComponentFactory* cf, void* data ) {
+}
+
+void _RegularTrilinear_Build( void* elementType, void* data ) {
+ _TrilinearElementType_Build( elementType, data );
+}
+
+void _RegularTrilinear_Initialise( void* elementType, void* data ) {
+ _TrilinearElementType_Initialise( elementType, data );
+}
+
+void _RegularTrilinear_Execute( void* elementType, void* data ) {
+}
+
+void _RegularTrilinear_Destroy( void* elementType, void* data ) {
+ RegularTrilinear* self = (RegularTrilinear*)elementType;
+
+ _TrilinearElementType_Destroy( self, data );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+#if 0
+void RegularTrilinear_ConvertGlobalCoordToElLocal( void* elementType, void* mesh, unsigned element,
+ const double* globalCoord, double* localCoord )
+{
+ RegularTrilinear* self = (RegularTrilinear*)elementType;
+ unsigned nInc, *inc;
+ double* vert[2];
+ double w;
+
+ assert( self && Stg_CheckType( self, RegularTrilinear ) );
+
+ Mesh_GetIncidence( mesh, MT_VOLUME, element, MT_VERTEX, self->inc );
+ nInc = IArray_GetSize( self->inc );
+ inc = IArray_GetSize( self->inc );
+
+ vert[0] = Mesh_GetVertex( mesh, inc[0] );
+ vert[1] = Mesh_GetVertex( mesh, inc[7] );
+ w = vert[1][0] - vert[0][0];
+ localCoord[0] = 2.0 * (globalCoord[0] - vert[0][0]) / w - 1.0;
+ w = vert[1][1] - vert[0][1];
+ localCoord[1] = 2.0 * (globalCoord[1] - vert[0][1]) / w - 1.0;
+ w = vert[1][2] - vert[0][2];
+ localCoord[2] = 2.0 * (globalCoord[2] - vert[0][2]) / w - 1.0;
+
+ assert( Num_InRange( localCoord[0], -1.0, 1.0 ) );
+ assert( Num_InRange( localCoord[1], -1.0, 1.0 ) );
+ assert( Num_InRange( localCoord[2], -1.0, 1.0 ) );
+}
+#endif
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/ShapeFeVariable.c
--- a/Discretisation/src/ShapeFeVariable.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: ShapeFeVariable.c 532 2006-04-04 00:21:59Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <string.h>
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "types.h"
-#include "FeMesh.h"
-#include "FeVariable.h"
-#include "ShapeFeVariable.h"
-
-#include <assert.h>
-
-const Type ShapeFeVariable_Type = "ShapeFeVariable";
-
-void* ShapeFeVariable_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(ShapeFeVariable);
- Type type = ShapeFeVariable_Type;
- Stg_Class_DeleteFunction* _delete = _ShapeFeVariable_Delete;
- Stg_Class_PrintFunction* _print = _ShapeFeVariable_Print;
- Stg_Class_CopyFunction* _copy = _ShapeFeVariable_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (Stg_Component_DefaultConstructorFunction*)ShapeFeVariable_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _ShapeFeVariable_AssignFromXML;
- Stg_Component_BuildFunction* _build = _ShapeFeVariable_Build;
- Stg_Component_InitialiseFunction* _initialise = _ShapeFeVariable_Initialise;
- Stg_Component_ExecuteFunction* _execute = _ShapeFeVariable_Execute;
- Stg_Component_DestroyFunction* _destroy = _ShapeFeVariable_Destroy;
- FieldVariable_InterpolateValueAtFunction* _interpolateValueAt = _FeVariable_InterpolateValueAt;
- FieldVariable_GetValueFunction* _getMinGlobalFieldMagnitude = _FeVariable_GetMinGlobalFieldMagnitude;
- FieldVariable_GetValueFunction* _getMaxGlobalFieldMagnitude = _FeVariable_GetMaxGlobalFieldMagnitude;
- FieldVariable_GetCoordFunction* _getMinAndMaxLocalCoords = _FeVariable_GetMinAndMaxLocalCoords;
- FieldVariable_GetCoordFunction* _getMinAndMaxGlobalCoords = _FeVariable_GetMinAndMaxGlobalCoords;
- FeVariable_InterpolateWithinElementFunction* _interpolateWithinElement = _FeVariable_InterpolateNodeValuesToElLocalCoord;
- FeVariable_GetValueAtNodeFunction* _getValueAtNode = _FeVariable_GetValueAtNode;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = (AllocationType)ZERO;
- FeVariable_SyncShadowValuesFunc* _syncShadowValues = ZERO;
-
- return (ShapeFeVariable*) _ShapeFeVariable_New( SHAPEFEVARIABLE_PASSARGS );
-}
-
-ShapeFeVariable* _ShapeFeVariable_New( SHAPEFEVARIABLE_DEFARGS ) {
- ShapeFeVariable* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(ShapeFeVariable) );
- /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
- /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
- and so should be set to ZERO in any children of this class. */
- nameAllocationType = NON_GLOBAL;
- _syncShadowValues = _FeVariable_SyncShadowValues;
-
- self = (ShapeFeVariable*) _FeVariable_New( FEVARIABLE_PASSARGS );
-
- return self;
-}
-
-void _ShapeFeVariable_Init( void* shapeFeVariable, Stg_Shape* shape ) {
- ShapeFeVariable* self = (ShapeFeVariable*) shapeFeVariable;
-
- self->shape = shape;
-
- /* EP_AppendClassHook( Context_GetEntryPoint( context, AbstractContext_EP_UpdateClass ), ParticleFeVariable_Update, self ); */
-}
-
-void _ShapeFeVariable_Delete( void* _shapeFeVariable ) {
- ShapeFeVariable* self = (ShapeFeVariable*) _shapeFeVariable;
-
- _FeVariable_Delete( self );
-}
-
-void _ShapeFeVariable_Print( void* _shapeFeVariable, Stream* stream ) {
- ShapeFeVariable* self = (ShapeFeVariable*) _shapeFeVariable;
-
- /* Print parent */
- _FeVariable_Print( self, stream );
-
- Journal_PrintPointer( stream, self->shape );
-}
-
-void* _ShapeFeVariable_Copy( const void* shapeFeVariable, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- /* ShapeFeVariable* self = (ShapeFeVariable*)shapeFeVariable; */
- ShapeFeVariable* newShapeFeVariable;
-
- assert(0);
- return (void*)newShapeFeVariable;
-}
-
-void _ShapeFeVariable_AssignFromXML( void* shapeFeVariable, Stg_ComponentFactory* cf, void* data ) {
- ShapeFeVariable* self = (ShapeFeVariable*) shapeFeVariable;
-
- _FeVariable_AssignFromXML( self, cf, data );
-
- _ShapeFeVariable_Init( self, Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Shape", Stg_Shape, True, data ) ) ;
-}
-
-void _ShapeFeVariable_Build( void* shapeFeVariable, void* data ) {
- ShapeFeVariable* self = (ShapeFeVariable*) shapeFeVariable;
-
- Stg_Component_Build( self->shape, data, False );
- _FeVariable_Build( self, data );
-}
-
-void _ShapeFeVariable_Initialise( void* shapeFeVariable, void* data ) {
- ShapeFeVariable* self = (ShapeFeVariable*) shapeFeVariable;
- Node_DomainIndex node_dI = 0;
-
- Stg_Component_Initialise( self->shape, data, False );
- _FeVariable_Initialise( self, data );
-
- /* Set up the basic "level set" describing if nodes are inside the shape or not */
- for ( node_dI = 0; node_dI < Mesh_GetDomainSize( self->feMesh, MT_VERTEX ); node_dI++ ) {
- if ( True == Stg_Shape_IsCoordInside( self->shape, Mesh_GetVertex( self->feMesh, node_dI ) ) ) {
- /* set value = 1 */
- FeVariable_SetComponentAtNode( self, node_dI, 0, 1 );
- }
- else {
- /* set value = 0 */
- FeVariable_SetComponentAtNode( self, node_dI, 0, 0 );
- }
- }
-}
-
-void _ShapeFeVariable_Execute( void* shapeFeVariable, void* data ) {
- ShapeFeVariable* self = (ShapeFeVariable*) shapeFeVariable;
-
- _FeVariable_Execute( self, data );
-}
-
-void _ShapeFeVariable_Destroy( void* shapeFeVariable, void* data ) {
- ShapeFeVariable* self = (ShapeFeVariable*) shapeFeVariable;
-
- _FeVariable_Destroy( self, data );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/ShapeFeVariable.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/ShapeFeVariable.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,178 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: ShapeFeVariable.c 532 2006-04-04 00:21:59Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <string.h>
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "types.h"
+#include "FeMesh.h"
+#include "FeVariable.h"
+#include "ShapeFeVariable.h"
+
+#include <assert.h>
+
+const Type ShapeFeVariable_Type = "ShapeFeVariable";
+
+void* ShapeFeVariable_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(ShapeFeVariable);
+ Type type = ShapeFeVariable_Type;
+ Stg_Class_DeleteFunction* _delete = _ShapeFeVariable_Delete;
+ Stg_Class_PrintFunction* _print = _ShapeFeVariable_Print;
+ Stg_Class_CopyFunction* _copy = _ShapeFeVariable_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (Stg_Component_DefaultConstructorFunction*)ShapeFeVariable_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _ShapeFeVariable_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _ShapeFeVariable_Build;
+ Stg_Component_InitialiseFunction* _initialise = _ShapeFeVariable_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _ShapeFeVariable_Execute;
+ Stg_Component_DestroyFunction* _destroy = _ShapeFeVariable_Destroy;
+ FieldVariable_InterpolateValueAtFunction* _interpolateValueAt = _FeVariable_InterpolateValueAt;
+ FieldVariable_GetValueFunction* _getMinGlobalFieldMagnitude = _FeVariable_GetMinGlobalFieldMagnitude;
+ FieldVariable_GetValueFunction* _getMaxGlobalFieldMagnitude = _FeVariable_GetMaxGlobalFieldMagnitude;
+ FieldVariable_GetCoordFunction* _getMinAndMaxLocalCoords = _FeVariable_GetMinAndMaxLocalCoords;
+ FieldVariable_GetCoordFunction* _getMinAndMaxGlobalCoords = _FeVariable_GetMinAndMaxGlobalCoords;
+ FeVariable_InterpolateWithinElementFunction* _interpolateWithinElement = _FeVariable_InterpolateNodeValuesToElLocalCoord;
+ FeVariable_GetValueAtNodeFunction* _getValueAtNode = _FeVariable_GetValueAtNode;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = (AllocationType)ZERO;
+ FeVariable_SyncShadowValuesFunc* _syncShadowValues = ZERO;
+
+ return (ShapeFeVariable*) _ShapeFeVariable_New( SHAPEFEVARIABLE_PASSARGS );
+}
+
+ShapeFeVariable* _ShapeFeVariable_New( SHAPEFEVARIABLE_DEFARGS ) {
+ ShapeFeVariable* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(ShapeFeVariable) );
+ /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
+ /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
+ and so should be set to ZERO in any children of this class. */
+ nameAllocationType = NON_GLOBAL;
+ _syncShadowValues = _FeVariable_SyncShadowValues;
+
+ self = (ShapeFeVariable*) _FeVariable_New( FEVARIABLE_PASSARGS );
+
+ return self;
+}
+
+void _ShapeFeVariable_Init( void* shapeFeVariable, Stg_Shape* shape ) {
+ ShapeFeVariable* self = (ShapeFeVariable*) shapeFeVariable;
+
+ self->shape = shape;
+
+ /* EP_AppendClassHook( Context_GetEntryPoint( context, AbstractContext_EP_UpdateClass ), ParticleFeVariable_Update, self ); */
+}
+
+void _ShapeFeVariable_Delete( void* _shapeFeVariable ) {
+ ShapeFeVariable* self = (ShapeFeVariable*) _shapeFeVariable;
+
+ _FeVariable_Delete( self );
+}
+
+void _ShapeFeVariable_Print( void* _shapeFeVariable, Stream* stream ) {
+ ShapeFeVariable* self = (ShapeFeVariable*) _shapeFeVariable;
+
+ /* Print parent */
+ _FeVariable_Print( self, stream );
+
+ Journal_PrintPointer( stream, self->shape );
+}
+
+void* _ShapeFeVariable_Copy( const void* shapeFeVariable, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ /* ShapeFeVariable* self = (ShapeFeVariable*)shapeFeVariable; */
+ ShapeFeVariable* newShapeFeVariable;
+
+ assert(0);
+ return (void*)newShapeFeVariable;
+}
+
+void _ShapeFeVariable_AssignFromXML( void* shapeFeVariable, Stg_ComponentFactory* cf, void* data ) {
+ ShapeFeVariable* self = (ShapeFeVariable*) shapeFeVariable;
+
+ _FeVariable_AssignFromXML( self, cf, data );
+
+ _ShapeFeVariable_Init( self, Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Shape", Stg_Shape, True, data ) ) ;
+}
+
+void _ShapeFeVariable_Build( void* shapeFeVariable, void* data ) {
+ ShapeFeVariable* self = (ShapeFeVariable*) shapeFeVariable;
+
+ Stg_Component_Build( self->shape, data, False );
+ _FeVariable_Build( self, data );
+}
+
+void _ShapeFeVariable_Initialise( void* shapeFeVariable, void* data ) {
+ ShapeFeVariable* self = (ShapeFeVariable*) shapeFeVariable;
+ Node_DomainIndex node_dI = 0;
+
+ Stg_Component_Initialise( self->shape, data, False );
+ _FeVariable_Initialise( self, data );
+
+ /* Set up the basic "level set" describing if nodes are inside the shape or not */
+ for ( node_dI = 0; node_dI < Mesh_GetDomainSize( self->feMesh, MT_VERTEX ); node_dI++ ) {
+ if ( True == Stg_Shape_IsCoordInside( self->shape, Mesh_GetVertex( self->feMesh, node_dI ) ) ) {
+ /* set value = 1 */
+ FeVariable_SetComponentAtNode( self, node_dI, 0, 1 );
+ }
+ else {
+ /* set value = 0 */
+ FeVariable_SetComponentAtNode( self, node_dI, 0, 0 );
+ }
+ }
+}
+
+void _ShapeFeVariable_Execute( void* shapeFeVariable, void* data ) {
+ ShapeFeVariable* self = (ShapeFeVariable*) shapeFeVariable;
+
+ _FeVariable_Execute( self, data );
+}
+
+void _ShapeFeVariable_Destroy( void* shapeFeVariable, void* data ) {
+ ShapeFeVariable* self = (ShapeFeVariable*) shapeFeVariable;
+
+ _FeVariable_Destroy( self, data );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/TrilinearElementType.c
--- a/Discretisation/src/TrilinearElementType.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,388 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: TrilinearElementType.c 1180 2008-07-16 01:34:25Z DavidLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "ElementType.h"
-#include "TrilinearElementType.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-const Type TrilinearElementType_Type = "TrilinearElementType";
-
-#define _TrilinearElementType_NodeCount 8
-
-void* _TrilinearElementType_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(TrilinearElementType);
- Type type = TrilinearElementType_Type;
- Stg_Class_DeleteFunction* _delete = _TrilinearElementType_Delete;
- Stg_Class_PrintFunction* _print = _TrilinearElementType_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _TrilinearElementType_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _TrilinearElementType_AssignFromXML;
- Stg_Component_BuildFunction* _build = _TrilinearElementType_Build;
- Stg_Component_InitialiseFunction* _initialise = _TrilinearElementType_Initialise;
- Stg_Component_ExecuteFunction* _execute = _TrilinearElementType_Execute;
- Stg_Component_DestroyFunction* _destroy = _TrilinearElementType_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _TrilinearElementType_SF_allNodes;
- ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _TrilinearElementType_SF_allLocalDerivs_allNodes;
- ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
- ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _TrilinearElementType_JacobianDeterminantSurface;
- ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
-
- return _TrilinearElementType_New( TRILINEARELEMENTTYPE_PASSARGS );
-}
-
-TrilinearElementType* TrilinearElementType_New( Name name ) {
- TrilinearElementType* self = (TrilinearElementType*)_TrilinearElementType_DefaultNew( name );
-
- self->isConstructed = True;
- _ElementType_Init( (ElementType*)self, _TrilinearElementType_NodeCount );
- _TrilinearElementType_Init( self );
-
- return self;
-}
-
-TrilinearElementType* _TrilinearElementType_New( TRILINEARELEMENTTYPE_DEFARGS ) {
- TrilinearElementType* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(TrilinearElementType) );
- self = (TrilinearElementType*)_ElementType_New( ELEMENTTYPE_PASSARGS );
-
- /* General info */
-
- /* Virtual functions */
-
- /* TrilinearElementType info */
-
- return self;
-}
-
-void _TrilinearElementType_Init( TrilinearElementType* self ) {
- Dimension_Index dim, dim_I=0;
-
- /* General and Virtual info should already be set */
-
- /* TrilinearElementType info */
- dim = self->dim = 3;
- for ( dim_I = 0; dim_I < dim; dim_I++ ) {
- self->minElLocalCoord[dim_I] = -1;
- self->maxElLocalCoord[dim_I] = 1;
- self->elLocalLength[dim_I] = self->maxElLocalCoord[dim_I] - self->minElLocalCoord[dim_I];
- }
-
- /* Set up the tetrahedral indices. */
- self->tetInds = Memory_Alloc_2DArray( unsigned, 10, 4, (Name)"Mesh_HexType::tetInds" );
- self->tetInds[0][0] = 0; self->tetInds[0][1] = 1; self->tetInds[0][2] = 2; self->tetInds[0][3] = 4;
- self->tetInds[1][0] = 1; self->tetInds[1][1] = 2; self->tetInds[1][2] = 3; self->tetInds[1][3] = 7;
- self->tetInds[2][0] = 1; self->tetInds[2][1] = 4; self->tetInds[2][2] = 5; self->tetInds[2][3] = 7;
- self->tetInds[3][0] = 2; self->tetInds[3][1] = 4; self->tetInds[3][2] = 6; self->tetInds[3][3] = 7;
- self->tetInds[4][0] = 1; self->tetInds[4][1] = 2; self->tetInds[4][2] = 4; self->tetInds[4][3] = 7;
- self->tetInds[5][0] = 0; self->tetInds[5][1] = 1; self->tetInds[5][2] = 3; self->tetInds[5][3] = 5;
- self->tetInds[6][0] = 0; self->tetInds[6][1] = 4; self->tetInds[6][2] = 5; self->tetInds[6][3] = 6;
- self->tetInds[7][0] = 0; self->tetInds[7][1] = 2; self->tetInds[7][2] = 3; self->tetInds[7][3] = 6;
- self->tetInds[8][0] = 3; self->tetInds[8][1] = 5; self->tetInds[8][2] = 6; self->tetInds[8][3] = 7;
- self->tetInds[9][0] = 0; self->tetInds[9][1] = 3; self->tetInds[9][2] = 5; self->tetInds[9][3] = 6;
-}
-
-void _TrilinearElementType_Delete( void* elementType ) {
- TrilinearElementType* self = (TrilinearElementType*)elementType;
-
- /* Stg_Class_Delete parent*/
- _ElementType_Delete( self );
-}
-
-void _TrilinearElementType_Print( void* elementType, Stream* stream ) {
- TrilinearElementType* self = (TrilinearElementType*)elementType;
-
- /* Set the Journal for printing informations */
- Stream* trilinearElementTypeStream = stream;
-
- /* General info */
- Journal_Printf( trilinearElementTypeStream, "TrilinearElementType (ptr): %p\n", self );
-
- /* Print parent */
- _ElementType_Print( self, trilinearElementTypeStream );
-
- /* Virtual info */
-
- /* TrilinearElementType info */
-}
-
-void _TrilinearElementType_AssignFromXML( void* elementType, Stg_ComponentFactory *cf, void* data ){
-
-}
-
-void _TrilinearElementType_Initialise( void* elementType, void *data ){
- TrilinearElementType* self = (TrilinearElementType*)elementType;
- unsigned** faceNodes;
-
- faceNodes = Memory_Alloc_2DArray( unsigned, 6, 4, (Name)"node indices for element faces" );
-
- faceNodes[0][0] = 0; faceNodes[0][1] = 1; faceNodes[0][2] = 4; faceNodes[0][3] = 5;
- /* the top face */
- faceNodes[1][0] = 2; faceNodes[1][1] = 3; faceNodes[1][2] = 6; faceNodes[1][3] = 7;
- faceNodes[2][0] = 0; faceNodes[2][1] = 4; faceNodes[2][2] = 2; faceNodes[2][3] = 6;
- faceNodes[3][0] = 1; faceNodes[3][1] = 5; faceNodes[3][2] = 3; faceNodes[3][3] = 7;
- faceNodes[4][0] = 0; faceNodes[4][1] = 1; faceNodes[4][2] = 2; faceNodes[4][3] = 3;
- faceNodes[5][0] = 4; faceNodes[5][1] = 5; faceNodes[5][2] = 6; faceNodes[5][3] = 7;
-
- self->faceNodes = faceNodes;
-
- self->evaluatedShapeFunc = Memory_Alloc_Array( double, self->nodeCount, "evaluatedShapeFuncs" );
- self->GNi = Memory_Alloc_2DArray( double, self->dim, self->nodeCount, (Name)"localShapeFuncDerivitives" );
-
-}
-
-void _TrilinearElementType_Execute( void* elementType, void *data ){
-
-}
-
-void _TrilinearElementType_Destroy( void* elementType, void *data ){
- TrilinearElementType* self = (TrilinearElementType*)elementType;
-
- Memory_Free( self->faceNodes );
- Memory_Free( self->evaluatedShapeFunc );
- Memory_Free( self->GNi );
-
- FreeArray( self->tetInds );
-
- _ElementType_Destroy( self, data );
-}
-
-void _TrilinearElementType_Build( void* elementType, void *data ) {
-}
-
-#if 0
-void _TrilinearElementType_ConvertGlobalCoordToElementLocal( void* elementType, Element_DomainIndex element,const Coord globalCoord, Coord localCoord )
-{
- TrilinearElementType* self = (TrilinearElementType*)elementType;
- Dimension_Index dim_I;
-
- for ( dim_I=0; dim_I < 3; dim_I++ ) {
- }
-}
-#endif
-
-
-/*
-
- - Shape function definitions
- - Local node numbering convention for billinear, trilinear element (xi, eta, zeta)
- - Local coordinate domain spans -1 <= xi,eta,zeta <= 1
-
- eta
- |
- |____ xi
- /
- /
- zeta
-
-
- eta
- |
-3-----2
-| |__|___xi
-| |
-0-----1
-(zeta = -1 plane)
-
-
- eta
- |
-7-----6
-| |__|___xi
-| |
-4-----5
-(zeta = +1 plane)
-
-
-*/
-void _TrilinearElementType_SF_allNodes( void* elementType, const double localCoord[], double* const evaluatedValues ) {
- double xi, eta, zeta;
-
- xi = localCoord[0];
- eta = localCoord[1];
- zeta = localCoord[2];
-
- evaluatedValues[0] = 0.125*( 1.0-xi )*( 1.0-eta )*( 1.0-zeta );
- evaluatedValues[2] = 0.125*( 1.0-xi )*( 1.0+eta )*( 1.0-zeta );
- evaluatedValues[3] = 0.125*( 1.0+xi )*( 1.0+eta )*( 1.0-zeta );
- evaluatedValues[1] = 0.125*( 1.0+xi )*( 1.0-eta )*( 1.0-zeta );
-
- evaluatedValues[4] = 0.125*( 1.0-xi )*( 1.0-eta )*( 1.0+zeta );
- evaluatedValues[6] = 0.125*( 1.0-xi )*( 1.0+eta )*( 1.0+zeta );
- evaluatedValues[7] = 0.125*( 1.0+xi )*( 1.0+eta )*( 1.0+zeta );
- evaluatedValues[5] = 0.125*( 1.0+xi )*( 1.0-eta )*( 1.0+zeta );
-}
-
-
-void _TrilinearElementType_SF_allLocalDerivs_allNodes( void* elementType, const double localCoord[],
- double** const evaluatedDerivatives )
-{
- double xi, eta, zeta;
-
- xi = localCoord[0];
- eta = localCoord[1];
- zeta = localCoord[2];
-
- /* derivatives wrt xi */
- evaluatedDerivatives[0][0] = - 0.125*( 1.0-eta )*( 1.0-zeta );
- evaluatedDerivatives[0][2] = - 0.125*( 1.0+eta )*( 1.0-zeta );
- evaluatedDerivatives[0][3] = 0.125*( 1.0+eta )*( 1.0-zeta );
- evaluatedDerivatives[0][1] = 0.125*( 1.0-eta )*( 1.0-zeta );
- evaluatedDerivatives[0][4] = - 0.125*( 1.0-eta )*( 1.0+zeta );
- evaluatedDerivatives[0][6] = - 0.125*( 1.0+eta )*( 1.0+zeta );
- evaluatedDerivatives[0][7] = 0.125*( 1.0+eta )*( 1.0+zeta );
- evaluatedDerivatives[0][5] = 0.125*( 1.0-eta )*( 1.0+zeta );
-
- /* derivatives wrt eta */
- evaluatedDerivatives[1][0] = - 0.125*( 1.0-xi )*( 1.0-zeta );
- evaluatedDerivatives[1][2] = 0.125*( 1.0-xi )*( 1.0-zeta );
- evaluatedDerivatives[1][3] = 0.125*( 1.0+xi )*( 1.0-zeta );
- evaluatedDerivatives[1][1] = - 0.125*( 1.0+xi )*( 1.0-zeta );
- evaluatedDerivatives[1][4] = - 0.125*( 1.0-xi )*( 1.0+zeta );
- evaluatedDerivatives[1][6] = 0.125*( 1.0-xi )*( 1.0+zeta );
- evaluatedDerivatives[1][7] = 0.125*( 1.0+xi )*( 1.0+zeta );
- evaluatedDerivatives[1][5] = - 0.125*( 1.0+xi )*( 1.0+zeta );
-
- /* derivatives wrt zeta */
- evaluatedDerivatives[2][0] = -0.125*( 1.0-xi )*( 1.0-eta );
- evaluatedDerivatives[2][2] = -0.125*( 1.0-xi )*( 1.0+eta );
- evaluatedDerivatives[2][3] = -0.125*( 1.0+xi )*( 1.0+eta );
- evaluatedDerivatives[2][1] = -0.125*( 1.0+xi )*( 1.0-eta );
- evaluatedDerivatives[2][4] = 0.125*( 1.0-xi )*( 1.0-eta );
- evaluatedDerivatives[2][6] = 0.125*( 1.0-xi )*( 1.0+eta );
- evaluatedDerivatives[2][7] = 0.125*( 1.0+xi )*( 1.0+eta );
- evaluatedDerivatives[2][5] = 0.125*( 1.0+xi )*( 1.0-eta );
-}
-
-
-#if 0
-void _TrilinearElementType_ConvertGlobalCoordToElLocal(
- void* elementType,
- void* _mesh,
- unsigned element,
- const double* globalCoord,
- double* elLocalCoord )
-{
- TrilinearElementType* self = (TrilinearElementType*)elementType;
- Mesh* mesh = (Mesh*)_mesh;
- unsigned inside;
- double bc[4];
- static double lCrds[8][3] = {{-1.0, -1.0, -1.0}, {1.0, -1.0, -1.0},
- {-1.0, 1.0, -1.0}, {1.0, 1.0, -1.0},
- {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0},
- {-1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}};
- unsigned nInc, *inc;
- unsigned bc_i;
-
- Mesh_GetIncidence( mesh, MT_VOLUME, element, MT_VERTEX, self->inc );
- nInc = IArray_GetSize( self->inc );
- inc = IArray_GetPtr( self->inc );
- assert( nInc == 8 );
-
- insist( Simplex_Search3D( mesh->verts, inc, 10, self->tetInds, (double*)globalCoord, bc, &inside ), == True );
-
- elLocalCoord[0] = bc[0] * lCrds[self->tetInds[inside][0]][0];
- elLocalCoord[1] = bc[0] * lCrds[self->tetInds[inside][0]][1];
- elLocalCoord[2] = bc[0] * lCrds[self->tetInds[inside][0]][2];
- for( bc_i = 1; bc_i < 4; bc_i++ ) {
- elLocalCoord[0] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][0];
- elLocalCoord[1] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][1];
- elLocalCoord[2] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][2];
- }
-}
-#endif
-
-double _TrilinearElementType_JacobianDeterminantSurface( void* elementType, void* _mesh, unsigned element_I, const double localCoord[],
- unsigned face_I, unsigned norm )
-{
- TrilinearElementType* self = (TrilinearElementType*) elementType;
- Mesh* mesh = (Mesh*)_mesh;
- unsigned surfaceDim[2];
- double x[4], y[4];
- double s, t;
- double dxds, dxdt, dyds, dydt;
- double detJac;
- unsigned nodes[4];
-
- surfaceDim[0] = ( norm + 1 ) % 3;
- surfaceDim[1] = ( norm + 2 ) % 3;
-
- s = localCoord[surfaceDim[0]];
- t = localCoord[surfaceDim[1]];
-
- ElementType_GetFaceNodes( self, mesh, element_I, face_I, 4, nodes );
-
- x[0] = Mesh_GetVertex( mesh, nodes[0] )[surfaceDim[0]];
- x[1] = Mesh_GetVertex( mesh, nodes[1] )[surfaceDim[0]];
- x[2] = Mesh_GetVertex( mesh, nodes[2] )[surfaceDim[0]];
- x[3] = Mesh_GetVertex( mesh, nodes[3] )[surfaceDim[0]];
-
- y[0] = Mesh_GetVertex( mesh, nodes[0] )[surfaceDim[1]];
- y[1] = Mesh_GetVertex( mesh, nodes[1] )[surfaceDim[1]];
- y[2] = Mesh_GetVertex( mesh, nodes[2] )[surfaceDim[1]];
- y[3] = Mesh_GetVertex( mesh, nodes[3] )[surfaceDim[1]];
-
- dxds = 0.25 * ( - ( 1.0 - t )*x[0] + ( 1.0 - t )*x[1] - ( 1.0 + t )*x[2] + ( 1.0 + t )*x[3] );
- dyds = 0.25 * ( - ( 1.0 - t )*y[0] + ( 1.0 - t )*y[1] - ( 1.0 + t )*y[2] + ( 1.0 + t )*y[3] );
- dxdt = 0.25 * ( - ( 1.0 - s )*x[0] - ( 1.0 + s )*x[1] + ( 1.0 - s )*x[2] + ( 1.0 + s )*x[3] );
- dydt = 0.25 * ( - ( 1.0 - s )*y[0] - ( 1.0 + s )*y[1] + ( 1.0 - s )*y[2] + ( 1.0 + s )*y[3] );
-
- detJac = dxds * dydt - dxdt * dyds;
-
- return fabs( detJac );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/TrilinearElementType.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/TrilinearElementType.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,388 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: TrilinearElementType.c 1180 2008-07-16 01:34:25Z DavidLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "ElementType.h"
+#include "TrilinearElementType.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+const Type TrilinearElementType_Type = "TrilinearElementType";
+
+#define _TrilinearElementType_NodeCount 8
+
+void* _TrilinearElementType_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(TrilinearElementType);
+ Type type = TrilinearElementType_Type;
+ Stg_Class_DeleteFunction* _delete = _TrilinearElementType_Delete;
+ Stg_Class_PrintFunction* _print = _TrilinearElementType_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _TrilinearElementType_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _TrilinearElementType_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _TrilinearElementType_Build;
+ Stg_Component_InitialiseFunction* _initialise = _TrilinearElementType_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _TrilinearElementType_Execute;
+ Stg_Component_DestroyFunction* _destroy = _TrilinearElementType_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _TrilinearElementType_SF_allNodes;
+ ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _TrilinearElementType_SF_allLocalDerivs_allNodes;
+ ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
+ ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _TrilinearElementType_JacobianDeterminantSurface;
+ ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
+
+ return _TrilinearElementType_New( TRILINEARELEMENTTYPE_PASSARGS );
+}
+
+TrilinearElementType* TrilinearElementType_New( Name name ) {
+ TrilinearElementType* self = (TrilinearElementType*)_TrilinearElementType_DefaultNew( name );
+
+ self->isConstructed = True;
+ _ElementType_Init( (ElementType*)self, _TrilinearElementType_NodeCount );
+ _TrilinearElementType_Init( self );
+
+ return self;
+}
+
+TrilinearElementType* _TrilinearElementType_New( TRILINEARELEMENTTYPE_DEFARGS ) {
+ TrilinearElementType* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(TrilinearElementType) );
+ self = (TrilinearElementType*)_ElementType_New( ELEMENTTYPE_PASSARGS );
+
+ /* General info */
+
+ /* Virtual functions */
+
+ /* TrilinearElementType info */
+
+ return self;
+}
+
+void _TrilinearElementType_Init( TrilinearElementType* self ) {
+ Dimension_Index dim, dim_I=0;
+
+ /* General and Virtual info should already be set */
+
+ /* TrilinearElementType info */
+ dim = self->dim = 3;
+ for ( dim_I = 0; dim_I < dim; dim_I++ ) {
+ self->minElLocalCoord[dim_I] = -1;
+ self->maxElLocalCoord[dim_I] = 1;
+ self->elLocalLength[dim_I] = self->maxElLocalCoord[dim_I] - self->minElLocalCoord[dim_I];
+ }
+
+ /* Set up the tetrahedral indices. */
+ self->tetInds = Memory_Alloc_2DArray( unsigned, 10, 4, (Name)"Mesh_HexType::tetInds" );
+ self->tetInds[0][0] = 0; self->tetInds[0][1] = 1; self->tetInds[0][2] = 2; self->tetInds[0][3] = 4;
+ self->tetInds[1][0] = 1; self->tetInds[1][1] = 2; self->tetInds[1][2] = 3; self->tetInds[1][3] = 7;
+ self->tetInds[2][0] = 1; self->tetInds[2][1] = 4; self->tetInds[2][2] = 5; self->tetInds[2][3] = 7;
+ self->tetInds[3][0] = 2; self->tetInds[3][1] = 4; self->tetInds[3][2] = 6; self->tetInds[3][3] = 7;
+ self->tetInds[4][0] = 1; self->tetInds[4][1] = 2; self->tetInds[4][2] = 4; self->tetInds[4][3] = 7;
+ self->tetInds[5][0] = 0; self->tetInds[5][1] = 1; self->tetInds[5][2] = 3; self->tetInds[5][3] = 5;
+ self->tetInds[6][0] = 0; self->tetInds[6][1] = 4; self->tetInds[6][2] = 5; self->tetInds[6][3] = 6;
+ self->tetInds[7][0] = 0; self->tetInds[7][1] = 2; self->tetInds[7][2] = 3; self->tetInds[7][3] = 6;
+ self->tetInds[8][0] = 3; self->tetInds[8][1] = 5; self->tetInds[8][2] = 6; self->tetInds[8][3] = 7;
+ self->tetInds[9][0] = 0; self->tetInds[9][1] = 3; self->tetInds[9][2] = 5; self->tetInds[9][3] = 6;
+}
+
+void _TrilinearElementType_Delete( void* elementType ) {
+ TrilinearElementType* self = (TrilinearElementType*)elementType;
+
+ /* Stg_Class_Delete parent*/
+ _ElementType_Delete( self );
+}
+
+void _TrilinearElementType_Print( void* elementType, Stream* stream ) {
+ TrilinearElementType* self = (TrilinearElementType*)elementType;
+
+ /* Set the Journal for printing informations */
+ Stream* trilinearElementTypeStream = stream;
+
+ /* General info */
+ Journal_Printf( trilinearElementTypeStream, "TrilinearElementType (ptr): %p\n", self );
+
+ /* Print parent */
+ _ElementType_Print( self, trilinearElementTypeStream );
+
+ /* Virtual info */
+
+ /* TrilinearElementType info */
+}
+
+void _TrilinearElementType_AssignFromXML( void* elementType, Stg_ComponentFactory *cf, void* data ){
+
+}
+
+void _TrilinearElementType_Initialise( void* elementType, void *data ){
+ TrilinearElementType* self = (TrilinearElementType*)elementType;
+ unsigned** faceNodes;
+
+ faceNodes = Memory_Alloc_2DArray( unsigned, 6, 4, (Name)"node indices for element faces" );
+
+ faceNodes[0][0] = 0; faceNodes[0][1] = 1; faceNodes[0][2] = 4; faceNodes[0][3] = 5;
+ /* the top face */
+ faceNodes[1][0] = 2; faceNodes[1][1] = 3; faceNodes[1][2] = 6; faceNodes[1][3] = 7;
+ faceNodes[2][0] = 0; faceNodes[2][1] = 4; faceNodes[2][2] = 2; faceNodes[2][3] = 6;
+ faceNodes[3][0] = 1; faceNodes[3][1] = 5; faceNodes[3][2] = 3; faceNodes[3][3] = 7;
+ faceNodes[4][0] = 0; faceNodes[4][1] = 1; faceNodes[4][2] = 2; faceNodes[4][3] = 3;
+ faceNodes[5][0] = 4; faceNodes[5][1] = 5; faceNodes[5][2] = 6; faceNodes[5][3] = 7;
+
+ self->faceNodes = faceNodes;
+
+ self->evaluatedShapeFunc = Memory_Alloc_Array( double, self->nodeCount, "evaluatedShapeFuncs" );
+ self->GNi = Memory_Alloc_2DArray( double, self->dim, self->nodeCount, (Name)"localShapeFuncDerivitives" );
+
+}
+
+void _TrilinearElementType_Execute( void* elementType, void *data ){
+
+}
+
+void _TrilinearElementType_Destroy( void* elementType, void *data ){
+ TrilinearElementType* self = (TrilinearElementType*)elementType;
+
+ Memory_Free( self->faceNodes );
+ Memory_Free( self->evaluatedShapeFunc );
+ Memory_Free( self->GNi );
+
+ FreeArray( self->tetInds );
+
+ _ElementType_Destroy( self, data );
+}
+
+void _TrilinearElementType_Build( void* elementType, void *data ) {
+}
+
+#if 0
+void _TrilinearElementType_ConvertGlobalCoordToElementLocal( void* elementType, Element_DomainIndex element,const Coord globalCoord, Coord localCoord )
+{
+ TrilinearElementType* self = (TrilinearElementType*)elementType;
+ Dimension_Index dim_I;
+
+ for ( dim_I=0; dim_I < 3; dim_I++ ) {
+ }
+}
+#endif
+
+
+/*
+
+ - Shape function definitions
+ - Local node numbering convention for billinear, trilinear element (xi, eta, zeta)
+ - Local coordinate domain spans -1 <= xi,eta,zeta <= 1
+
+ eta
+ |
+ |____ xi
+ /
+ /
+ zeta
+
+
+ eta
+ |
+3-----2
+| |__|___xi
+| |
+0-----1
+(zeta = -1 plane)
+
+
+ eta
+ |
+7-----6
+| |__|___xi
+| |
+4-----5
+(zeta = +1 plane)
+
+
+*/
+void _TrilinearElementType_SF_allNodes( void* elementType, const double localCoord[], double* const evaluatedValues ) {
+ double xi, eta, zeta;
+
+ xi = localCoord[0];
+ eta = localCoord[1];
+ zeta = localCoord[2];
+
+ evaluatedValues[0] = 0.125*( 1.0-xi )*( 1.0-eta )*( 1.0-zeta );
+ evaluatedValues[2] = 0.125*( 1.0-xi )*( 1.0+eta )*( 1.0-zeta );
+ evaluatedValues[3] = 0.125*( 1.0+xi )*( 1.0+eta )*( 1.0-zeta );
+ evaluatedValues[1] = 0.125*( 1.0+xi )*( 1.0-eta )*( 1.0-zeta );
+
+ evaluatedValues[4] = 0.125*( 1.0-xi )*( 1.0-eta )*( 1.0+zeta );
+ evaluatedValues[6] = 0.125*( 1.0-xi )*( 1.0+eta )*( 1.0+zeta );
+ evaluatedValues[7] = 0.125*( 1.0+xi )*( 1.0+eta )*( 1.0+zeta );
+ evaluatedValues[5] = 0.125*( 1.0+xi )*( 1.0-eta )*( 1.0+zeta );
+}
+
+
+void _TrilinearElementType_SF_allLocalDerivs_allNodes( void* elementType, const double localCoord[],
+ double** const evaluatedDerivatives )
+{
+ double xi, eta, zeta;
+
+ xi = localCoord[0];
+ eta = localCoord[1];
+ zeta = localCoord[2];
+
+ /* derivatives wrt xi */
+ evaluatedDerivatives[0][0] = - 0.125*( 1.0-eta )*( 1.0-zeta );
+ evaluatedDerivatives[0][2] = - 0.125*( 1.0+eta )*( 1.0-zeta );
+ evaluatedDerivatives[0][3] = 0.125*( 1.0+eta )*( 1.0-zeta );
+ evaluatedDerivatives[0][1] = 0.125*( 1.0-eta )*( 1.0-zeta );
+ evaluatedDerivatives[0][4] = - 0.125*( 1.0-eta )*( 1.0+zeta );
+ evaluatedDerivatives[0][6] = - 0.125*( 1.0+eta )*( 1.0+zeta );
+ evaluatedDerivatives[0][7] = 0.125*( 1.0+eta )*( 1.0+zeta );
+ evaluatedDerivatives[0][5] = 0.125*( 1.0-eta )*( 1.0+zeta );
+
+ /* derivatives wrt eta */
+ evaluatedDerivatives[1][0] = - 0.125*( 1.0-xi )*( 1.0-zeta );
+ evaluatedDerivatives[1][2] = 0.125*( 1.0-xi )*( 1.0-zeta );
+ evaluatedDerivatives[1][3] = 0.125*( 1.0+xi )*( 1.0-zeta );
+ evaluatedDerivatives[1][1] = - 0.125*( 1.0+xi )*( 1.0-zeta );
+ evaluatedDerivatives[1][4] = - 0.125*( 1.0-xi )*( 1.0+zeta );
+ evaluatedDerivatives[1][6] = 0.125*( 1.0-xi )*( 1.0+zeta );
+ evaluatedDerivatives[1][7] = 0.125*( 1.0+xi )*( 1.0+zeta );
+ evaluatedDerivatives[1][5] = - 0.125*( 1.0+xi )*( 1.0+zeta );
+
+ /* derivatives wrt zeta */
+ evaluatedDerivatives[2][0] = -0.125*( 1.0-xi )*( 1.0-eta );
+ evaluatedDerivatives[2][2] = -0.125*( 1.0-xi )*( 1.0+eta );
+ evaluatedDerivatives[2][3] = -0.125*( 1.0+xi )*( 1.0+eta );
+ evaluatedDerivatives[2][1] = -0.125*( 1.0+xi )*( 1.0-eta );
+ evaluatedDerivatives[2][4] = 0.125*( 1.0-xi )*( 1.0-eta );
+ evaluatedDerivatives[2][6] = 0.125*( 1.0-xi )*( 1.0+eta );
+ evaluatedDerivatives[2][7] = 0.125*( 1.0+xi )*( 1.0+eta );
+ evaluatedDerivatives[2][5] = 0.125*( 1.0+xi )*( 1.0-eta );
+}
+
+
+#if 0
+void _TrilinearElementType_ConvertGlobalCoordToElLocal(
+ void* elementType,
+ void* _mesh,
+ unsigned element,
+ const double* globalCoord,
+ double* elLocalCoord )
+{
+ TrilinearElementType* self = (TrilinearElementType*)elementType;
+ Mesh* mesh = (Mesh*)_mesh;
+ unsigned inside;
+ double bc[4];
+ static double lCrds[8][3] = {{-1.0, -1.0, -1.0}, {1.0, -1.0, -1.0},
+ {-1.0, 1.0, -1.0}, {1.0, 1.0, -1.0},
+ {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0},
+ {-1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}};
+ unsigned nInc, *inc;
+ unsigned bc_i;
+
+ Mesh_GetIncidence( mesh, MT_VOLUME, element, MT_VERTEX, self->inc );
+ nInc = IArray_GetSize( self->inc );
+ inc = IArray_GetPtr( self->inc );
+ assert( nInc == 8 );
+
+ insist( Simplex_Search3D( mesh->verts, inc, 10, self->tetInds, (double*)globalCoord, bc, &inside ), == True );
+
+ elLocalCoord[0] = bc[0] * lCrds[self->tetInds[inside][0]][0];
+ elLocalCoord[1] = bc[0] * lCrds[self->tetInds[inside][0]][1];
+ elLocalCoord[2] = bc[0] * lCrds[self->tetInds[inside][0]][2];
+ for( bc_i = 1; bc_i < 4; bc_i++ ) {
+ elLocalCoord[0] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][0];
+ elLocalCoord[1] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][1];
+ elLocalCoord[2] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][2];
+ }
+}
+#endif
+
+double _TrilinearElementType_JacobianDeterminantSurface( void* elementType, void* _mesh, unsigned element_I, const double localCoord[],
+ unsigned face_I, unsigned norm )
+{
+ TrilinearElementType* self = (TrilinearElementType*) elementType;
+ Mesh* mesh = (Mesh*)_mesh;
+ unsigned surfaceDim[2];
+ double x[4], y[4];
+ double s, t;
+ double dxds, dxdt, dyds, dydt;
+ double detJac;
+ unsigned nodes[4];
+
+ surfaceDim[0] = ( norm + 1 ) % 3;
+ surfaceDim[1] = ( norm + 2 ) % 3;
+
+ s = localCoord[surfaceDim[0]];
+ t = localCoord[surfaceDim[1]];
+
+ ElementType_GetFaceNodes( self, mesh, element_I, face_I, 4, nodes );
+
+ x[0] = Mesh_GetVertex( mesh, nodes[0] )[surfaceDim[0]];
+ x[1] = Mesh_GetVertex( mesh, nodes[1] )[surfaceDim[0]];
+ x[2] = Mesh_GetVertex( mesh, nodes[2] )[surfaceDim[0]];
+ x[3] = Mesh_GetVertex( mesh, nodes[3] )[surfaceDim[0]];
+
+ y[0] = Mesh_GetVertex( mesh, nodes[0] )[surfaceDim[1]];
+ y[1] = Mesh_GetVertex( mesh, nodes[1] )[surfaceDim[1]];
+ y[2] = Mesh_GetVertex( mesh, nodes[2] )[surfaceDim[1]];
+ y[3] = Mesh_GetVertex( mesh, nodes[3] )[surfaceDim[1]];
+
+ dxds = 0.25 * ( - ( 1.0 - t )*x[0] + ( 1.0 - t )*x[1] - ( 1.0 + t )*x[2] + ( 1.0 + t )*x[3] );
+ dyds = 0.25 * ( - ( 1.0 - t )*y[0] + ( 1.0 - t )*y[1] - ( 1.0 + t )*y[2] + ( 1.0 + t )*y[3] );
+ dxdt = 0.25 * ( - ( 1.0 - s )*x[0] - ( 1.0 + s )*x[1] + ( 1.0 - s )*x[2] + ( 1.0 + s )*x[3] );
+ dydt = 0.25 * ( - ( 1.0 - s )*y[0] - ( 1.0 + s )*y[1] + ( 1.0 - s )*y[2] + ( 1.0 + s )*y[3] );
+
+ detJac = dxds * dydt - dxdt * dyds;
+
+ return fabs( detJac );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/TrilinearInnerElType.c
--- a/Discretisation/src/TrilinearInnerElType.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,323 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: TrilinearInnerElType.c 832 2007-05-16 01:11:18Z DaveLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "ElementType.h"
-#include "TrilinearInnerElType.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-const Type TrilinearInnerElType_Type = "TrilinearInnerElType";
-
-#define _TrilinearInnerElType_NodeCount 4
-
-void* _TrilinearInnerElType_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(TrilinearInnerElType);
- Type type = TrilinearInnerElType_Type;
- Stg_Class_DeleteFunction* _delete = _TrilinearInnerElType_Delete;
- Stg_Class_PrintFunction* _print = _TrilinearInnerElType_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _TrilinearInnerElType_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _TrilinearInnerElType_AssignFromXML;
- Stg_Component_BuildFunction* _build = _TrilinearInnerElType_Build;
- Stg_Component_InitialiseFunction* _initialise = _TrilinearInnerElType_Initialise;
- Stg_Component_ExecuteFunction* _execute = _TrilinearInnerElType_Execute;
- Stg_Component_DestroyFunction* _destroy = _TrilinearInnerElType_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _TrilinearInnerElType_SF_allNodes;
- ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _TrilinearInnerElType_SF_allLocalDerivs_allNodes;
- ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
- ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _ElementType_JacobianDeterminantSurface;
- ElementType_SurfaceNormalFunction* _surfaceNormal = _TrilinearInnerElType_SurfaceNormal;
-
- return _TrilinearInnerElType_New( TRILINEARINNERELTYPE_PASSARGS );
-}
-
-TrilinearInnerElType* TrilinearInnerElType_New( Name name ) {
- TrilinearInnerElType* self = (TrilinearInnerElType*)_TrilinearInnerElType_DefaultNew( name );
-
- self->isConstructed = True;
- _ElementType_Init( (ElementType*)self, _TrilinearInnerElType_NodeCount );
- _TrilinearInnerElType_Init( self );
-
- return self;
-}
-
-TrilinearInnerElType* _TrilinearInnerElType_New( TRILINEARINNERELTYPE_DEFARGS ) {
- TrilinearInnerElType* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(TrilinearInnerElType) );
- self = (TrilinearInnerElType*)_ElementType_New( ELEMENTTYPE_PASSARGS );
-
- /* General info */
-
- /* Virtual functions */
-
- /* TrilinearInnerElType info */
-
- return self;
-}
-
-void _TrilinearInnerElType_Init( TrilinearInnerElType* self ) {
- Dimension_Index dim_I=0;
-
- /* General and Virtual info should already be set */
-
- /* TriInnerEllementType info */
- for ( dim_I = 0; dim_I < 3; dim_I++ ) {
- self->minElLocalCoord[dim_I] = -1;
- self->maxElLocalCoord[dim_I] = 1;
- self->elLocalLength[dim_I] = self->maxElLocalCoord[dim_I] - self->minElLocalCoord[dim_I];
- }
-
- /* Set up the tetrahedral indices. */
- self->tetInds = Memory_Alloc_2DArray( unsigned, 10, 4, (Name)"Mesh_HexType::tetInds" );
- self->tetInds[0][0] = 0; self->tetInds[0][1] = 1; self->tetInds[0][2] = 2; self->tetInds[0][3] = 4;
- self->tetInds[1][0] = 1; self->tetInds[1][1] = 2; self->tetInds[1][2] = 3; self->tetInds[1][3] = 7;
- self->tetInds[2][0] = 1; self->tetInds[2][1] = 4; self->tetInds[2][2] = 5; self->tetInds[2][3] = 7;
- self->tetInds[3][0] = 2; self->tetInds[3][1] = 4; self->tetInds[3][2] = 6; self->tetInds[3][3] = 7;
- self->tetInds[4][0] = 1; self->tetInds[4][1] = 2; self->tetInds[4][2] = 4; self->tetInds[4][3] = 7;
- self->tetInds[5][0] = 0; self->tetInds[5][1] = 1; self->tetInds[5][2] = 3; self->tetInds[5][3] = 5;
- self->tetInds[6][0] = 0; self->tetInds[6][1] = 4; self->tetInds[6][2] = 5; self->tetInds[6][3] = 6;
- self->tetInds[7][0] = 0; self->tetInds[7][1] = 2; self->tetInds[7][2] = 3; self->tetInds[7][3] = 6;
- self->tetInds[8][0] = 3; self->tetInds[8][1] = 5; self->tetInds[8][2] = 6; self->tetInds[8][3] = 7;
- self->tetInds[9][0] = 0; self->tetInds[9][1] = 3; self->tetInds[9][2] = 5; self->tetInds[9][3] = 6;
-}
-
-void _TrilinearInnerElType_Delete( void* elementType ) {
- TrilinearInnerElType* self = (TrilinearInnerElType*)elementType;
-
- /* Stg_Class_Delete parent*/
- _ElementType_Delete( self );
-}
-
-void _TrilinearInnerElType_Print( void* elementType, Stream* stream ) {
- TrilinearInnerElType* self = (TrilinearInnerElType*)elementType;
-
- /* Set the Journal for printing informations */
- Stream* trilinearInnerElTypeStream = stream;
-
- /* General info */
- Journal_Printf( trilinearInnerElTypeStream, "TrilinearInnerElType (ptr): %p\n", self );
-
- /* Print parent */
- _ElementType_Print( self, trilinearInnerElTypeStream );
-
- /* Virtual info */
-
- /* TrilinearInnerElType info */
-}
-
-void _TrilinearInnerElType_AssignFromXML( void* elementType, Stg_ComponentFactory *cf, void* data ){
-
-}
-
-void _TrilinearInnerElType_Initialise( void* elementType, void *data ){
-
-}
-
-void _TrilinearInnerElType_Execute( void* elementType, void *data ){
-
-}
-
-void _TrilinearInnerElType_Destroy( void* elementType, void *data ){
- TrilinearInnerElType* self = (TrilinearInnerElType*)elementType;
-
- FreeArray( self->tetInds );
-
- _ElementType_Destroy( self, data );
-}
-
-void _TrilinearInnerElType_Build( void* elementType, void *data ) {
-
-}
-
-#if 0
-void _TrilinearInnerElType_ConvertGlobalCoordToElementLocal( void* elementType, Element_DomainIndex element,const Coord globalCoord, Coord localCoord )
-{
- TrilinearInnerElType* self = (TrilinearInnerElType*)elementType;
- Dimension_Index dim_I;
-
- for ( dim_I=0; dim_I < 3; dim_I++ ) {
- }
-}
-#endif
-
-
-/*
-
- - Shape function definitions
- - Local node numbering convention for billinear, trilinear element (xi, eta, zeta)
- - Local coordinate domain spans -1 <= xi,eta,zeta <= 1
-
- eta
- |
- |____ xi
- /
- /
- zeta
-
-
- eta
- |
-3-----2
-| |__|___xi
-| |
-0-----1
-(zeta = -1 plane)
-
-
- eta
- |
-7-----6
-| |__|___xi
-| |
-4-----5
-(zeta = +1 plane)
-
-
-*/
-void _TrilinearInnerElType_SF_allNodes( void* elementType, const double localCoord[], double* const evaluatedValues ) {
- double xi, eta, zeta;
- double fac;
-
- xi = localCoord[0];
- eta = localCoord[1];
- zeta = localCoord[2];
-
- fac = 1.0/9.0;
-
- evaluatedValues[0] = fac*( - 4.0*xi - 20.0*eta + 12.0*zeta + 3.0 );
- evaluatedValues[1] = fac*( 16.0*xi - 64.0*eta + 60.0*zeta + 6.0 );
- evaluatedValues[2] = fac*( 36.0*eta - 36.0*zeta );
- evaluatedValues[3] = fac*( -12.0*xi + 48.0*eta - 36.0*zeta );
-}
-
-
-
-void _TrilinearInnerElType_SF_allLocalDerivs_allNodes( void* elementType, const double localCoord[],
- double** const evaluatedDerivatives )
-{
- double xi, eta, zeta;
- double fac;
-
- xi = localCoord[0];
- eta = localCoord[1];
- zeta = localCoord[2];
-
- fac = 1.0/9.0;
-
- evaluatedDerivatives[0][0] = fac*( - 4.0 );
- evaluatedDerivatives[0][1] = fac*( 16.0 );
- evaluatedDerivatives[0][2] = 0.0 ;
- evaluatedDerivatives[0][3] = fac*( -12.0 );
-
- evaluatedDerivatives[1][0] = fac*( -20.0 );
- evaluatedDerivatives[1][1] = fac*( -64.0 );
- evaluatedDerivatives[1][2] = 4.0 ;
- evaluatedDerivatives[1][3] = fac*( 48.0 );
-
- evaluatedDerivatives[2][0] = fac*( 12.0 );
- evaluatedDerivatives[2][1] = fac*( 60.0 );
- evaluatedDerivatives[2][2] = - 4.0 ;
- evaluatedDerivatives[2][3] = - 4.0 ;
-}
-
-/* get rid of this function and just use the superclass (elementType) version, as for BilinearInner class?? */
-/*
-void _TrilinearInnerElType_ConvertGlobalCoordToElLocal(
- void* elementType,
- void* _mesh,
- unsigned element,
- const double* globalCoord,
- double* elLocalCoord )
-{
- TrilinearInnerElType* self = (TrilinearInnerElType*)elementType;
- Mesh* mesh = (Mesh*)_mesh;
- unsigned inside;
- double bc[4];
- static double lCrds[8][3] = {{-1.0, -1.0, -1.0}, {1.0, -1.0, -1.0},
- {-1.0, 1.0, -1.0}, {1.0, 1.0, -1.0},
- {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0},
- {-1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}};
- unsigned nInc, *inc;
- unsigned bc_i;
-
- Mesh_GetIncidence( mesh, MT_VOLUME, element, MT_VERTEX, &nInc, &inc );
- assert( nInc == 8 );
-
- insist( Simplex_Search3D( mesh->verts, inc, 10, self->tetInds, (double*)globalCoord, bc, &inside ), == True );
-
- elLocalCoord[0] = bc[0] * lCrds[self->tetInds[inside][0]][0];
- elLocalCoord[1] = bc[0] * lCrds[self->tetInds[inside][0]][1];
- elLocalCoord[2] = bc[0] * lCrds[self->tetInds[inside][0]][2];
- for( bc_i = 1; bc_i < 4; bc_i++ ) {
- elLocalCoord[0] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][0];
- elLocalCoord[1] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][1];
- elLocalCoord[2] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][2];
- }
-}*/
-
-int _TrilinearInnerElType_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* normal ) {
- Stream* errStream = Journal_Register( ErrorStream_Type, (Name)ElementType_Type );
-
- Journal_Printf( errStream, "Surface normal function not yet implemented for this element type.\n" );
- assert( 0 );
-
- normal = NULL;
-
- return -1;
-}
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/TrilinearInnerElType.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/TrilinearInnerElType.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,323 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: TrilinearInnerElType.c 832 2007-05-16 01:11:18Z DaveLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "ElementType.h"
+#include "TrilinearInnerElType.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+const Type TrilinearInnerElType_Type = "TrilinearInnerElType";
+
+#define _TrilinearInnerElType_NodeCount 4
+
+void* _TrilinearInnerElType_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(TrilinearInnerElType);
+ Type type = TrilinearInnerElType_Type;
+ Stg_Class_DeleteFunction* _delete = _TrilinearInnerElType_Delete;
+ Stg_Class_PrintFunction* _print = _TrilinearInnerElType_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _TrilinearInnerElType_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _TrilinearInnerElType_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _TrilinearInnerElType_Build;
+ Stg_Component_InitialiseFunction* _initialise = _TrilinearInnerElType_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _TrilinearInnerElType_Execute;
+ Stg_Component_DestroyFunction* _destroy = _TrilinearInnerElType_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _TrilinearInnerElType_SF_allNodes;
+ ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _TrilinearInnerElType_SF_allLocalDerivs_allNodes;
+ ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
+ ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _ElementType_JacobianDeterminantSurface;
+ ElementType_SurfaceNormalFunction* _surfaceNormal = _TrilinearInnerElType_SurfaceNormal;
+
+ return _TrilinearInnerElType_New( TRILINEARINNERELTYPE_PASSARGS );
+}
+
+TrilinearInnerElType* TrilinearInnerElType_New( Name name ) {
+ TrilinearInnerElType* self = (TrilinearInnerElType*)_TrilinearInnerElType_DefaultNew( name );
+
+ self->isConstructed = True;
+ _ElementType_Init( (ElementType*)self, _TrilinearInnerElType_NodeCount );
+ _TrilinearInnerElType_Init( self );
+
+ return self;
+}
+
+TrilinearInnerElType* _TrilinearInnerElType_New( TRILINEARINNERELTYPE_DEFARGS ) {
+ TrilinearInnerElType* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(TrilinearInnerElType) );
+ self = (TrilinearInnerElType*)_ElementType_New( ELEMENTTYPE_PASSARGS );
+
+ /* General info */
+
+ /* Virtual functions */
+
+ /* TrilinearInnerElType info */
+
+ return self;
+}
+
+void _TrilinearInnerElType_Init( TrilinearInnerElType* self ) {
+ Dimension_Index dim_I=0;
+
+ /* General and Virtual info should already be set */
+
+ /* TriInnerEllementType info */
+ for ( dim_I = 0; dim_I < 3; dim_I++ ) {
+ self->minElLocalCoord[dim_I] = -1;
+ self->maxElLocalCoord[dim_I] = 1;
+ self->elLocalLength[dim_I] = self->maxElLocalCoord[dim_I] - self->minElLocalCoord[dim_I];
+ }
+
+ /* Set up the tetrahedral indices. */
+ self->tetInds = Memory_Alloc_2DArray( unsigned, 10, 4, (Name)"Mesh_HexType::tetInds" );
+ self->tetInds[0][0] = 0; self->tetInds[0][1] = 1; self->tetInds[0][2] = 2; self->tetInds[0][3] = 4;
+ self->tetInds[1][0] = 1; self->tetInds[1][1] = 2; self->tetInds[1][2] = 3; self->tetInds[1][3] = 7;
+ self->tetInds[2][0] = 1; self->tetInds[2][1] = 4; self->tetInds[2][2] = 5; self->tetInds[2][3] = 7;
+ self->tetInds[3][0] = 2; self->tetInds[3][1] = 4; self->tetInds[3][2] = 6; self->tetInds[3][3] = 7;
+ self->tetInds[4][0] = 1; self->tetInds[4][1] = 2; self->tetInds[4][2] = 4; self->tetInds[4][3] = 7;
+ self->tetInds[5][0] = 0; self->tetInds[5][1] = 1; self->tetInds[5][2] = 3; self->tetInds[5][3] = 5;
+ self->tetInds[6][0] = 0; self->tetInds[6][1] = 4; self->tetInds[6][2] = 5; self->tetInds[6][3] = 6;
+ self->tetInds[7][0] = 0; self->tetInds[7][1] = 2; self->tetInds[7][2] = 3; self->tetInds[7][3] = 6;
+ self->tetInds[8][0] = 3; self->tetInds[8][1] = 5; self->tetInds[8][2] = 6; self->tetInds[8][3] = 7;
+ self->tetInds[9][0] = 0; self->tetInds[9][1] = 3; self->tetInds[9][2] = 5; self->tetInds[9][3] = 6;
+}
+
+void _TrilinearInnerElType_Delete( void* elementType ) {
+ TrilinearInnerElType* self = (TrilinearInnerElType*)elementType;
+
+ /* Stg_Class_Delete parent*/
+ _ElementType_Delete( self );
+}
+
+void _TrilinearInnerElType_Print( void* elementType, Stream* stream ) {
+ TrilinearInnerElType* self = (TrilinearInnerElType*)elementType;
+
+ /* Set the Journal for printing informations */
+ Stream* trilinearInnerElTypeStream = stream;
+
+ /* General info */
+ Journal_Printf( trilinearInnerElTypeStream, "TrilinearInnerElType (ptr): %p\n", self );
+
+ /* Print parent */
+ _ElementType_Print( self, trilinearInnerElTypeStream );
+
+ /* Virtual info */
+
+ /* TrilinearInnerElType info */
+}
+
+void _TrilinearInnerElType_AssignFromXML( void* elementType, Stg_ComponentFactory *cf, void* data ){
+
+}
+
+void _TrilinearInnerElType_Initialise( void* elementType, void *data ){
+
+}
+
+void _TrilinearInnerElType_Execute( void* elementType, void *data ){
+
+}
+
+void _TrilinearInnerElType_Destroy( void* elementType, void *data ){
+ TrilinearInnerElType* self = (TrilinearInnerElType*)elementType;
+
+ FreeArray( self->tetInds );
+
+ _ElementType_Destroy( self, data );
+}
+
+void _TrilinearInnerElType_Build( void* elementType, void *data ) {
+
+}
+
+#if 0
+void _TrilinearInnerElType_ConvertGlobalCoordToElementLocal( void* elementType, Element_DomainIndex element,const Coord globalCoord, Coord localCoord )
+{
+ TrilinearInnerElType* self = (TrilinearInnerElType*)elementType;
+ Dimension_Index dim_I;
+
+ for ( dim_I=0; dim_I < 3; dim_I++ ) {
+ }
+}
+#endif
+
+
+/*
+
+ - Shape function definitions
+ - Local node numbering convention for billinear, trilinear element (xi, eta, zeta)
+ - Local coordinate domain spans -1 <= xi,eta,zeta <= 1
+
+ eta
+ |
+ |____ xi
+ /
+ /
+ zeta
+
+
+ eta
+ |
+3-----2
+| |__|___xi
+| |
+0-----1
+(zeta = -1 plane)
+
+
+ eta
+ |
+7-----6
+| |__|___xi
+| |
+4-----5
+(zeta = +1 plane)
+
+
+*/
+void _TrilinearInnerElType_SF_allNodes( void* elementType, const double localCoord[], double* const evaluatedValues ) {
+ double xi, eta, zeta;
+ double fac;
+
+ xi = localCoord[0];
+ eta = localCoord[1];
+ zeta = localCoord[2];
+
+ fac = 1.0/9.0;
+
+ evaluatedValues[0] = fac*( - 4.0*xi - 20.0*eta + 12.0*zeta + 3.0 );
+ evaluatedValues[1] = fac*( 16.0*xi - 64.0*eta + 60.0*zeta + 6.0 );
+ evaluatedValues[2] = fac*( 36.0*eta - 36.0*zeta );
+ evaluatedValues[3] = fac*( -12.0*xi + 48.0*eta - 36.0*zeta );
+}
+
+
+
+void _TrilinearInnerElType_SF_allLocalDerivs_allNodes( void* elementType, const double localCoord[],
+ double** const evaluatedDerivatives )
+{
+ double xi, eta, zeta;
+ double fac;
+
+ xi = localCoord[0];
+ eta = localCoord[1];
+ zeta = localCoord[2];
+
+ fac = 1.0/9.0;
+
+ evaluatedDerivatives[0][0] = fac*( - 4.0 );
+ evaluatedDerivatives[0][1] = fac*( 16.0 );
+ evaluatedDerivatives[0][2] = 0.0 ;
+ evaluatedDerivatives[0][3] = fac*( -12.0 );
+
+ evaluatedDerivatives[1][0] = fac*( -20.0 );
+ evaluatedDerivatives[1][1] = fac*( -64.0 );
+ evaluatedDerivatives[1][2] = 4.0 ;
+ evaluatedDerivatives[1][3] = fac*( 48.0 );
+
+ evaluatedDerivatives[2][0] = fac*( 12.0 );
+ evaluatedDerivatives[2][1] = fac*( 60.0 );
+ evaluatedDerivatives[2][2] = - 4.0 ;
+ evaluatedDerivatives[2][3] = - 4.0 ;
+}
+
+/* get rid of this function and just use the superclass (elementType) version, as for BilinearInner class?? */
+/*
+void _TrilinearInnerElType_ConvertGlobalCoordToElLocal(
+ void* elementType,
+ void* _mesh,
+ unsigned element,
+ const double* globalCoord,
+ double* elLocalCoord )
+{
+ TrilinearInnerElType* self = (TrilinearInnerElType*)elementType;
+ Mesh* mesh = (Mesh*)_mesh;
+ unsigned inside;
+ double bc[4];
+ static double lCrds[8][3] = {{-1.0, -1.0, -1.0}, {1.0, -1.0, -1.0},
+ {-1.0, 1.0, -1.0}, {1.0, 1.0, -1.0},
+ {-1.0, -1.0, 1.0}, {1.0, -1.0, 1.0},
+ {-1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}};
+ unsigned nInc, *inc;
+ unsigned bc_i;
+
+ Mesh_GetIncidence( mesh, MT_VOLUME, element, MT_VERTEX, &nInc, &inc );
+ assert( nInc == 8 );
+
+ insist( Simplex_Search3D( mesh->verts, inc, 10, self->tetInds, (double*)globalCoord, bc, &inside ), == True );
+
+ elLocalCoord[0] = bc[0] * lCrds[self->tetInds[inside][0]][0];
+ elLocalCoord[1] = bc[0] * lCrds[self->tetInds[inside][0]][1];
+ elLocalCoord[2] = bc[0] * lCrds[self->tetInds[inside][0]][2];
+ for( bc_i = 1; bc_i < 4; bc_i++ ) {
+ elLocalCoord[0] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][0];
+ elLocalCoord[1] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][1];
+ elLocalCoord[2] += bc[bc_i] * lCrds[self->tetInds[inside][bc_i]][2];
+ }
+}*/
+
+int _TrilinearInnerElType_SurfaceNormal( void* elementType, unsigned element_I, unsigned dim, double* xi, double* normal ) {
+ Stream* errStream = Journal_Register( ErrorStream_Type, (Name)ElementType_Type );
+
+ Journal_Printf( errStream, "Surface normal function not yet implemented for this element type.\n" );
+ assert( 0 );
+
+ normal = NULL;
+
+ return -1;
+}
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/Triquadratic.c
--- a/Discretisation/src/Triquadratic.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,446 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Dave Lee, Computational Engineer, VPAC. (dave at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Biquadratic.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <mpi.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "Discretisation.h"
-
-#include "Triquadratic.h"
-
-/* Textual name of this class */
-const Type Triquadratic_Type = "Triquadratic";
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-#define TRIQUADRATICNODECOUNT 27
-
-Triquadratic* Triquadratic_New( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(Triquadratic);
- Type type = Triquadratic_Type;
- Stg_Class_DeleteFunction* _delete = _Triquadratic_Delete;
- Stg_Class_PrintFunction* _print = _Triquadratic_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_Triquadratic_New;
- Stg_Component_ConstructFunction* _construct = _Triquadratic_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Triquadratic_Build;
- Stg_Component_InitialiseFunction* _initialise = _Triquadratic_Initialise;
- Stg_Component_ExecuteFunction* _execute = _Triquadratic_Execute;
- Stg_Component_DestroyFunction* _destroy = _Triquadratic_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = Triquadratic_EvalBasis;
- ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = Triquadratic_EvalLocalDerivs;
- ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
- ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = Triquadratic_JacobianDeterminantSurface;
- ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
-
- return _Triquadratic_New( TRIQUADRATIC_PASSARGS );
-}
-
-Triquadratic* _Triquadratic_New( TRIQUADRATIC_DEFARGS ) {
- Triquadratic* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(Triquadratic) );
- self = (Triquadratic*)_ElementType_New( ELEMENTTYPE_PASSARGS );
-
- /* Virtual info */
-
- /* Triquadratic info */
- self->isConstructed = True;
- _ElementType_Init( (ElementType*)self, TRIQUADRATICNODECOUNT );
- _Triquadratic_Init( self );
-
- return self;
-}
-
-void _Triquadratic_Init( Triquadratic* self ) {
- assert( self && Stg_CheckType( self, Triquadratic ) );
-
- self->dim = 3;
-}
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _Triquadratic_Delete( void* elementType ) {
- Triquadratic* self = (Triquadratic*)elementType;
-
- /* Delete the parent */
- _ElementType_Delete( self );
-}
-
-void _Triquadratic_Print( void* elementType, Stream* stream ) {
- Triquadratic* self = (Triquadratic*)elementType;
-
- /* Set the Journal for printing informations */
- Stream* elementTypeStream;
- elementTypeStream = Journal_Register( InfoStream_Type, (Name)"TriquadraticStream" );
-
- /* Print parent */
- Journal_Printf( stream, "Triquadratic (ptr): (%p)\n", self );
- _ElementType_Print( self, stream );
-}
-
-void _Triquadratic_AssignFromXML( void* elementType, Stg_ComponentFactory* cf, void* data ) {
-}
-
-void _Triquadratic_Build( void* elementType, void* data ) {
-}
-
-void _Triquadratic_Initialise( void* elementType, void* data ) {
- Triquadratic* self = (Triquadratic*)elementType;
- unsigned** faceNodes;
-
- faceNodes = Memory_Alloc_2DArray( unsigned, 6, 9, (Name)"node indices for element faces" );
-
- faceNodes[0][0] = 0; faceNodes[0][1] = 1; faceNodes[0][2] = 2;
- faceNodes[0][3] = 9; faceNodes[0][4] = 10; faceNodes[0][5] = 11;
- faceNodes[0][6] = 18; faceNodes[0][7] = 19; faceNodes[0][8] = 20;
-
- faceNodes[1][0] = 6; faceNodes[1][1] = 7; faceNodes[1][2] = 8;
- faceNodes[1][3] = 15; faceNodes[1][4] = 16; faceNodes[1][5] = 17;
- faceNodes[1][6] = 24; faceNodes[1][7] = 25; faceNodes[1][8] = 26;
-
- faceNodes[2][0] = 0; faceNodes[2][1] = 9; faceNodes[2][2] = 18;
- faceNodes[2][3] = 3; faceNodes[2][4] = 12; faceNodes[2][5] = 21;
- faceNodes[2][6] = 6; faceNodes[2][7] = 15; faceNodes[2][8] = 24;
-
- faceNodes[3][0] = 2; faceNodes[3][1] = 11; faceNodes[3][2] = 20;
- faceNodes[3][3] = 5; faceNodes[3][4] = 14; faceNodes[3][5] = 23;
- faceNodes[3][6] = 8; faceNodes[3][7] = 17; faceNodes[3][8] = 26;
-
- faceNodes[4][0] = 0; faceNodes[4][1] = 1; faceNodes[4][2] = 2;
- faceNodes[4][3] = 3; faceNodes[4][4] = 4; faceNodes[4][5] = 5;
- faceNodes[4][6] = 6; faceNodes[4][7] = 7; faceNodes[4][8] = 8;
-
- faceNodes[5][0] = 18; faceNodes[5][1] = 19; faceNodes[5][2] = 20;
- faceNodes[5][3] = 21; faceNodes[5][4] = 22; faceNodes[5][5] = 23;
- faceNodes[5][6] = 24; faceNodes[5][7] = 25; faceNodes[5][8] = 26;
-
- self->faceNodes = faceNodes;
-
- self->evaluatedShapeFunc = Memory_Alloc_Array( double, self->nodeCount, "evaluatedShapeFuncs" );
- self->GNi = Memory_Alloc_2DArray( double, self->dim, self->nodeCount, (Name)"evaluatedShapeFuncDerivatives" );
-}
-
-void _Triquadratic_Execute( void* elementType, void* data ) {
-}
-
-void _Triquadratic_Destroy( void* elementType, void* data ) {
- Triquadratic* self = (Triquadratic*)elementType;
-
- Memory_Free( self->faceNodes );
- Memory_Free( self->evaluatedShapeFunc );
- Memory_Free( self->GNi );
-
- _ElementType_Destroy( elementType, data );
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-/*
-
- - Shape function definitions
- - Local node numbering convention for billinear, trilinear element (xi, eta, zeta)
- - Local coordinate domain spans -1 <= xi,eta,zeta <= 1
-
- eta
- |
- |____ xi
- /
- /
- zeta
-
-
- eta
- |
-3-----2
-| |__|___xi
-| |
-0-----1
-(zeta = -1 plane)
-
-
- eta
- |
-7-----6
-| |__|___xi
-| |
-4-----5
-(zeta = +1 plane)
-
-
-*/
-
-void Triquadratic_EvalBasis( void* elementType, const double* localCoord, double* basis ) {
- double xi = localCoord[0], eta = localCoord[1], zeta = localCoord[2];
- double a0 = xi - 1.0, b0 = eta - 1.0, c0 = zeta - 1.0;
- double a1 = 1.0 - xi * xi, b1 = 1.0 - eta * eta, c1 = 1.0 - zeta * zeta;
- double a2 = xi + 1.0, b2 = eta + 1.0, c2 = zeta + 1.0;
- double m0 = 0.5 * xi;
- double m1 = 0.5 * eta;
- double m2 = 0.5 * zeta;
- double m3 = 0.25 * xi * eta;
- double m4 = 0.25 * xi * zeta;
- double m5 = 0.25 * eta * zeta;
- double m6 = 0.125 * xi * eta * zeta;
-
- basis[0] = m6 * a0 * b0 * c0;
- basis[1] = m5 * a1 * b0 * c0;
- basis[2] = m6 * a2 * b0 * c0;
-
- basis[3] = m4 * a0 * b1 * c0;
- basis[4] = m2 * a1 * b1 * c0;
- basis[5] = m4 * a2 * b1 * c0;
-
- basis[6] = m6 * a0 * b2 * c0;
- basis[7] = m5 * a1 * b2 * c0;
- basis[8] = m6 * a2 * b2 * c0;
-
-
- basis[9] = m3 * a0 * b0 * c1;
- basis[10] = m1 * a1 * b0 * c1;
- basis[11] = m3 * a2 * b0 * c1;
-
- basis[12] = m0 * a0 * b1 * c1;
- basis[13] = a1 * b1 * c1;
- basis[14] = m0 * a2 * b1 * c1;
-
- basis[15] = m3 * a0 * b2 * c1;
- basis[16] = m1 * a1 * b2 * c1;
- basis[17] = m3 * a2 * b2 * c1;
-
-
- basis[18] = m6 * a0 * b0 * c2;
- basis[19] = m5 * a1 * b0 * c2;
- basis[20] = m6 * a2 * b0 * c2;
-
- basis[21] = m4 * a0 * b1 * c2;
- basis[22] = m2 * a1 * b1 * c2;
- basis[23] = m4 * a2 * b1 * c2;
-
- basis[24] = m6 * a0 * b2 * c2;
- basis[25] = m5 * a1 * b2 * c2;
- basis[26] = m6 * a2 * b2 * c2;
-}
-
-void Triquadratic_EvalLocalDerivs( void* elementType, const double* localCoord, double** derivs ) {
- double xi = localCoord[0], eta = localCoord[1], zeta = localCoord[2];
- double a0 = xi - 1.0, b0 = eta - 1.0, c0 = zeta - 1.0;
- double a1 = 1.0 - xi * xi, b1 = 1.0 - eta * eta, c1 = 1.0 - zeta * zeta;
- double a2 = xi + 1.0, b2 = eta + 1.0, c2 = zeta + 1.0;
- double m0 = 0.5 * xi;
- double m1 = 0.5 * eta;
- double m2 = 0.5 * zeta;
- double m3 = 0.25 * xi * eta;
- double m4 = 0.25 * xi * zeta;
- double m5 = 0.25 * eta * zeta;
- double a3 = xi - 0.5, b3 = eta - 0.5, c3 = zeta - 0.5;
- double a4 = -2.0 * xi, b4 = -2.0 * eta, c4 = -2.0 * zeta;
- double a5 = xi + 0.5, b5 = eta + 0.5, c5 = zeta + 0.5;
-
- /* first face perp. to zeta */
- derivs[0][0] = a3 * m5 * b0 * c0;
- derivs[1][0] = b3 * m4 * a0 * c0;
- derivs[2][0] = c3 * m3 * a0 * b0;
-
- derivs[0][1] = a4 * m5 * b0 * c0;
- derivs[1][1] = b3 * m2 * a1 * c0;
- derivs[2][1] = c3 * m1 * a1 * b0;
-
- derivs[0][2] = a5 * m5 * b0 * c0;
- derivs[1][2] = b3 * m4 * a2 * c0;
- derivs[2][2] = c3 * m3 * a2 * b0;
-
-
- derivs[0][3] = a3 * m2 * b1 * c0;
- derivs[1][3] = b4 * m4 * a0 * c0;
- derivs[2][3] = c3 * m0 * a0 * b1;
-
- derivs[0][4] = a4 * m2 * b1 * c0;
- derivs[1][4] = b4 * m2 * a1 * c0;
- derivs[2][4] = c3 * a1 * b1;
-
- derivs[0][5] = a5 * m2 * b1 * c0;
- derivs[1][5] = b4 * m4 * a2 * c0;
- derivs[2][5] = c3 * m0 * a2 * b1;
-
-
- derivs[0][6] = a3 * m5 * b2 * c0;
- derivs[1][6] = b5 * m4 * a0 * c0;
- derivs[2][6] = c3 * m3 * a0 * b2;
-
- derivs[0][7] = a4 * m5 * b2 * c0;
- derivs[1][7] = b5 * m2 * a1 * c0;
- derivs[2][7] = c3 * m1 * a1 * b2;
-
- derivs[0][8] = a5 * m5 * b2 * c0;
- derivs[1][8] = b5 * m4 * a2 * c0;
- derivs[2][8] = c3 * m3 * a2 * b2;
-
- /* second face perp. to zeta */
- derivs[0][9] = a3 * m1 * b0 * c1;
- derivs[1][9] = b3 * m0 * a0 * c1;
- derivs[2][9] = c4 * m3 * a0 * b0;
-
- derivs[0][10] = a4 * m1 * b0 * c1;
- derivs[1][10] = b3 * a1 * c1;
- derivs[2][10] = c4 * m1 * a1 * b0;
-
- derivs[0][11] = a5 * m1 * b0 * c1;
- derivs[1][11] = b3 * m0 * a2 * c1;
- derivs[2][11] = c4 * m3 * a2 * b0;
-
-
- derivs[0][12] = a3 * b1 * c1;
- derivs[1][12] = b4 * m0 * a0 * c1;
- derivs[2][12] = c4 * m0 * a0 * b1;
-
- derivs[0][13] = a4 * b1 * c1;
- derivs[1][13] = b4 * a1 * c1;
- derivs[2][13] = c4 * a1 * b1;
-
- derivs[0][14] = a5 * b1 * c1;
- derivs[1][14] = b4 * m0 * a2 * c1;
- derivs[2][14] = c4 * m0 * a2 * b1;
-
-
- derivs[0][15] = a3 * m1 * b2 * c1;
- derivs[1][15] = b5 * m0 * a0 * c1;
- derivs[2][15] = c4 * m3 * a0 * b2;
-
- derivs[0][16] = a4 * m1 * b2 * c1;
- derivs[1][16] = b5 * a1 * c1;
- derivs[2][16] = c4 * m1 * a1 * b2;
-
- derivs[0][17] = a5 * m1 * b2 * c1;
- derivs[1][17] = b5 * m0 * a2 * c1;
- derivs[2][17] = c4 * m3 * a2 * b2;
-
- /* back face perp. to zeta */
- derivs[0][18] = a3 * m5 * b0 * c2;
- derivs[1][18] = b3 * m4 * a0 * c2;
- derivs[2][18] = c5 * m3 * a0 * b0;
-
- derivs[0][19] = a4 * m5 * b0 * c2;
- derivs[1][19] = b3 * m2 * a1 * c2;
- derivs[2][19] = c5 * m1 * a1 * b0;
-
- derivs[0][20] = a5 * m5 * b0 * c2;
- derivs[1][20] = b3 * m4 * a2 * c2;
- derivs[2][20] = c5 * m3 * a2 * b0;
-
-
- derivs[0][21] = a3 * m2 * b1 * c2;
- derivs[1][21] = b4 * m4 * a0 * c2;
- derivs[2][21] = c5 * m0 * a0 * b1;
-
- derivs[0][22] = a4 * m2 * b1 * c2;
- derivs[1][22] = b4 * m2 * a1 * c2;
- derivs[2][22] = c5 * a1 * b1;
-
- derivs[0][23] = a5 * m2 * b1 * c2;
- derivs[1][23] = b4 * m4 * a2 * c2;
- derivs[2][23] = c5 * m0 * a2 * b1;
-
-
- derivs[0][24] = a3 * m5 * b2 * c2;
- derivs[1][24] = b5 * m4 * a0 * c2;
- derivs[2][24] = c5 * m3 * a0 * b2;
-
- derivs[0][25] = a4 * m5 * b2 * c2;
- derivs[1][25] = b5 * m2 * a1 * c2;
- derivs[2][25] = c5 * m1 * a1 * b2;
-
- derivs[0][26] = a5 * m5 * b2 * c2;
- derivs[1][26] = b5 * m4 * a2 * c2;
- derivs[2][26] = c5 * m3 * a2 * b2;
-}
-
-double Triquadratic_JacobianDeterminantSurface( void* elementType, void* _mesh, unsigned element_I, const double localCoord[],
- unsigned face_I, unsigned norm )
-{
- Triquadratic* self = (Triquadratic*) elementType;
- Mesh* mesh = (Mesh*)_mesh;
- unsigned surfaceDim[2];
- double x[9], y[9];
- double s, t;
- double dxds, dxdt, dyds, dydt;
- double detJac;
- Index node_i;
- double s0, s1, s2, t0, t1, t2;
- double ds0, ds1, ds2, dt0, dt1, dt2;
- unsigned nodes[9];
-
- surfaceDim[0] = ( norm + 1 ) % 3;
- surfaceDim[1] = ( norm + 2 ) % 3;
-
- s = localCoord[surfaceDim[0]];
- t = localCoord[surfaceDim[1]];
-
- s0 = 0.5 * s * ( s - 1.0 ); s1 = 1.0 - s * s; s2 = 0.5 * s * ( s + 1.0 );
- t0 = 0.5 * t * ( t - 1.0 ); t1 = 1.0 - t * t; t2 = 0.5 * t * ( t + 1.0 );
-
- ds0 = s - 0.5; ds1 = -2.0 * s; ds2 = s + 0.5;
- dt0 = t - 0.5; dt1 = -2.0 * t; dt2 = t + 0.5;
-
- ElementType_GetFaceNodes( self, mesh, element_I, face_I, 9, nodes );
-
- for( node_i = 0; node_i < 9; node_i++ ) {
- x[node_i] = Mesh_GetVertex( mesh, nodes[node_i] )[surfaceDim[0]];
- y[node_i] = Mesh_GetVertex( mesh, nodes[node_i] )[surfaceDim[1]];
- }
-
- dxds = ds0*t0*x[0] + ds1*t0*x[1] + ds2*t0*x[2] + ds0*t1*x[3] + ds1*t1*x[4] + ds2*t1*x[5] + ds0*t2*x[6] + ds1*t2*x[7] + ds2*t2*x[8];
- dxdt = s0*dt0*x[0] + s1*dt0*x[1] + s2*dt0*x[2] + s0*dt1*x[3] + s1*dt1*x[4] + s2*dt1*x[5] + s0*dt2*x[6] + s1*dt2*x[8] + s2*dt2*x[8];
- dyds = ds0*t0*y[0] + ds1*t0*y[1] + ds2*t0*y[2] + ds0*t1*y[3] + ds1*t1*y[4] + ds2*t1*y[5] + ds0*t2*y[6] + ds1*t2*y[7] + ds2*t2*y[8];
- dydt = s0*dt0*y[0] + s1*dt0*y[1] + s2*dt0*y[2] + s0*dt1*y[3] + s1*dt1*y[4] + s2*dt1*y[5] + s0*dt2*y[6] + s1*dt2*y[8] + s2*dt2*y[8];
-
- detJac = dxds * dydt - dxdt * dyds;
-
- return fabs( detJac );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/src/Triquadratic.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/src/Triquadratic.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,446 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Dave Lee, Computational Engineer, VPAC. (dave at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Biquadratic.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "Discretisation.h"
+
+#include "Triquadratic.h"
+
+/* Textual name of this class */
+const Type Triquadratic_Type = "Triquadratic";
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+#define TRIQUADRATICNODECOUNT 27
+
+Triquadratic* Triquadratic_New( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(Triquadratic);
+ Type type = Triquadratic_Type;
+ Stg_Class_DeleteFunction* _delete = _Triquadratic_Delete;
+ Stg_Class_PrintFunction* _print = _Triquadratic_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_Triquadratic_New;
+ Stg_Component_ConstructFunction* _construct = _Triquadratic_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Triquadratic_Build;
+ Stg_Component_InitialiseFunction* _initialise = _Triquadratic_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _Triquadratic_Execute;
+ Stg_Component_DestroyFunction* _destroy = _Triquadratic_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = Triquadratic_EvalBasis;
+ ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = Triquadratic_EvalLocalDerivs;
+ ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ElementType_ConvertGlobalCoordToElLocal;
+ ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = Triquadratic_JacobianDeterminantSurface;
+ ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
+
+ return _Triquadratic_New( TRIQUADRATIC_PASSARGS );
+}
+
+Triquadratic* _Triquadratic_New( TRIQUADRATIC_DEFARGS ) {
+ Triquadratic* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(Triquadratic) );
+ self = (Triquadratic*)_ElementType_New( ELEMENTTYPE_PASSARGS );
+
+ /* Virtual info */
+
+ /* Triquadratic info */
+ self->isConstructed = True;
+ _ElementType_Init( (ElementType*)self, TRIQUADRATICNODECOUNT );
+ _Triquadratic_Init( self );
+
+ return self;
+}
+
+void _Triquadratic_Init( Triquadratic* self ) {
+ assert( self && Stg_CheckType( self, Triquadratic ) );
+
+ self->dim = 3;
+}
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _Triquadratic_Delete( void* elementType ) {
+ Triquadratic* self = (Triquadratic*)elementType;
+
+ /* Delete the parent */
+ _ElementType_Delete( self );
+}
+
+void _Triquadratic_Print( void* elementType, Stream* stream ) {
+ Triquadratic* self = (Triquadratic*)elementType;
+
+ /* Set the Journal for printing informations */
+ Stream* elementTypeStream;
+ elementTypeStream = Journal_Register( InfoStream_Type, (Name)"TriquadraticStream" );
+
+ /* Print parent */
+ Journal_Printf( stream, "Triquadratic (ptr): (%p)\n", self );
+ _ElementType_Print( self, stream );
+}
+
+void _Triquadratic_AssignFromXML( void* elementType, Stg_ComponentFactory* cf, void* data ) {
+}
+
+void _Triquadratic_Build( void* elementType, void* data ) {
+}
+
+void _Triquadratic_Initialise( void* elementType, void* data ) {
+ Triquadratic* self = (Triquadratic*)elementType;
+ unsigned** faceNodes;
+
+ faceNodes = Memory_Alloc_2DArray( unsigned, 6, 9, (Name)"node indices for element faces" );
+
+ faceNodes[0][0] = 0; faceNodes[0][1] = 1; faceNodes[0][2] = 2;
+ faceNodes[0][3] = 9; faceNodes[0][4] = 10; faceNodes[0][5] = 11;
+ faceNodes[0][6] = 18; faceNodes[0][7] = 19; faceNodes[0][8] = 20;
+
+ faceNodes[1][0] = 6; faceNodes[1][1] = 7; faceNodes[1][2] = 8;
+ faceNodes[1][3] = 15; faceNodes[1][4] = 16; faceNodes[1][5] = 17;
+ faceNodes[1][6] = 24; faceNodes[1][7] = 25; faceNodes[1][8] = 26;
+
+ faceNodes[2][0] = 0; faceNodes[2][1] = 9; faceNodes[2][2] = 18;
+ faceNodes[2][3] = 3; faceNodes[2][4] = 12; faceNodes[2][5] = 21;
+ faceNodes[2][6] = 6; faceNodes[2][7] = 15; faceNodes[2][8] = 24;
+
+ faceNodes[3][0] = 2; faceNodes[3][1] = 11; faceNodes[3][2] = 20;
+ faceNodes[3][3] = 5; faceNodes[3][4] = 14; faceNodes[3][5] = 23;
+ faceNodes[3][6] = 8; faceNodes[3][7] = 17; faceNodes[3][8] = 26;
+
+ faceNodes[4][0] = 0; faceNodes[4][1] = 1; faceNodes[4][2] = 2;
+ faceNodes[4][3] = 3; faceNodes[4][4] = 4; faceNodes[4][5] = 5;
+ faceNodes[4][6] = 6; faceNodes[4][7] = 7; faceNodes[4][8] = 8;
+
+ faceNodes[5][0] = 18; faceNodes[5][1] = 19; faceNodes[5][2] = 20;
+ faceNodes[5][3] = 21; faceNodes[5][4] = 22; faceNodes[5][5] = 23;
+ faceNodes[5][6] = 24; faceNodes[5][7] = 25; faceNodes[5][8] = 26;
+
+ self->faceNodes = faceNodes;
+
+ self->evaluatedShapeFunc = Memory_Alloc_Array( double, self->nodeCount, "evaluatedShapeFuncs" );
+ self->GNi = Memory_Alloc_2DArray( double, self->dim, self->nodeCount, (Name)"evaluatedShapeFuncDerivatives" );
+}
+
+void _Triquadratic_Execute( void* elementType, void* data ) {
+}
+
+void _Triquadratic_Destroy( void* elementType, void* data ) {
+ Triquadratic* self = (Triquadratic*)elementType;
+
+ Memory_Free( self->faceNodes );
+ Memory_Free( self->evaluatedShapeFunc );
+ Memory_Free( self->GNi );
+
+ _ElementType_Destroy( elementType, data );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+/*
+
+ - Shape function definitions
+ - Local node numbering convention for billinear, trilinear element (xi, eta, zeta)
+ - Local coordinate domain spans -1 <= xi,eta,zeta <= 1
+
+ eta
+ |
+ |____ xi
+ /
+ /
+ zeta
+
+
+ eta
+ |
+3-----2
+| |__|___xi
+| |
+0-----1
+(zeta = -1 plane)
+
+
+ eta
+ |
+7-----6
+| |__|___xi
+| |
+4-----5
+(zeta = +1 plane)
+
+
+*/
+
+void Triquadratic_EvalBasis( void* elementType, const double* localCoord, double* basis ) {
+ double xi = localCoord[0], eta = localCoord[1], zeta = localCoord[2];
+ double a0 = xi - 1.0, b0 = eta - 1.0, c0 = zeta - 1.0;
+ double a1 = 1.0 - xi * xi, b1 = 1.0 - eta * eta, c1 = 1.0 - zeta * zeta;
+ double a2 = xi + 1.0, b2 = eta + 1.0, c2 = zeta + 1.0;
+ double m0 = 0.5 * xi;
+ double m1 = 0.5 * eta;
+ double m2 = 0.5 * zeta;
+ double m3 = 0.25 * xi * eta;
+ double m4 = 0.25 * xi * zeta;
+ double m5 = 0.25 * eta * zeta;
+ double m6 = 0.125 * xi * eta * zeta;
+
+ basis[0] = m6 * a0 * b0 * c0;
+ basis[1] = m5 * a1 * b0 * c0;
+ basis[2] = m6 * a2 * b0 * c0;
+
+ basis[3] = m4 * a0 * b1 * c0;
+ basis[4] = m2 * a1 * b1 * c0;
+ basis[5] = m4 * a2 * b1 * c0;
+
+ basis[6] = m6 * a0 * b2 * c0;
+ basis[7] = m5 * a1 * b2 * c0;
+ basis[8] = m6 * a2 * b2 * c0;
+
+
+ basis[9] = m3 * a0 * b0 * c1;
+ basis[10] = m1 * a1 * b0 * c1;
+ basis[11] = m3 * a2 * b0 * c1;
+
+ basis[12] = m0 * a0 * b1 * c1;
+ basis[13] = a1 * b1 * c1;
+ basis[14] = m0 * a2 * b1 * c1;
+
+ basis[15] = m3 * a0 * b2 * c1;
+ basis[16] = m1 * a1 * b2 * c1;
+ basis[17] = m3 * a2 * b2 * c1;
+
+
+ basis[18] = m6 * a0 * b0 * c2;
+ basis[19] = m5 * a1 * b0 * c2;
+ basis[20] = m6 * a2 * b0 * c2;
+
+ basis[21] = m4 * a0 * b1 * c2;
+ basis[22] = m2 * a1 * b1 * c2;
+ basis[23] = m4 * a2 * b1 * c2;
+
+ basis[24] = m6 * a0 * b2 * c2;
+ basis[25] = m5 * a1 * b2 * c2;
+ basis[26] = m6 * a2 * b2 * c2;
+}
+
+void Triquadratic_EvalLocalDerivs( void* elementType, const double* localCoord, double** derivs ) {
+ double xi = localCoord[0], eta = localCoord[1], zeta = localCoord[2];
+ double a0 = xi - 1.0, b0 = eta - 1.0, c0 = zeta - 1.0;
+ double a1 = 1.0 - xi * xi, b1 = 1.0 - eta * eta, c1 = 1.0 - zeta * zeta;
+ double a2 = xi + 1.0, b2 = eta + 1.0, c2 = zeta + 1.0;
+ double m0 = 0.5 * xi;
+ double m1 = 0.5 * eta;
+ double m2 = 0.5 * zeta;
+ double m3 = 0.25 * xi * eta;
+ double m4 = 0.25 * xi * zeta;
+ double m5 = 0.25 * eta * zeta;
+ double a3 = xi - 0.5, b3 = eta - 0.5, c3 = zeta - 0.5;
+ double a4 = -2.0 * xi, b4 = -2.0 * eta, c4 = -2.0 * zeta;
+ double a5 = xi + 0.5, b5 = eta + 0.5, c5 = zeta + 0.5;
+
+ /* first face perp. to zeta */
+ derivs[0][0] = a3 * m5 * b0 * c0;
+ derivs[1][0] = b3 * m4 * a0 * c0;
+ derivs[2][0] = c3 * m3 * a0 * b0;
+
+ derivs[0][1] = a4 * m5 * b0 * c0;
+ derivs[1][1] = b3 * m2 * a1 * c0;
+ derivs[2][1] = c3 * m1 * a1 * b0;
+
+ derivs[0][2] = a5 * m5 * b0 * c0;
+ derivs[1][2] = b3 * m4 * a2 * c0;
+ derivs[2][2] = c3 * m3 * a2 * b0;
+
+
+ derivs[0][3] = a3 * m2 * b1 * c0;
+ derivs[1][3] = b4 * m4 * a0 * c0;
+ derivs[2][3] = c3 * m0 * a0 * b1;
+
+ derivs[0][4] = a4 * m2 * b1 * c0;
+ derivs[1][4] = b4 * m2 * a1 * c0;
+ derivs[2][4] = c3 * a1 * b1;
+
+ derivs[0][5] = a5 * m2 * b1 * c0;
+ derivs[1][5] = b4 * m4 * a2 * c0;
+ derivs[2][5] = c3 * m0 * a2 * b1;
+
+
+ derivs[0][6] = a3 * m5 * b2 * c0;
+ derivs[1][6] = b5 * m4 * a0 * c0;
+ derivs[2][6] = c3 * m3 * a0 * b2;
+
+ derivs[0][7] = a4 * m5 * b2 * c0;
+ derivs[1][7] = b5 * m2 * a1 * c0;
+ derivs[2][7] = c3 * m1 * a1 * b2;
+
+ derivs[0][8] = a5 * m5 * b2 * c0;
+ derivs[1][8] = b5 * m4 * a2 * c0;
+ derivs[2][8] = c3 * m3 * a2 * b2;
+
+ /* second face perp. to zeta */
+ derivs[0][9] = a3 * m1 * b0 * c1;
+ derivs[1][9] = b3 * m0 * a0 * c1;
+ derivs[2][9] = c4 * m3 * a0 * b0;
+
+ derivs[0][10] = a4 * m1 * b0 * c1;
+ derivs[1][10] = b3 * a1 * c1;
+ derivs[2][10] = c4 * m1 * a1 * b0;
+
+ derivs[0][11] = a5 * m1 * b0 * c1;
+ derivs[1][11] = b3 * m0 * a2 * c1;
+ derivs[2][11] = c4 * m3 * a2 * b0;
+
+
+ derivs[0][12] = a3 * b1 * c1;
+ derivs[1][12] = b4 * m0 * a0 * c1;
+ derivs[2][12] = c4 * m0 * a0 * b1;
+
+ derivs[0][13] = a4 * b1 * c1;
+ derivs[1][13] = b4 * a1 * c1;
+ derivs[2][13] = c4 * a1 * b1;
+
+ derivs[0][14] = a5 * b1 * c1;
+ derivs[1][14] = b4 * m0 * a2 * c1;
+ derivs[2][14] = c4 * m0 * a2 * b1;
+
+
+ derivs[0][15] = a3 * m1 * b2 * c1;
+ derivs[1][15] = b5 * m0 * a0 * c1;
+ derivs[2][15] = c4 * m3 * a0 * b2;
+
+ derivs[0][16] = a4 * m1 * b2 * c1;
+ derivs[1][16] = b5 * a1 * c1;
+ derivs[2][16] = c4 * m1 * a1 * b2;
+
+ derivs[0][17] = a5 * m1 * b2 * c1;
+ derivs[1][17] = b5 * m0 * a2 * c1;
+ derivs[2][17] = c4 * m3 * a2 * b2;
+
+ /* back face perp. to zeta */
+ derivs[0][18] = a3 * m5 * b0 * c2;
+ derivs[1][18] = b3 * m4 * a0 * c2;
+ derivs[2][18] = c5 * m3 * a0 * b0;
+
+ derivs[0][19] = a4 * m5 * b0 * c2;
+ derivs[1][19] = b3 * m2 * a1 * c2;
+ derivs[2][19] = c5 * m1 * a1 * b0;
+
+ derivs[0][20] = a5 * m5 * b0 * c2;
+ derivs[1][20] = b3 * m4 * a2 * c2;
+ derivs[2][20] = c5 * m3 * a2 * b0;
+
+
+ derivs[0][21] = a3 * m2 * b1 * c2;
+ derivs[1][21] = b4 * m4 * a0 * c2;
+ derivs[2][21] = c5 * m0 * a0 * b1;
+
+ derivs[0][22] = a4 * m2 * b1 * c2;
+ derivs[1][22] = b4 * m2 * a1 * c2;
+ derivs[2][22] = c5 * a1 * b1;
+
+ derivs[0][23] = a5 * m2 * b1 * c2;
+ derivs[1][23] = b4 * m4 * a2 * c2;
+ derivs[2][23] = c5 * m0 * a2 * b1;
+
+
+ derivs[0][24] = a3 * m5 * b2 * c2;
+ derivs[1][24] = b5 * m4 * a0 * c2;
+ derivs[2][24] = c5 * m3 * a0 * b2;
+
+ derivs[0][25] = a4 * m5 * b2 * c2;
+ derivs[1][25] = b5 * m2 * a1 * c2;
+ derivs[2][25] = c5 * m1 * a1 * b2;
+
+ derivs[0][26] = a5 * m5 * b2 * c2;
+ derivs[1][26] = b5 * m4 * a2 * c2;
+ derivs[2][26] = c5 * m3 * a2 * b2;
+}
+
+double Triquadratic_JacobianDeterminantSurface( void* elementType, void* _mesh, unsigned element_I, const double localCoord[],
+ unsigned face_I, unsigned norm )
+{
+ Triquadratic* self = (Triquadratic*) elementType;
+ Mesh* mesh = (Mesh*)_mesh;
+ unsigned surfaceDim[2];
+ double x[9], y[9];
+ double s, t;
+ double dxds, dxdt, dyds, dydt;
+ double detJac;
+ Index node_i;
+ double s0, s1, s2, t0, t1, t2;
+ double ds0, ds1, ds2, dt0, dt1, dt2;
+ unsigned nodes[9];
+
+ surfaceDim[0] = ( norm + 1 ) % 3;
+ surfaceDim[1] = ( norm + 2 ) % 3;
+
+ s = localCoord[surfaceDim[0]];
+ t = localCoord[surfaceDim[1]];
+
+ s0 = 0.5 * s * ( s - 1.0 ); s1 = 1.0 - s * s; s2 = 0.5 * s * ( s + 1.0 );
+ t0 = 0.5 * t * ( t - 1.0 ); t1 = 1.0 - t * t; t2 = 0.5 * t * ( t + 1.0 );
+
+ ds0 = s - 0.5; ds1 = -2.0 * s; ds2 = s + 0.5;
+ dt0 = t - 0.5; dt1 = -2.0 * t; dt2 = t + 0.5;
+
+ ElementType_GetFaceNodes( self, mesh, element_I, face_I, 9, nodes );
+
+ for( node_i = 0; node_i < 9; node_i++ ) {
+ x[node_i] = Mesh_GetVertex( mesh, nodes[node_i] )[surfaceDim[0]];
+ y[node_i] = Mesh_GetVertex( mesh, nodes[node_i] )[surfaceDim[1]];
+ }
+
+ dxds = ds0*t0*x[0] + ds1*t0*x[1] + ds2*t0*x[2] + ds0*t1*x[3] + ds1*t1*x[4] + ds2*t1*x[5] + ds0*t2*x[6] + ds1*t2*x[7] + ds2*t2*x[8];
+ dxdt = s0*dt0*x[0] + s1*dt0*x[1] + s2*dt0*x[2] + s0*dt1*x[3] + s1*dt1*x[4] + s2*dt1*x[5] + s0*dt2*x[6] + s1*dt2*x[8] + s2*dt2*x[8];
+ dyds = ds0*t0*y[0] + ds1*t0*y[1] + ds2*t0*y[2] + ds0*t1*y[3] + ds1*t1*y[4] + ds2*t1*y[5] + ds0*t2*y[6] + ds1*t2*y[7] + ds2*t2*y[8];
+ dydt = s0*dt0*y[0] + s1*dt0*y[1] + s2*dt0*y[2] + s0*dt1*y[3] + s1*dt1*y[4] + s2*dt1*y[5] + s0*dt2*y[6] + s1*dt2*y[8] + s2*dt2*y[8];
+
+ detJac = dxds * dydt - dxdt * dyds;
+
+ return fabs( detJac );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/tests/C2GeneratorSuite.c
--- a/Discretisation/tests/C2GeneratorSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,681 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** Role:
-** Tests the C2GeneratorSuite
-**
-** $Id: testTemplate.c 3462 2006-02-19 06:53:24Z WalterLandry $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "pcu/pcu.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include "C2GeneratorSuite.h"
-
-typedef struct {
- Mesh* mesh;
-} C2GeneratorSuiteData;
-
-void C2GeneratorSuite_Setup( C2GeneratorSuiteData* data ) {
- C2Generator* gen;
- int nRanks;
- unsigned sizes[3];
- double minCrd[3];
- double maxCrd[3];
-
- Journal_Enable_AllTypedStream( False );
-
- insist( MPI_Comm_size( MPI_COMM_WORLD, &nRanks ), == MPI_SUCCESS );
- sizes[0] = sizes[1] = sizes[2] = nRanks * 4;
- minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
- maxCrd[0] = minCrd[1] = minCrd[2] = (double)nRanks;
-
- gen = C2Generator_New( "", NULL );
- MeshGenerator_SetDimSize( gen, 3 );
- CartesianGenerator_SetShadowDepth( gen, 1 );
- C2Generator_SetTopologyParams( gen, sizes, 0, NULL, NULL );
- CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
- Stg_Component_Build( gen, NULL, False );
- Stg_Component_Initialise( gen, NULL, False );
-
- data->mesh = Mesh_New( "", NULL );
- CartesianGenerator_Generate( gen, data->mesh, NULL );
- /* need 2 lines below to setup mesh */
- Stg_Component_Build( data->mesh, NULL, False );
- Stg_Component_Initialise( data->mesh, NULL, False );
-}
-
-void C2GeneratorSuite_Teardown( C2GeneratorSuiteData* data ) {
- Stg_Component_Destroy( data->mesh, NULL, True );
-}
-
-void C2GeneratorSuite_TestElementVertexInc( C2GeneratorSuiteData* data ) {
- unsigned dim = Mesh_GetDimSize( data->mesh );
- Sync* elSync = (Sync*)IGraph_GetDomain( (IGraph*)data->mesh->topo, dim );
- Sync* vertSync = (Sync*)IGraph_GetDomain( (IGraph*)data->mesh->topo, MT_VERTEX );
- Grid* elGrid = *(Grid**)Mesh_GetExtension( data->mesh, Grid**, "elementGrid" );
- Grid* vertGrid = *(Grid**)Mesh_GetExtension( data->mesh, Grid**, "vertexGrid" );
- IArray* inc = IArray_New();
- unsigned* incVerts;
- unsigned nIncVerts;
- unsigned el_i;
- unsigned gEl;
- unsigned dimInds[3];
- unsigned gNode0, gNode1, gNode2;
- int checkNodes;
-
- for( el_i = 0; el_i < Mesh_GetLocalSize( data->mesh, (MeshTopology_Dim)dim ); el_i++ ) {
- gEl = Sync_DomainToGlobal( elSync, el_i );
- Grid_Lift( elGrid, gEl, dimInds );
- dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
-
- MeshTopology_GetIncidence( (IGraph*)data->mesh->topo, dim, el_i, MT_VERTEX, inc );
- nIncVerts = IArray_GetSize( inc );
- incVerts = (unsigned*)IArray_GetPtr( inc );
-
- pcu_check_true( nIncVerts == 27 );
-
- gNode0 = Grid_Project( vertGrid, dimInds );
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[0] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2; gNode0 += vertGrid->sizes[0];
- dimInds[0] -= 2; dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[3] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[4] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[5] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2; gNode0 += vertGrid->sizes[0];
- dimInds[0] -= 2; dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[6] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[7] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[8] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2; gNode0 -= 2 * vertGrid->sizes[0]; gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
- dimInds[0] -= 2; dimInds[1] -= 2; dimInds[2]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[9] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[10] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[11] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2; gNode0 += vertGrid->sizes[0];
- dimInds[0] -= 2; dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[12] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[13] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[14] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2; gNode0 += vertGrid->sizes[0];
- dimInds[0] -= 2; dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[15] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[16] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[17] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2; gNode0 -= 2 * vertGrid->sizes[0]; gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
- dimInds[0] -= 2; dimInds[1] -= 2; dimInds[2]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[18] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[19] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[20] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2; gNode0 += vertGrid->sizes[0];
- dimInds[0] -= 2; dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[21] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[22] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[23] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2; gNode0 += vertGrid->sizes[0];
- dimInds[0] -= 2; dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[24] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[25] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[26] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
- }
-
- NewClass_Delete( inc );
-}
-
-void C2GeneratorSuite_TestEdgeVertexInc( C2GeneratorSuiteData* data ) {
- Grid* elGrid = *(Grid**)Mesh_GetExtension( data->mesh, Grid**, "elementGrid" );
- Grid* vertGrid = *(Grid**)Mesh_GetExtension( data->mesh, Grid**, "vertexGrid" );
- Grid* edgeGrid_0 = Grid_New();
- Grid* edgeGrid_1 = Grid_New();
- Grid* edgeGrid_2 = Grid_New();
- Sync* vertSync = (Sync*)IGraph_GetDomain( (IGraph*)data->mesh->topo, MT_VERTEX );
- Sync* edgeSync = (Sync*)IGraph_GetDomain( (IGraph*)data->mesh->topo, MT_EDGE );
- IArray* inc = IArray_New();
- unsigned* incVerts;
- unsigned nIncVerts;
- unsigned dim = ((IGraph*)data->mesh->topo)->nDims;
- unsigned sizes[3];
- unsigned edge_i;
- unsigned gEdge;
- unsigned dimInds[3];
- unsigned gNode0, gNode1, gNode2;
- int checkNodes;
-
- sizes[0] = elGrid->sizes[0];
- sizes[1] = elGrid->sizes[1] + 1;
- sizes[2] = elGrid->sizes[2] + 1;
- Grid_SetNumDims( edgeGrid_0, dim );
- Grid_SetSizes( edgeGrid_0, sizes );
- sizes[0] = elGrid->sizes[0] + 1;
- sizes[1] = elGrid->sizes[1];
- sizes[2] = elGrid->sizes[2] + 1;
- Grid_SetNumDims( edgeGrid_1, dim );
- Grid_SetSizes( edgeGrid_1, sizes );
- sizes[0] = elGrid->sizes[0] + 1;
- sizes[1] = elGrid->sizes[1] + 1;
- sizes[2] = elGrid->sizes[2];
- Grid_SetNumDims( edgeGrid_2, dim );
- Grid_SetSizes( edgeGrid_2, sizes );
-
- for( edge_i = 0; edge_i < Sync_GetNumDomains( edgeSync ); edge_i++ ) {
- gEdge = Sync_DomainToGlobal( edgeSync, edge_i );
-
- MeshTopology_GetIncidence( (IGraph*)data->mesh->topo, MT_EDGE, edge_i, MT_VERTEX, inc );
- nIncVerts = IArray_GetSize( inc );
- incVerts = (unsigned*)IArray_GetPtr( inc );
-
- pcu_check_true( nIncVerts == 3 );
-
- if( gEdge < edgeGrid_0->nPoints ) {
- Grid_Lift( edgeGrid_0, gEdge, dimInds );
- dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
-
- gNode0 = Grid_Project( vertGrid, dimInds );
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[0] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
- }
- else if( gEdge < edgeGrid_0->nPoints + edgeGrid_1->nPoints ) {
- Grid_Lift( edgeGrid_1, gEdge - edgeGrid_0->nPoints, dimInds );
- dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
-
- gNode0 = Grid_Project( vertGrid, dimInds );
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 += vertGrid->sizes[0];
- dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 += vertGrid->sizes[0];
- dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
- }
- else if( gEdge < edgeGrid_0->nPoints + edgeGrid_1->nPoints + edgeGrid_2->nPoints ) {
- Grid_Lift( edgeGrid_2, gEdge - edgeGrid_0->nPoints - edgeGrid_1->nPoints, dimInds );
- dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
-
- gNode0 = Grid_Project( vertGrid, dimInds );
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[0] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
- dimInds[2]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
- dimInds[2]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
- }
- }
-
- FreeObject( edgeGrid_0 );
- FreeObject( edgeGrid_1 );
- FreeObject( edgeGrid_2 );
-
- NewClass_Delete( inc );
-}
-
-void C2GeneratorSuite_TestFaceVertexInc( C2GeneratorSuiteData* data ) {
- Grid* elGrid = *(Grid**)Mesh_GetExtension( data->mesh, Grid**, "elementGrid" );
- Grid* vertGrid = *(Grid**)Mesh_GetExtension( data->mesh, Grid**, "vertexGrid" );
- Grid* faceGrid_0 = Grid_New();
- Grid* faceGrid_1 = Grid_New();
- Grid* faceGrid_2 = Grid_New();
- Sync* vertSync = (Sync*)IGraph_GetDomain( (IGraph*)data->mesh->topo, MT_VERTEX );
- Sync* faceSync = (Sync*)IGraph_GetDomain( (IGraph*)data->mesh->topo, MT_FACE );
- IArray* inc = IArray_New();
- unsigned* incVerts;
- unsigned nIncVerts;
- unsigned dim = ((IGraph*)data->mesh->topo)->nDims;
- unsigned sizes[3];
- unsigned face_i;
- unsigned gFace;
- unsigned dimInds[3];
- unsigned gNode0, gNode1, gNode2;
- int checkNodes;
-
- sizes[0] = elGrid->sizes[0];
- sizes[1] = elGrid->sizes[1];
- sizes[2] = elGrid->sizes[2] + 1;
- Grid_SetNumDims( faceGrid_0, dim );
- Grid_SetSizes( faceGrid_0, sizes );
- sizes[0] = elGrid->sizes[0];
- sizes[1] = elGrid->sizes[1] + 1;
- sizes[2] = elGrid->sizes[2];
- Grid_SetNumDims( faceGrid_1, dim );
- Grid_SetSizes( faceGrid_1, sizes );
- sizes[0] = elGrid->sizes[0] + 1;
- sizes[1] = elGrid->sizes[1];
- sizes[2] = elGrid->sizes[2];
- Grid_SetNumDims( faceGrid_2, dim );
- Grid_SetSizes( faceGrid_2, sizes );
-
- for( face_i = 0; face_i < ((IGraph*)data->mesh->topo)->remotes[MT_FACE]->nDomains; face_i++ ) {
- gFace = Sync_DomainToGlobal( faceSync, face_i );
-
- MeshTopology_GetIncidence( (IGraph*)data->mesh->topo, MT_FACE, face_i, MT_VERTEX, inc );
- nIncVerts = IArray_GetSize( inc );
- incVerts = (unsigned*)IArray_GetPtr( inc );
-
- pcu_check_true( nIncVerts == 9 );
-
- if( gFace < faceGrid_0->nPoints ) {
- Grid_Lift( faceGrid_0, gFace, dimInds );
- dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
-
- gNode0 = Grid_Project( vertGrid, dimInds );
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[0] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2; gNode0 += vertGrid->sizes[0];
- dimInds[0] -= 2; dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[3] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[4] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[5] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2; gNode0 += vertGrid->sizes[0];
- dimInds[0] -= 2; dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[6] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[7] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[8] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
- }
- else if( gFace < faceGrid_0->nPoints + faceGrid_1->nPoints ) {
- Grid_Lift( faceGrid_1, gFace - faceGrid_0->nPoints, dimInds );
- dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
-
- gNode0 = Grid_Project( vertGrid, dimInds );
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[0] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2; gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
- dimInds[0] -= 2; dimInds[2]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[3] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[4] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[5] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2; gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
- dimInds[0] -= 2; dimInds[2]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[6] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[7] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0++;
- dimInds[0]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[8] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
- }
- else if( gFace < faceGrid_0->nPoints + faceGrid_1->nPoints + faceGrid_2->nPoints ) {
- Grid_Lift( faceGrid_2, gFace - faceGrid_0->nPoints - faceGrid_1->nPoints, dimInds );
- dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
-
- gNode0 = Grid_Project( vertGrid, dimInds );
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[0] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 += vertGrid->sizes[0];
- dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 += vertGrid->sizes[0];
- dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2 * vertGrid->sizes[0]; gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
- dimInds[1] -= 2; dimInds[2]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[3] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 += vertGrid->sizes[0];
- dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[4] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 += vertGrid->sizes[0];
- dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[5] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 -= 2 * vertGrid->sizes[0]; gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
- dimInds[1] -= 2; dimInds[2]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[6] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 += vertGrid->sizes[0];
- dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[7] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
-
- gNode0 += vertGrid->sizes[0];
- dimInds[1]++;
- gNode1 = Grid_Project( vertGrid, dimInds );
- gNode2 = Sync_DomainToGlobal( vertSync, incVerts[8] );
- checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
- pcu_check_true( checkNodes );
- }
- }
-
- FreeObject( faceGrid_0 );
- FreeObject( faceGrid_1 );
- FreeObject( faceGrid_2 );
-
- NewClass_Delete( inc );
-}
-void C2GeneratorSuite( pcu_suite_t* suite ) {
- pcu_suite_setData( suite, C2GeneratorSuiteData );
- pcu_suite_setFixtures( suite, C2GeneratorSuite_Setup, C2GeneratorSuite_Teardown );
- pcu_suite_addTest( suite, C2GeneratorSuite_TestElementVertexInc );
- pcu_suite_addTest( suite, C2GeneratorSuite_TestEdgeVertexInc );
- pcu_suite_addTest( suite, C2GeneratorSuite_TestFaceVertexInc );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/tests/C2GeneratorSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/tests/C2GeneratorSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,681 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** Role:
+** Tests the C2GeneratorSuite
+**
+** $Id: testTemplate.c 3462 2006-02-19 06:53:24Z WalterLandry $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pcu/pcu.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include "C2GeneratorSuite.h"
+
+typedef struct {
+ Mesh* mesh;
+} C2GeneratorSuiteData;
+
+void C2GeneratorSuite_Setup( C2GeneratorSuiteData* data ) {
+ C2Generator* gen;
+ int nRanks;
+ unsigned sizes[3];
+ double minCrd[3];
+ double maxCrd[3];
+
+ Journal_Enable_AllTypedStream( False );
+
+ insist( MPI_Comm_size( MPI_COMM_WORLD, &nRanks ), == MPI_SUCCESS );
+ sizes[0] = sizes[1] = sizes[2] = nRanks * 4;
+ minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
+ maxCrd[0] = minCrd[1] = minCrd[2] = (double)nRanks;
+
+ gen = C2Generator_New( "", NULL );
+ MeshGenerator_SetDimSize( gen, 3 );
+ CartesianGenerator_SetShadowDepth( gen, 1 );
+ C2Generator_SetTopologyParams( gen, sizes, 0, NULL, NULL );
+ CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+ Stg_Component_Build( gen, NULL, False );
+ Stg_Component_Initialise( gen, NULL, False );
+
+ data->mesh = Mesh_New( "", NULL );
+ CartesianGenerator_Generate( gen, data->mesh, NULL );
+ /* need 2 lines below to setup mesh */
+ Stg_Component_Build( data->mesh, NULL, False );
+ Stg_Component_Initialise( data->mesh, NULL, False );
+}
+
+void C2GeneratorSuite_Teardown( C2GeneratorSuiteData* data ) {
+ Stg_Component_Destroy( data->mesh, NULL, True );
+}
+
+void C2GeneratorSuite_TestElementVertexInc( C2GeneratorSuiteData* data ) {
+ unsigned dim = Mesh_GetDimSize( data->mesh );
+ Sync* elSync = (Sync*)IGraph_GetDomain( (IGraph*)data->mesh->topo, dim );
+ Sync* vertSync = (Sync*)IGraph_GetDomain( (IGraph*)data->mesh->topo, MT_VERTEX );
+ Grid* elGrid = *(Grid**)Mesh_GetExtension( data->mesh, Grid**, "elementGrid" );
+ Grid* vertGrid = *(Grid**)Mesh_GetExtension( data->mesh, Grid**, "vertexGrid" );
+ IArray* inc = IArray_New();
+ unsigned* incVerts;
+ unsigned nIncVerts;
+ unsigned el_i;
+ unsigned gEl;
+ unsigned dimInds[3];
+ unsigned gNode0, gNode1, gNode2;
+ int checkNodes;
+
+ for( el_i = 0; el_i < Mesh_GetLocalSize( data->mesh, (MeshTopology_Dim)dim ); el_i++ ) {
+ gEl = Sync_DomainToGlobal( elSync, el_i );
+ Grid_Lift( elGrid, gEl, dimInds );
+ dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
+
+ MeshTopology_GetIncidence( (IGraph*)data->mesh->topo, dim, el_i, MT_VERTEX, inc );
+ nIncVerts = IArray_GetSize( inc );
+ incVerts = (unsigned*)IArray_GetPtr( inc );
+
+ pcu_check_true( nIncVerts == 27 );
+
+ gNode0 = Grid_Project( vertGrid, dimInds );
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[0] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2; gNode0 += vertGrid->sizes[0];
+ dimInds[0] -= 2; dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[3] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[4] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[5] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2; gNode0 += vertGrid->sizes[0];
+ dimInds[0] -= 2; dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[6] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[7] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[8] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2; gNode0 -= 2 * vertGrid->sizes[0]; gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
+ dimInds[0] -= 2; dimInds[1] -= 2; dimInds[2]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[9] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[10] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[11] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2; gNode0 += vertGrid->sizes[0];
+ dimInds[0] -= 2; dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[12] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[13] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[14] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2; gNode0 += vertGrid->sizes[0];
+ dimInds[0] -= 2; dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[15] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[16] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[17] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2; gNode0 -= 2 * vertGrid->sizes[0]; gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
+ dimInds[0] -= 2; dimInds[1] -= 2; dimInds[2]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[18] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[19] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[20] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2; gNode0 += vertGrid->sizes[0];
+ dimInds[0] -= 2; dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[21] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[22] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[23] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2; gNode0 += vertGrid->sizes[0];
+ dimInds[0] -= 2; dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[24] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[25] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[26] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+ }
+
+ NewClass_Delete( inc );
+}
+
+void C2GeneratorSuite_TestEdgeVertexInc( C2GeneratorSuiteData* data ) {
+ Grid* elGrid = *(Grid**)Mesh_GetExtension( data->mesh, Grid**, "elementGrid" );
+ Grid* vertGrid = *(Grid**)Mesh_GetExtension( data->mesh, Grid**, "vertexGrid" );
+ Grid* edgeGrid_0 = Grid_New();
+ Grid* edgeGrid_1 = Grid_New();
+ Grid* edgeGrid_2 = Grid_New();
+ Sync* vertSync = (Sync*)IGraph_GetDomain( (IGraph*)data->mesh->topo, MT_VERTEX );
+ Sync* edgeSync = (Sync*)IGraph_GetDomain( (IGraph*)data->mesh->topo, MT_EDGE );
+ IArray* inc = IArray_New();
+ unsigned* incVerts;
+ unsigned nIncVerts;
+ unsigned dim = ((IGraph*)data->mesh->topo)->nDims;
+ unsigned sizes[3];
+ unsigned edge_i;
+ unsigned gEdge;
+ unsigned dimInds[3];
+ unsigned gNode0, gNode1, gNode2;
+ int checkNodes;
+
+ sizes[0] = elGrid->sizes[0];
+ sizes[1] = elGrid->sizes[1] + 1;
+ sizes[2] = elGrid->sizes[2] + 1;
+ Grid_SetNumDims( edgeGrid_0, dim );
+ Grid_SetSizes( edgeGrid_0, sizes );
+ sizes[0] = elGrid->sizes[0] + 1;
+ sizes[1] = elGrid->sizes[1];
+ sizes[2] = elGrid->sizes[2] + 1;
+ Grid_SetNumDims( edgeGrid_1, dim );
+ Grid_SetSizes( edgeGrid_1, sizes );
+ sizes[0] = elGrid->sizes[0] + 1;
+ sizes[1] = elGrid->sizes[1] + 1;
+ sizes[2] = elGrid->sizes[2];
+ Grid_SetNumDims( edgeGrid_2, dim );
+ Grid_SetSizes( edgeGrid_2, sizes );
+
+ for( edge_i = 0; edge_i < Sync_GetNumDomains( edgeSync ); edge_i++ ) {
+ gEdge = Sync_DomainToGlobal( edgeSync, edge_i );
+
+ MeshTopology_GetIncidence( (IGraph*)data->mesh->topo, MT_EDGE, edge_i, MT_VERTEX, inc );
+ nIncVerts = IArray_GetSize( inc );
+ incVerts = (unsigned*)IArray_GetPtr( inc );
+
+ pcu_check_true( nIncVerts == 3 );
+
+ if( gEdge < edgeGrid_0->nPoints ) {
+ Grid_Lift( edgeGrid_0, gEdge, dimInds );
+ dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
+
+ gNode0 = Grid_Project( vertGrid, dimInds );
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[0] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+ }
+ else if( gEdge < edgeGrid_0->nPoints + edgeGrid_1->nPoints ) {
+ Grid_Lift( edgeGrid_1, gEdge - edgeGrid_0->nPoints, dimInds );
+ dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
+
+ gNode0 = Grid_Project( vertGrid, dimInds );
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 += vertGrid->sizes[0];
+ dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 += vertGrid->sizes[0];
+ dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+ }
+ else if( gEdge < edgeGrid_0->nPoints + edgeGrid_1->nPoints + edgeGrid_2->nPoints ) {
+ Grid_Lift( edgeGrid_2, gEdge - edgeGrid_0->nPoints - edgeGrid_1->nPoints, dimInds );
+ dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
+
+ gNode0 = Grid_Project( vertGrid, dimInds );
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[0] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
+ dimInds[2]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
+ dimInds[2]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+ }
+ }
+
+ FreeObject( edgeGrid_0 );
+ FreeObject( edgeGrid_1 );
+ FreeObject( edgeGrid_2 );
+
+ NewClass_Delete( inc );
+}
+
+void C2GeneratorSuite_TestFaceVertexInc( C2GeneratorSuiteData* data ) {
+ Grid* elGrid = *(Grid**)Mesh_GetExtension( data->mesh, Grid**, "elementGrid" );
+ Grid* vertGrid = *(Grid**)Mesh_GetExtension( data->mesh, Grid**, "vertexGrid" );
+ Grid* faceGrid_0 = Grid_New();
+ Grid* faceGrid_1 = Grid_New();
+ Grid* faceGrid_2 = Grid_New();
+ Sync* vertSync = (Sync*)IGraph_GetDomain( (IGraph*)data->mesh->topo, MT_VERTEX );
+ Sync* faceSync = (Sync*)IGraph_GetDomain( (IGraph*)data->mesh->topo, MT_FACE );
+ IArray* inc = IArray_New();
+ unsigned* incVerts;
+ unsigned nIncVerts;
+ unsigned dim = ((IGraph*)data->mesh->topo)->nDims;
+ unsigned sizes[3];
+ unsigned face_i;
+ unsigned gFace;
+ unsigned dimInds[3];
+ unsigned gNode0, gNode1, gNode2;
+ int checkNodes;
+
+ sizes[0] = elGrid->sizes[0];
+ sizes[1] = elGrid->sizes[1];
+ sizes[2] = elGrid->sizes[2] + 1;
+ Grid_SetNumDims( faceGrid_0, dim );
+ Grid_SetSizes( faceGrid_0, sizes );
+ sizes[0] = elGrid->sizes[0];
+ sizes[1] = elGrid->sizes[1] + 1;
+ sizes[2] = elGrid->sizes[2];
+ Grid_SetNumDims( faceGrid_1, dim );
+ Grid_SetSizes( faceGrid_1, sizes );
+ sizes[0] = elGrid->sizes[0] + 1;
+ sizes[1] = elGrid->sizes[1];
+ sizes[2] = elGrid->sizes[2];
+ Grid_SetNumDims( faceGrid_2, dim );
+ Grid_SetSizes( faceGrid_2, sizes );
+
+ for( face_i = 0; face_i < ((IGraph*)data->mesh->topo)->remotes[MT_FACE]->nDomains; face_i++ ) {
+ gFace = Sync_DomainToGlobal( faceSync, face_i );
+
+ MeshTopology_GetIncidence( (IGraph*)data->mesh->topo, MT_FACE, face_i, MT_VERTEX, inc );
+ nIncVerts = IArray_GetSize( inc );
+ incVerts = (unsigned*)IArray_GetPtr( inc );
+
+ pcu_check_true( nIncVerts == 9 );
+
+ if( gFace < faceGrid_0->nPoints ) {
+ Grid_Lift( faceGrid_0, gFace, dimInds );
+ dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
+
+ gNode0 = Grid_Project( vertGrid, dimInds );
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[0] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2; gNode0 += vertGrid->sizes[0];
+ dimInds[0] -= 2; dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[3] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[4] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[5] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2; gNode0 += vertGrid->sizes[0];
+ dimInds[0] -= 2; dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[6] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[7] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[8] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+ }
+ else if( gFace < faceGrid_0->nPoints + faceGrid_1->nPoints ) {
+ Grid_Lift( faceGrid_1, gFace - faceGrid_0->nPoints, dimInds );
+ dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
+
+ gNode0 = Grid_Project( vertGrid, dimInds );
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[0] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2; gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
+ dimInds[0] -= 2; dimInds[2]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[3] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[4] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[5] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2; gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
+ dimInds[0] -= 2; dimInds[2]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[6] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[7] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0++;
+ dimInds[0]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[8] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+ }
+ else if( gFace < faceGrid_0->nPoints + faceGrid_1->nPoints + faceGrid_2->nPoints ) {
+ Grid_Lift( faceGrid_2, gFace - faceGrid_0->nPoints - faceGrid_1->nPoints, dimInds );
+ dimInds[0] *= 2; dimInds[1] *= 2; dimInds[2] *= 2;
+
+ gNode0 = Grid_Project( vertGrid, dimInds );
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[0] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 += vertGrid->sizes[0];
+ dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[1] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 += vertGrid->sizes[0];
+ dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[2] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2 * vertGrid->sizes[0]; gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
+ dimInds[1] -= 2; dimInds[2]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[3] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 += vertGrid->sizes[0];
+ dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[4] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 += vertGrid->sizes[0];
+ dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[5] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 -= 2 * vertGrid->sizes[0]; gNode0 += vertGrid->sizes[0] * vertGrid->sizes[1];
+ dimInds[1] -= 2; dimInds[2]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[6] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 += vertGrid->sizes[0];
+ dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[7] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+
+ gNode0 += vertGrid->sizes[0];
+ dimInds[1]++;
+ gNode1 = Grid_Project( vertGrid, dimInds );
+ gNode2 = Sync_DomainToGlobal( vertSync, incVerts[8] );
+ checkNodes = (gNode0 == gNode1) && (gNode1 == gNode2);
+ pcu_check_true( checkNodes );
+ }
+ }
+
+ FreeObject( faceGrid_0 );
+ FreeObject( faceGrid_1 );
+ FreeObject( faceGrid_2 );
+
+ NewClass_Delete( inc );
+}
+void C2GeneratorSuite( pcu_suite_t* suite ) {
+ pcu_suite_setData( suite, C2GeneratorSuiteData );
+ pcu_suite_setFixtures( suite, C2GeneratorSuite_Setup, C2GeneratorSuite_Teardown );
+ pcu_suite_addTest( suite, C2GeneratorSuite_TestElementVertexInc );
+ pcu_suite_addTest( suite, C2GeneratorSuite_TestEdgeVertexInc );
+ pcu_suite_addTest( suite, C2GeneratorSuite_TestFaceVertexInc );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/tests/ElementTypeRegisterSuite.c
--- a/Discretisation/tests/ElementTypeRegisterSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** Role:
-** Tests the ElementTypeRegisterSuite
-**
-** $Id: testElementTypeRegister.c 3462 2006-02-19 06:53:24Z WalterLandry $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "pcu/pcu.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include "ElementTypeRegisterSuite.h"
-
-typedef struct {
- ElementType_Register* etReg;
-} ElementTypeRegisterSuiteData;
-
-void ElementTypeRegisterSuite_Setup( ElementTypeRegisterSuiteData* data ) {
- data->etReg = ElementType_Register_New( "elementType_Register" );
-
- Journal_Enable_AllTypedStream( False );
-
- _ElementType_Register_Init( data->etReg );
-
- ElementType_Register_Add( data->etReg, (ElementType*)ConstantElementType_New( "constant" ) );
- ElementType_Register_Add( data->etReg, (ElementType*)BilinearElementType_New( "bilinear" ) );
- ElementType_Register_Add( data->etReg, (ElementType*)TrilinearElementType_New( "trilinear" ) );
- ElementType_Register_Add( data->etReg, (ElementType*)Biquadratic_New( "biquadratic" ) );
- ElementType_Register_Add( data->etReg, (ElementType*)Triquadratic_New( "triquadratic" ) );
-}
-
-void ElementTypeRegisterSuite_Teardown( ElementTypeRegisterSuiteData* data ) {
- Stg_Class_Delete( data->etReg );
-}
-
-void ElementTypeRegisterSuite_Test( ElementTypeRegisterSuiteData* data ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(ConstantElementType);
- Type type = "TestElementType_0";
- Stg_Class_DeleteFunction* _delete = _ConstantElementType_Delete;
- Stg_Class_PrintFunction* _print = _ConstantElementType_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = ConstantElementType_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _ConstantElementType_AssignFromXML;
- Stg_Component_BuildFunction* _build = _ConstantElementType_Build;
- Stg_Component_InitialiseFunction* _initialise = _ConstantElementType_Initialise;
- Stg_Component_ExecuteFunction* _execute = _ConstantElementType_Execute;
- Stg_Component_DestroyFunction* _destroy = _ConstantElementType_Destroy;
- Name name = "TestElementType_0_Name";
- AllocationType nameAllocationType = NON_GLOBAL;
- ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _ConstantElementType_SF_allNodes;
- ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _ConstantElementType_SF_allLocalDerivs_allNodes;
- ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ConstantElementType_ConvertGlobalCoordToElLocal;
- ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _ElementType_JacobianDeterminantSurface;
- ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
-
- ElementType* elType;
- //unsigned numTypes = data->etReg->count;
- unsigned newIndex;
- unsigned testIndex;
-
- /* manually create extra types to test the list re-sizing */
- newIndex = ElementType_Register_Add( data->etReg, _ElementType_New( ELEMENTTYPE_PASSARGS ) );
- pcu_check_true( newIndex == data->etReg->count - 1 );
-
- type = "TestElementType_1";
- name = "TestElementType_1_Name";
-
- newIndex = ElementType_Register_Add( data->etReg, _ElementType_New( ELEMENTTYPE_PASSARGS ) );
- pcu_check_true( newIndex == data->etReg->count - 1 );
-
- type = "TestElementType_2";
- name = "TestElementType_2_Name";
-
- newIndex = ElementType_Register_Add( data->etReg, _ElementType_New( ELEMENTTYPE_PASSARGS ) );
- pcu_check_true( newIndex == data->etReg->count - 1 );
-
- testIndex = ElementType_Register_GetIndex( data->etReg, ConstantElementType_Type );
- elType = ElementType_Register_At( data->etReg, testIndex );
- pcu_check_true( !strcmp( elType->type, ConstantElementType_Type ) );
-
- testIndex = ElementType_Register_GetIndex( data->etReg, BilinearElementType_Type );
- elType = ElementType_Register_At( data->etReg, testIndex );
- pcu_check_true( !strcmp( elType->type, BilinearElementType_Type ) );
-
- testIndex = ElementType_Register_GetIndex( data->etReg, TrilinearElementType_Type );
- elType = ElementType_Register_At( data->etReg, testIndex );
- pcu_check_true( !strcmp( elType->type, TrilinearElementType_Type ) );
-
- testIndex = ElementType_Register_GetIndex( data->etReg, Biquadratic_Type );
- elType = ElementType_Register_At( data->etReg, testIndex );
- pcu_check_true( !strcmp( elType->type, Biquadratic_Type ) );
-
- testIndex = ElementType_Register_GetIndex( data->etReg, Triquadratic_Type );
- elType = ElementType_Register_At( data->etReg, testIndex );
- pcu_check_true( !strcmp( elType->type, Triquadratic_Type ) );
-}
-
-void ElementTypeRegisterSuite( pcu_suite_t* suite ) {
- pcu_suite_setData( suite, ElementTypeRegisterSuiteData );
- pcu_suite_setFixtures( suite, ElementTypeRegisterSuite_Setup, ElementTypeRegisterSuite_Teardown );
- pcu_suite_addTest( suite, ElementTypeRegisterSuite_Test );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/tests/ElementTypeRegisterSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/tests/ElementTypeRegisterSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,134 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** Role:
+** Tests the ElementTypeRegisterSuite
+**
+** $Id: testElementTypeRegister.c 3462 2006-02-19 06:53:24Z WalterLandry $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pcu/pcu.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include "ElementTypeRegisterSuite.h"
+
+typedef struct {
+ ElementType_Register* etReg;
+} ElementTypeRegisterSuiteData;
+
+void ElementTypeRegisterSuite_Setup( ElementTypeRegisterSuiteData* data ) {
+ data->etReg = ElementType_Register_New( "elementType_Register" );
+
+ Journal_Enable_AllTypedStream( False );
+
+ _ElementType_Register_Init( data->etReg );
+
+ ElementType_Register_Add( data->etReg, (ElementType*)ConstantElementType_New( "constant" ) );
+ ElementType_Register_Add( data->etReg, (ElementType*)BilinearElementType_New( "bilinear" ) );
+ ElementType_Register_Add( data->etReg, (ElementType*)TrilinearElementType_New( "trilinear" ) );
+ ElementType_Register_Add( data->etReg, (ElementType*)Biquadratic_New( "biquadratic" ) );
+ ElementType_Register_Add( data->etReg, (ElementType*)Triquadratic_New( "triquadratic" ) );
+}
+
+void ElementTypeRegisterSuite_Teardown( ElementTypeRegisterSuiteData* data ) {
+ Stg_Class_Delete( data->etReg );
+}
+
+void ElementTypeRegisterSuite_Test( ElementTypeRegisterSuiteData* data ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(ConstantElementType);
+ Type type = "TestElementType_0";
+ Stg_Class_DeleteFunction* _delete = _ConstantElementType_Delete;
+ Stg_Class_PrintFunction* _print = _ConstantElementType_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = ConstantElementType_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _ConstantElementType_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _ConstantElementType_Build;
+ Stg_Component_InitialiseFunction* _initialise = _ConstantElementType_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _ConstantElementType_Execute;
+ Stg_Component_DestroyFunction* _destroy = _ConstantElementType_Destroy;
+ Name name = "TestElementType_0_Name";
+ AllocationType nameAllocationType = NON_GLOBAL;
+ ElementType_EvaluateShapeFunctionsAtFunction* _evaluateShapeFunctionsAt = _ConstantElementType_SF_allNodes;
+ ElementType_EvaluateShapeFunctionLocalDerivsAtFunction* _evaluateShapeFunctionLocalDerivsAt = _ConstantElementType_SF_allLocalDerivs_allNodes;
+ ElementType_ConvertGlobalCoordToElLocalFunction* _convertGlobalCoordToElLocal = _ConstantElementType_ConvertGlobalCoordToElLocal;
+ ElementType_JacobianDeterminantSurfaceFunction* _jacobianDeterminantSurface = _ElementType_JacobianDeterminantSurface;
+ ElementType_SurfaceNormalFunction* _surfaceNormal = _ElementType_SurfaceNormal;
+
+ ElementType* elType;
+ //unsigned numTypes = data->etReg->count;
+ unsigned newIndex;
+ unsigned testIndex;
+
+ /* manually create extra types to test the list re-sizing */
+ newIndex = ElementType_Register_Add( data->etReg, _ElementType_New( ELEMENTTYPE_PASSARGS ) );
+ pcu_check_true( newIndex == data->etReg->count - 1 );
+
+ type = "TestElementType_1";
+ name = "TestElementType_1_Name";
+
+ newIndex = ElementType_Register_Add( data->etReg, _ElementType_New( ELEMENTTYPE_PASSARGS ) );
+ pcu_check_true( newIndex == data->etReg->count - 1 );
+
+ type = "TestElementType_2";
+ name = "TestElementType_2_Name";
+
+ newIndex = ElementType_Register_Add( data->etReg, _ElementType_New( ELEMENTTYPE_PASSARGS ) );
+ pcu_check_true( newIndex == data->etReg->count - 1 );
+
+ testIndex = ElementType_Register_GetIndex( data->etReg, ConstantElementType_Type );
+ elType = ElementType_Register_At( data->etReg, testIndex );
+ pcu_check_true( !strcmp( elType->type, ConstantElementType_Type ) );
+
+ testIndex = ElementType_Register_GetIndex( data->etReg, BilinearElementType_Type );
+ elType = ElementType_Register_At( data->etReg, testIndex );
+ pcu_check_true( !strcmp( elType->type, BilinearElementType_Type ) );
+
+ testIndex = ElementType_Register_GetIndex( data->etReg, TrilinearElementType_Type );
+ elType = ElementType_Register_At( data->etReg, testIndex );
+ pcu_check_true( !strcmp( elType->type, TrilinearElementType_Type ) );
+
+ testIndex = ElementType_Register_GetIndex( data->etReg, Biquadratic_Type );
+ elType = ElementType_Register_At( data->etReg, testIndex );
+ pcu_check_true( !strcmp( elType->type, Biquadratic_Type ) );
+
+ testIndex = ElementType_Register_GetIndex( data->etReg, Triquadratic_Type );
+ elType = ElementType_Register_At( data->etReg, testIndex );
+ pcu_check_true( !strcmp( elType->type, Triquadratic_Type ) );
+}
+
+void ElementTypeRegisterSuite( pcu_suite_t* suite ) {
+ pcu_suite_setData( suite, ElementTypeRegisterSuiteData );
+ pcu_suite_setFixtures( suite, ElementTypeRegisterSuite_Setup, ElementTypeRegisterSuite_Teardown );
+ pcu_suite_addTest( suite, ElementTypeRegisterSuite_Test );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/tests/ElementTypeSuite.c
--- a/Discretisation/tests/ElementTypeSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,559 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** Role:
-** Tests the ElementTypeSuite
-**
-** $Id: testElementType.c 3462 2006-02-19 06:53:24Z WalterLandry $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "pcu/pcu.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include "ElementTypeSuite.h"
-
-#define TOLERANCE 1.0e-8
-#define EPSILON 1.0e-8
-
-typedef struct {
- Dictionary* dict;
-} ElementTypeSuiteData;
-
-FeMesh* BuildMeshLinear( unsigned nDims, unsigned* sizes, double* minCrd, double* maxCrd ) {
- CartesianGenerator* gen;
- FeMesh* feMesh;
- unsigned maxDecomp[3] = {0, 1, 1};
-
- gen = CartesianGenerator_New( "", NULL );
- CartesianGenerator_SetDimSize( gen, nDims );
- CartesianGenerator_SetTopologyParams( gen, sizes, 0, NULL, maxDecomp );
- CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
- CartesianGenerator_SetShadowDepth( gen, 0 );
-
- feMesh = FeMesh_New( "", NULL );
- Mesh_SetGenerator( feMesh, gen );
- FeMesh_SetElementFamily( feMesh, "linear" );
- Stg_Component_Build( feMesh, NULL, False );
- Stg_Component_Initialise( feMesh, NULL, False );
-
- return feMesh;
-}
-
-FeMesh* BuildMeshQuadratic( unsigned nDims, unsigned* sizes, double* minCrd, double* maxCrd ) {
- CartesianGenerator* gen;
- FeMesh* feMesh;
- unsigned maxDecomp[3] = {0, 1, 1};
-
- gen = (CartesianGenerator*)C2Generator_New( "", NULL );
- CartesianGenerator_SetDimSize( gen, nDims );
- C2Generator_SetTopologyParams( gen, sizes, 0, NULL, maxDecomp );
- CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
- CartesianGenerator_SetShadowDepth( gen, 0 );
-
- feMesh = FeMesh_New( "", NULL );
- Mesh_SetGenerator( feMesh, gen );
- FeMesh_SetElementFamily( feMesh, "quadratic" );
- Stg_Component_Build( feMesh, NULL, False );
- Stg_Component_Initialise( feMesh, NULL, False );
-
- return feMesh;
-}
-
-void ElementTypeSuite_Setup( ElementTypeSuiteData* data ) {
- Journal_Enable_AllTypedStream( False );
-
- data->dict = Dictionary_New();
-}
-
-void ElementTypeSuite_Teardown( ElementTypeSuiteData* data ) {
- Stg_Class_Delete( data->dict );
-}
-
-void ElementTypeSuite_TestLinear2D( ElementTypeSuiteData* data ) {
- FeMesh* feMesh;
- unsigned maxTests = 40;
- unsigned test_i;
- Coord gCoord, lCoord, gCoord_fromLocal;
- unsigned el, elNodeCount, elNode_i;
- ElementType* elType;
- IArray* inc = IArray_New();
- unsigned* elNodes;
- double Ni[4];
- double vecNorm;
- int dim = 2;
- unsigned sizes[3] = { 6, 6, 1 };
- double minCrd[3] = { 0.0, 0.0, 0.0 };
- double maxCrd[3] = { 1.2, 1.2, 1.2 };
-
- feMesh = BuildMeshLinear( dim, sizes, minCrd, maxCrd );
-
- srand48( 0 );
- for( test_i = 0; test_i < maxTests; test_i++ ) {
- gCoord[I_AXIS] = drand48();
- gCoord[J_AXIS] = drand48();
-
- Mesh_Algorithms_SearchElements( feMesh->algorithms, gCoord, &el );
- elNodeCount = FeMesh_GetElementNodeSize( feMesh, el );
- elType = FeMesh_GetElementType( feMesh, el );
- _ElementType_ConvertGlobalCoordToElLocal( elType, feMesh, el, gCoord, lCoord );
- ElementType_EvaluateShapeFunctionsAt( elType, lCoord, Ni );
-
- Mesh_GetIncidence( feMesh, (MeshTopology_Dim)dim, el, MT_VERTEX, inc );
- elNodes = (unsigned*)IArray_GetPtr( inc );
- memset( gCoord_fromLocal, 0, sizeof( double ) * dim );
- for( elNode_i = 0; elNode_i < elNodeCount; elNode_i++ ) {
- gCoord_fromLocal[I_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][I_AXIS];
- gCoord_fromLocal[J_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][J_AXIS];
- }
-
- vecNorm = sqrt( (gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS])*(gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS]) +
- (gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS])*(gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS]) );
-
- pcu_check_true( vecNorm < TOLERANCE );
- }
-
- NewClass_Delete( inc );
- Stg_Component_Destroy( feMesh, NULL, True );
-}
-
-void ElementTypeSuite_TestLinear3D( ElementTypeSuiteData* data ) {
- FeMesh* feMesh;
- unsigned maxTests = 40;
- unsigned test_i;
- Coord gCoord, lCoord, gCoord_fromLocal;
- unsigned el, elNodeCount, elNode_i;
- ElementType* elType;
- IArray* inc = IArray_New();
- unsigned* elNodes;
- double Ni[8];
- double vecNorm;
- int dim = 3;
- unsigned sizes[3] = { 6, 6, 1 };
- double minCrd[3] = { 0.0, 0.0, 0.0 };
- double maxCrd[3] = { 1.2, 1.2, 1.2 };
-
- feMesh = BuildMeshLinear( dim, sizes, minCrd, maxCrd );
-
- srand48( 0 );
- for( test_i = 0; test_i < maxTests; test_i++ ) {
- gCoord[I_AXIS] = drand48();
- gCoord[J_AXIS] = drand48();
- gCoord[K_AXIS] = drand48();
-
- Mesh_Algorithms_SearchElements( feMesh->algorithms, gCoord, &el );
- elNodeCount = FeMesh_GetElementNodeSize( feMesh, el );
- elType = FeMesh_GetElementType( feMesh, el );
- _ElementType_ConvertGlobalCoordToElLocal( elType, feMesh, el, gCoord, lCoord );
- ElementType_EvaluateShapeFunctionsAt( elType, lCoord, Ni );
-
- Mesh_GetIncidence( feMesh, (MeshTopology_Dim)dim, el, MT_VERTEX, inc );
- elNodes = (unsigned*)IArray_GetPtr( inc );
- memset( gCoord_fromLocal, 0, sizeof( double ) * dim );
- for( elNode_i = 0; elNode_i < elNodeCount; elNode_i++ ) {
- gCoord_fromLocal[I_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][I_AXIS];
- gCoord_fromLocal[J_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][J_AXIS];
- gCoord_fromLocal[K_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][K_AXIS];
- }
-
- vecNorm = sqrt( (gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS])*(gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS]) +
- (gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS])*(gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS]) +
- (gCoord[K_AXIS] - gCoord_fromLocal[K_AXIS])*(gCoord[K_AXIS] - gCoord_fromLocal[K_AXIS]) );
-
- pcu_check_true( vecNorm < TOLERANCE );
- }
-
- NewClass_Delete( inc );
- Stg_Component_Destroy( feMesh, NULL, True );
-}
-
-void ElementTypeSuite_TestQuadratic2D( ElementTypeSuiteData* data ) {
- FeMesh* feMesh;
- unsigned maxTests = 40;
- unsigned test_i;
- Coord gCoord, lCoord, gCoord_fromLocal;
- unsigned el, elNodeCount, elNode_i;
- ElementType* elType;
- IArray* inc = IArray_New();
- unsigned* elNodes;
- double Ni[9];
- double vecNorm;
- int dim = 2;
- unsigned sizes[3] = { 6, 6, 1 };
- double minCrd[3] = { 0.0, 0.0, 0.0 };
- double maxCrd[3] = { 1.2, 1.2, 1.2 };
-
- feMesh = BuildMeshQuadratic( dim, sizes, minCrd, maxCrd );
-
- srand48( 0 );
- for( test_i = 0; test_i < maxTests; test_i++ ) {
- gCoord[I_AXIS] = drand48();
- gCoord[J_AXIS] = drand48();
-
- Mesh_Algorithms_SearchElements( feMesh->algorithms, gCoord, &el );
- elNodeCount = FeMesh_GetElementNodeSize( feMesh, el );
- elType = FeMesh_GetElementType( feMesh, el );
- _ElementType_ConvertGlobalCoordToElLocal( elType, feMesh, el, gCoord, lCoord );
- ElementType_EvaluateShapeFunctionsAt( elType, lCoord, Ni );
-
- Mesh_GetIncidence( feMesh, (MeshTopology_Dim)dim, el, MT_VERTEX, inc );
- elNodes = (unsigned*)IArray_GetPtr( inc );
- memset( gCoord_fromLocal, 0, sizeof( double ) * dim );
- for( elNode_i = 0; elNode_i < elNodeCount; elNode_i++ ) {
- gCoord_fromLocal[I_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][I_AXIS];
- gCoord_fromLocal[J_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][J_AXIS];
- }
-
- vecNorm = sqrt( (gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS])*(gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS]) +
- (gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS])*(gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS]) );
-
- pcu_check_true( vecNorm < TOLERANCE );
- }
-
- NewClass_Delete( inc );
- Stg_Component_Destroy( feMesh, NULL, True );
-}
-
-void ElementTypeSuite_TestQuadratic3D( ElementTypeSuiteData* data ) {
- FeMesh* feMesh;
- unsigned maxTests = 40;
- unsigned test_i;
- Coord gCoord, lCoord, gCoord_fromLocal;
- unsigned el, elNodeCount, elNode_i;
- ElementType* elType;
- IArray* inc = IArray_New();
- unsigned* elNodes;
- double Ni[27];
- double vecNorm;
- int dim = 3;
- unsigned sizes[3] = { 6, 6, 1 };
- double minCrd[3] = { 0.0, 0.0, 0.0 };
- double maxCrd[3] = { 1.2, 1.2, 1.2 };
-
- feMesh = BuildMeshQuadratic( dim, sizes, minCrd, maxCrd );
-
- srand48( 0 );
- for( test_i = 0; test_i < maxTests; test_i++ ) {
- gCoord[I_AXIS] = drand48();
- gCoord[J_AXIS] = drand48();
- gCoord[K_AXIS] = drand48();
-
- Mesh_Algorithms_SearchElements( feMesh->algorithms, gCoord, &el );
- elNodeCount = FeMesh_GetElementNodeSize( feMesh, el );
- elType = FeMesh_GetElementType( feMesh, el );
- _ElementType_ConvertGlobalCoordToElLocal( elType, feMesh, el, gCoord, lCoord );
- ElementType_EvaluateShapeFunctionsAt( elType, lCoord, Ni );
-
- Mesh_GetIncidence( feMesh, (MeshTopology_Dim)dim, el, MT_VERTEX, inc );
- elNodes = (unsigned*)IArray_GetPtr( inc );
- memset( gCoord_fromLocal, 0, sizeof( double ) * dim );
- for( elNode_i = 0; elNode_i < elNodeCount; elNode_i++ ) {
- gCoord_fromLocal[I_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][I_AXIS];
- gCoord_fromLocal[J_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][J_AXIS];
- gCoord_fromLocal[K_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][K_AXIS];
- }
-
- vecNorm = sqrt( (gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS])*(gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS]) +
- (gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS])*(gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS]) +
- (gCoord[K_AXIS] - gCoord_fromLocal[K_AXIS])*(gCoord[K_AXIS] - gCoord_fromLocal[K_AXIS]) );
-
- pcu_check_true( vecNorm < TOLERANCE );
- }
-
- NewClass_Delete( inc );
- Stg_Component_Destroy( feMesh, NULL, True );
-}
-
-void ElementTypeSuite_TestSurfaceJacobian_Linear2D( ElementTypeSuiteData* data ) {
- FeMesh* feMesh;
- ElementType* elType;
- unsigned sizes[2] = { 4, 3 };
- double minCrd[2] = { 0.0, 0.0 };
- double maxCrd[2] = { 4.0, 3.0 };
- double xi[4][2][2]; /* [face][point][dim] */
- unsigned face_i, ip_i;
- double norm[3];
- unsigned faceIndex;
- unsigned faceAxis[4] = { 1, 1, 0, 0 };
- double weight = 1.0;
- double detJac;
- double faceLen;
-
- xi[0][0][0] = -0.57735026918962584; xi[0][0][1] = -1.0;
- xi[0][1][0] = +0.57735026918962584; xi[0][1][1] = -1.0;
-
- xi[1][0][0] = -0.57735026918962584; xi[1][0][1] = +1.0;
- xi[1][1][0] = +0.57735026918962584; xi[1][1][1] = +1.0;
-
- xi[2][0][0] = -1.0; xi[2][0][1] = -0.57735026918962584;
- xi[2][1][0] = -1.0; xi[2][1][1] = +0.57735026918962584;
-
- xi[3][0][0] = +1.0; xi[3][0][1] = -0.57735026918962584;
- xi[3][1][0] = +1.0; xi[3][1][1] = +0.57735026918962584;
-
- feMesh = BuildMeshLinear( 2, sizes, minCrd, maxCrd );
- elType = FeMesh_GetElementType( feMesh, 0 );
-
- for( face_i = 0; face_i < 4; face_i++ ) {
- faceLen = 0.0;
- for( ip_i = 0; ip_i < 2; ip_i++ ) {
- faceIndex = ElementType_SurfaceNormal( elType, 0, 2, xi[face_i][ip_i], norm );
- detJac = ElementType_JacobianDeterminantSurface( elType, feMesh, 0, xi[face_i][ip_i], faceIndex, faceAxis[face_i] );
-
- faceLen += detJac * weight;
- }
-
- pcu_check_true( fabs( faceLen - 1.0 ) < EPSILON );
- }
-
- Stg_Component_Destroy( feMesh, NULL, True );
-}
-
-void ElementTypeSuite_TestSurfaceJacobian_Linear3D( ElementTypeSuiteData* data ) {
- FeMesh* feMesh;
- ElementType* elType;
- unsigned sizes[3] = { 4, 3, 5 };
- double minCrd[3] = { 0.0, 0.0, 0.0 };
- double maxCrd[3] = { 4.0, 3.0, 5.0 };
- double xi[6][4][3]; /* [face][point][dim] */
- unsigned face_i, ip_i;
- double norm[3];
- unsigned faceIndex;
- unsigned faceAxis[6] = { 1, 1, 0, 0, 2, 2 };
- double weight = 1.0;
- double detJac;
- double faceArea;
-
- xi[0][0][0] = -0.57735026918962584; xi[0][0][1] = -1.0; xi[0][0][2] = -0.57735026918962584;
- xi[0][1][0] = +0.57735026918962584; xi[0][1][1] = -1.0; xi[0][1][2] = -0.57735026918962584;
- xi[0][2][0] = -0.57735026918962584; xi[0][2][1] = -1.0; xi[0][2][2] = +0.57735026918962584;
- xi[0][3][0] = +0.57735026918962584; xi[0][3][1] = -1.0; xi[0][3][2] = +0.57735026918962584;
-
- xi[1][0][0] = -0.57735026918962584; xi[1][0][1] = +1.0; xi[1][0][2] = -0.57735026918962584;
- xi[1][1][0] = +0.57735026918962584; xi[1][1][1] = +1.0; xi[1][1][2] = -0.57735026918962584;
- xi[1][2][0] = -0.57735026918962584; xi[1][2][1] = +1.0; xi[1][2][2] = +0.57735026918962584;
- xi[1][3][0] = +0.57735026918962584; xi[1][3][1] = +1.0; xi[1][3][2] = +0.57735026918962584;
-
- xi[2][0][0] = -1.0; xi[2][0][1] = -0.57735026918962584; xi[2][0][2] = -0.57735026918962584;
- xi[2][1][0] = -1.0; xi[2][1][1] = +0.57735026918962584; xi[2][1][2] = -0.57735026918962584;
- xi[2][2][0] = -1.0; xi[2][2][1] = -0.57735026918962584; xi[2][2][2] = +0.57735026918962584;
- xi[2][3][0] = -1.0; xi[2][3][1] = +0.57735026918962584; xi[2][3][2] = +0.57735026918962584;
-
- xi[3][0][0] = +1.0; xi[3][0][1] = -0.57735026918962584; xi[3][0][2] = -0.57735026918962584;
- xi[3][1][0] = +1.0; xi[3][1][1] = +0.57735026918962584; xi[3][1][2] = -0.57735026918962584;
- xi[3][2][0] = +1.0; xi[3][2][1] = -0.57735026918962584; xi[3][2][2] = +0.57735026918962584;
- xi[3][3][0] = +1.0; xi[3][3][1] = +0.57735026918962584; xi[3][3][2] = +0.57735026918962584;
-
- xi[4][0][0] = -0.57735026918962584; xi[4][0][1] = -0.57735026918962584; xi[4][0][2] = -1.0;
- xi[4][1][0] = +0.57735026918962584; xi[4][1][1] = -0.57735026918962584; xi[4][1][2] = -1.0;
- xi[4][2][0] = -0.57735026918962584; xi[4][2][1] = +0.57735026918962584; xi[4][2][2] = -1.0;
- xi[4][3][0] = +0.57735026918962584; xi[4][3][1] = +0.57735026918962584; xi[4][3][2] = -1.0;
-
- xi[5][0][0] = -0.57735026918962584; xi[5][0][1] = -0.57735026918962584; xi[5][0][2] = +1.0;
- xi[5][1][0] = +0.57735026918962584; xi[5][1][1] = -0.57735026918962584; xi[5][1][2] = +1.0;
- xi[5][2][0] = -0.57735026918962584; xi[5][2][1] = +0.57735026918962584; xi[5][2][2] = +1.0;
- xi[5][3][0] = +0.57735026918962584; xi[5][3][1] = +0.57735026918962584; xi[5][3][2] = +1.0;
-
- feMesh = BuildMeshLinear( 3, sizes, minCrd, maxCrd );
- elType = FeMesh_GetElementType( feMesh, 0 );
-
- for( face_i = 0; face_i < 6; face_i++ ) {
- faceArea = 0.0;
- for( ip_i = 0; ip_i < 4; ip_i++ ) {
- faceIndex = ElementType_SurfaceNormal( elType, 0, 3, xi[face_i][ip_i], norm );
- detJac = ElementType_JacobianDeterminantSurface( elType, feMesh, 0, xi[face_i][ip_i], faceIndex, faceAxis[face_i] );
-
- faceArea += detJac * weight;
- }
-
- pcu_check_true( fabs( faceArea - 1.0 ) < EPSILON );
- }
-
- Stg_Component_Destroy( feMesh, NULL, True );
-}
-
-void ElementTypeSuite_TestSurfaceJacobian_Quadratic2D( ElementTypeSuiteData* data ) {
- FeMesh* feMesh;
- ElementType* elType;
- unsigned sizes[2] = { 4, 3 };
- double minCrd[2] = { 0.0, 0.0 };
- double maxCrd[2] = { 4.0, 3.0 };
- double xi[4][3][2]; /* [face][point][dim] */
- unsigned face_i, ip_i;
- double norm[3];
- unsigned faceIndex;
- unsigned faceAxis[4] = { 1, 1, 0, 0 };
- double weight[3] = { 0.5555555555555555, 0.8888888888888889, 0.5555555555555555 };
- double detJac;
- double faceLen;
-
- xi[0][0][0] = -0.7745966692414834; xi[0][0][1] = -1.0;
- xi[0][1][0] = 0.0; xi[0][1][1] = -1.0;
- xi[0][2][0] = +0.7745966692414834; xi[0][2][1] = -1.0;
-
- xi[1][0][0] = -0.7745966692414834; xi[1][0][1] = +1.0;
- xi[1][1][0] = 0.0; xi[1][1][1] = +1.0;
- xi[1][2][0] = +0.7745966692414834; xi[1][2][1] = +1.0;
-
- xi[2][0][0] = -1.0; xi[2][0][1] = -0.7745966692414834;
- xi[2][1][0] = -1.0; xi[2][1][1] = 0.0;
- xi[2][2][0] = -1.0; xi[2][2][1] = +0.7745966692414834;
-
- xi[3][0][0] = +1.0; xi[3][0][1] = -0.7745966692414834;
- xi[3][1][0] = +1.0; xi[3][1][1] = 0.0;
- xi[3][2][0] = +1.0; xi[3][2][1] = +0.7745966692414834;
-
- feMesh = BuildMeshQuadratic( 2, sizes, minCrd, maxCrd );
- elType = FeMesh_GetElementType( feMesh, 0 );
-
- for( face_i = 0; face_i < 4; face_i++ ) {
- faceLen = 0.0;
- for( ip_i = 0; ip_i < 3; ip_i++ ) {
- faceIndex = ElementType_SurfaceNormal( elType, 0, 2, xi[face_i][ip_i], norm );
- detJac = ElementType_JacobianDeterminantSurface( elType, feMesh, 0, xi[face_i][ip_i], faceIndex, faceAxis[face_i] );
-
- faceLen += detJac * weight[ip_i];
- }
-
- pcu_check_true( fabs( faceLen - 1.0 ) < EPSILON );
- }
-
- Stg_Component_Destroy( feMesh, NULL, True );
-}
-
-void ElementTypeSuite_TestSurfaceJacobian_Quadratic3D( ElementTypeSuiteData* data ) {
- FeMesh* feMesh;
- ElementType* elType;
- unsigned sizes[3] = { 4, 3, 5 };
- double minCrd[3] = { 0.0, 0.0, 0.0 };
- double maxCrd[3] = { 4.0, 3.0, 5.0 };
- double xi[6][9][3]; /* [face][point][dim] */
- unsigned face_i, ip_i;
- double norm[3];
- unsigned faceIndex;
- unsigned faceAxis[6] = { 1, 1, 0, 0, 2, 2 };
- double weight[9] = { 0.30864197530864201, 0.49382716049382713, 0.30864197530864201,
- 0.49382716049382713, 0.79012345679012341, 0.49382716049382713,
- 0.30864197530864201, 0.49382716049382713, 0.30864197530864201 };
- double detJac;
- double faceArea;
-
- xi[0][0][0] = -0.7745966692414834; xi[0][0][1] = -1.0; xi[0][0][2] = -0.7745966692414834;
- xi[0][1][0] = 0.0; xi[0][1][1] = -1.0; xi[0][1][2] = -0.7745966692414834;
- xi[0][2][0] = +0.7745966692414834; xi[0][2][1] = -1.0; xi[0][2][2] = -0.7745966692414834;
- xi[0][3][0] = -0.7745966692414834; xi[0][3][1] = -1.0; xi[0][3][2] = 0.0;
- xi[0][4][0] = 0.0; xi[0][4][1] = -1.0; xi[0][4][2] = 0.0;
- xi[0][5][0] = +0.7745966692414834; xi[0][5][1] = -1.0; xi[0][5][2] = 0.0;
- xi[0][6][0] = -0.7745966692414834; xi[0][6][1] = -1.0; xi[0][6][2] = +0.7745966692414834;
- xi[0][7][0] = 0.0; xi[0][7][1] = -1.0; xi[0][7][2] = +0.7745966692414834;
- xi[0][8][0] = +0.7745966692414834; xi[0][8][1] = -1.0; xi[0][8][2] = +0.7745966692414834;
-
- xi[1][0][0] = -0.7745966692414834; xi[1][0][1] = +1.0; xi[1][0][2] = -0.7745966692414834;
- xi[1][1][0] = 0.0; xi[1][1][1] = +1.0; xi[1][1][2] = -0.7745966692414834;
- xi[1][2][0] = +0.7745966692414834; xi[1][2][1] = +1.0; xi[1][2][2] = -0.7745966692414834;
- xi[1][3][0] = -0.7745966692414834; xi[1][3][1] = +1.0; xi[1][3][2] = 0.0;
- xi[1][4][0] = 0.0; xi[1][4][1] = +1.0; xi[1][4][2] = 0.0;
- xi[1][5][0] = +0.7745966692414834; xi[1][5][1] = +1.0; xi[1][5][2] = 0.0;
- xi[1][6][0] = -0.7745966692414834; xi[1][6][1] = +1.0; xi[1][6][2] = +0.7745966692414834;
- xi[1][7][0] = 0.0; xi[1][7][1] = -1.0; xi[1][7][2] = +0.7745966692414834;
- xi[1][8][0] = +0.7745966692414834; xi[1][8][1] = -1.0; xi[1][8][2] = +0.7745966692414834;
-
- xi[2][0][0] = -1.0; xi[2][0][1] = -0.7745966692414834; xi[2][0][2] = -0.7745966692414834;
- xi[2][1][0] = -1.0; xi[2][1][1] = 0.0; xi[2][1][2] = -0.7745966692414834;
- xi[2][2][0] = -1.0; xi[2][2][1] = +0.7745966692414834; xi[2][2][2] = -0.7745966692414834;
- xi[2][3][0] = -1.0; xi[2][3][1] = -0.7745966692414834; xi[2][3][2] = 0.0;
- xi[2][4][0] = -1.0; xi[2][4][1] = 0.0; xi[2][4][2] = 0.0;
- xi[2][5][0] = -1.0; xi[2][5][1] = +0.7745966692414834; xi[2][5][2] = 0.0;
- xi[2][6][0] = -1.0; xi[2][6][1] = -0.7745966692414834; xi[2][6][2] = +0.7745966692414834;
- xi[2][7][0] = -1.0; xi[2][7][1] = 0.0; xi[2][7][2] = +0.7745966692414834;
- xi[2][8][0] = -1.0; xi[2][8][1] = +0.7745966692414834; xi[2][8][2] = +0.7745966692414834;
-
- xi[3][0][0] = +1.0; xi[3][0][1] = -0.7745966692414834; xi[3][0][2] = -0.7745966692414834;
- xi[3][1][0] = +1.0; xi[3][1][1] = 0.0; xi[3][1][2] = -0.7745966692414834;
- xi[3][2][0] = +1.0; xi[3][2][1] = +0.7745966692414834; xi[3][2][2] = -0.7745966692414834;
- xi[3][3][0] = +1.0; xi[3][3][1] = -0.7745966692414834; xi[3][3][2] = 0.0;
- xi[3][4][0] = +1.0; xi[3][4][1] = 0.0; xi[3][4][2] = 0.0;
- xi[3][5][0] = +1.0; xi[3][5][1] = +0.7745966692414834; xi[3][5][2] = 0.0;
- xi[3][6][0] = +1.0; xi[3][6][1] = -0.7745966692414834; xi[3][6][2] = +0.7745966692414834;
- xi[3][7][0] = +1.0; xi[3][7][1] = 0.0; xi[3][7][2] = +0.7745966692414834;
- xi[3][8][0] = +1.0; xi[3][8][1] = +0.7745966692414834; xi[3][8][2] = +0.7745966692414834;
-
- xi[4][0][0] = -0.7745966692414834; xi[4][0][1] = -0.7745966692414834; xi[4][0][2] = -1.0;
- xi[4][1][0] = 0.0; xi[4][1][1] = -0.7745966692414834; xi[4][1][2] = -1.0;
- xi[4][2][0] = +0.7745966692414834; xi[4][2][1] = -0.7745966692414834; xi[4][2][2] = -1.0;
- xi[4][3][0] = -0.7745966692414834; xi[4][3][1] = 0.0; xi[4][3][2] = -1.0;
- xi[4][4][0] = 0.0; xi[4][4][1] = 0.0; xi[4][4][2] = -1.0;
- xi[4][5][0] = +0.7745966692414834; xi[4][5][1] = 0.0; xi[4][5][2] = -1.0;
- xi[4][6][0] = -0.7745966692414834; xi[4][6][1] = +0.7745966692414834; xi[4][6][2] = -1.0;
- xi[4][7][0] = 0.0; xi[4][7][1] = +0.7745966692414834; xi[4][7][2] = -1.0;
- xi[4][8][0] = +0.7745966692414834; xi[4][8][1] = +0.7745966692414834; xi[4][8][2] = -1.0;
-
- xi[5][0][0] = -0.7745966692414834; xi[5][0][1] = -0.7745966692414834; xi[5][0][2] = +1.0;
- xi[5][1][0] = 0.0; xi[5][1][1] = -0.7745966692414834; xi[5][1][2] = +1.0;
- xi[5][2][0] = +0.7745966692414834; xi[5][2][1] = -0.7745966692414834; xi[5][2][2] = +1.0;
- xi[5][3][0] = -0.7745966692414834; xi[5][3][1] = 0.0; xi[5][3][2] = +1.0;
- xi[5][4][0] = 0.0; xi[5][4][1] = 0.0; xi[5][4][2] = +1.0;
- xi[5][5][0] = +0.7745966692414834; xi[5][5][1] = 0.0; xi[5][5][2] = +1.0;
- xi[5][6][0] = -0.7745966692414834; xi[5][6][1] = +0.7745966692414834; xi[5][6][2] = +1.0;
- xi[5][7][0] = 0.0; xi[5][7][1] = +0.7745966692414834; xi[5][7][2] = +1.0;
- xi[5][8][0] = +0.7745966692414834; xi[5][8][1] = +0.7745966692414834; xi[5][8][2] = +1.0;
-
- feMesh = BuildMeshQuadratic( 3, sizes, minCrd, maxCrd );
- elType = FeMesh_GetElementType( feMesh, 0 );
-
- for( face_i = 0; face_i < 6; face_i++ ) {
- faceArea = 0.0;
- for( ip_i = 0; ip_i < 9; ip_i++ ) {
- faceIndex = ElementType_SurfaceNormal( elType, 0, 3, xi[face_i][ip_i], norm );
- detJac = ElementType_JacobianDeterminantSurface( elType, feMesh, 0, xi[face_i][ip_i], faceIndex, faceAxis[face_i] );
-
- faceArea += detJac * weight[ip_i];
- }
-
- pcu_check_true( fabs( faceArea - 1.0 ) < EPSILON );
- }
-
- Stg_Component_Destroy( feMesh, NULL, True );
-}
-
-void ElementTypeSuite( pcu_suite_t* suite ) {
- pcu_suite_setData( suite, ElementTypeSuiteData );
- pcu_suite_setFixtures( suite, ElementTypeSuite_Setup, ElementTypeSuite_Teardown );
- pcu_suite_addTest( suite, ElementTypeSuite_TestLinear2D );
- pcu_suite_addTest( suite, ElementTypeSuite_TestLinear3D );
- pcu_suite_addTest( suite, ElementTypeSuite_TestQuadratic2D );
- pcu_suite_addTest( suite, ElementTypeSuite_TestQuadratic3D );
- pcu_suite_addTest( suite, ElementTypeSuite_TestSurfaceJacobian_Linear2D );
- pcu_suite_addTest( suite, ElementTypeSuite_TestSurfaceJacobian_Linear3D );
- pcu_suite_addTest( suite, ElementTypeSuite_TestSurfaceJacobian_Quadratic2D );
- pcu_suite_addTest( suite, ElementTypeSuite_TestSurfaceJacobian_Quadratic3D );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/tests/ElementTypeSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/tests/ElementTypeSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,559 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** Role:
+** Tests the ElementTypeSuite
+**
+** $Id: testElementType.c 3462 2006-02-19 06:53:24Z WalterLandry $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pcu/pcu.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include "ElementTypeSuite.h"
+
+#define TOLERANCE 1.0e-8
+#define EPSILON 1.0e-8
+
+typedef struct {
+ Dictionary* dict;
+} ElementTypeSuiteData;
+
+FeMesh* BuildMeshLinear( unsigned nDims, unsigned* sizes, double* minCrd, double* maxCrd ) {
+ CartesianGenerator* gen;
+ FeMesh* feMesh;
+ unsigned maxDecomp[3] = {0, 1, 1};
+
+ gen = CartesianGenerator_New( "", NULL );
+ CartesianGenerator_SetDimSize( gen, nDims );
+ CartesianGenerator_SetTopologyParams( gen, sizes, 0, NULL, maxDecomp );
+ CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+ CartesianGenerator_SetShadowDepth( gen, 0 );
+
+ feMesh = FeMesh_New( "", NULL );
+ Mesh_SetGenerator( feMesh, gen );
+ FeMesh_SetElementFamily( feMesh, "linear" );
+ Stg_Component_Build( feMesh, NULL, False );
+ Stg_Component_Initialise( feMesh, NULL, False );
+
+ return feMesh;
+}
+
+FeMesh* BuildMeshQuadratic( unsigned nDims, unsigned* sizes, double* minCrd, double* maxCrd ) {
+ CartesianGenerator* gen;
+ FeMesh* feMesh;
+ unsigned maxDecomp[3] = {0, 1, 1};
+
+ gen = (CartesianGenerator*)C2Generator_New( "", NULL );
+ CartesianGenerator_SetDimSize( gen, nDims );
+ C2Generator_SetTopologyParams( gen, sizes, 0, NULL, maxDecomp );
+ CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+ CartesianGenerator_SetShadowDepth( gen, 0 );
+
+ feMesh = FeMesh_New( "", NULL );
+ Mesh_SetGenerator( feMesh, gen );
+ FeMesh_SetElementFamily( feMesh, "quadratic" );
+ Stg_Component_Build( feMesh, NULL, False );
+ Stg_Component_Initialise( feMesh, NULL, False );
+
+ return feMesh;
+}
+
+void ElementTypeSuite_Setup( ElementTypeSuiteData* data ) {
+ Journal_Enable_AllTypedStream( False );
+
+ data->dict = Dictionary_New();
+}
+
+void ElementTypeSuite_Teardown( ElementTypeSuiteData* data ) {
+ Stg_Class_Delete( data->dict );
+}
+
+void ElementTypeSuite_TestLinear2D( ElementTypeSuiteData* data ) {
+ FeMesh* feMesh;
+ unsigned maxTests = 40;
+ unsigned test_i;
+ Coord gCoord, lCoord, gCoord_fromLocal;
+ unsigned el, elNodeCount, elNode_i;
+ ElementType* elType;
+ IArray* inc = IArray_New();
+ unsigned* elNodes;
+ double Ni[4];
+ double vecNorm;
+ int dim = 2;
+ unsigned sizes[3] = { 6, 6, 1 };
+ double minCrd[3] = { 0.0, 0.0, 0.0 };
+ double maxCrd[3] = { 1.2, 1.2, 1.2 };
+
+ feMesh = BuildMeshLinear( dim, sizes, minCrd, maxCrd );
+
+ srand48( 0 );
+ for( test_i = 0; test_i < maxTests; test_i++ ) {
+ gCoord[I_AXIS] = drand48();
+ gCoord[J_AXIS] = drand48();
+
+ Mesh_Algorithms_SearchElements( feMesh->algorithms, gCoord, &el );
+ elNodeCount = FeMesh_GetElementNodeSize( feMesh, el );
+ elType = FeMesh_GetElementType( feMesh, el );
+ _ElementType_ConvertGlobalCoordToElLocal( elType, feMesh, el, gCoord, lCoord );
+ ElementType_EvaluateShapeFunctionsAt( elType, lCoord, Ni );
+
+ Mesh_GetIncidence( feMesh, (MeshTopology_Dim)dim, el, MT_VERTEX, inc );
+ elNodes = (unsigned*)IArray_GetPtr( inc );
+ memset( gCoord_fromLocal, 0, sizeof( double ) * dim );
+ for( elNode_i = 0; elNode_i < elNodeCount; elNode_i++ ) {
+ gCoord_fromLocal[I_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][I_AXIS];
+ gCoord_fromLocal[J_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][J_AXIS];
+ }
+
+ vecNorm = sqrt( (gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS])*(gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS]) +
+ (gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS])*(gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS]) );
+
+ pcu_check_true( vecNorm < TOLERANCE );
+ }
+
+ NewClass_Delete( inc );
+ Stg_Component_Destroy( feMesh, NULL, True );
+}
+
+void ElementTypeSuite_TestLinear3D( ElementTypeSuiteData* data ) {
+ FeMesh* feMesh;
+ unsigned maxTests = 40;
+ unsigned test_i;
+ Coord gCoord, lCoord, gCoord_fromLocal;
+ unsigned el, elNodeCount, elNode_i;
+ ElementType* elType;
+ IArray* inc = IArray_New();
+ unsigned* elNodes;
+ double Ni[8];
+ double vecNorm;
+ int dim = 3;
+ unsigned sizes[3] = { 6, 6, 1 };
+ double minCrd[3] = { 0.0, 0.0, 0.0 };
+ double maxCrd[3] = { 1.2, 1.2, 1.2 };
+
+ feMesh = BuildMeshLinear( dim, sizes, minCrd, maxCrd );
+
+ srand48( 0 );
+ for( test_i = 0; test_i < maxTests; test_i++ ) {
+ gCoord[I_AXIS] = drand48();
+ gCoord[J_AXIS] = drand48();
+ gCoord[K_AXIS] = drand48();
+
+ Mesh_Algorithms_SearchElements( feMesh->algorithms, gCoord, &el );
+ elNodeCount = FeMesh_GetElementNodeSize( feMesh, el );
+ elType = FeMesh_GetElementType( feMesh, el );
+ _ElementType_ConvertGlobalCoordToElLocal( elType, feMesh, el, gCoord, lCoord );
+ ElementType_EvaluateShapeFunctionsAt( elType, lCoord, Ni );
+
+ Mesh_GetIncidence( feMesh, (MeshTopology_Dim)dim, el, MT_VERTEX, inc );
+ elNodes = (unsigned*)IArray_GetPtr( inc );
+ memset( gCoord_fromLocal, 0, sizeof( double ) * dim );
+ for( elNode_i = 0; elNode_i < elNodeCount; elNode_i++ ) {
+ gCoord_fromLocal[I_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][I_AXIS];
+ gCoord_fromLocal[J_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][J_AXIS];
+ gCoord_fromLocal[K_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][K_AXIS];
+ }
+
+ vecNorm = sqrt( (gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS])*(gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS]) +
+ (gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS])*(gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS]) +
+ (gCoord[K_AXIS] - gCoord_fromLocal[K_AXIS])*(gCoord[K_AXIS] - gCoord_fromLocal[K_AXIS]) );
+
+ pcu_check_true( vecNorm < TOLERANCE );
+ }
+
+ NewClass_Delete( inc );
+ Stg_Component_Destroy( feMesh, NULL, True );
+}
+
+void ElementTypeSuite_TestQuadratic2D( ElementTypeSuiteData* data ) {
+ FeMesh* feMesh;
+ unsigned maxTests = 40;
+ unsigned test_i;
+ Coord gCoord, lCoord, gCoord_fromLocal;
+ unsigned el, elNodeCount, elNode_i;
+ ElementType* elType;
+ IArray* inc = IArray_New();
+ unsigned* elNodes;
+ double Ni[9];
+ double vecNorm;
+ int dim = 2;
+ unsigned sizes[3] = { 6, 6, 1 };
+ double minCrd[3] = { 0.0, 0.0, 0.0 };
+ double maxCrd[3] = { 1.2, 1.2, 1.2 };
+
+ feMesh = BuildMeshQuadratic( dim, sizes, minCrd, maxCrd );
+
+ srand48( 0 );
+ for( test_i = 0; test_i < maxTests; test_i++ ) {
+ gCoord[I_AXIS] = drand48();
+ gCoord[J_AXIS] = drand48();
+
+ Mesh_Algorithms_SearchElements( feMesh->algorithms, gCoord, &el );
+ elNodeCount = FeMesh_GetElementNodeSize( feMesh, el );
+ elType = FeMesh_GetElementType( feMesh, el );
+ _ElementType_ConvertGlobalCoordToElLocal( elType, feMesh, el, gCoord, lCoord );
+ ElementType_EvaluateShapeFunctionsAt( elType, lCoord, Ni );
+
+ Mesh_GetIncidence( feMesh, (MeshTopology_Dim)dim, el, MT_VERTEX, inc );
+ elNodes = (unsigned*)IArray_GetPtr( inc );
+ memset( gCoord_fromLocal, 0, sizeof( double ) * dim );
+ for( elNode_i = 0; elNode_i < elNodeCount; elNode_i++ ) {
+ gCoord_fromLocal[I_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][I_AXIS];
+ gCoord_fromLocal[J_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][J_AXIS];
+ }
+
+ vecNorm = sqrt( (gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS])*(gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS]) +
+ (gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS])*(gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS]) );
+
+ pcu_check_true( vecNorm < TOLERANCE );
+ }
+
+ NewClass_Delete( inc );
+ Stg_Component_Destroy( feMesh, NULL, True );
+}
+
+void ElementTypeSuite_TestQuadratic3D( ElementTypeSuiteData* data ) {
+ FeMesh* feMesh;
+ unsigned maxTests = 40;
+ unsigned test_i;
+ Coord gCoord, lCoord, gCoord_fromLocal;
+ unsigned el, elNodeCount, elNode_i;
+ ElementType* elType;
+ IArray* inc = IArray_New();
+ unsigned* elNodes;
+ double Ni[27];
+ double vecNorm;
+ int dim = 3;
+ unsigned sizes[3] = { 6, 6, 1 };
+ double minCrd[3] = { 0.0, 0.0, 0.0 };
+ double maxCrd[3] = { 1.2, 1.2, 1.2 };
+
+ feMesh = BuildMeshQuadratic( dim, sizes, minCrd, maxCrd );
+
+ srand48( 0 );
+ for( test_i = 0; test_i < maxTests; test_i++ ) {
+ gCoord[I_AXIS] = drand48();
+ gCoord[J_AXIS] = drand48();
+ gCoord[K_AXIS] = drand48();
+
+ Mesh_Algorithms_SearchElements( feMesh->algorithms, gCoord, &el );
+ elNodeCount = FeMesh_GetElementNodeSize( feMesh, el );
+ elType = FeMesh_GetElementType( feMesh, el );
+ _ElementType_ConvertGlobalCoordToElLocal( elType, feMesh, el, gCoord, lCoord );
+ ElementType_EvaluateShapeFunctionsAt( elType, lCoord, Ni );
+
+ Mesh_GetIncidence( feMesh, (MeshTopology_Dim)dim, el, MT_VERTEX, inc );
+ elNodes = (unsigned*)IArray_GetPtr( inc );
+ memset( gCoord_fromLocal, 0, sizeof( double ) * dim );
+ for( elNode_i = 0; elNode_i < elNodeCount; elNode_i++ ) {
+ gCoord_fromLocal[I_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][I_AXIS];
+ gCoord_fromLocal[J_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][J_AXIS];
+ gCoord_fromLocal[K_AXIS] += Ni[elNode_i] * feMesh->verts[elNodes[elNode_i]][K_AXIS];
+ }
+
+ vecNorm = sqrt( (gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS])*(gCoord[I_AXIS] - gCoord_fromLocal[I_AXIS]) +
+ (gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS])*(gCoord[J_AXIS] - gCoord_fromLocal[J_AXIS]) +
+ (gCoord[K_AXIS] - gCoord_fromLocal[K_AXIS])*(gCoord[K_AXIS] - gCoord_fromLocal[K_AXIS]) );
+
+ pcu_check_true( vecNorm < TOLERANCE );
+ }
+
+ NewClass_Delete( inc );
+ Stg_Component_Destroy( feMesh, NULL, True );
+}
+
+void ElementTypeSuite_TestSurfaceJacobian_Linear2D( ElementTypeSuiteData* data ) {
+ FeMesh* feMesh;
+ ElementType* elType;
+ unsigned sizes[2] = { 4, 3 };
+ double minCrd[2] = { 0.0, 0.0 };
+ double maxCrd[2] = { 4.0, 3.0 };
+ double xi[4][2][2]; /* [face][point][dim] */
+ unsigned face_i, ip_i;
+ double norm[3];
+ unsigned faceIndex;
+ unsigned faceAxis[4] = { 1, 1, 0, 0 };
+ double weight = 1.0;
+ double detJac;
+ double faceLen;
+
+ xi[0][0][0] = -0.57735026918962584; xi[0][0][1] = -1.0;
+ xi[0][1][0] = +0.57735026918962584; xi[0][1][1] = -1.0;
+
+ xi[1][0][0] = -0.57735026918962584; xi[1][0][1] = +1.0;
+ xi[1][1][0] = +0.57735026918962584; xi[1][1][1] = +1.0;
+
+ xi[2][0][0] = -1.0; xi[2][0][1] = -0.57735026918962584;
+ xi[2][1][0] = -1.0; xi[2][1][1] = +0.57735026918962584;
+
+ xi[3][0][0] = +1.0; xi[3][0][1] = -0.57735026918962584;
+ xi[3][1][0] = +1.0; xi[3][1][1] = +0.57735026918962584;
+
+ feMesh = BuildMeshLinear( 2, sizes, minCrd, maxCrd );
+ elType = FeMesh_GetElementType( feMesh, 0 );
+
+ for( face_i = 0; face_i < 4; face_i++ ) {
+ faceLen = 0.0;
+ for( ip_i = 0; ip_i < 2; ip_i++ ) {
+ faceIndex = ElementType_SurfaceNormal( elType, 0, 2, xi[face_i][ip_i], norm );
+ detJac = ElementType_JacobianDeterminantSurface( elType, feMesh, 0, xi[face_i][ip_i], faceIndex, faceAxis[face_i] );
+
+ faceLen += detJac * weight;
+ }
+
+ pcu_check_true( fabs( faceLen - 1.0 ) < EPSILON );
+ }
+
+ Stg_Component_Destroy( feMesh, NULL, True );
+}
+
+void ElementTypeSuite_TestSurfaceJacobian_Linear3D( ElementTypeSuiteData* data ) {
+ FeMesh* feMesh;
+ ElementType* elType;
+ unsigned sizes[3] = { 4, 3, 5 };
+ double minCrd[3] = { 0.0, 0.0, 0.0 };
+ double maxCrd[3] = { 4.0, 3.0, 5.0 };
+ double xi[6][4][3]; /* [face][point][dim] */
+ unsigned face_i, ip_i;
+ double norm[3];
+ unsigned faceIndex;
+ unsigned faceAxis[6] = { 1, 1, 0, 0, 2, 2 };
+ double weight = 1.0;
+ double detJac;
+ double faceArea;
+
+ xi[0][0][0] = -0.57735026918962584; xi[0][0][1] = -1.0; xi[0][0][2] = -0.57735026918962584;
+ xi[0][1][0] = +0.57735026918962584; xi[0][1][1] = -1.0; xi[0][1][2] = -0.57735026918962584;
+ xi[0][2][0] = -0.57735026918962584; xi[0][2][1] = -1.0; xi[0][2][2] = +0.57735026918962584;
+ xi[0][3][0] = +0.57735026918962584; xi[0][3][1] = -1.0; xi[0][3][2] = +0.57735026918962584;
+
+ xi[1][0][0] = -0.57735026918962584; xi[1][0][1] = +1.0; xi[1][0][2] = -0.57735026918962584;
+ xi[1][1][0] = +0.57735026918962584; xi[1][1][1] = +1.0; xi[1][1][2] = -0.57735026918962584;
+ xi[1][2][0] = -0.57735026918962584; xi[1][2][1] = +1.0; xi[1][2][2] = +0.57735026918962584;
+ xi[1][3][0] = +0.57735026918962584; xi[1][3][1] = +1.0; xi[1][3][2] = +0.57735026918962584;
+
+ xi[2][0][0] = -1.0; xi[2][0][1] = -0.57735026918962584; xi[2][0][2] = -0.57735026918962584;
+ xi[2][1][0] = -1.0; xi[2][1][1] = +0.57735026918962584; xi[2][1][2] = -0.57735026918962584;
+ xi[2][2][0] = -1.0; xi[2][2][1] = -0.57735026918962584; xi[2][2][2] = +0.57735026918962584;
+ xi[2][3][0] = -1.0; xi[2][3][1] = +0.57735026918962584; xi[2][3][2] = +0.57735026918962584;
+
+ xi[3][0][0] = +1.0; xi[3][0][1] = -0.57735026918962584; xi[3][0][2] = -0.57735026918962584;
+ xi[3][1][0] = +1.0; xi[3][1][1] = +0.57735026918962584; xi[3][1][2] = -0.57735026918962584;
+ xi[3][2][0] = +1.0; xi[3][2][1] = -0.57735026918962584; xi[3][2][2] = +0.57735026918962584;
+ xi[3][3][0] = +1.0; xi[3][3][1] = +0.57735026918962584; xi[3][3][2] = +0.57735026918962584;
+
+ xi[4][0][0] = -0.57735026918962584; xi[4][0][1] = -0.57735026918962584; xi[4][0][2] = -1.0;
+ xi[4][1][0] = +0.57735026918962584; xi[4][1][1] = -0.57735026918962584; xi[4][1][2] = -1.0;
+ xi[4][2][0] = -0.57735026918962584; xi[4][2][1] = +0.57735026918962584; xi[4][2][2] = -1.0;
+ xi[4][3][0] = +0.57735026918962584; xi[4][3][1] = +0.57735026918962584; xi[4][3][2] = -1.0;
+
+ xi[5][0][0] = -0.57735026918962584; xi[5][0][1] = -0.57735026918962584; xi[5][0][2] = +1.0;
+ xi[5][1][0] = +0.57735026918962584; xi[5][1][1] = -0.57735026918962584; xi[5][1][2] = +1.0;
+ xi[5][2][0] = -0.57735026918962584; xi[5][2][1] = +0.57735026918962584; xi[5][2][2] = +1.0;
+ xi[5][3][0] = +0.57735026918962584; xi[5][3][1] = +0.57735026918962584; xi[5][3][2] = +1.0;
+
+ feMesh = BuildMeshLinear( 3, sizes, minCrd, maxCrd );
+ elType = FeMesh_GetElementType( feMesh, 0 );
+
+ for( face_i = 0; face_i < 6; face_i++ ) {
+ faceArea = 0.0;
+ for( ip_i = 0; ip_i < 4; ip_i++ ) {
+ faceIndex = ElementType_SurfaceNormal( elType, 0, 3, xi[face_i][ip_i], norm );
+ detJac = ElementType_JacobianDeterminantSurface( elType, feMesh, 0, xi[face_i][ip_i], faceIndex, faceAxis[face_i] );
+
+ faceArea += detJac * weight;
+ }
+
+ pcu_check_true( fabs( faceArea - 1.0 ) < EPSILON );
+ }
+
+ Stg_Component_Destroy( feMesh, NULL, True );
+}
+
+void ElementTypeSuite_TestSurfaceJacobian_Quadratic2D( ElementTypeSuiteData* data ) {
+ FeMesh* feMesh;
+ ElementType* elType;
+ unsigned sizes[2] = { 4, 3 };
+ double minCrd[2] = { 0.0, 0.0 };
+ double maxCrd[2] = { 4.0, 3.0 };
+ double xi[4][3][2]; /* [face][point][dim] */
+ unsigned face_i, ip_i;
+ double norm[3];
+ unsigned faceIndex;
+ unsigned faceAxis[4] = { 1, 1, 0, 0 };
+ double weight[3] = { 0.5555555555555555, 0.8888888888888889, 0.5555555555555555 };
+ double detJac;
+ double faceLen;
+
+ xi[0][0][0] = -0.7745966692414834; xi[0][0][1] = -1.0;
+ xi[0][1][0] = 0.0; xi[0][1][1] = -1.0;
+ xi[0][2][0] = +0.7745966692414834; xi[0][2][1] = -1.0;
+
+ xi[1][0][0] = -0.7745966692414834; xi[1][0][1] = +1.0;
+ xi[1][1][0] = 0.0; xi[1][1][1] = +1.0;
+ xi[1][2][0] = +0.7745966692414834; xi[1][2][1] = +1.0;
+
+ xi[2][0][0] = -1.0; xi[2][0][1] = -0.7745966692414834;
+ xi[2][1][0] = -1.0; xi[2][1][1] = 0.0;
+ xi[2][2][0] = -1.0; xi[2][2][1] = +0.7745966692414834;
+
+ xi[3][0][0] = +1.0; xi[3][0][1] = -0.7745966692414834;
+ xi[3][1][0] = +1.0; xi[3][1][1] = 0.0;
+ xi[3][2][0] = +1.0; xi[3][2][1] = +0.7745966692414834;
+
+ feMesh = BuildMeshQuadratic( 2, sizes, minCrd, maxCrd );
+ elType = FeMesh_GetElementType( feMesh, 0 );
+
+ for( face_i = 0; face_i < 4; face_i++ ) {
+ faceLen = 0.0;
+ for( ip_i = 0; ip_i < 3; ip_i++ ) {
+ faceIndex = ElementType_SurfaceNormal( elType, 0, 2, xi[face_i][ip_i], norm );
+ detJac = ElementType_JacobianDeterminantSurface( elType, feMesh, 0, xi[face_i][ip_i], faceIndex, faceAxis[face_i] );
+
+ faceLen += detJac * weight[ip_i];
+ }
+
+ pcu_check_true( fabs( faceLen - 1.0 ) < EPSILON );
+ }
+
+ Stg_Component_Destroy( feMesh, NULL, True );
+}
+
+void ElementTypeSuite_TestSurfaceJacobian_Quadratic3D( ElementTypeSuiteData* data ) {
+ FeMesh* feMesh;
+ ElementType* elType;
+ unsigned sizes[3] = { 4, 3, 5 };
+ double minCrd[3] = { 0.0, 0.0, 0.0 };
+ double maxCrd[3] = { 4.0, 3.0, 5.0 };
+ double xi[6][9][3]; /* [face][point][dim] */
+ unsigned face_i, ip_i;
+ double norm[3];
+ unsigned faceIndex;
+ unsigned faceAxis[6] = { 1, 1, 0, 0, 2, 2 };
+ double weight[9] = { 0.30864197530864201, 0.49382716049382713, 0.30864197530864201,
+ 0.49382716049382713, 0.79012345679012341, 0.49382716049382713,
+ 0.30864197530864201, 0.49382716049382713, 0.30864197530864201 };
+ double detJac;
+ double faceArea;
+
+ xi[0][0][0] = -0.7745966692414834; xi[0][0][1] = -1.0; xi[0][0][2] = -0.7745966692414834;
+ xi[0][1][0] = 0.0; xi[0][1][1] = -1.0; xi[0][1][2] = -0.7745966692414834;
+ xi[0][2][0] = +0.7745966692414834; xi[0][2][1] = -1.0; xi[0][2][2] = -0.7745966692414834;
+ xi[0][3][0] = -0.7745966692414834; xi[0][3][1] = -1.0; xi[0][3][2] = 0.0;
+ xi[0][4][0] = 0.0; xi[0][4][1] = -1.0; xi[0][4][2] = 0.0;
+ xi[0][5][0] = +0.7745966692414834; xi[0][5][1] = -1.0; xi[0][5][2] = 0.0;
+ xi[0][6][0] = -0.7745966692414834; xi[0][6][1] = -1.0; xi[0][6][2] = +0.7745966692414834;
+ xi[0][7][0] = 0.0; xi[0][7][1] = -1.0; xi[0][7][2] = +0.7745966692414834;
+ xi[0][8][0] = +0.7745966692414834; xi[0][8][1] = -1.0; xi[0][8][2] = +0.7745966692414834;
+
+ xi[1][0][0] = -0.7745966692414834; xi[1][0][1] = +1.0; xi[1][0][2] = -0.7745966692414834;
+ xi[1][1][0] = 0.0; xi[1][1][1] = +1.0; xi[1][1][2] = -0.7745966692414834;
+ xi[1][2][0] = +0.7745966692414834; xi[1][2][1] = +1.0; xi[1][2][2] = -0.7745966692414834;
+ xi[1][3][0] = -0.7745966692414834; xi[1][3][1] = +1.0; xi[1][3][2] = 0.0;
+ xi[1][4][0] = 0.0; xi[1][4][1] = +1.0; xi[1][4][2] = 0.0;
+ xi[1][5][0] = +0.7745966692414834; xi[1][5][1] = +1.0; xi[1][5][2] = 0.0;
+ xi[1][6][0] = -0.7745966692414834; xi[1][6][1] = +1.0; xi[1][6][2] = +0.7745966692414834;
+ xi[1][7][0] = 0.0; xi[1][7][1] = -1.0; xi[1][7][2] = +0.7745966692414834;
+ xi[1][8][0] = +0.7745966692414834; xi[1][8][1] = -1.0; xi[1][8][2] = +0.7745966692414834;
+
+ xi[2][0][0] = -1.0; xi[2][0][1] = -0.7745966692414834; xi[2][0][2] = -0.7745966692414834;
+ xi[2][1][0] = -1.0; xi[2][1][1] = 0.0; xi[2][1][2] = -0.7745966692414834;
+ xi[2][2][0] = -1.0; xi[2][2][1] = +0.7745966692414834; xi[2][2][2] = -0.7745966692414834;
+ xi[2][3][0] = -1.0; xi[2][3][1] = -0.7745966692414834; xi[2][3][2] = 0.0;
+ xi[2][4][0] = -1.0; xi[2][4][1] = 0.0; xi[2][4][2] = 0.0;
+ xi[2][5][0] = -1.0; xi[2][5][1] = +0.7745966692414834; xi[2][5][2] = 0.0;
+ xi[2][6][0] = -1.0; xi[2][6][1] = -0.7745966692414834; xi[2][6][2] = +0.7745966692414834;
+ xi[2][7][0] = -1.0; xi[2][7][1] = 0.0; xi[2][7][2] = +0.7745966692414834;
+ xi[2][8][0] = -1.0; xi[2][8][1] = +0.7745966692414834; xi[2][8][2] = +0.7745966692414834;
+
+ xi[3][0][0] = +1.0; xi[3][0][1] = -0.7745966692414834; xi[3][0][2] = -0.7745966692414834;
+ xi[3][1][0] = +1.0; xi[3][1][1] = 0.0; xi[3][1][2] = -0.7745966692414834;
+ xi[3][2][0] = +1.0; xi[3][2][1] = +0.7745966692414834; xi[3][2][2] = -0.7745966692414834;
+ xi[3][3][0] = +1.0; xi[3][3][1] = -0.7745966692414834; xi[3][3][2] = 0.0;
+ xi[3][4][0] = +1.0; xi[3][4][1] = 0.0; xi[3][4][2] = 0.0;
+ xi[3][5][0] = +1.0; xi[3][5][1] = +0.7745966692414834; xi[3][5][2] = 0.0;
+ xi[3][6][0] = +1.0; xi[3][6][1] = -0.7745966692414834; xi[3][6][2] = +0.7745966692414834;
+ xi[3][7][0] = +1.0; xi[3][7][1] = 0.0; xi[3][7][2] = +0.7745966692414834;
+ xi[3][8][0] = +1.0; xi[3][8][1] = +0.7745966692414834; xi[3][8][2] = +0.7745966692414834;
+
+ xi[4][0][0] = -0.7745966692414834; xi[4][0][1] = -0.7745966692414834; xi[4][0][2] = -1.0;
+ xi[4][1][0] = 0.0; xi[4][1][1] = -0.7745966692414834; xi[4][1][2] = -1.0;
+ xi[4][2][0] = +0.7745966692414834; xi[4][2][1] = -0.7745966692414834; xi[4][2][2] = -1.0;
+ xi[4][3][0] = -0.7745966692414834; xi[4][3][1] = 0.0; xi[4][3][2] = -1.0;
+ xi[4][4][0] = 0.0; xi[4][4][1] = 0.0; xi[4][4][2] = -1.0;
+ xi[4][5][0] = +0.7745966692414834; xi[4][5][1] = 0.0; xi[4][5][2] = -1.0;
+ xi[4][6][0] = -0.7745966692414834; xi[4][6][1] = +0.7745966692414834; xi[4][6][2] = -1.0;
+ xi[4][7][0] = 0.0; xi[4][7][1] = +0.7745966692414834; xi[4][7][2] = -1.0;
+ xi[4][8][0] = +0.7745966692414834; xi[4][8][1] = +0.7745966692414834; xi[4][8][2] = -1.0;
+
+ xi[5][0][0] = -0.7745966692414834; xi[5][0][1] = -0.7745966692414834; xi[5][0][2] = +1.0;
+ xi[5][1][0] = 0.0; xi[5][1][1] = -0.7745966692414834; xi[5][1][2] = +1.0;
+ xi[5][2][0] = +0.7745966692414834; xi[5][2][1] = -0.7745966692414834; xi[5][2][2] = +1.0;
+ xi[5][3][0] = -0.7745966692414834; xi[5][3][1] = 0.0; xi[5][3][2] = +1.0;
+ xi[5][4][0] = 0.0; xi[5][4][1] = 0.0; xi[5][4][2] = +1.0;
+ xi[5][5][0] = +0.7745966692414834; xi[5][5][1] = 0.0; xi[5][5][2] = +1.0;
+ xi[5][6][0] = -0.7745966692414834; xi[5][6][1] = +0.7745966692414834; xi[5][6][2] = +1.0;
+ xi[5][7][0] = 0.0; xi[5][7][1] = +0.7745966692414834; xi[5][7][2] = +1.0;
+ xi[5][8][0] = +0.7745966692414834; xi[5][8][1] = +0.7745966692414834; xi[5][8][2] = +1.0;
+
+ feMesh = BuildMeshQuadratic( 3, sizes, minCrd, maxCrd );
+ elType = FeMesh_GetElementType( feMesh, 0 );
+
+ for( face_i = 0; face_i < 6; face_i++ ) {
+ faceArea = 0.0;
+ for( ip_i = 0; ip_i < 9; ip_i++ ) {
+ faceIndex = ElementType_SurfaceNormal( elType, 0, 3, xi[face_i][ip_i], norm );
+ detJac = ElementType_JacobianDeterminantSurface( elType, feMesh, 0, xi[face_i][ip_i], faceIndex, faceAxis[face_i] );
+
+ faceArea += detJac * weight[ip_i];
+ }
+
+ pcu_check_true( fabs( faceArea - 1.0 ) < EPSILON );
+ }
+
+ Stg_Component_Destroy( feMesh, NULL, True );
+}
+
+void ElementTypeSuite( pcu_suite_t* suite ) {
+ pcu_suite_setData( suite, ElementTypeSuiteData );
+ pcu_suite_setFixtures( suite, ElementTypeSuite_Setup, ElementTypeSuite_Teardown );
+ pcu_suite_addTest( suite, ElementTypeSuite_TestLinear2D );
+ pcu_suite_addTest( suite, ElementTypeSuite_TestLinear3D );
+ pcu_suite_addTest( suite, ElementTypeSuite_TestQuadratic2D );
+ pcu_suite_addTest( suite, ElementTypeSuite_TestQuadratic3D );
+ pcu_suite_addTest( suite, ElementTypeSuite_TestSurfaceJacobian_Linear2D );
+ pcu_suite_addTest( suite, ElementTypeSuite_TestSurfaceJacobian_Linear3D );
+ pcu_suite_addTest( suite, ElementTypeSuite_TestSurfaceJacobian_Quadratic2D );
+ pcu_suite_addTest( suite, ElementTypeSuite_TestSurfaceJacobian_Quadratic3D );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/tests/FeEquationNumberSuite.c
--- a/Discretisation/tests/FeEquationNumberSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,335 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** Role:
-** Tests the FeEquationNumberSuite
-**
-** $Id: testFeEquationNumber.c 3462 2006-02-19 06:53:24Z WalterLandry $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "pcu/pcu.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include "FeEquationNumberSuite.h"
-
-typedef struct {
-} FeEquationNumberSuiteData;
-
-FeEquationNumber* buildEqNum() {
- CartesianGenerator* gen;
- FeMesh* feMesh;
- DofLayout* dofs;
- FeEquationNumber* eqNum;
- Variable_Register* varReg;
- Variable* vars[2];
- int maxDecomp[3] = {0, 1, 1};
- int sizes[3];
- double minCrd[3];
- double maxCrd[3];
- SizeT dataOffs = 1;
- Variable_DataType dataType = Variable_DataType_Double;
- int nDataTypes = 1;
- char* dataNames = "nothing";
- static SizeT structSize = sizeof(double);
- static int arraySize;
- static void* arrayPtrs[2];
- int nRanks;
-
- MPI_Comm_size( MPI_COMM_WORLD, &nRanks );
- sizes[0] = nRanks * 2;
- sizes[1] = sizes[2] = 2;
- minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
- maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nRanks;
-
- gen = CartesianGenerator_New( "", NULL );
- CartesianGenerator_SetDimSize( gen, 3 );
- CartesianGenerator_SetTopologyParams( gen, (unsigned*)sizes, 0, NULL, (unsigned*)maxDecomp );
- CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
- CartesianGenerator_SetShadowDepth( gen, 0 );
-
- feMesh = FeMesh_New( "", NULL );
- Mesh_SetGenerator( feMesh, gen );
- FeMesh_SetElementFamily( feMesh, "linear" );
- Stg_Component_Build( feMesh, NULL, False );
-
- varReg = Variable_Register_New();
-
- arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
- arrayPtrs[0] = Memory_Alloc_Array_Unnamed( double, arraySize );
- arrayPtrs[1] = Memory_Alloc_Array_Unnamed( double, arraySize );
- vars[0] = Variable_New( "one", NULL, 1, &dataOffs, &dataType, (unsigned*)&nDataTypes,
- (Name*)(&dataNames), &structSize, (unsigned*)&arraySize, NULL, arrayPtrs, varReg );
- vars[1] = Variable_New( "two", NULL, 1, &dataOffs, &dataType, (unsigned*)&nDataTypes,
- (Name*)(&dataNames), &structSize, (unsigned*)&arraySize, NULL, arrayPtrs + 1, varReg );
-
- dofs = DofLayout_New( "", NULL, varReg, 0, feMesh );
- dofs->nBaseVariables = 2;
- dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, 2 );
- dofs->baseVariables[0] = vars[0];
- dofs->baseVariables[1] = vars[1];
- Stg_Component_Build( dofs, NULL, False );
- Stg_Component_Initialise( dofs, NULL, False );
-
- eqNum = FeEquationNumber_New( "", NULL, feMesh, dofs, NULL, NULL );
- Stg_Component_Build( eqNum, NULL, False );
- Stg_Component_Initialise( eqNum, NULL, False );
-
- return eqNum;
-}
-
-FeEquationNumber* buildEqNumBCs() {
- CartesianGenerator* gen;
- FeMesh* feMesh;
- DofLayout* dofs;
- FeEquationNumber* eqNum;
- Variable_Register* varReg;
- Variable* vars[2];
- int maxDecomp[3] = {0, 1, 1};
- int sizes[3];
- double minCrd[3];
- double maxCrd[3];
- SizeT dataOffs = 1;
- Variable_DataType dataType = Variable_DataType_Double;
- int nDataTypes = 1;
- char* dataNames = "nothing";
- static SizeT structSize = sizeof(double);
- static int arraySize;
- static void* arrayPtrs[2];
- int nRanks;
- VariableCondition* bcs;
- ConditionFunction_Register* cfReg;
- Dictionary* dict;
- XML_IO_Handler* ioHandler;
- char filename[PCU_PATH_MAX];
-
- MPI_Comm_size( MPI_COMM_WORLD, &nRanks );
- sizes[0] = nRanks * 2;
- sizes[1] = sizes[2] = 2;
- minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
- maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nRanks;
-
- gen = CartesianGenerator_New( "", NULL );
- CartesianGenerator_SetDimSize( gen, 3 );
- CartesianGenerator_SetTopologyParams( gen, (unsigned*)sizes, 0, NULL, (unsigned*)maxDecomp );
- CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
- CartesianGenerator_SetShadowDepth( gen, 0 );
-
- feMesh = FeMesh_New( "", NULL );
- Mesh_SetGenerator( feMesh, gen );
- FeMesh_SetElementFamily( feMesh, "linear" );
- Stg_Component_Build( feMesh, NULL, False );
-
- varReg = Variable_Register_New();
- cfReg = ConditionFunction_Register_New();
-
- arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
- arrayPtrs[0] = Memory_Alloc_Array_Unnamed( double, arraySize );
- arrayPtrs[1] = Memory_Alloc_Array_Unnamed( double, arraySize );
- vars[0] = Variable_New( "one", NULL, 1, &dataOffs, &dataType, (unsigned*)&nDataTypes,
- (Name*)(&dataNames), &structSize, (unsigned*)&arraySize, NULL, arrayPtrs, varReg );
- vars[1] = Variable_New( "two", NULL, 1, &dataOffs, &dataType, (unsigned*)&nDataTypes,
- (Name*)(&dataNames), &structSize, (unsigned*)&arraySize, NULL, arrayPtrs + 1, varReg );
-
- dofs = DofLayout_New( "", NULL, varReg, 0, feMesh );
- dofs->nBaseVariables = 2;
- dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, 2 );
- dofs->baseVariables[0] = vars[0];
- dofs->baseVariables[1] = vars[1];
- Stg_Component_Build( dofs, NULL, False );
- Stg_Component_Initialise( dofs, NULL, False );
-
- ioHandler = XML_IO_Handler_New();
- dict = Dictionary_New();
- pcu_filename_input( "wallVC.xml", filename );
- IO_Handler_ReadAllFromFile( ioHandler, filename, dict );
- bcs = (VariableCondition*)WallVC_New( "", NULL, "wallVC", varReg, cfReg, dict, feMesh );
- Stg_Component_Build( bcs, NULL, False );
- Stg_Component_Initialise( bcs, NULL, False );
-
- eqNum = FeEquationNumber_New( "", NULL, feMesh, dofs, bcs, NULL );
- Stg_Component_Build( eqNum, NULL, False );
- Stg_Component_Initialise( eqNum, NULL, False );
-
- return eqNum;
-}
-
-void FeEquationNumberSuite_Setup( FeEquationNumberSuiteData* data ) {
- Journal_Enable_AllTypedStream( False );
-}
-
-void FeEquationNumberSuite_Teardown( FeEquationNumberSuiteData* data ) {
-}
-
-void FeEquationNumberSuite_TestLocal( FeEquationNumberSuiteData* data ) {
- FeEquationNumber* eqNum;
- FeMesh* feMesh;
- int eqNumsPerProc;
- int curEqNum;
- int nDofs;
- int rank;
- int n_i, dof_i;
-
- eqNum = buildEqNum();
- pcu_check_true( eqNum );
-
- MPI_Comm_rank( MPI_COMM_WORLD, &rank );
- feMesh = eqNum->feMesh;
- eqNumsPerProc = (Mesh_GetDimSize( feMesh ) == 3) ? 27 : (Mesh_GetDimSize( feMesh ) == 2) ? 9 : 3;
- curEqNum = eqNumsPerProc * rank;
- if( rank >= 1 )
- curEqNum -= (eqNumsPerProc / 3) * (rank - 1);
- curEqNum *= 2;
-
- for( n_i = 0; n_i < Mesh_GetLocalSize( feMesh, MT_VERTEX ); n_i++ ) {
- nDofs = eqNum->dofLayout->dofCounts[n_i];
- for( dof_i = 0; dof_i < nDofs; dof_i++ ) {
- if( eqNum->destinationArray[n_i][dof_i] != curEqNum++ )
- break;
- }
- if( dof_i < nDofs )
- break;
- }
- pcu_check_true( n_i == Mesh_GetLocalSize( feMesh, (MeshTopology_Dim)0 ) );
-
- FreeObject( eqNum );
-}
-
-void FeEquationNumberSuite_TestShadow( FeEquationNumberSuiteData* data ) {
- FeEquationNumber* eqNum;
- FeMesh* feMesh;
- int eqNumsPerProc;
- int curEqNum;
- int nDofs;
- int rank;
- int nLocalNodes, nDomainNodes;
- int n_i, dof_i;
-
- eqNum = buildEqNum();
- pcu_check_true( eqNum );
-
- MPI_Comm_rank( MPI_COMM_WORLD, &rank );
- feMesh = eqNum->feMesh;
- eqNumsPerProc = (Mesh_GetDimSize( feMesh ) == 3) ? 27 : (Mesh_GetDimSize( feMesh ) == 2) ? 9 : 3;
- if( rank >= 2 ) {
- curEqNum = eqNumsPerProc;
- curEqNum += 2 * (eqNumsPerProc / 3) * (rank - 2);
- curEqNum += 1;
- }
- else if( rank == 1 )
- curEqNum = 2;
- curEqNum *= 2;
-
- nLocalNodes = Mesh_GetLocalSize( feMesh, MT_VERTEX );
- nDomainNodes = Mesh_GetDomainSize( feMesh, MT_VERTEX );
- for( n_i = nLocalNodes; n_i < nDomainNodes; n_i++ ) {
- nDofs = eqNum->dofLayout->dofCounts[n_i];
- for( dof_i = 0; dof_i < nDofs; dof_i++ ) {
- if( eqNum->destinationArray[n_i][dof_i] != curEqNum++ )
- break;
- }
- if( dof_i < nDofs )
- break;
-
- if( rank == 1 )
- curEqNum += 4;
- else
- curEqNum += 2;
- }
- pcu_check_true( n_i == Mesh_GetDomainSize( feMesh, (MeshTopology_Dim)0 ) );
-
- FreeObject( eqNum );
-}
-
-void FeEquationNumberSuite_TestBCs( FeEquationNumberSuiteData* data ) {
- FeEquationNumber* eqNum;
- FeMesh* feMesh;
- unsigned nLocalNodes, nDomainNodes;
- unsigned eqNumsPerProc;
- unsigned curEqNum;
- unsigned nDofs;
- unsigned dof_i;
- unsigned eq;
- int rank;
- unsigned n_i;
-
- eqNum = buildEqNumBCs();
- pcu_check_true( eqNum );
-
- MPI_Comm_rank( MPI_COMM_WORLD, &rank );
- feMesh = eqNum->feMesh;
- eqNumsPerProc = (Mesh_GetDimSize( feMesh ) == 3) ? 18 : (Mesh_GetDimSize( feMesh ) == 2) ? 6 : 0;
- if( rank >= 2 ) {
- curEqNum = eqNumsPerProc;
- curEqNum += 2 * (eqNumsPerProc / 3) * (rank - 2);
- curEqNum += 1;
- }
- else if( rank == 1 )
- curEqNum = 2;
- curEqNum *= 2;
-
- nLocalNodes = Mesh_GetLocalSize( feMesh, MT_VERTEX );
- nDomainNodes = Mesh_GetDomainSize( feMesh, MT_VERTEX );
- for( n_i = nLocalNodes; n_i < nDomainNodes; n_i++ ) {
- nDofs = eqNum->dofLayout->dofCounts[n_i];
- for( dof_i = 0; dof_i < nDofs; dof_i++ ) {
- eq = eqNum->destinationArray[n_i][dof_i];
-
- if( n_i % 3 == 0 ) {
- if( eq != (unsigned)-1 )
- break;
- }
- else if( eq != curEqNum++ )
- break;
- }
- if( dof_i < nDofs )
- break;
-
- if( n_i % 3 != 0 ) {
- if( rank == 1 )
- curEqNum += 4;
- else
- curEqNum += 2;
- }
- }
- pcu_check_true( n_i == nDomainNodes );
-
- FreeObject( eqNum );
-}
-
-void FeEquationNumberSuite( pcu_suite_t* suite ) {
- pcu_suite_setData( suite, FeEquationNumberSuiteData );
- pcu_suite_setFixtures( suite, FeEquationNumberSuite_Setup, FeEquationNumberSuite_Teardown );
- pcu_suite_addTest( suite, FeEquationNumberSuite_TestLocal );
- pcu_suite_addTest( suite, FeEquationNumberSuite_TestShadow );
- pcu_suite_addTest( suite, FeEquationNumberSuite_TestBCs );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/tests/FeEquationNumberSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/tests/FeEquationNumberSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,335 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** Role:
+** Tests the FeEquationNumberSuite
+**
+** $Id: testFeEquationNumber.c 3462 2006-02-19 06:53:24Z WalterLandry $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pcu/pcu.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include "FeEquationNumberSuite.h"
+
+typedef struct {
+} FeEquationNumberSuiteData;
+
+FeEquationNumber* buildEqNum() {
+ CartesianGenerator* gen;
+ FeMesh* feMesh;
+ DofLayout* dofs;
+ FeEquationNumber* eqNum;
+ Variable_Register* varReg;
+ Variable* vars[2];
+ int maxDecomp[3] = {0, 1, 1};
+ int sizes[3];
+ double minCrd[3];
+ double maxCrd[3];
+ SizeT dataOffs = 1;
+ Variable_DataType dataType = Variable_DataType_Double;
+ int nDataTypes = 1;
+ char* dataNames = "nothing";
+ static SizeT structSize = sizeof(double);
+ static int arraySize;
+ static void* arrayPtrs[2];
+ int nRanks;
+
+ MPI_Comm_size( MPI_COMM_WORLD, &nRanks );
+ sizes[0] = nRanks * 2;
+ sizes[1] = sizes[2] = 2;
+ minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
+ maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nRanks;
+
+ gen = CartesianGenerator_New( "", NULL );
+ CartesianGenerator_SetDimSize( gen, 3 );
+ CartesianGenerator_SetTopologyParams( gen, (unsigned*)sizes, 0, NULL, (unsigned*)maxDecomp );
+ CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+ CartesianGenerator_SetShadowDepth( gen, 0 );
+
+ feMesh = FeMesh_New( "", NULL );
+ Mesh_SetGenerator( feMesh, gen );
+ FeMesh_SetElementFamily( feMesh, "linear" );
+ Stg_Component_Build( feMesh, NULL, False );
+
+ varReg = Variable_Register_New();
+
+ arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+ arrayPtrs[0] = Memory_Alloc_Array_Unnamed( double, arraySize );
+ arrayPtrs[1] = Memory_Alloc_Array_Unnamed( double, arraySize );
+ vars[0] = Variable_New( "one", NULL, 1, &dataOffs, &dataType, (unsigned*)&nDataTypes,
+ (Name*)(&dataNames), &structSize, (unsigned*)&arraySize, NULL, arrayPtrs, varReg );
+ vars[1] = Variable_New( "two", NULL, 1, &dataOffs, &dataType, (unsigned*)&nDataTypes,
+ (Name*)(&dataNames), &structSize, (unsigned*)&arraySize, NULL, arrayPtrs + 1, varReg );
+
+ dofs = DofLayout_New( "", NULL, varReg, 0, feMesh );
+ dofs->nBaseVariables = 2;
+ dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, 2 );
+ dofs->baseVariables[0] = vars[0];
+ dofs->baseVariables[1] = vars[1];
+ Stg_Component_Build( dofs, NULL, False );
+ Stg_Component_Initialise( dofs, NULL, False );
+
+ eqNum = FeEquationNumber_New( "", NULL, feMesh, dofs, NULL, NULL );
+ Stg_Component_Build( eqNum, NULL, False );
+ Stg_Component_Initialise( eqNum, NULL, False );
+
+ return eqNum;
+}
+
+FeEquationNumber* buildEqNumBCs() {
+ CartesianGenerator* gen;
+ FeMesh* feMesh;
+ DofLayout* dofs;
+ FeEquationNumber* eqNum;
+ Variable_Register* varReg;
+ Variable* vars[2];
+ int maxDecomp[3] = {0, 1, 1};
+ int sizes[3];
+ double minCrd[3];
+ double maxCrd[3];
+ SizeT dataOffs = 1;
+ Variable_DataType dataType = Variable_DataType_Double;
+ int nDataTypes = 1;
+ char* dataNames = "nothing";
+ static SizeT structSize = sizeof(double);
+ static int arraySize;
+ static void* arrayPtrs[2];
+ int nRanks;
+ VariableCondition* bcs;
+ ConditionFunction_Register* cfReg;
+ Dictionary* dict;
+ XML_IO_Handler* ioHandler;
+ char filename[PCU_PATH_MAX];
+
+ MPI_Comm_size( MPI_COMM_WORLD, &nRanks );
+ sizes[0] = nRanks * 2;
+ sizes[1] = sizes[2] = 2;
+ minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
+ maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nRanks;
+
+ gen = CartesianGenerator_New( "", NULL );
+ CartesianGenerator_SetDimSize( gen, 3 );
+ CartesianGenerator_SetTopologyParams( gen, (unsigned*)sizes, 0, NULL, (unsigned*)maxDecomp );
+ CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+ CartesianGenerator_SetShadowDepth( gen, 0 );
+
+ feMesh = FeMesh_New( "", NULL );
+ Mesh_SetGenerator( feMesh, gen );
+ FeMesh_SetElementFamily( feMesh, "linear" );
+ Stg_Component_Build( feMesh, NULL, False );
+
+ varReg = Variable_Register_New();
+ cfReg = ConditionFunction_Register_New();
+
+ arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+ arrayPtrs[0] = Memory_Alloc_Array_Unnamed( double, arraySize );
+ arrayPtrs[1] = Memory_Alloc_Array_Unnamed( double, arraySize );
+ vars[0] = Variable_New( "one", NULL, 1, &dataOffs, &dataType, (unsigned*)&nDataTypes,
+ (Name*)(&dataNames), &structSize, (unsigned*)&arraySize, NULL, arrayPtrs, varReg );
+ vars[1] = Variable_New( "two", NULL, 1, &dataOffs, &dataType, (unsigned*)&nDataTypes,
+ (Name*)(&dataNames), &structSize, (unsigned*)&arraySize, NULL, arrayPtrs + 1, varReg );
+
+ dofs = DofLayout_New( "", NULL, varReg, 0, feMesh );
+ dofs->nBaseVariables = 2;
+ dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, 2 );
+ dofs->baseVariables[0] = vars[0];
+ dofs->baseVariables[1] = vars[1];
+ Stg_Component_Build( dofs, NULL, False );
+ Stg_Component_Initialise( dofs, NULL, False );
+
+ ioHandler = XML_IO_Handler_New();
+ dict = Dictionary_New();
+ pcu_filename_input( "wallVC.xml", filename );
+ IO_Handler_ReadAllFromFile( ioHandler, filename, dict );
+ bcs = (VariableCondition*)WallVC_New( "", NULL, "wallVC", varReg, cfReg, dict, feMesh );
+ Stg_Component_Build( bcs, NULL, False );
+ Stg_Component_Initialise( bcs, NULL, False );
+
+ eqNum = FeEquationNumber_New( "", NULL, feMesh, dofs, bcs, NULL );
+ Stg_Component_Build( eqNum, NULL, False );
+ Stg_Component_Initialise( eqNum, NULL, False );
+
+ return eqNum;
+}
+
+void FeEquationNumberSuite_Setup( FeEquationNumberSuiteData* data ) {
+ Journal_Enable_AllTypedStream( False );
+}
+
+void FeEquationNumberSuite_Teardown( FeEquationNumberSuiteData* data ) {
+}
+
+void FeEquationNumberSuite_TestLocal( FeEquationNumberSuiteData* data ) {
+ FeEquationNumber* eqNum;
+ FeMesh* feMesh;
+ int eqNumsPerProc;
+ int curEqNum;
+ int nDofs;
+ int rank;
+ int n_i, dof_i;
+
+ eqNum = buildEqNum();
+ pcu_check_true( eqNum );
+
+ MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+ feMesh = eqNum->feMesh;
+ eqNumsPerProc = (Mesh_GetDimSize( feMesh ) == 3) ? 27 : (Mesh_GetDimSize( feMesh ) == 2) ? 9 : 3;
+ curEqNum = eqNumsPerProc * rank;
+ if( rank >= 1 )
+ curEqNum -= (eqNumsPerProc / 3) * (rank - 1);
+ curEqNum *= 2;
+
+ for( n_i = 0; n_i < Mesh_GetLocalSize( feMesh, MT_VERTEX ); n_i++ ) {
+ nDofs = eqNum->dofLayout->dofCounts[n_i];
+ for( dof_i = 0; dof_i < nDofs; dof_i++ ) {
+ if( eqNum->destinationArray[n_i][dof_i] != curEqNum++ )
+ break;
+ }
+ if( dof_i < nDofs )
+ break;
+ }
+ pcu_check_true( n_i == Mesh_GetLocalSize( feMesh, (MeshTopology_Dim)0 ) );
+
+ FreeObject( eqNum );
+}
+
+void FeEquationNumberSuite_TestShadow( FeEquationNumberSuiteData* data ) {
+ FeEquationNumber* eqNum;
+ FeMesh* feMesh;
+ int eqNumsPerProc;
+ int curEqNum;
+ int nDofs;
+ int rank;
+ int nLocalNodes, nDomainNodes;
+ int n_i, dof_i;
+
+ eqNum = buildEqNum();
+ pcu_check_true( eqNum );
+
+ MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+ feMesh = eqNum->feMesh;
+ eqNumsPerProc = (Mesh_GetDimSize( feMesh ) == 3) ? 27 : (Mesh_GetDimSize( feMesh ) == 2) ? 9 : 3;
+ if( rank >= 2 ) {
+ curEqNum = eqNumsPerProc;
+ curEqNum += 2 * (eqNumsPerProc / 3) * (rank - 2);
+ curEqNum += 1;
+ }
+ else if( rank == 1 )
+ curEqNum = 2;
+ curEqNum *= 2;
+
+ nLocalNodes = Mesh_GetLocalSize( feMesh, MT_VERTEX );
+ nDomainNodes = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+ for( n_i = nLocalNodes; n_i < nDomainNodes; n_i++ ) {
+ nDofs = eqNum->dofLayout->dofCounts[n_i];
+ for( dof_i = 0; dof_i < nDofs; dof_i++ ) {
+ if( eqNum->destinationArray[n_i][dof_i] != curEqNum++ )
+ break;
+ }
+ if( dof_i < nDofs )
+ break;
+
+ if( rank == 1 )
+ curEqNum += 4;
+ else
+ curEqNum += 2;
+ }
+ pcu_check_true( n_i == Mesh_GetDomainSize( feMesh, (MeshTopology_Dim)0 ) );
+
+ FreeObject( eqNum );
+}
+
+void FeEquationNumberSuite_TestBCs( FeEquationNumberSuiteData* data ) {
+ FeEquationNumber* eqNum;
+ FeMesh* feMesh;
+ unsigned nLocalNodes, nDomainNodes;
+ unsigned eqNumsPerProc;
+ unsigned curEqNum;
+ unsigned nDofs;
+ unsigned dof_i;
+ unsigned eq;
+ int rank;
+ unsigned n_i;
+
+ eqNum = buildEqNumBCs();
+ pcu_check_true( eqNum );
+
+ MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+ feMesh = eqNum->feMesh;
+ eqNumsPerProc = (Mesh_GetDimSize( feMesh ) == 3) ? 18 : (Mesh_GetDimSize( feMesh ) == 2) ? 6 : 0;
+ if( rank >= 2 ) {
+ curEqNum = eqNumsPerProc;
+ curEqNum += 2 * (eqNumsPerProc / 3) * (rank - 2);
+ curEqNum += 1;
+ }
+ else if( rank == 1 )
+ curEqNum = 2;
+ curEqNum *= 2;
+
+ nLocalNodes = Mesh_GetLocalSize( feMesh, MT_VERTEX );
+ nDomainNodes = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+ for( n_i = nLocalNodes; n_i < nDomainNodes; n_i++ ) {
+ nDofs = eqNum->dofLayout->dofCounts[n_i];
+ for( dof_i = 0; dof_i < nDofs; dof_i++ ) {
+ eq = eqNum->destinationArray[n_i][dof_i];
+
+ if( n_i % 3 == 0 ) {
+ if( eq != (unsigned)-1 )
+ break;
+ }
+ else if( eq != curEqNum++ )
+ break;
+ }
+ if( dof_i < nDofs )
+ break;
+
+ if( n_i % 3 != 0 ) {
+ if( rank == 1 )
+ curEqNum += 4;
+ else
+ curEqNum += 2;
+ }
+ }
+ pcu_check_true( n_i == nDomainNodes );
+
+ FreeObject( eqNum );
+}
+
+void FeEquationNumberSuite( pcu_suite_t* suite ) {
+ pcu_suite_setData( suite, FeEquationNumberSuiteData );
+ pcu_suite_setFixtures( suite, FeEquationNumberSuite_Setup, FeEquationNumberSuite_Teardown );
+ pcu_suite_addTest( suite, FeEquationNumberSuite_TestLocal );
+ pcu_suite_addTest( suite, FeEquationNumberSuite_TestShadow );
+ pcu_suite_addTest( suite, FeEquationNumberSuite_TestBCs );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/tests/FeVariableSuite.c
--- a/Discretisation/tests/FeVariableSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,283 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** Role:
-** Tests the FeVariableSuite
-**
-** $Id: testFeVariable.c 3462 2006-02-19 06:53:24Z WalterLandry $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "pcu/pcu.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include "FeVariableSuite.h"
-
-#define EPSILON 1.0E-6
-
-typedef struct {
-} FeVariableSuiteData;
-
-struct _Particle {
- __IntegrationPoint;
-};
-
-FeVariable* BuildFeVariable_AsPosition( unsigned dim ) {
- CartesianGenerator* gen;
- FeMesh* feMesh;
- DofLayout* dofs;
- FeEquationNumber* eqNum;
- Variable_Register* varReg;
- int maxDecomp[3] = {0, 1, 1};
- int sizes[3];
- double minCrd[3];
- double maxCrd[3];
- static int arraySize;
- static double* arrayPtrs[3];
- int nRanks;
- Variable* var;
- FieldVariable_Register* fieldReg;
- FeVariable* feVar;
- int n_i;
-
- MPI_Comm_size( MPI_COMM_WORLD, &nRanks );
- sizes[0] = nRanks * 3;
- sizes[1] = sizes[2] = 3;
- minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
- maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nRanks;
-
- gen = CartesianGenerator_New( "", NULL );
- CartesianGenerator_SetDimSize( gen, dim );
- CartesianGenerator_SetTopologyParams( gen, (unsigned*)sizes, 0, NULL, (unsigned*)maxDecomp );
- CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
- CartesianGenerator_SetShadowDepth( gen, 0 );
-
- feMesh = FeMesh_New( "", NULL );
- Mesh_SetGenerator( feMesh, gen );
- FeMesh_SetElementFamily( feMesh, "linear" );
- Stg_Component_Build( feMesh, NULL, False );
-
- varReg = Variable_Register_New();
-
- arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
- arrayPtrs[0] = Memory_Alloc_Array_Unnamed( double, arraySize * dim );
-
- var = Variable_NewVector( "velocity", NULL, Variable_DataType_Double, dim, (unsigned*)&arraySize, NULL,
- (void**)arrayPtrs, varReg, "vx", "vy", "vz" );
- Variable_Register_BuildAll( varReg );
-
- dofs = DofLayout_New( "", NULL, varReg, 0, feMesh );
- dofs->nBaseVariables = dim;
- dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, dim );
- dofs->baseVariables[0] = var->components[0];
- dofs->baseVariables[1] = var->components[1];
- dofs->baseVariables[2] = var->components[2];
- Stg_Component_Build( dofs, NULL, False );
- Stg_Component_Initialise( dofs, NULL, False );
-
- eqNum = FeEquationNumber_New( "", NULL, feMesh, dofs, NULL, NULL );
- Stg_Component_Build( eqNum, NULL, False );
- Stg_Component_Initialise( eqNum, NULL, False );
-
- fieldReg = FieldVariable_Register_New();
- feVar = FeVariable_New( "velocity", NULL, feMesh, NULL, dofs, NULL, NULL, NULL, dim, True, False, False, fieldReg );
-
- for( n_i = 0; n_i < Mesh_GetLocalSize( feMesh, (MeshTopology_Dim)0 ); n_i++ ) {
- double* pos = Mesh_GetVertex( feMesh, n_i );
- Variable_SetValue( var, n_i, pos );
- }
-
- /* Build and initialise system */
- Stg_Component_Build( feVar, 0, False );
- Stg_Component_Initialise( feVar, 0, False );
-
- return feVar;
-}
-
-FeVariable* BuildFeVariable_AsConstant( unsigned dim ) {
- CartesianGenerator* gen;
- FeMesh* feMesh;
- DofLayout* dofs;
- FeEquationNumber* eqNum;
- Variable_Register* varReg;
- int maxDecomp[3] = {0, 1, 1};
- int sizes[3];
- double minCrd[3];
- double maxCrd[3];
- static int arraySize;
- static double* arrayPtr;
- int nRanks;
- Variable* var;
- FieldVariable_Register* fieldReg;
- FeVariable* feVar;
- int n_i;
- double constant[3] = {1.0, 1.0, 1.0};
-
- MPI_Comm_size( MPI_COMM_WORLD, &nRanks );
- sizes[0] = nRanks * 3;
- sizes[1] = sizes[2] = 3;
- minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
- maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nRanks;
-
- gen = CartesianGenerator_New( "", NULL );
- CartesianGenerator_SetDimSize( gen, dim );
- CartesianGenerator_SetTopologyParams( gen, (unsigned*)sizes, 0, NULL, (unsigned*)maxDecomp );
- CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
- CartesianGenerator_SetShadowDepth( gen, 0 );
-
- feMesh = FeMesh_New( "", NULL );
- Mesh_SetGenerator( feMesh, gen );
- FeMesh_SetElementFamily( feMesh, "linear" );
- Stg_Component_Build( feMesh, NULL, False );
-
- varReg = Variable_Register_New();
-
- arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
- arrayPtr = Memory_Alloc_Array_Unnamed( double, arraySize );
-
- var = Variable_NewScalar( "pressure", NULL, Variable_DataType_Double, (Index*)(unsigned*)&arraySize, NULL, (void**)&arrayPtr, varReg );
- Variable_Register_BuildAll( varReg );
-
- dofs = DofLayout_New( "", NULL, varReg, 0, feMesh );
- dofs->nBaseVariables = 1;
- dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, 1 );
- dofs->baseVariables[0] = var;
- Stg_Component_Build( dofs, NULL, False );
- Stg_Component_Initialise( dofs, NULL, False );
-
- eqNum = FeEquationNumber_New( "", NULL, feMesh, dofs, NULL, NULL );
- Stg_Component_Build( eqNum, NULL, False );
- Stg_Component_Initialise( eqNum, NULL, False );
-
- fieldReg = FieldVariable_Register_New();
- feVar = FeVariable_New( "pressure", NULL, feMesh, NULL, dofs, NULL, NULL, NULL, dim, True, False, False, fieldReg );
-
- for( n_i = 0; n_i < Mesh_GetLocalSize( feMesh, (MeshTopology_Dim)0 ); n_i++ ) {
- Variable_SetValue( var, n_i, constant );
- }
-
- /* Build and initialise system */
- Stg_Component_Build( feVar, 0, False );
- Stg_Component_Initialise( feVar, 0, False );
-
- return feVar;
-}
-
-Swarm* BuildSwarm( FeMesh* mesh ) {
- ElementCellLayout* elCellLayout;
- GaussParticleLayout* gaussLayout;
- ExtensionManager_Register* extMgr_Reg;
- Swarm* swarm;
- unsigned dim = Mesh_GetDimSize( mesh );
- unsigned partPerDim[3] = { 2, 2, 2 };
-
- extMgr_Reg = ExtensionManager_Register_New();
- elCellLayout = ElementCellLayout_New( "elementCellLayout", NULL, mesh );
- gaussLayout = GaussParticleLayout_New( "gaussParticleLayout", NULL, LocalCoordSystem, True, dim, partPerDim );
- swarm = Swarm_New( "gaussSwarm", NULL, elCellLayout, gaussLayout, dim, sizeof(Particle), extMgr_Reg, NULL, MPI_COMM_WORLD, NULL );
-
- Stg_Component_Build( swarm, NULL, True );
- Stg_Component_Initialise( swarm, NULL, True );
-
- return swarm;
-}
-
-void FeVariableSuite_Setup( FeVariableSuiteData* data ) {
-}
-
-void FeVariableSuite_Teardown( FeVariableSuiteData* data ) {
-}
-
-void FeVariableSuite_Interpolate( FeVariableSuiteData* data ) {
- FeVariable* feVar = BuildFeVariable_AsPosition( 3 );
- IArray* inc = IArray_New();
- unsigned el_i;
- unsigned vert_i;
- unsigned nVerts;
- unsigned* verts;
- double* vert;
- double value[3];
- InterpolationResult interpRes;
- unsigned dim_i;
-
- for( el_i = 0; el_i < Mesh_GetDomainSize( feVar->feMesh, (MeshTopology_Dim)3 ); el_i++ ) {
- Mesh_GetIncidence( feVar->feMesh, (MeshTopology_Dim)3, el_i, MT_VERTEX, inc );
- nVerts = IArray_GetSize( inc );
- verts = (unsigned*)IArray_GetPtr( inc );
-
- for( vert_i = 0; vert_i < nVerts; vert_i++ ) {
- vert = Mesh_GetVertex( feVar->feMesh, verts[vert_i] );
- interpRes = FieldVariable_InterpolateValueAt( feVar, vert, value );
-
- if( interpRes != LOCAL && interpRes != SHADOW )
- continue;
-
- for( dim_i = 0; dim_i < 3; dim_i++ ) {
- pcu_check_true( fabs( vert[dim_i] - value[dim_i] ) < EPSILON );
- }
- }
- }
-
- NewClass_Delete( inc );
- Stg_Component_Destroy( feVar, NULL, True );
-}
-
-void FeVariableSuite_Integrate( FeVariableSuiteData* data ) {
- FeVariable* feVar;
- Swarm* swarm;
- double globalMin[3];
- double globalMax[3];
- double volFromSize = 1.0;
- double volFromInt;
- unsigned dim_i;
-
- feVar = BuildFeVariable_AsConstant( 3 );
- swarm = BuildSwarm( feVar->feMesh );
-
- Mesh_GetGlobalCoordRange( feVar->feMesh, globalMin, globalMax );
- for( dim_i = 0; dim_i < 3; dim_i++ )
- volFromSize *= globalMax[dim_i] - globalMin[dim_i];
-
- volFromInt = FeVariable_Integrate( feVar, swarm );
-
- pcu_check_true( fabs( volFromSize - volFromInt ) < EPSILON );
-
- Stg_Component_Destroy( feVar, NULL, True );
- Stg_Component_Destroy( swarm, NULL, True );
-}
-
-void FeVariableSuite( pcu_suite_t* suite ) {
- pcu_suite_setData( suite, FeVariableSuiteData );
- pcu_suite_setFixtures( suite, FeVariableSuite_Setup, FeVariableSuite_Teardown );
- pcu_suite_addTest( suite, FeVariableSuite_Interpolate );
- pcu_suite_addTest( suite, FeVariableSuite_Integrate );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/tests/FeVariableSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/tests/FeVariableSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,283 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** Role:
+** Tests the FeVariableSuite
+**
+** $Id: testFeVariable.c 3462 2006-02-19 06:53:24Z WalterLandry $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pcu/pcu.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include "FeVariableSuite.h"
+
+#define EPSILON 1.0E-6
+
+typedef struct {
+} FeVariableSuiteData;
+
+struct _Particle {
+ __IntegrationPoint;
+};
+
+FeVariable* BuildFeVariable_AsPosition( unsigned dim ) {
+ CartesianGenerator* gen;
+ FeMesh* feMesh;
+ DofLayout* dofs;
+ FeEquationNumber* eqNum;
+ Variable_Register* varReg;
+ int maxDecomp[3] = {0, 1, 1};
+ int sizes[3];
+ double minCrd[3];
+ double maxCrd[3];
+ static int arraySize;
+ static double* arrayPtrs[3];
+ int nRanks;
+ Variable* var;
+ FieldVariable_Register* fieldReg;
+ FeVariable* feVar;
+ int n_i;
+
+ MPI_Comm_size( MPI_COMM_WORLD, &nRanks );
+ sizes[0] = nRanks * 3;
+ sizes[1] = sizes[2] = 3;
+ minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
+ maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nRanks;
+
+ gen = CartesianGenerator_New( "", NULL );
+ CartesianGenerator_SetDimSize( gen, dim );
+ CartesianGenerator_SetTopologyParams( gen, (unsigned*)sizes, 0, NULL, (unsigned*)maxDecomp );
+ CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+ CartesianGenerator_SetShadowDepth( gen, 0 );
+
+ feMesh = FeMesh_New( "", NULL );
+ Mesh_SetGenerator( feMesh, gen );
+ FeMesh_SetElementFamily( feMesh, "linear" );
+ Stg_Component_Build( feMesh, NULL, False );
+
+ varReg = Variable_Register_New();
+
+ arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+ arrayPtrs[0] = Memory_Alloc_Array_Unnamed( double, arraySize * dim );
+
+ var = Variable_NewVector( "velocity", NULL, Variable_DataType_Double, dim, (unsigned*)&arraySize, NULL,
+ (void**)arrayPtrs, varReg, "vx", "vy", "vz" );
+ Variable_Register_BuildAll( varReg );
+
+ dofs = DofLayout_New( "", NULL, varReg, 0, feMesh );
+ dofs->nBaseVariables = dim;
+ dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, dim );
+ dofs->baseVariables[0] = var->components[0];
+ dofs->baseVariables[1] = var->components[1];
+ dofs->baseVariables[2] = var->components[2];
+ Stg_Component_Build( dofs, NULL, False );
+ Stg_Component_Initialise( dofs, NULL, False );
+
+ eqNum = FeEquationNumber_New( "", NULL, feMesh, dofs, NULL, NULL );
+ Stg_Component_Build( eqNum, NULL, False );
+ Stg_Component_Initialise( eqNum, NULL, False );
+
+ fieldReg = FieldVariable_Register_New();
+ feVar = FeVariable_New( "velocity", NULL, feMesh, NULL, dofs, NULL, NULL, NULL, dim, True, False, False, fieldReg );
+
+ for( n_i = 0; n_i < Mesh_GetLocalSize( feMesh, (MeshTopology_Dim)0 ); n_i++ ) {
+ double* pos = Mesh_GetVertex( feMesh, n_i );
+ Variable_SetValue( var, n_i, pos );
+ }
+
+ /* Build and initialise system */
+ Stg_Component_Build( feVar, 0, False );
+ Stg_Component_Initialise( feVar, 0, False );
+
+ return feVar;
+}
+
+FeVariable* BuildFeVariable_AsConstant( unsigned dim ) {
+ CartesianGenerator* gen;
+ FeMesh* feMesh;
+ DofLayout* dofs;
+ FeEquationNumber* eqNum;
+ Variable_Register* varReg;
+ int maxDecomp[3] = {0, 1, 1};
+ int sizes[3];
+ double minCrd[3];
+ double maxCrd[3];
+ static int arraySize;
+ static double* arrayPtr;
+ int nRanks;
+ Variable* var;
+ FieldVariable_Register* fieldReg;
+ FeVariable* feVar;
+ int n_i;
+ double constant[3] = {1.0, 1.0, 1.0};
+
+ MPI_Comm_size( MPI_COMM_WORLD, &nRanks );
+ sizes[0] = nRanks * 3;
+ sizes[1] = sizes[2] = 3;
+ minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
+ maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nRanks;
+
+ gen = CartesianGenerator_New( "", NULL );
+ CartesianGenerator_SetDimSize( gen, dim );
+ CartesianGenerator_SetTopologyParams( gen, (unsigned*)sizes, 0, NULL, (unsigned*)maxDecomp );
+ CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+ CartesianGenerator_SetShadowDepth( gen, 0 );
+
+ feMesh = FeMesh_New( "", NULL );
+ Mesh_SetGenerator( feMesh, gen );
+ FeMesh_SetElementFamily( feMesh, "linear" );
+ Stg_Component_Build( feMesh, NULL, False );
+
+ varReg = Variable_Register_New();
+
+ arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+ arrayPtr = Memory_Alloc_Array_Unnamed( double, arraySize );
+
+ var = Variable_NewScalar( "pressure", NULL, Variable_DataType_Double, (Index*)(unsigned*)&arraySize, NULL, (void**)&arrayPtr, varReg );
+ Variable_Register_BuildAll( varReg );
+
+ dofs = DofLayout_New( "", NULL, varReg, 0, feMesh );
+ dofs->nBaseVariables = 1;
+ dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, 1 );
+ dofs->baseVariables[0] = var;
+ Stg_Component_Build( dofs, NULL, False );
+ Stg_Component_Initialise( dofs, NULL, False );
+
+ eqNum = FeEquationNumber_New( "", NULL, feMesh, dofs, NULL, NULL );
+ Stg_Component_Build( eqNum, NULL, False );
+ Stg_Component_Initialise( eqNum, NULL, False );
+
+ fieldReg = FieldVariable_Register_New();
+ feVar = FeVariable_New( "pressure", NULL, feMesh, NULL, dofs, NULL, NULL, NULL, dim, True, False, False, fieldReg );
+
+ for( n_i = 0; n_i < Mesh_GetLocalSize( feMesh, (MeshTopology_Dim)0 ); n_i++ ) {
+ Variable_SetValue( var, n_i, constant );
+ }
+
+ /* Build and initialise system */
+ Stg_Component_Build( feVar, 0, False );
+ Stg_Component_Initialise( feVar, 0, False );
+
+ return feVar;
+}
+
+Swarm* BuildSwarm( FeMesh* mesh ) {
+ ElementCellLayout* elCellLayout;
+ GaussParticleLayout* gaussLayout;
+ ExtensionManager_Register* extMgr_Reg;
+ Swarm* swarm;
+ unsigned dim = Mesh_GetDimSize( mesh );
+ unsigned partPerDim[3] = { 2, 2, 2 };
+
+ extMgr_Reg = ExtensionManager_Register_New();
+ elCellLayout = ElementCellLayout_New( "elementCellLayout", NULL, mesh );
+ gaussLayout = GaussParticleLayout_New( "gaussParticleLayout", NULL, LocalCoordSystem, True, dim, partPerDim );
+ swarm = Swarm_New( "gaussSwarm", NULL, elCellLayout, gaussLayout, dim, sizeof(Particle), extMgr_Reg, NULL, MPI_COMM_WORLD, NULL );
+
+ Stg_Component_Build( swarm, NULL, True );
+ Stg_Component_Initialise( swarm, NULL, True );
+
+ return swarm;
+}
+
+void FeVariableSuite_Setup( FeVariableSuiteData* data ) {
+}
+
+void FeVariableSuite_Teardown( FeVariableSuiteData* data ) {
+}
+
+void FeVariableSuite_Interpolate( FeVariableSuiteData* data ) {
+ FeVariable* feVar = BuildFeVariable_AsPosition( 3 );
+ IArray* inc = IArray_New();
+ unsigned el_i;
+ unsigned vert_i;
+ unsigned nVerts;
+ unsigned* verts;
+ double* vert;
+ double value[3];
+ InterpolationResult interpRes;
+ unsigned dim_i;
+
+ for( el_i = 0; el_i < Mesh_GetDomainSize( feVar->feMesh, (MeshTopology_Dim)3 ); el_i++ ) {
+ Mesh_GetIncidence( feVar->feMesh, (MeshTopology_Dim)3, el_i, MT_VERTEX, inc );
+ nVerts = IArray_GetSize( inc );
+ verts = (unsigned*)IArray_GetPtr( inc );
+
+ for( vert_i = 0; vert_i < nVerts; vert_i++ ) {
+ vert = Mesh_GetVertex( feVar->feMesh, verts[vert_i] );
+ interpRes = FieldVariable_InterpolateValueAt( feVar, vert, value );
+
+ if( interpRes != LOCAL && interpRes != SHADOW )
+ continue;
+
+ for( dim_i = 0; dim_i < 3; dim_i++ ) {
+ pcu_check_true( fabs( vert[dim_i] - value[dim_i] ) < EPSILON );
+ }
+ }
+ }
+
+ NewClass_Delete( inc );
+ Stg_Component_Destroy( feVar, NULL, True );
+}
+
+void FeVariableSuite_Integrate( FeVariableSuiteData* data ) {
+ FeVariable* feVar;
+ Swarm* swarm;
+ double globalMin[3];
+ double globalMax[3];
+ double volFromSize = 1.0;
+ double volFromInt;
+ unsigned dim_i;
+
+ feVar = BuildFeVariable_AsConstant( 3 );
+ swarm = BuildSwarm( feVar->feMesh );
+
+ Mesh_GetGlobalCoordRange( feVar->feMesh, globalMin, globalMax );
+ for( dim_i = 0; dim_i < 3; dim_i++ )
+ volFromSize *= globalMax[dim_i] - globalMin[dim_i];
+
+ volFromInt = FeVariable_Integrate( feVar, swarm );
+
+ pcu_check_true( fabs( volFromSize - volFromInt ) < EPSILON );
+
+ Stg_Component_Destroy( feVar, NULL, True );
+ Stg_Component_Destroy( swarm, NULL, True );
+}
+
+void FeVariableSuite( pcu_suite_t* suite ) {
+ pcu_suite_setData( suite, FeVariableSuiteData );
+ pcu_suite_setFixtures( suite, FeVariableSuite_Setup, FeVariableSuite_Teardown );
+ pcu_suite_addTest( suite, FeVariableSuite_Interpolate );
+ pcu_suite_addTest( suite, FeVariableSuite_Integrate );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/tests/TrilinearElementTypeSuite.c
--- a/Discretisation/tests/TrilinearElementTypeSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** Role:
-** Tests the TrilinearElementTypeSuite
-**
-** $Id: testTrilinearElementType.c 3462 2006-02-19 06:53:24Z WalterLandry $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "pcu/pcu.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include "TrilinearElementTypeSuite.h"
-
-typedef struct {
-} TrilinearElementTypeSuiteData;
-
-FeMesh* buildMesh() {
- CartesianGenerator* gen;
- int nRanks;
- unsigned sizes[3];
- double minCrd[3];
- double maxCrd[3];
- FeMesh* mesh;
-
- insist( MPI_Comm_size( MPI_COMM_WORLD, &nRanks ), == MPI_SUCCESS );
- sizes[0] = sizes[1] = sizes[2] = nRanks * 4;
- minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
- maxCrd[0] = minCrd[1] = minCrd[2] = (double)nRanks;
-
- gen = CartesianGenerator_New( "", NULL );
- MeshGenerator_SetDimSize( gen, 3 );
- CartesianGenerator_SetShadowDepth( gen, 1 );
- CartesianGenerator_SetTopologyParams( gen, sizes, 0, NULL, NULL );
- CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
-
- mesh = FeMesh_New( "", NULL );
- Mesh_SetGenerator( mesh, gen );
- FeMesh_SetElementFamily( mesh, "linear" );
- Stg_Component_Build( mesh, NULL, False );
-
- return mesh;
-}
-
-void TrilinearElementTypeSuite_Setup( TrilinearElementTypeSuiteData* data ) {
- Journal_Enable_AllTypedStream( False );
-
- //Stream_RedirectAllToFile( "TrilinearElementTypeSuite" );
-}
-
-void TrilinearElementTypeSuite_Teardown( TrilinearElementTypeSuiteData* data ) {
- //Stream_PurgeAllRedirectedFiles();
-}
-
-void TrilinearElementTypeSuite_TestShape( TrilinearElementTypeSuiteData* data ) {
- FeMesh* mesh = NULL;
- int nEls, nVerts, nDims;
- const int *verts;
- double* vert = NULL;
- double lCrd[3] = { 0.0, 0.0, 0.0 };
- double basis[8] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
- IArray* inc;
- int e_i, v_i, v_j;
-
- mesh = buildMesh();
- pcu_check_true( mesh );
- Stg_Component_Initialise( mesh, data, True );
-
- nDims = Mesh_GetDimSize( mesh );
- nEls = Mesh_GetDomainSize( mesh, (MeshTopology_Dim)nDims );
- inc = IArray_New();
-
- for( e_i = 0; e_i < nEls; e_i++ ) {
- Mesh_GetIncidence( mesh, (MeshTopology_Dim)nDims, e_i, (MeshTopology_Dim)0, inc );
- nVerts = IArray_GetSize( inc );
- verts = IArray_GetPtr( inc );
-
- for( v_i = 0; v_i < nVerts; v_i++ ) {
- vert = Mesh_GetVertex( mesh, verts[v_i] );
- FeMesh_CoordGlobalToLocal( mesh, e_i, vert, lCrd );
- FeMesh_EvalBasis( mesh, e_i, lCrd, basis );
-
- for( v_j = 0; v_j < nVerts; v_j++ ) {
- if( (v_i == v_j && !Num_Approx( basis[v_j], 1.0 )) || (v_i != v_j && !Num_Approx( basis[v_j], 0.0 )) ) {
- break;
- }
- }
- if( v_j < nVerts )
- break;
- }
- if( v_i < nVerts )
- break;
- }
- pcu_check_true( e_i == nEls );
-
- NewClass_Delete( inc );
-
- _Stg_Component_Delete( mesh );
-}
-
-void TrilinearElementTypeSuite( pcu_suite_t* suite ) {
- pcu_suite_setData( suite, TrilinearElementTypeSuiteData );
- pcu_suite_setFixtures( suite, TrilinearElementTypeSuite_Setup, TrilinearElementTypeSuite_Teardown );
- pcu_suite_addTest( suite, TrilinearElementTypeSuite_TestShape );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 Discretisation/tests/TrilinearElementTypeSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Discretisation/tests/TrilinearElementTypeSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,135 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** Role:
+** Tests the TrilinearElementTypeSuite
+**
+** $Id: testTrilinearElementType.c 3462 2006-02-19 06:53:24Z WalterLandry $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pcu/pcu.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include "TrilinearElementTypeSuite.h"
+
+typedef struct {
+} TrilinearElementTypeSuiteData;
+
+FeMesh* buildMesh() {
+ CartesianGenerator* gen;
+ int nRanks;
+ unsigned sizes[3];
+ double minCrd[3];
+ double maxCrd[3];
+ FeMesh* mesh;
+
+ insist( MPI_Comm_size( MPI_COMM_WORLD, &nRanks ), == MPI_SUCCESS );
+ sizes[0] = sizes[1] = sizes[2] = nRanks * 4;
+ minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
+ maxCrd[0] = minCrd[1] = minCrd[2] = (double)nRanks;
+
+ gen = CartesianGenerator_New( "", NULL );
+ MeshGenerator_SetDimSize( gen, 3 );
+ CartesianGenerator_SetShadowDepth( gen, 1 );
+ CartesianGenerator_SetTopologyParams( gen, sizes, 0, NULL, NULL );
+ CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+
+ mesh = FeMesh_New( "", NULL );
+ Mesh_SetGenerator( mesh, gen );
+ FeMesh_SetElementFamily( mesh, "linear" );
+ Stg_Component_Build( mesh, NULL, False );
+
+ return mesh;
+}
+
+void TrilinearElementTypeSuite_Setup( TrilinearElementTypeSuiteData* data ) {
+ Journal_Enable_AllTypedStream( False );
+
+ //Stream_RedirectAllToFile( "TrilinearElementTypeSuite" );
+}
+
+void TrilinearElementTypeSuite_Teardown( TrilinearElementTypeSuiteData* data ) {
+ //Stream_PurgeAllRedirectedFiles();
+}
+
+void TrilinearElementTypeSuite_TestShape( TrilinearElementTypeSuiteData* data ) {
+ FeMesh* mesh = NULL;
+ int nEls, nVerts, nDims;
+ const int *verts;
+ double* vert = NULL;
+ double lCrd[3] = { 0.0, 0.0, 0.0 };
+ double basis[8] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
+ IArray* inc;
+ int e_i, v_i, v_j;
+
+ mesh = buildMesh();
+ pcu_check_true( mesh );
+ Stg_Component_Initialise( mesh, data, True );
+
+ nDims = Mesh_GetDimSize( mesh );
+ nEls = Mesh_GetDomainSize( mesh, (MeshTopology_Dim)nDims );
+ inc = IArray_New();
+
+ for( e_i = 0; e_i < nEls; e_i++ ) {
+ Mesh_GetIncidence( mesh, (MeshTopology_Dim)nDims, e_i, (MeshTopology_Dim)0, inc );
+ nVerts = IArray_GetSize( inc );
+ verts = IArray_GetPtr( inc );
+
+ for( v_i = 0; v_i < nVerts; v_i++ ) {
+ vert = Mesh_GetVertex( mesh, verts[v_i] );
+ FeMesh_CoordGlobalToLocal( mesh, e_i, vert, lCrd );
+ FeMesh_EvalBasis( mesh, e_i, lCrd, basis );
+
+ for( v_j = 0; v_j < nVerts; v_j++ ) {
+ if( (v_i == v_j && !Num_Approx( basis[v_j], 1.0 )) || (v_i != v_j && !Num_Approx( basis[v_j], 0.0 )) ) {
+ break;
+ }
+ }
+ if( v_j < nVerts )
+ break;
+ }
+ if( v_i < nVerts )
+ break;
+ }
+ pcu_check_true( e_i == nEls );
+
+ NewClass_Delete( inc );
+
+ _Stg_Component_Delete( mesh );
+}
+
+void TrilinearElementTypeSuite( pcu_suite_t* suite ) {
+ pcu_suite_setData( suite, TrilinearElementTypeSuiteData );
+ pcu_suite_setFixtures( suite, TrilinearElementTypeSuite_Setup, TrilinearElementTypeSuite_Teardown );
+ pcu_suite_addTest( suite, TrilinearElementTypeSuite_TestShape );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SConscript
--- a/SConscript Wed May 11 14:43:33 2011 -0700
+++ b/SConscript Thu May 12 11:19:05 2011 -0700
@@ -60,8 +60,8 @@ for d in dirs:
defs = env.Install(inc_dir, Glob(src_dir + '/*.def'))
# Build our source files.
- srcs = Glob(src_dir + '/*.c')
- srcs = [s for s in srcs if s.path.find('-meta.c') == -1]
+ srcs = Glob(src_dir + '/*.cxx')
+ srcs = [s for s in srcs if s.path.find('-meta.cxx') == -1]
objs += env.SharedObject(srcs, CPPDEFINES=cpp_defs)
# Build any meta files.
@@ -73,7 +73,7 @@ for d in dirs:
env.Depends(hdrs + objs, defs)
# Build any test suites we might find.
- suites += env.Object(Glob(tst_dir + '/*Suite.c'))
+ suites += env.Object(Glob(tst_dir + '/*Suite.cxx'))
# Install any test expected and input files
tst_exp += env.Install(tst_install_dir + '/expected', Glob(tst_exp_dir + '/*'))
@@ -118,8 +118,8 @@ for d in dirs:
env.Install('include/StgFEM/' + d.split('/')[-1], Glob(d + '/*.h'))
- srcs = Glob(d + '/*.c')
- srcs = [s for s in srcs if s.path.find('-meta.c') == -1]
+ srcs = Glob(d + '/*.cxx')
+ srcs = [s for s in srcs if s.path.find('-meta.cxx') == -1]
cur_objs = env.SharedObject(srcs, CPPDEFINES=cpp_defs)
cur_objs += env.stgSharedMeta(Glob(d + '/*.meta'), CPPDEFINES=cpp_defs)
@@ -220,7 +220,7 @@ if env['static_libs']:
reg_c += '\n stg_num_modules += %d;\n'%len(pl_regs)
reg_c += '}\n'
- reg_filename = os.path.join(env['build_dir'], 'StgFEM', 'stgfem_static_modules.c')
+ reg_filename = os.path.join(env['build_dir'], 'StgFEM', 'stgfem_static_modules.cxx')
if not os.path.exists(os.path.dirname(reg_filename)):
os.makedirs(os.path.dirname(reg_filename))
reg_file = open(reg_filename, 'w')
@@ -229,12 +229,12 @@ if env['static_libs']:
reg_obj = env.Object(reg_filename)
# Add our register function to the StGermain module file.
- f = open(File(env['build_dir'] + '/StGermain/stg_static_modules.c').abspath, 'r')
+ f = open(File(env['build_dir'] + '/StGermain/stg_static_modules.cxx').abspath, 'r')
txt = f.readlines()
f.close()
txt.insert(-2, ' stgfem_register_static_modules();\n')
txt.insert(0, 'void stgfem_register_static_modules();\n')
- f = open(File(env['build_dir'] + '/StGermain/stg_static_modules.c').abspath, 'w')
+ f = open(File(env['build_dir'] + '/StGermain/stg_static_modules.cxx').abspath, 'w')
f.writelines(txt)
f.close()
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.c
--- a/SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,461 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: AdvectionDiffusionSLE.c 999 2008-01-09 04:13:42Z DavidLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <assert.h>
-#include <string.h>
-
-#include "mpi.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-
-#include "types.h"
-#include "AdvectionDiffusionSLE.h"
-#include "UpwindParameter.h"
-#include "Residual.h"
-#include "Multicorrector.h"
-#include "Timestep.h"
-
-const Type AdvectionDiffusionSLE_Type = "AdvectionDiffusionSLE";
-
-AdvectionDiffusionSLE* AdvectionDiffusionSLE_New(
- Name name,
- SLE_Solver* solver,
- FiniteElementContext* context,
- Bool isNonLinear,
- double nonLinearTolerance,
- Iteration_Index nonLinearMaxIterations,
- Bool killNonConvergent,
- EntryPoint_Register* entryPoint_Register,
- MPI_Comm comm,
- FeVariable* phiField,
- ForceVector* residual,
- Stg_Component* massMatrix,
- Dimension_Index dim,
- double courantFactor,
- Variable_Register* variable_Register,
- FieldVariable_Register* fieldVariable_Register )
-{
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) _AdvectionDiffusionSLE_DefaultNew( name );
-
- self->isConstructed = True;
- _SystemLinearEquations_Init( self, solver, NULL, context, False, isNonLinear, nonLinearTolerance,
- nonLinearMaxIterations, killNonConvergent, 1, "", "", entryPoint_Register, comm );
- _AdvectionDiffusionSLE_Init( self, phiField, residual, massMatrix, dim, courantFactor, variable_Register, fieldVariable_Register );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-AdvectionDiffusionSLE* _AdvectionDiffusionSLE_New( ADVECTIONDIFFUSIONSLE_DEFARGS )
-{
- AdvectionDiffusionSLE* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(AdvectionDiffusionSLE) );
- self = (AdvectionDiffusionSLE*) _SystemLinearEquations_New( SYSTEMLINEAREQUATIONS_PASSARGS );
-
- return self;
-}
-
-void _AdvectionDiffusionSLE_Init(
- void* sle,
- FeVariable* phiField,
- ForceVector* residual,
- Stg_Component* massMatrix,
- Dimension_Index dim,
- double courantFactor,
- Variable_Register* variable_Register,
- FieldVariable_Register* fieldVariable_Register )
-{
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*)sle;
-
- /* Assign values */
- self->phiField = phiField;
- self->residual = residual;
- self->massMatrix = massMatrix;
- self->dim = dim;
- self->courantFactor = courantFactor;
-
- /* Solution Vectors are loaded up as part of the algorithm so we can remove this one */
- EP_Remove( self->executeEP, "UpdateSolutionOntoNodes" );
- EP_Remove( self->executeEP, "MatrixSetup" );
- EP_Remove( self->executeEP, "VectorSetup" );
-
- /* Put Pointer of Solver onto vectors */
- if (residual) {
- residual->applicationDepExtraInfo = (Stg_Component*) self;
- SystemLinearEquations_AddForceVector( self, residual );
- }
- if (massMatrix && Stg_Class_IsInstance( massMatrix, ForceVector_Type ) ) {
- ((ForceVector*) massMatrix)->applicationDepExtraInfo = (Stg_Component*) self;
- SystemLinearEquations_AddForceVector( self, massMatrix );
- }
- else if (massMatrix && Stg_Class_IsInstance( massMatrix, StiffnessMatrix_Type ) ) {
- ((StiffnessMatrix*) massMatrix)->applicationDepInfo = (Stg_Component*) self;
- SystemLinearEquations_AddStiffnessMatrix( self, massMatrix );
- }
-
- self->variableReg = variable_Register;
- self->fieldVariableReg = fieldVariable_Register;
-
- if ( self->context ) {
- /* Create a specific name for the calcDt hook */
- char* tmpName = Memory_Alloc_Array_Unnamed( char, strlen(self->name) + 7 + 1 );
- sprintf( tmpName, "%s_CalcDt", self->name );
- EntryPoint_AppendClassHook( self->context->calcDtEP, tmpName, (void*)AdvectionDiffusionSLE_CalculateDt, self->type, self );
- //EP_AppendClassHook( self->context->calcDtEP, AdvectionDiffusionSLE_CalculateDt, self );
- Memory_Free( tmpName );
- }
-}
-
-/** Virtual Functions from "Class" Class */
-void _AdvectionDiffusionSLE_Delete( void* sle ) {
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*)sle;
-
- _SystemLinearEquations_Delete( self );
-}
-
-void _AdvectionDiffusionSLE_Print( void* sle, Stream* stream ) {
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
-
- Journal_Printf( stream, "Printing contents of SLE Advection Diffusion '%s':\n", self->name );
- Stream_Indent( stream );
- Journal_PrintPointer( stream, self );
- _Stg_Component_Print( self, stream );
-
- Journal_Printf( stream, "Items from Constructor:\n");
- Stream_Indent( stream );
- Journal_PrintPointer( stream, self->phiField );
- Journal_PrintPointer( stream, self->residual );
- Journal_PrintPointer( stream, self->massMatrix );
- Journal_PrintUnsignedInt( stream, self->dim );
- Stream_UnIndent( stream );
-
- Journal_Printf( stream, "Items from created by SLE self:\n");
- Stream_Indent( stream );
- Journal_PrintPointer( stream, self->phiDotArray );
- Journal_PrintPointer( stream, self->phiDotField );
- Journal_PrintPointer( stream, self->phiDotDofLayout );
- Journal_PrintPointer( stream, self->phiVector );
- Journal_PrintPointer( stream, self->phiDotVector );
- Stream_UnIndent( stream );
-
- Journal_Printf( stream, "Parameters set from dictionary:\n");
- Stream_Indent( stream );
- Journal_PrintDouble( stream, self->courantFactor );
- Stream_UnIndent( stream );
-
- Journal_Printf( stream, "Stored Values:\n");
- Stream_Indent( stream );
- Journal_PrintDouble( stream, self->maxDiffusivity );
- Stream_UnIndent( stream );
-
- Stream_UnIndent( stream );
-}
-
-
-void* _AdvectionDiffusionSLE_Copy( const void* _sle, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) _sle;
- AdvectionDiffusionSLE* newSLE;
-
- newSLE = (AdvectionDiffusionSLE*)_SystemLinearEquations_Copy( self, dest, deep, nameExt, ptrMap );
-
- /* TODO: Copy Method */
- abort();
-
- return (void*)newSLE;
-}
-
-void* _AdvectionDiffusionSLE_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(AdvectionDiffusionSLE);
- Type type = AdvectionDiffusionSLE_Type;
- Stg_Class_DeleteFunction* _delete = _AdvectionDiffusionSLE_Delete;
- Stg_Class_PrintFunction* _print = _AdvectionDiffusionSLE_Print;
- Stg_Class_CopyFunction* _copy = _AdvectionDiffusionSLE_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _AdvectionDiffusionSLE_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _AdvectionDiffusionSLE_AssignFromXML;
- Stg_Component_BuildFunction* _build = _AdvectionDiffusionSLE_Build;
- Stg_Component_InitialiseFunction* _initialise = _AdvectionDiffusionSLE_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AdvectionDiffusionSLE_Execute;
- Stg_Component_DestroyFunction* _destroy = _AdvectionDiffusionSLE_Destroy;
- SystemLinearEquations_LM_SetupFunction* _LM_Setup = _SystemLinearEquations_LM_Setup;
- SystemLinearEquations_MatrixSetupFunction* _matrixSetup = _SystemLinearEquations_MatrixSetup;
- SystemLinearEquations_VectorSetupFunction* _vectorSetup = _SystemLinearEquations_VectorSetup;
- SystemLinearEquations_MG_SelectStiffMatsFunc* _mgSelectStiffMats = _SystemLinearEquations_MG_SelectStiffMats;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = (AllocationType)ZERO;
- SystemLinearEquations_UpdateSolutionOntoNodesFunc* _updateSolutionOntoNodes = ZERO;
-
- return (void*) _AdvectionDiffusionSLE_New( ADVECTIONDIFFUSIONSLE_PASSARGS );
-}
-
-void _AdvectionDiffusionSLE_AssignFromXML( void* sle, Stg_ComponentFactory* cf, void* data ) {
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
- Stream* error = Journal_Register( Error_Type, (Name)self->type );
- FeVariable* phiField;
- ForceVector* residual;
- Stg_Component* massMatrix;
- Dimension_Index dim;
- double courantFactor;
- FieldVariable_Register* fieldVariable_Register;
- Variable_Register* variable_Register;
-
- /* Construct Parent */
- _SystemLinearEquations_AssignFromXML( self, cf, data );
-
- /* Get Registers */
- variable_Register = self->context->variable_Register;
- assert( variable_Register );
- fieldVariable_Register = self->context->fieldVariable_Register;
- assert( fieldVariable_Register );
-
- /* Get Dependency Stg_Components */
- phiField = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"PhiField", FeVariable, True, data );
- residual = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Residual", ForceVector, True, data );
- massMatrix = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"MassMatrix", Stg_Component, True, data );
-
- dim = Stg_ComponentFactory_GetRootDictUnsignedInt( cf, (Dictionary_Entry_Key)"dim", 0 );
-
- courantFactor = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"courantFactor", 0.5 );
- Journal_Firewall( 0.0 < courantFactor && courantFactor <= 1.0,
- error, "In func %s: CourantFactor read in from dictionary = %2.4f - This must be from 0 - 1.\n",
- __func__, courantFactor );
-
- _AdvectionDiffusionSLE_Init(
- self,
- phiField,
- residual,
- massMatrix,
- dim,
- courantFactor,
- variable_Register,
- fieldVariable_Register );
-}
-
-void _AdvectionDiffusionSLE_Destroy( void* sle, void* data ) {
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
-
- Memory_Free( self->phiDotArray );
-
- _SystemLinearEquations_Destroy( self, data );
-}
-
-/** Virtual Functions from "Stg_Component" Class */
-void _AdvectionDiffusionSLE_Build( void* sle, void* data ) {
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
- Stream* errorStream = Journal_MyStream( Error_Type, self );
- Index forceTerm_I;
- Index forceTermCount = Stg_ObjectList_Count( self->residual->forceTermList );
- ForceTerm* forceTerm;
- unsigned int *nodeDomainCountPtr;
- Variable* variable;
- Node_DomainIndex node_I;
-
- Journal_DPrintf( self->debug, "In %s()\n", __func__ );
-
- /* Create New FeVariable for Phi Dot */
- if (self->phiField) {
- Variable_Register* variable_Register;
- FieldVariable_Register* fieldVariable_Register;
- char* fieldName, *dofName, *fieldDotName, *phiVecName, *phiDotVecName;
-
- variable_Register = self->variableReg;
- fieldVariable_Register = self->fieldVariableReg;
-
- Stg_Component_Build( self->phiField->feMesh, NULL, False );
-
- assert( Class_IsSuper( self->phiField->feMesh->topo, IGraph ) );
- nodeDomainCountPtr = (unsigned*)(&((IGraph*)self->phiField->feMesh->topo)->remotes[MT_VERTEX]->nDomains);
-
- /* must create unique names otherwise multiple instances of this component
- * will index incorrect instances of this component's data */
- fieldName = Memory_Alloc_Array_Unnamed( char, strlen(self->name)+8 );
- sprintf( fieldName, "%s-phiDot", self->name );
-
- dofName = Memory_Alloc_Array_Unnamed( char, strlen(self->name)+11 );
- sprintf( dofName, "%s-dofLayout", self->name );
-
- fieldDotName = Memory_Alloc_Array_Unnamed( char, strlen(self->name)+13 );
- sprintf( fieldDotName, "%s-phiDotField", self->name );
-
- phiVecName = Memory_Alloc_Array_Unnamed( char, strlen(self->name)+11 );
- sprintf( phiVecName, "%s-phiVector", self->name );
-
- phiDotVecName = Memory_Alloc_Array_Unnamed( char, strlen(self->name)+14 );
- sprintf( phiDotVecName, "%s-phiDotVector", self->name );
-
- variable = Variable_NewScalar( fieldName, (AbstractContext*)self->context, Variable_DataType_Double, (Index*)nodeDomainCountPtr, NULL, (void**)&self->phiDotArray, variable_Register );
-
- self->phiDotDofLayout = DofLayout_New( dofName, (DomainContext*)self->context, variable_Register, *nodeDomainCountPtr, NULL );
- //self->phiDotDofLayout = DofLayout_New( "dofLayout1", variable_Register, *nodeDomainCountPtr, NULL );
- for( node_I = 0; node_I < *nodeDomainCountPtr ; node_I++ )
- DofLayout_AddDof_ByVarName( self->phiDotDofLayout, variable->name, node_I );
-
- self->phiDotField = FeVariable_New_FromTemplate(
- fieldDotName,
- (DomainContext*) self->context,
- self->phiField,
- self->phiDotDofLayout,
- NULL,
- False, False,
- fieldVariable_Register );
- self->phiDotField->context = (DomainContext*)self->context;
-
- /* Construct Solution Vectors */
- self->phiVector = SolutionVector_New( phiVecName, self->context, self->phiField->communicator, self->phiField );
- self->phiDotVector = SolutionVector_New( phiDotVecName, self->context, self->phiField->communicator, self->phiDotField );
-
- /* free original name variables */
- Memory_Free(fieldName);
- Memory_Free(dofName);
- Memory_Free(fieldDotName);
- Memory_Free(phiVecName);
- Memory_Free(phiDotVecName);
- }
-
- _SystemLinearEquations_Build( self, data );
-
- /* Get pointer to residual force term
- * All Advection Diffusion SLE's need a force term of type AdvDiffResidualForceTerm for the algorithm to work
- * this chunk of code is making sure that one and only one is registered to the force vector */
- for ( forceTerm_I = 0 ; forceTerm_I < forceTermCount ; forceTerm_I++ ) {
- forceTerm = (ForceTerm*) Stg_ObjectList_At( self->residual->forceTermList, forceTerm_I );
-
- if ( Stg_Class_IsInstance( forceTerm, AdvDiffResidualForceTerm_Type ) ) {
- /* Check to make sure this force term is unique */
- if (self->advDiffResidualForceTerm != NULL) {
- Journal_Firewall( self->advDiffResidualForceTerm == NULL, errorStream,
- "Error - More than one force term of type '%s' registered on %s '%s'. \n\tThey are %s and %s.\n",
- AdvDiffResidualForceTerm_Type, self->type, self->name,
- self->advDiffResidualForceTerm->name, forceTerm->name);
- }
-
- /* Store pointer to force term */
- self->advDiffResidualForceTerm = (AdvDiffResidualForceTerm*) forceTerm;
-
- /* HACK */
- Stg_Component_Build( self->advDiffResidualForceTerm->velocityField, data, False );
-
- }
- }
- /* Ensure that there is at least one force term with proper residual type */
- Journal_Firewall( self->advDiffResidualForceTerm != NULL, errorStream,
- "Error - No force terms of type '%s' registered on %s '%s'.\n",
- AdvDiffResidualForceTerm_Type, self->type, self->name );
-
- if ( self->phiDotField ) {
- self->phiDotArray = Memory_Alloc_Array(
- double, Mesh_GetDomainSize( self->phiDotField->feMesh, MT_VERTEX ), "phiDotArray" );
- }
-
- /* Force Vectors */
- if ( self->residual )
- Stg_Component_Build( self->residual, data, False );
- if ( self->massMatrix )
- Stg_Component_Build( self->massMatrix, data, False );
-
- /* Solution Vectors */
- if ( self->phiVector )
- Stg_Component_Build( self->phiVector, data, False );
- if ( self->phiDotVector )
- Stg_Component_Build( self->phiDotVector, data, False );
-}
-
-void _AdvectionDiffusionSLE_Initialise( void* sle, void* data ) {
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
- FiniteElementContext* context = (FiniteElementContext*) data;
-
- Journal_DPrintf( self->debug, "In %s()\n", __func__ );
-
- _SystemLinearEquations_Initialise( self, data );
-
- Stg_Component_Initialise( self->phiDotField, data, False );
-
-/* Stream* stream = Journal_Register( Info_Type, (Name)self->type ); */
-/* FeVariable_PrintLocalDiscreteValues( self->phiDotField, stream ); */
-
- if ( False == context->loadFromCheckPoint ) {
- DofLayout_SetAllToZero( self->phiDotField->dofLayout );
- }
-
- /* Force Vectors */
- Stg_Component_Initialise( self->residual, data, False );
- Stg_Component_Initialise( self->massMatrix, data, False );
-
- /* Solution Vectors */
- Stg_Component_Initialise( self->phiVector, data, False );
- Stg_Component_Initialise( self->phiDotVector, data, False );
-
- AdvectionDiffusionSLE_ResetStoredValues( self );
-}
-
-void _AdvectionDiffusionSLE_Execute( void* sle, void* _context ) {
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
- FiniteElementContext* context = (FiniteElementContext*) _context;
- double dt = context->dt;
-
- AdvectionDiffusionSLE_ResetStoredValues( self );
- self->currentDt = dt;
-
- _SystemLinearEquations_Execute( self, context );
-}
-
-
-//Vector* _AdvectionDiffusionSLE_GetResidual( void* sle, Index fv_I ) {
-Vec _AdvectionDiffusionSLE_GetResidual( void* sle, Index fv_I ) {
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
- return self->residual->vector;
-}
-
-#define SMALL_VALUE 1.0e-99
-
-void AdvectionDiffusionSLE_ResetStoredValues( void* sle ) {
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
-
- self->maxDiffusivity = SMALL_VALUE;
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/AdvectionDiffusion/src/AdvectionDiffusionSLE.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,461 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: AdvectionDiffusionSLE.c 999 2008-01-09 04:13:42Z DavidLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <assert.h>
+#include <string.h>
+
+#include "mpi.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+
+#include "types.h"
+#include "AdvectionDiffusionSLE.h"
+#include "UpwindParameter.h"
+#include "Residual.h"
+#include "Multicorrector.h"
+#include "Timestep.h"
+
+const Type AdvectionDiffusionSLE_Type = "AdvectionDiffusionSLE";
+
+AdvectionDiffusionSLE* AdvectionDiffusionSLE_New(
+ Name name,
+ SLE_Solver* solver,
+ FiniteElementContext* context,
+ Bool isNonLinear,
+ double nonLinearTolerance,
+ Iteration_Index nonLinearMaxIterations,
+ Bool killNonConvergent,
+ EntryPoint_Register* entryPoint_Register,
+ MPI_Comm comm,
+ FeVariable* phiField,
+ ForceVector* residual,
+ Stg_Component* massMatrix,
+ Dimension_Index dim,
+ double courantFactor,
+ Variable_Register* variable_Register,
+ FieldVariable_Register* fieldVariable_Register )
+{
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) _AdvectionDiffusionSLE_DefaultNew( name );
+
+ self->isConstructed = True;
+ _SystemLinearEquations_Init( self, solver, NULL, context, False, isNonLinear, nonLinearTolerance,
+ nonLinearMaxIterations, killNonConvergent, 1, "", "", entryPoint_Register, comm );
+ _AdvectionDiffusionSLE_Init( self, phiField, residual, massMatrix, dim, courantFactor, variable_Register, fieldVariable_Register );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+AdvectionDiffusionSLE* _AdvectionDiffusionSLE_New( ADVECTIONDIFFUSIONSLE_DEFARGS )
+{
+ AdvectionDiffusionSLE* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(AdvectionDiffusionSLE) );
+ self = (AdvectionDiffusionSLE*) _SystemLinearEquations_New( SYSTEMLINEAREQUATIONS_PASSARGS );
+
+ return self;
+}
+
+void _AdvectionDiffusionSLE_Init(
+ void* sle,
+ FeVariable* phiField,
+ ForceVector* residual,
+ Stg_Component* massMatrix,
+ Dimension_Index dim,
+ double courantFactor,
+ Variable_Register* variable_Register,
+ FieldVariable_Register* fieldVariable_Register )
+{
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*)sle;
+
+ /* Assign values */
+ self->phiField = phiField;
+ self->residual = residual;
+ self->massMatrix = massMatrix;
+ self->dim = dim;
+ self->courantFactor = courantFactor;
+
+ /* Solution Vectors are loaded up as part of the algorithm so we can remove this one */
+ EP_Remove( self->executeEP, "UpdateSolutionOntoNodes" );
+ EP_Remove( self->executeEP, "MatrixSetup" );
+ EP_Remove( self->executeEP, "VectorSetup" );
+
+ /* Put Pointer of Solver onto vectors */
+ if (residual) {
+ residual->applicationDepExtraInfo = (Stg_Component*) self;
+ SystemLinearEquations_AddForceVector( self, residual );
+ }
+ if (massMatrix && Stg_Class_IsInstance( massMatrix, ForceVector_Type ) ) {
+ ((ForceVector*) massMatrix)->applicationDepExtraInfo = (Stg_Component*) self;
+ SystemLinearEquations_AddForceVector( self, massMatrix );
+ }
+ else if (massMatrix && Stg_Class_IsInstance( massMatrix, StiffnessMatrix_Type ) ) {
+ ((StiffnessMatrix*) massMatrix)->applicationDepInfo = (Stg_Component*) self;
+ SystemLinearEquations_AddStiffnessMatrix( self, massMatrix );
+ }
+
+ self->variableReg = variable_Register;
+ self->fieldVariableReg = fieldVariable_Register;
+
+ if ( self->context ) {
+ /* Create a specific name for the calcDt hook */
+ char* tmpName = Memory_Alloc_Array_Unnamed( char, strlen(self->name) + 7 + 1 );
+ sprintf( tmpName, "%s_CalcDt", self->name );
+ EntryPoint_AppendClassHook( self->context->calcDtEP, tmpName, (void*)AdvectionDiffusionSLE_CalculateDt, self->type, self );
+ //EP_AppendClassHook( self->context->calcDtEP, AdvectionDiffusionSLE_CalculateDt, self );
+ Memory_Free( tmpName );
+ }
+}
+
+/** Virtual Functions from "Class" Class */
+void _AdvectionDiffusionSLE_Delete( void* sle ) {
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*)sle;
+
+ _SystemLinearEquations_Delete( self );
+}
+
+void _AdvectionDiffusionSLE_Print( void* sle, Stream* stream ) {
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
+
+ Journal_Printf( stream, "Printing contents of SLE Advection Diffusion '%s':\n", self->name );
+ Stream_Indent( stream );
+ Journal_PrintPointer( stream, self );
+ _Stg_Component_Print( self, stream );
+
+ Journal_Printf( stream, "Items from Constructor:\n");
+ Stream_Indent( stream );
+ Journal_PrintPointer( stream, self->phiField );
+ Journal_PrintPointer( stream, self->residual );
+ Journal_PrintPointer( stream, self->massMatrix );
+ Journal_PrintUnsignedInt( stream, self->dim );
+ Stream_UnIndent( stream );
+
+ Journal_Printf( stream, "Items from created by SLE self:\n");
+ Stream_Indent( stream );
+ Journal_PrintPointer( stream, self->phiDotArray );
+ Journal_PrintPointer( stream, self->phiDotField );
+ Journal_PrintPointer( stream, self->phiDotDofLayout );
+ Journal_PrintPointer( stream, self->phiVector );
+ Journal_PrintPointer( stream, self->phiDotVector );
+ Stream_UnIndent( stream );
+
+ Journal_Printf( stream, "Parameters set from dictionary:\n");
+ Stream_Indent( stream );
+ Journal_PrintDouble( stream, self->courantFactor );
+ Stream_UnIndent( stream );
+
+ Journal_Printf( stream, "Stored Values:\n");
+ Stream_Indent( stream );
+ Journal_PrintDouble( stream, self->maxDiffusivity );
+ Stream_UnIndent( stream );
+
+ Stream_UnIndent( stream );
+}
+
+
+void* _AdvectionDiffusionSLE_Copy( const void* _sle, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) _sle;
+ AdvectionDiffusionSLE* newSLE;
+
+ newSLE = (AdvectionDiffusionSLE*)_SystemLinearEquations_Copy( self, dest, deep, nameExt, ptrMap );
+
+ /* TODO: Copy Method */
+ abort();
+
+ return (void*)newSLE;
+}
+
+void* _AdvectionDiffusionSLE_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(AdvectionDiffusionSLE);
+ Type type = AdvectionDiffusionSLE_Type;
+ Stg_Class_DeleteFunction* _delete = _AdvectionDiffusionSLE_Delete;
+ Stg_Class_PrintFunction* _print = _AdvectionDiffusionSLE_Print;
+ Stg_Class_CopyFunction* _copy = _AdvectionDiffusionSLE_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _AdvectionDiffusionSLE_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _AdvectionDiffusionSLE_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _AdvectionDiffusionSLE_Build;
+ Stg_Component_InitialiseFunction* _initialise = _AdvectionDiffusionSLE_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AdvectionDiffusionSLE_Execute;
+ Stg_Component_DestroyFunction* _destroy = _AdvectionDiffusionSLE_Destroy;
+ SystemLinearEquations_LM_SetupFunction* _LM_Setup = _SystemLinearEquations_LM_Setup;
+ SystemLinearEquations_MatrixSetupFunction* _matrixSetup = _SystemLinearEquations_MatrixSetup;
+ SystemLinearEquations_VectorSetupFunction* _vectorSetup = _SystemLinearEquations_VectorSetup;
+ SystemLinearEquations_MG_SelectStiffMatsFunc* _mgSelectStiffMats = _SystemLinearEquations_MG_SelectStiffMats;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = (AllocationType)ZERO;
+ SystemLinearEquations_UpdateSolutionOntoNodesFunc* _updateSolutionOntoNodes = ZERO;
+
+ return (void*) _AdvectionDiffusionSLE_New( ADVECTIONDIFFUSIONSLE_PASSARGS );
+}
+
+void _AdvectionDiffusionSLE_AssignFromXML( void* sle, Stg_ComponentFactory* cf, void* data ) {
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
+ Stream* error = Journal_Register( Error_Type, (Name)self->type );
+ FeVariable* phiField;
+ ForceVector* residual;
+ Stg_Component* massMatrix;
+ Dimension_Index dim;
+ double courantFactor;
+ FieldVariable_Register* fieldVariable_Register;
+ Variable_Register* variable_Register;
+
+ /* Construct Parent */
+ _SystemLinearEquations_AssignFromXML( self, cf, data );
+
+ /* Get Registers */
+ variable_Register = self->context->variable_Register;
+ assert( variable_Register );
+ fieldVariable_Register = self->context->fieldVariable_Register;
+ assert( fieldVariable_Register );
+
+ /* Get Dependency Stg_Components */
+ phiField = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"PhiField", FeVariable, True, data );
+ residual = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Residual", ForceVector, True, data );
+ massMatrix = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"MassMatrix", Stg_Component, True, data );
+
+ dim = Stg_ComponentFactory_GetRootDictUnsignedInt( cf, (Dictionary_Entry_Key)"dim", 0 );
+
+ courantFactor = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"courantFactor", 0.5 );
+ Journal_Firewall( 0.0 < courantFactor && courantFactor <= 1.0,
+ error, "In func %s: CourantFactor read in from dictionary = %2.4f - This must be from 0 - 1.\n",
+ __func__, courantFactor );
+
+ _AdvectionDiffusionSLE_Init(
+ self,
+ phiField,
+ residual,
+ massMatrix,
+ dim,
+ courantFactor,
+ variable_Register,
+ fieldVariable_Register );
+}
+
+void _AdvectionDiffusionSLE_Destroy( void* sle, void* data ) {
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
+
+ Memory_Free( self->phiDotArray );
+
+ _SystemLinearEquations_Destroy( self, data );
+}
+
+/** Virtual Functions from "Stg_Component" Class */
+void _AdvectionDiffusionSLE_Build( void* sle, void* data ) {
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
+ Stream* errorStream = Journal_MyStream( Error_Type, self );
+ Index forceTerm_I;
+ Index forceTermCount = Stg_ObjectList_Count( self->residual->forceTermList );
+ ForceTerm* forceTerm;
+ unsigned int *nodeDomainCountPtr;
+ Variable* variable;
+ Node_DomainIndex node_I;
+
+ Journal_DPrintf( self->debug, "In %s()\n", __func__ );
+
+ /* Create New FeVariable for Phi Dot */
+ if (self->phiField) {
+ Variable_Register* variable_Register;
+ FieldVariable_Register* fieldVariable_Register;
+ char* fieldName, *dofName, *fieldDotName, *phiVecName, *phiDotVecName;
+
+ variable_Register = self->variableReg;
+ fieldVariable_Register = self->fieldVariableReg;
+
+ Stg_Component_Build( self->phiField->feMesh, NULL, False );
+
+ assert( Class_IsSuper( self->phiField->feMesh->topo, IGraph ) );
+ nodeDomainCountPtr = (unsigned*)(&((IGraph*)self->phiField->feMesh->topo)->remotes[MT_VERTEX]->nDomains);
+
+ /* must create unique names otherwise multiple instances of this component
+ * will index incorrect instances of this component's data */
+ fieldName = Memory_Alloc_Array_Unnamed( char, strlen(self->name)+8 );
+ sprintf( fieldName, "%s-phiDot", self->name );
+
+ dofName = Memory_Alloc_Array_Unnamed( char, strlen(self->name)+11 );
+ sprintf( dofName, "%s-dofLayout", self->name );
+
+ fieldDotName = Memory_Alloc_Array_Unnamed( char, strlen(self->name)+13 );
+ sprintf( fieldDotName, "%s-phiDotField", self->name );
+
+ phiVecName = Memory_Alloc_Array_Unnamed( char, strlen(self->name)+11 );
+ sprintf( phiVecName, "%s-phiVector", self->name );
+
+ phiDotVecName = Memory_Alloc_Array_Unnamed( char, strlen(self->name)+14 );
+ sprintf( phiDotVecName, "%s-phiDotVector", self->name );
+
+ variable = Variable_NewScalar( fieldName, (AbstractContext*)self->context, Variable_DataType_Double, (Index*)nodeDomainCountPtr, NULL, (void**)&self->phiDotArray, variable_Register );
+
+ self->phiDotDofLayout = DofLayout_New( dofName, (DomainContext*)self->context, variable_Register, *nodeDomainCountPtr, NULL );
+ //self->phiDotDofLayout = DofLayout_New( "dofLayout1", variable_Register, *nodeDomainCountPtr, NULL );
+ for( node_I = 0; node_I < *nodeDomainCountPtr ; node_I++ )
+ DofLayout_AddDof_ByVarName( self->phiDotDofLayout, variable->name, node_I );
+
+ self->phiDotField = FeVariable_New_FromTemplate(
+ fieldDotName,
+ (DomainContext*) self->context,
+ self->phiField,
+ self->phiDotDofLayout,
+ NULL,
+ False, False,
+ fieldVariable_Register );
+ self->phiDotField->context = (DomainContext*)self->context;
+
+ /* Construct Solution Vectors */
+ self->phiVector = SolutionVector_New( phiVecName, self->context, self->phiField->communicator, self->phiField );
+ self->phiDotVector = SolutionVector_New( phiDotVecName, self->context, self->phiField->communicator, self->phiDotField );
+
+ /* free original name variables */
+ Memory_Free(fieldName);
+ Memory_Free(dofName);
+ Memory_Free(fieldDotName);
+ Memory_Free(phiVecName);
+ Memory_Free(phiDotVecName);
+ }
+
+ _SystemLinearEquations_Build( self, data );
+
+ /* Get pointer to residual force term
+ * All Advection Diffusion SLE's need a force term of type AdvDiffResidualForceTerm for the algorithm to work
+ * this chunk of code is making sure that one and only one is registered to the force vector */
+ for ( forceTerm_I = 0 ; forceTerm_I < forceTermCount ; forceTerm_I++ ) {
+ forceTerm = (ForceTerm*) Stg_ObjectList_At( self->residual->forceTermList, forceTerm_I );
+
+ if ( Stg_Class_IsInstance( forceTerm, AdvDiffResidualForceTerm_Type ) ) {
+ /* Check to make sure this force term is unique */
+ if (self->advDiffResidualForceTerm != NULL) {
+ Journal_Firewall( self->advDiffResidualForceTerm == NULL, errorStream,
+ "Error - More than one force term of type '%s' registered on %s '%s'. \n\tThey are %s and %s.\n",
+ AdvDiffResidualForceTerm_Type, self->type, self->name,
+ self->advDiffResidualForceTerm->name, forceTerm->name);
+ }
+
+ /* Store pointer to force term */
+ self->advDiffResidualForceTerm = (AdvDiffResidualForceTerm*) forceTerm;
+
+ /* HACK */
+ Stg_Component_Build( self->advDiffResidualForceTerm->velocityField, data, False );
+
+ }
+ }
+ /* Ensure that there is at least one force term with proper residual type */
+ Journal_Firewall( self->advDiffResidualForceTerm != NULL, errorStream,
+ "Error - No force terms of type '%s' registered on %s '%s'.\n",
+ AdvDiffResidualForceTerm_Type, self->type, self->name );
+
+ if ( self->phiDotField ) {
+ self->phiDotArray = Memory_Alloc_Array(
+ double, Mesh_GetDomainSize( self->phiDotField->feMesh, MT_VERTEX ), "phiDotArray" );
+ }
+
+ /* Force Vectors */
+ if ( self->residual )
+ Stg_Component_Build( self->residual, data, False );
+ if ( self->massMatrix )
+ Stg_Component_Build( self->massMatrix, data, False );
+
+ /* Solution Vectors */
+ if ( self->phiVector )
+ Stg_Component_Build( self->phiVector, data, False );
+ if ( self->phiDotVector )
+ Stg_Component_Build( self->phiDotVector, data, False );
+}
+
+void _AdvectionDiffusionSLE_Initialise( void* sle, void* data ) {
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
+ FiniteElementContext* context = (FiniteElementContext*) data;
+
+ Journal_DPrintf( self->debug, "In %s()\n", __func__ );
+
+ _SystemLinearEquations_Initialise( self, data );
+
+ Stg_Component_Initialise( self->phiDotField, data, False );
+
+/* Stream* stream = Journal_Register( Info_Type, (Name)self->type ); */
+/* FeVariable_PrintLocalDiscreteValues( self->phiDotField, stream ); */
+
+ if ( False == context->loadFromCheckPoint ) {
+ DofLayout_SetAllToZero( self->phiDotField->dofLayout );
+ }
+
+ /* Force Vectors */
+ Stg_Component_Initialise( self->residual, data, False );
+ Stg_Component_Initialise( self->massMatrix, data, False );
+
+ /* Solution Vectors */
+ Stg_Component_Initialise( self->phiVector, data, False );
+ Stg_Component_Initialise( self->phiDotVector, data, False );
+
+ AdvectionDiffusionSLE_ResetStoredValues( self );
+}
+
+void _AdvectionDiffusionSLE_Execute( void* sle, void* _context ) {
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
+ FiniteElementContext* context = (FiniteElementContext*) _context;
+ double dt = context->dt;
+
+ AdvectionDiffusionSLE_ResetStoredValues( self );
+ self->currentDt = dt;
+
+ _SystemLinearEquations_Execute( self, context );
+}
+
+
+//Vector* _AdvectionDiffusionSLE_GetResidual( void* sle, Index fv_I ) {
+Vec _AdvectionDiffusionSLE_GetResidual( void* sle, Index fv_I ) {
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
+ return self->residual->vector;
+}
+
+#define SMALL_VALUE 1.0e-99
+
+void AdvectionDiffusionSLE_ResetStoredValues( void* sle ) {
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) sle;
+
+ self->maxDiffusivity = SMALL_VALUE;
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/Finalise.c
--- a/SLE/ProvidedSystems/AdvectionDiffusion/src/Finalise.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "types.h"
-#include "Finalise.h"
-
-#include <stdio.h>
-
-Bool StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Finalise( void ) {
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/Finalise.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/AdvectionDiffusion/src/Finalise.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,58 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "types.h"
+#include "Finalise.h"
+
+#include <stdio.h>
+
+Bool StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Finalise( void ) {
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/Init.c
--- a/SLE/ProvidedSystems/AdvectionDiffusion/src/Init.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "types.h"
-#include "Init.h"
-#include "AdvectionDiffusion.h"
-
-#include <stdio.h>
-
-Stream* StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Debug = NULL;
-
-/** Initialises the Linear Algebra package, then any init for this package
-such as streams etc */
-Bool StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Init( int* argc, char** argv[] ) {
- Stg_ComponentRegister* componentRegister = Stg_ComponentRegister_Get_ComponentRegister();
-
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- /* initialise this level's streams */
- StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Debug = Stream_RegisterChild( StgFEM_SLE_Debug,
- "ProvidedSystems_AdvectionDiffusion" );
-
- Stg_ComponentRegister_Add( componentRegister, AdvectionDiffusionSLE_Type, (Name)"0", _AdvectionDiffusionSLE_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, AdvDiffResidualForceTerm_Type, (Name)"0", _AdvDiffResidualForceTerm_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, LumpedMassMatrixForceTerm_Type, (Name)"0", _LumpedMassMatrixForceTerm_DefaultNew );
- Stg_ComponentRegister_Add( componentRegister, AdvDiffMulticorrector_Type, (Name)"0", _AdvDiffMulticorrector_DefaultNew );
-
- RegisterParent( AdvectionDiffusionSLE_Type, SystemLinearEquations_Type );
- RegisterParent( AdvDiffResidualForceTerm_Type, ForceTerm_Type );
- RegisterParent( LumpedMassMatrixForceTerm_Type, ForceTerm_Type );
- RegisterParent( AdvDiffMulticorrector_Type, SLE_Solver_Type );
-
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/Init.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/AdvectionDiffusion/src/Init.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,79 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "types.h"
+#include "Init.h"
+#include "AdvectionDiffusion.h"
+
+#include <stdio.h>
+
+Stream* StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Debug = NULL;
+
+/** Initialises the Linear Algebra package, then any init for this package
+such as streams etc */
+Bool StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Init( int* argc, char** argv[] ) {
+ Stg_ComponentRegister* componentRegister = Stg_ComponentRegister_Get_ComponentRegister();
+
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ /* initialise this level's streams */
+ StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Debug = Stream_RegisterChild( StgFEM_SLE_Debug,
+ "ProvidedSystems_AdvectionDiffusion" );
+
+ Stg_ComponentRegister_Add( componentRegister, AdvectionDiffusionSLE_Type, (Name)"0", _AdvectionDiffusionSLE_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, AdvDiffResidualForceTerm_Type, (Name)"0", _AdvDiffResidualForceTerm_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, LumpedMassMatrixForceTerm_Type, (Name)"0", _LumpedMassMatrixForceTerm_DefaultNew );
+ Stg_ComponentRegister_Add( componentRegister, AdvDiffMulticorrector_Type, (Name)"0", _AdvDiffMulticorrector_DefaultNew );
+
+ RegisterParent( AdvectionDiffusionSLE_Type, SystemLinearEquations_Type );
+ RegisterParent( AdvDiffResidualForceTerm_Type, ForceTerm_Type );
+ RegisterParent( LumpedMassMatrixForceTerm_Type, ForceTerm_Type );
+ RegisterParent( AdvDiffMulticorrector_Type, SLE_Solver_Type );
+
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/LumpedMassMatrixForceTerm.c
--- a/SLE/ProvidedSystems/AdvectionDiffusion/src/LumpedMassMatrixForceTerm.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,236 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: LumpedMassMatrixForceTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include <StgFEM/SLE/SystemSetup/SystemSetup.h>
-
-#include "types.h"
-#include "LumpedMassMatrixForceTerm.h"
-
-#include <assert.h>
-#include <string.h>
-
-/* Textual name of this class */
-const Type LumpedMassMatrixForceTerm_Type = "LumpedMassMatrixForceTerm";
-
-LumpedMassMatrixForceTerm* LumpedMassMatrixForceTerm_New(
- Name name,
- FiniteElementContext* context,
- ForceVector* forceVector,
- Swarm* integrationSwarm )
-{
- LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*) _LumpedMassMatrixForceTerm_DefaultNew( name );
-
- self->isConstructed = True;
- _ForceTerm_Init( self, context, forceVector, integrationSwarm, NULL );
- _LumpedMassMatrixForceTerm_Init( self );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-LumpedMassMatrixForceTerm* _LumpedMassMatrixForceTerm_New( LUMPEDMASSMATRIXFORCETERM_DEFARGS )
-{
- LumpedMassMatrixForceTerm* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(LumpedMassMatrixForceTerm) );
- /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
- /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
- and so should be set to ZERO in any children of this class. */
- nameAllocationType = NON_GLOBAL;
-
- self = (LumpedMassMatrixForceTerm*) _ForceTerm_New( FORCETERM_PASSARGS );
-
- /* Virtual info */
-
- return self;
-}
-
-void _LumpedMassMatrixForceTerm_Init( void* forceTerm ) {
-}
-
-void _LumpedMassMatrixForceTerm_Delete( void* forceTerm ) {
- LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
-
- _ForceTerm_Delete( self );
-}
-
-void _LumpedMassMatrixForceTerm_Print( void* forceTerm, Stream* stream ) {
- LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
-
- _ForceTerm_Print( self, stream );
-
- /* General info */
-}
-
-void* _LumpedMassMatrixForceTerm_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(LumpedMassMatrixForceTerm);
- Type type = LumpedMassMatrixForceTerm_Type;
- Stg_Class_DeleteFunction* _delete = _LumpedMassMatrixForceTerm_Delete;
- Stg_Class_PrintFunction* _print = _LumpedMassMatrixForceTerm_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LumpedMassMatrixForceTerm_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _LumpedMassMatrixForceTerm_AssignFromXML;
- Stg_Component_BuildFunction* _build = _LumpedMassMatrixForceTerm_Build;
- Stg_Component_InitialiseFunction* _initialise = _LumpedMassMatrixForceTerm_Initialise;
- Stg_Component_ExecuteFunction* _execute = _LumpedMassMatrixForceTerm_Execute;
- Stg_Component_DestroyFunction* _destroy = _LumpedMassMatrixForceTerm_Destroy;
- ForceTerm_AssembleElementFunction* _assembleElement = _LumpedMassMatrixForceTerm_AssembleElement;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_LumpedMassMatrixForceTerm_New( LUMPEDMASSMATRIXFORCETERM_PASSARGS );
-}
-
-void _LumpedMassMatrixForceTerm_AssignFromXML( void* forceTerm, Stg_ComponentFactory* cf, void* data ) {
- LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
-
- /* Construct Parent */
- _ForceTerm_AssignFromXML( self, cf, data );
-
- _LumpedMassMatrixForceTerm_Init( self );
-}
-
-void _LumpedMassMatrixForceTerm_Build( void* forceTerm, void* data ) {
- LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
-
- _ForceTerm_Build( self, data );
-}
-
-void _LumpedMassMatrixForceTerm_Initialise( void* forceTerm, void* data ) {
- LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
-
- _ForceTerm_Initialise( self, data );
-}
-
-void _LumpedMassMatrixForceTerm_Execute( void* forceTerm, void* data ) {
- LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
-
- _ForceTerm_Execute( self, data );
-}
-
-void _LumpedMassMatrixForceTerm_Destroy( void* forceTerm, void* data ) {
- LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
-
- _ForceTerm_Destroy( self, data );
-}
-
-void _LumpedMassMatrixForceTerm_AssembleElement( void* forceTerm, ForceVector* forceVector ,Element_LocalIndex lElement_I, double* elForceVector ) {
- LumpedMassMatrixForceTerm* self = Stg_CheckType( forceTerm, LumpedMassMatrixForceTerm );
-
-#if 0
- if ( Stg_Class_IsInstance( mesh->layout->elementLayout, ParallelPipedHexaEL_Type ) ) {
- ForceTerm_SetAssembleElementFunction( self, _LumpedMassMatrixForceTerm_AssembleElement_Box );
- }
- else {
-#endif
- ForceTerm_SetAssembleElementFunction( self, _LumpedMassMatrixForceTerm_AssembleElement_General );
-#if 0
- }
-#endif
-
- ForceTerm_AssembleElement( self, forceVector, lElement_I, elForceVector );
-}
-
-void _LumpedMassMatrixForceTerm_AssembleElement_General( void* forceTerm, ForceVector* forceVector, Element_LocalIndex lElement_I, double* elForceVector ) {
- LumpedMassMatrixForceTerm* self = Stg_CheckType( forceTerm, LumpedMassMatrixForceTerm );
- FeVariable* feVariable = forceVector->feVariable;
- Dimension_Index dim = forceVector->dim;
- Swarm* swarm = self->integrationSwarm;
- FeMesh* feMesh = feVariable->feMesh;
- ElementType* elementType = FeMesh_GetElementType( feMesh, lElement_I );
- Cell_Index cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
- Particle_InCellIndex cellParticleCount;
- Particle_InCellIndex cParticle_I;
- IntegrationPoint* particle;
- Node_Index nodeRow_I;
- Node_Index nodeColumn_I;
- double factor;
- double detJac;
- double shapeFunc[27];
- unsigned elementNodeCount;
-
- elementNodeCount = FeMesh_GetElementNodeSize( feMesh, lElement_I );
- cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
-
- for( cParticle_I = 0 ; cParticle_I < cellParticleCount; cParticle_I++ ) {
- /* Find this particle in the element */
- particle = (IntegrationPoint*) Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
-
- /* Evalutate Shape Functions and Jacobian Determinant */
- ElementType_EvaluateShapeFunctionsAt( elementType, particle->xi, shapeFunc );
- detJac = ElementType_JacobianDeterminant( elementType, feMesh, lElement_I, particle->xi, dim );
-
- /* Integrate \int_{\Omgea} N_i N_i d\Omega and lump onto vector in one step */
- factor = detJac * particle->weight;
- for ( nodeRow_I = 0 ; nodeRow_I < elementNodeCount ; nodeRow_I++ )
- for ( nodeColumn_I = 0 ; nodeColumn_I < elementNodeCount ; nodeColumn_I++ )
- elForceVector[ nodeRow_I ] += shapeFunc[ nodeRow_I ] * shapeFunc[ nodeColumn_I ] * factor ;
- }
-}
-
-/** Shortcut for doing above calculation, optimised for a box shaped element */
-void _LumpedMassMatrixForceTerm_AssembleElement_Box( void* forceTerm, ForceVector* forceVector, Element_LocalIndex lElement_I, double* elForceVector ) {
- FeVariable* feVariable = forceVector->feVariable;
- Dimension_Index dim = forceVector->dim;
- FeMesh* feMesh = feVariable->feMesh;
- Element_NodeIndex elementNodeCount;
- ElementType* elementType;
- Node_Index node_I;
- double detJac;
- Coord xi = {0.0,0.0,0.0};
-
- elementNodeCount = FeMesh_GetElementNodeSize( feMesh, lElement_I );
- elementType = FeMesh_GetElementType( feMesh, lElement_I );
-
- detJac = ElementType_JacobianDeterminant( elementType, feMesh, lElement_I, xi, dim );
- for ( node_I = 0 ; node_I < elementNodeCount ; node_I++ )
- elForceVector[ node_I ] = detJac;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/LumpedMassMatrixForceTerm.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/AdvectionDiffusion/src/LumpedMassMatrixForceTerm.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,236 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: LumpedMassMatrixForceTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include <StgFEM/SLE/SystemSetup/SystemSetup.h>
+
+#include "types.h"
+#include "LumpedMassMatrixForceTerm.h"
+
+#include <assert.h>
+#include <string.h>
+
+/* Textual name of this class */
+const Type LumpedMassMatrixForceTerm_Type = "LumpedMassMatrixForceTerm";
+
+LumpedMassMatrixForceTerm* LumpedMassMatrixForceTerm_New(
+ Name name,
+ FiniteElementContext* context,
+ ForceVector* forceVector,
+ Swarm* integrationSwarm )
+{
+ LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*) _LumpedMassMatrixForceTerm_DefaultNew( name );
+
+ self->isConstructed = True;
+ _ForceTerm_Init( self, context, forceVector, integrationSwarm, NULL );
+ _LumpedMassMatrixForceTerm_Init( self );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+LumpedMassMatrixForceTerm* _LumpedMassMatrixForceTerm_New( LUMPEDMASSMATRIXFORCETERM_DEFARGS )
+{
+ LumpedMassMatrixForceTerm* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(LumpedMassMatrixForceTerm) );
+ /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
+ /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
+ and so should be set to ZERO in any children of this class. */
+ nameAllocationType = NON_GLOBAL;
+
+ self = (LumpedMassMatrixForceTerm*) _ForceTerm_New( FORCETERM_PASSARGS );
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _LumpedMassMatrixForceTerm_Init( void* forceTerm ) {
+}
+
+void _LumpedMassMatrixForceTerm_Delete( void* forceTerm ) {
+ LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
+
+ _ForceTerm_Delete( self );
+}
+
+void _LumpedMassMatrixForceTerm_Print( void* forceTerm, Stream* stream ) {
+ LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
+
+ _ForceTerm_Print( self, stream );
+
+ /* General info */
+}
+
+void* _LumpedMassMatrixForceTerm_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(LumpedMassMatrixForceTerm);
+ Type type = LumpedMassMatrixForceTerm_Type;
+ Stg_Class_DeleteFunction* _delete = _LumpedMassMatrixForceTerm_Delete;
+ Stg_Class_PrintFunction* _print = _LumpedMassMatrixForceTerm_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LumpedMassMatrixForceTerm_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _LumpedMassMatrixForceTerm_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _LumpedMassMatrixForceTerm_Build;
+ Stg_Component_InitialiseFunction* _initialise = _LumpedMassMatrixForceTerm_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _LumpedMassMatrixForceTerm_Execute;
+ Stg_Component_DestroyFunction* _destroy = _LumpedMassMatrixForceTerm_Destroy;
+ ForceTerm_AssembleElementFunction* _assembleElement = _LumpedMassMatrixForceTerm_AssembleElement;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_LumpedMassMatrixForceTerm_New( LUMPEDMASSMATRIXFORCETERM_PASSARGS );
+}
+
+void _LumpedMassMatrixForceTerm_AssignFromXML( void* forceTerm, Stg_ComponentFactory* cf, void* data ) {
+ LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
+
+ /* Construct Parent */
+ _ForceTerm_AssignFromXML( self, cf, data );
+
+ _LumpedMassMatrixForceTerm_Init( self );
+}
+
+void _LumpedMassMatrixForceTerm_Build( void* forceTerm, void* data ) {
+ LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
+
+ _ForceTerm_Build( self, data );
+}
+
+void _LumpedMassMatrixForceTerm_Initialise( void* forceTerm, void* data ) {
+ LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
+
+ _ForceTerm_Initialise( self, data );
+}
+
+void _LumpedMassMatrixForceTerm_Execute( void* forceTerm, void* data ) {
+ LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
+
+ _ForceTerm_Execute( self, data );
+}
+
+void _LumpedMassMatrixForceTerm_Destroy( void* forceTerm, void* data ) {
+ LumpedMassMatrixForceTerm* self = (LumpedMassMatrixForceTerm*)forceTerm;
+
+ _ForceTerm_Destroy( self, data );
+}
+
+void _LumpedMassMatrixForceTerm_AssembleElement( void* forceTerm, ForceVector* forceVector ,Element_LocalIndex lElement_I, double* elForceVector ) {
+ LumpedMassMatrixForceTerm* self = Stg_CheckType( forceTerm, LumpedMassMatrixForceTerm );
+
+#if 0
+ if ( Stg_Class_IsInstance( mesh->layout->elementLayout, ParallelPipedHexaEL_Type ) ) {
+ ForceTerm_SetAssembleElementFunction( self, _LumpedMassMatrixForceTerm_AssembleElement_Box );
+ }
+ else {
+#endif
+ ForceTerm_SetAssembleElementFunction( self, _LumpedMassMatrixForceTerm_AssembleElement_General );
+#if 0
+ }
+#endif
+
+ ForceTerm_AssembleElement( self, forceVector, lElement_I, elForceVector );
+}
+
+void _LumpedMassMatrixForceTerm_AssembleElement_General( void* forceTerm, ForceVector* forceVector, Element_LocalIndex lElement_I, double* elForceVector ) {
+ LumpedMassMatrixForceTerm* self = Stg_CheckType( forceTerm, LumpedMassMatrixForceTerm );
+ FeVariable* feVariable = forceVector->feVariable;
+ Dimension_Index dim = forceVector->dim;
+ Swarm* swarm = self->integrationSwarm;
+ FeMesh* feMesh = feVariable->feMesh;
+ ElementType* elementType = FeMesh_GetElementType( feMesh, lElement_I );
+ Cell_Index cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
+ Particle_InCellIndex cellParticleCount;
+ Particle_InCellIndex cParticle_I;
+ IntegrationPoint* particle;
+ Node_Index nodeRow_I;
+ Node_Index nodeColumn_I;
+ double factor;
+ double detJac;
+ double shapeFunc[27];
+ unsigned elementNodeCount;
+
+ elementNodeCount = FeMesh_GetElementNodeSize( feMesh, lElement_I );
+ cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
+
+ for( cParticle_I = 0 ; cParticle_I < cellParticleCount; cParticle_I++ ) {
+ /* Find this particle in the element */
+ particle = (IntegrationPoint*) Swarm_ParticleInCellAt( swarm, cell_I, cParticle_I );
+
+ /* Evalutate Shape Functions and Jacobian Determinant */
+ ElementType_EvaluateShapeFunctionsAt( elementType, particle->xi, shapeFunc );
+ detJac = ElementType_JacobianDeterminant( elementType, feMesh, lElement_I, particle->xi, dim );
+
+ /* Integrate \int_{\Omgea} N_i N_i d\Omega and lump onto vector in one step */
+ factor = detJac * particle->weight;
+ for ( nodeRow_I = 0 ; nodeRow_I < elementNodeCount ; nodeRow_I++ )
+ for ( nodeColumn_I = 0 ; nodeColumn_I < elementNodeCount ; nodeColumn_I++ )
+ elForceVector[ nodeRow_I ] += shapeFunc[ nodeRow_I ] * shapeFunc[ nodeColumn_I ] * factor ;
+ }
+}
+
+/** Shortcut for doing above calculation, optimised for a box shaped element */
+void _LumpedMassMatrixForceTerm_AssembleElement_Box( void* forceTerm, ForceVector* forceVector, Element_LocalIndex lElement_I, double* elForceVector ) {
+ FeVariable* feVariable = forceVector->feVariable;
+ Dimension_Index dim = forceVector->dim;
+ FeMesh* feMesh = feVariable->feMesh;
+ Element_NodeIndex elementNodeCount;
+ ElementType* elementType;
+ Node_Index node_I;
+ double detJac;
+ Coord xi = {0.0,0.0,0.0};
+
+ elementNodeCount = FeMesh_GetElementNodeSize( feMesh, lElement_I );
+ elementType = FeMesh_GetElementType( feMesh, lElement_I );
+
+ detJac = ElementType_JacobianDeterminant( elementType, feMesh, lElement_I, xi, dim );
+ for ( node_I = 0 ; node_I < elementNodeCount ; node_I++ )
+ elForceVector[ node_I ] = detJac;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/MassMatrix_Assembly.c
--- a/SLE/ProvidedSystems/AdvectionDiffusion/src/MassMatrix_Assembly.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: MassMatrix_Assembly.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include <StgFEM/SLE/SystemSetup/SystemSetup.h>
-
-#include "types.h"
-#include "AdvectionDiffusionSLE.h"
-#include "Multicorrector.h"
-#include "Residual.h"
-
-#include <string.h>
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/MassMatrix_Assembly.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/AdvectionDiffusion/src/MassMatrix_Assembly.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,56 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: MassMatrix_Assembly.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include <StgFEM/SLE/SystemSetup/SystemSetup.h>
+
+#include "types.h"
+#include "AdvectionDiffusionSLE.h"
+#include "Multicorrector.h"
+#include "Residual.h"
+
+#include <string.h>
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/Multicorrector.c
--- a/SLE/ProvidedSystems/AdvectionDiffusion/src/Multicorrector.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,364 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Multicorrector.c 985 2007-11-21 00:20:24Z MirkoVelic $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/SLE/SystemSetup/SystemSetup.h>
-
-#include "types.h"
-#include "AdvectionDiffusionSLE.h"
-#include "Multicorrector.h"
-#include "Residual.h"
-#include "MassMatrix_Assembly.h"
-
-#include <assert.h>
-
-/* Textual name of this class */
-const Type AdvDiffMulticorrector_Type = "AdvDiffMulticorrector";
-
-AdvDiffMulticorrector* AdvDiffMulticorrector_New(
- Name name,
- double gamma,
- Iteration_Index multiCorrectorIterations )
-{
- AdvDiffMulticorrector* self = (AdvDiffMulticorrector*) _AdvDiffMulticorrector_DefaultNew( name );
-
- AdvDiffMulticorrector_InitAll( self, gamma, multiCorrectorIterations );
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-AdvDiffMulticorrector* _AdvDiffMulticorrector_New( ADVDIFFMULTICORRECTOR_DEFARGS )
-{
- AdvDiffMulticorrector* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(AdvDiffMulticorrector) );
- self = (AdvDiffMulticorrector*) _SLE_Solver_New( SLE_SOLVER_PASSARGS );
-
- /* Virtual info */
-
- return self;
-}
-
-void _AdvDiffMulticorrector_Init(
- AdvDiffMulticorrector* self,
- double gamma,
- Iteration_Index multiCorrectorIterations )
-{
- self->gamma = gamma;
- self->multiCorrectorIterations = multiCorrectorIterations;
-}
-
-void AdvDiffMulticorrector_InitAll(
- void* solver,
- double gamma,
- Iteration_Index multiCorrectorIterations )
-{
- AdvDiffMulticorrector* self = (AdvDiffMulticorrector*) solver;
-
- SLE_Solver_InitAll( self, False, 0 );
- _AdvDiffMulticorrector_Init( self, gamma, multiCorrectorIterations );
-}
-
-void _AdvDiffMulticorrector_Delete( void* solver ) {
- AdvDiffMulticorrector* self = (AdvDiffMulticorrector*)solver;
-
- //FreeObject( self->matrixSolver );
- KSPDestroy( self->matrixSolver );
-
- _SLE_Solver_Delete( self );
-}
-
-void _AdvDiffMulticorrector_Print( void* solver, Stream* stream ) {
- AdvDiffMulticorrector* self = (AdvDiffMulticorrector*)solver;
-
- _SLE_Solver_Print( self, stream );
-
- Journal_PrintValue( stream, self->gamma );
- Journal_PrintValue( stream, self->multiCorrectorIterations );
-}
-
-void* _AdvDiffMulticorrector_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(AdvDiffMulticorrector);
- Type type = AdvDiffMulticorrector_Type;
- Stg_Class_DeleteFunction* _delete = _AdvDiffMulticorrector_Delete;
- Stg_Class_PrintFunction* _print = _AdvDiffMulticorrector_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _AdvDiffMulticorrector_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _AdvDiffMulticorrector_AssignFromXML;
- Stg_Component_BuildFunction* _build = _AdvDiffMulticorrector_Build;
- Stg_Component_InitialiseFunction* _initialise = _AdvDiffMulticorrector_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AdvDiffMulticorrector_Execute;
- Stg_Component_DestroyFunction* _destroy = _AdvDiffMulticorrector_Destroy;
- SLE_Solver_SolverSetupFunction* _solverSetup = _AdvDiffMulticorrector_SolverSetup;
- SLE_Solver_SolveFunction* _solve = _AdvDiffMulticorrector_Solve;
- SLE_Solver_GetResidualFunc* _getResidual = NULL;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_AdvDiffMulticorrector_New( ADVDIFFMULTICORRECTOR_PASSARGS );
-}
-
-void _AdvDiffMulticorrector_AssignFromXML( void* solver, Stg_ComponentFactory* cf, void* data ) {
- AdvDiffMulticorrector* self = (AdvDiffMulticorrector*)solver;
- double gamma;
- Iteration_Index multiCorrectorIterations;
-
- /* Construct Parent */
- _SLE_Solver_AssignFromXML( self, cf, data );
-
- gamma = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"gamma", 0.5 );
- multiCorrectorIterations = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"multiCorrectorIterations", 2 );
-
- _AdvDiffMulticorrector_Init( self, gamma, multiCorrectorIterations );
-
- if( self->matrixSolver == PETSC_NULL ) {
- KSPCreate( MPI_COMM_WORLD, &self->matrixSolver );
- }
-}
-
-void _AdvDiffMulticorrector_Build( void* solver, void* data ) {
- AdvDiffMulticorrector* self = Stg_CheckType( solver, AdvDiffMulticorrector );
-
- _SLE_Solver_Build( self, data );
-}
-
-void _AdvDiffMulticorrector_Initialise( void* solver, void* data ) {
- AdvDiffMulticorrector* self = (AdvDiffMulticorrector*)solver;
-
- _SLE_Solver_Initialise( self, data );
-}
-
-void _AdvDiffMulticorrector_Execute( void* solver, void* data ) {
- _SLE_Solver_Execute( solver, data );
-}
-
-void _AdvDiffMulticorrector_Destroy( void* solver, void* data ) {
- _SLE_Solver_Destroy( solver, data );
-}
-
-void _AdvDiffMulticorrector_SolverSetup( void* solver, void* data ) {
- AdvDiffMulticorrector* self = Stg_CheckType( solver, AdvDiffMulticorrector );
- AdvectionDiffusionSLE* sle = Stg_CheckType( data, AdvectionDiffusionSLE );
-
- __AdvDiffResidualForceTerm_UpdateLocalMemory( sle );
-
- if ( self->matrixSolver && Stg_Class_IsInstance( sle->massMatrix, StiffnessMatrix_Type ) ) {
- StiffnessMatrix* massMatrix = Stg_CheckType( sle->massMatrix, StiffnessMatrix );
- KSPSetOperators( self->matrixSolver, massMatrix->matrix, massMatrix->matrix, DIFFERENT_NONZERO_PATTERN );
- }
-}
-
-/* See Brooks, Hughes 1982 Section 4.2
- * All equations refer to this paper if not otherwise indicated */
-void _AdvDiffMulticorrector_Solve( void* solver, void* _sle ) {
- AdvDiffMulticorrector* self = (AdvDiffMulticorrector*) solver;
- AdvectionDiffusionSLE* sle = (AdvectionDiffusionSLE*) _sle;
- double dt = sle->currentDt;
- Index iteration_I;
- Vec deltaPhiDot;
-
- Journal_DPrintf( sle->debug, "In func %s:\n", __func__ );
-
- /* First apply BC's */
-
- FeVariable_ApplyBCs( sle->phiVector->feVariable, self->context );
- FeVariable_ApplyBCs( sle->phiDotVector->feVariable, self->context );
-
- /* Put mesh data onto vectors */
- SolutionVector_LoadCurrentFeVariableValuesOntoVector( sle->phiVector );
- SolutionVector_LoadCurrentFeVariableValuesOntoVector( sle->phiDotVector );
-
- /* Solve for predictor step */
- AdvDiffMulticorrector_Predictors( self, sle, dt );
-
- /* Allocate Memory For Corrector Step */
- //Vector_Duplicate( sle->phiVector->vector, (void**)&deltaPhiDot );
- //Vector_SetLocalSize( deltaPhiDot, Vector_GetLocalSize( sle->phiVector->vector ) );
- VecDuplicate( sle->phiVector->vector, &deltaPhiDot );
-
- /* Multi-corrector Steps */
- for ( iteration_I = 0 ; iteration_I < self->multiCorrectorIterations ; iteration_I++ ) {
- AdvDiffMulticorrector_Solution( self, sle, deltaPhiDot );
- AdvDiffMulticorrector_Correctors( self, sle, deltaPhiDot, dt );
-
- /* Put solutions onto meshes */
- SolutionVector_UpdateSolutionOntoNodes( sle->phiVector );
- SolutionVector_UpdateSolutionOntoNodes( sle->phiDotVector );
-
- SystemLinearEquations_ZeroAllVectors( sle, NULL );
- }
-
- /* Clean Up */
- //FreeObject( deltaPhiDot );
- VecDestroy( deltaPhiDot );
-}
-
-void ViewPETScVector( Vec vec, Stream* stream ) {
- PetscInt size;
- PetscScalar* array;
- unsigned entry_i;
-
- if( !stream )
- stream = Journal_Register( Info_Type, (Name)"tmp" );
-
- VecGetLocalSize( vec, &size );
- VecGetArray( vec, &array );
-
- for( entry_i = 0; entry_i < size; entry_i++ )
- Journal_Printf( stream, "\t%u: \t %.12g\n", entry_i, array[entry_i] );
-
- VecRestoreArray( vec, &array );
-}
-
-/** See Eqns. 4.2.3-4 */
-void AdvDiffMulticorrector_Predictors( AdvDiffMulticorrector* self, AdvectionDiffusionSLE* sle, double dt ) {
- double factor = dt * ( 1.0 - self->gamma );
- Stream* debugStream = sle->debug;
-
- Journal_DPrintf( debugStream, "In func %s:\n", __func__ );
-
- #if DEBUG
- if ( Stream_IsPrintableLevel( debugStream, 3 ) ) {
- Journal_DPrintf( debugStream, "At start of %s:\n", __func__ );
- Stream_Indent( debugStream );
-
- Journal_PrintValue( debugStream, dt );
- Journal_PrintValue( debugStream, self->gamma );
- Journal_PrintValue( debugStream, factor );
-
- Journal_DPrintf( debugStream, "Phi:\n" );
- ViewPETScVector( sle->phiVector->vector, debugStream );
- Journal_DPrintf( debugStream, "Phi Dot:\n" );
- ViewPETScVector( sle->phiDotVector->vector, debugStream );
-
- Stream_UnIndent( debugStream );
- }
- #endif
-
- /* Calculate Predictor for \phi -
- * Eq. 4.2.3: \phi_{n+1}^{(0)} = \phi_n + \Delta t(1 - \gamma)\dot \phi_n */
- //Vector_AddScaled( sle->phiVector->vector, factor, sle->phiDotVector->vector );
- VecAXPY( sle->phiVector->vector, factor, sle->phiDotVector->vector );
-
- /* Calculate Predictor for \dot \phi -
- * Eq. 4.2.4: \dot \phi_{n+1}^{(0)} = 0 */
- //Vector_Zero( sle->phiDotVector->vector );
- VecSet( sle->phiDotVector->vector, 0.0 );
-
- #if DEBUG
- if ( Stream_IsPrintableLevel( debugStream, 3 ) ) {
- Journal_DPrintf( debugStream, "At end of %s: Phi is:\n", __func__ );
- ViewPETScVector( sle->phiVector->vector, debugStream );
- }
- #endif
-}
-
-
-void AdvDiffMulticorrector_Solution( AdvDiffMulticorrector* self, AdvectionDiffusionSLE* sle, Vec deltaPhiDot ) {
- Journal_DPrintf( sle->debug, "In func %s:\n", __func__ );
-
- /* Calculate Residual - See Eq. 4.2.6 */
- SystemLinearEquations_VectorSetup( sle, NULL );
- SystemLinearEquations_MatrixSetup( sle, NULL );
-
- /* Calculate Mass Matrix out of three options - fully explicit, fully implicit, split operators */
- AdvDiffMulticorrector_CalculatePhiDot( self, sle, deltaPhiDot );
-
- #if DEBUG
- if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
- Journal_DPrintf( self->debug, "Delta Phi Dot is:\n" );
- ViewPETScVector( deltaPhiDot, self->debug );
- }
- #endif
-}
-
-
-
-/* Correct \phi and \dot \phi - See Eqns. 4.2.7-8 */
-void AdvDiffMulticorrector_Correctors( AdvDiffMulticorrector* self, AdvectionDiffusionSLE* sle, Vec deltaPhiDot, double dt ) {
- double factor = dt * self->gamma;
-
- Journal_DPrintf( sle->debug, "In func %s:\n", __func__ );
-
- /* Add correction to \phi - Eq. 4.2.7 */
- //Vector_AddScaled( sle->phiVector->vector, factor, deltaPhiDot );
- VecAXPY( sle->phiVector->vector, factor, deltaPhiDot );
-
- /* Add correction to \dot \phi - Eq. 4.2.8 */
- //Vector_AddScaled( sle->phiDotVector->vector, 1.0, deltaPhiDot );
- VecAXPY( sle->phiDotVector->vector, 1.0, deltaPhiDot );
-}
-
-
-void AdvDiffMulticorrector_CalculatePhiDot( AdvDiffMulticorrector* self, AdvectionDiffusionSLE* sle, Vec deltaPhiDot ) {
- Stg_Component* massMatrix = sle->massMatrix;
-
- if ( Stg_Class_IsInstance( massMatrix, ForceVector_Type ) )
- _AdvDiffMulticorrector_CalculatePhiDot_Explicit( self, sle, deltaPhiDot );
- else if ( Stg_Class_IsInstance( massMatrix, StiffnessMatrix_Type ) )
- _AdvDiffMulticorrector_CalculatePhiDot_Implicit( self, sle, deltaPhiDot );
- else {
- Journal_Firewall( False, Journal_Register( Error_Type, (Name)self->type ),
- "Error in func '%s': Cannot understand type '%s' for mass matrix '%s'.\n",
- __func__, massMatrix->name, massMatrix->type );
- }
-}
-
-/* Lump all things onto diagonal of matrix - which is stored as a vector - Eq. 4.2.11 */
-void _AdvDiffMulticorrector_CalculatePhiDot_Explicit( AdvDiffMulticorrector* self, AdvectionDiffusionSLE* sle, Vec deltaPhiDot ) {
- ForceVector* massMatrix = Stg_CheckType( sle->massMatrix, ForceVector );
-
- /* Calculate change in \dot \phi - See Eq. 4.2.5 */
- VecPointwiseDivide( deltaPhiDot, sle->residual->vector, massMatrix->vector );
-}
-
-void _AdvDiffMulticorrector_CalculatePhiDot_Implicit( AdvDiffMulticorrector* self, AdvectionDiffusionSLE* sle, Vec deltaPhiDot ) {
-
- KSPSolve( self->matrixSolver, deltaPhiDot, sle->residual->vector );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/Multicorrector.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/AdvectionDiffusion/src/Multicorrector.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,364 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Multicorrector.c 985 2007-11-21 00:20:24Z MirkoVelic $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include <StgFEM/SLE/SystemSetup/SystemSetup.h>
+
+#include "types.h"
+#include "AdvectionDiffusionSLE.h"
+#include "Multicorrector.h"
+#include "Residual.h"
+#include "MassMatrix_Assembly.h"
+
+#include <assert.h>
+
+/* Textual name of this class */
+const Type AdvDiffMulticorrector_Type = "AdvDiffMulticorrector";
+
+AdvDiffMulticorrector* AdvDiffMulticorrector_New(
+ Name name,
+ double gamma,
+ Iteration_Index multiCorrectorIterations )
+{
+ AdvDiffMulticorrector* self = (AdvDiffMulticorrector*) _AdvDiffMulticorrector_DefaultNew( name );
+
+ AdvDiffMulticorrector_InitAll( self, gamma, multiCorrectorIterations );
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+AdvDiffMulticorrector* _AdvDiffMulticorrector_New( ADVDIFFMULTICORRECTOR_DEFARGS )
+{
+ AdvDiffMulticorrector* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(AdvDiffMulticorrector) );
+ self = (AdvDiffMulticorrector*) _SLE_Solver_New( SLE_SOLVER_PASSARGS );
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _AdvDiffMulticorrector_Init(
+ AdvDiffMulticorrector* self,
+ double gamma,
+ Iteration_Index multiCorrectorIterations )
+{
+ self->gamma = gamma;
+ self->multiCorrectorIterations = multiCorrectorIterations;
+}
+
+void AdvDiffMulticorrector_InitAll(
+ void* solver,
+ double gamma,
+ Iteration_Index multiCorrectorIterations )
+{
+ AdvDiffMulticorrector* self = (AdvDiffMulticorrector*) solver;
+
+ SLE_Solver_InitAll( self, False, 0 );
+ _AdvDiffMulticorrector_Init( self, gamma, multiCorrectorIterations );
+}
+
+void _AdvDiffMulticorrector_Delete( void* solver ) {
+ AdvDiffMulticorrector* self = (AdvDiffMulticorrector*)solver;
+
+ //FreeObject( self->matrixSolver );
+ KSPDestroy( self->matrixSolver );
+
+ _SLE_Solver_Delete( self );
+}
+
+void _AdvDiffMulticorrector_Print( void* solver, Stream* stream ) {
+ AdvDiffMulticorrector* self = (AdvDiffMulticorrector*)solver;
+
+ _SLE_Solver_Print( self, stream );
+
+ Journal_PrintValue( stream, self->gamma );
+ Journal_PrintValue( stream, self->multiCorrectorIterations );
+}
+
+void* _AdvDiffMulticorrector_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(AdvDiffMulticorrector);
+ Type type = AdvDiffMulticorrector_Type;
+ Stg_Class_DeleteFunction* _delete = _AdvDiffMulticorrector_Delete;
+ Stg_Class_PrintFunction* _print = _AdvDiffMulticorrector_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _AdvDiffMulticorrector_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _AdvDiffMulticorrector_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _AdvDiffMulticorrector_Build;
+ Stg_Component_InitialiseFunction* _initialise = _AdvDiffMulticorrector_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AdvDiffMulticorrector_Execute;
+ Stg_Component_DestroyFunction* _destroy = _AdvDiffMulticorrector_Destroy;
+ SLE_Solver_SolverSetupFunction* _solverSetup = _AdvDiffMulticorrector_SolverSetup;
+ SLE_Solver_SolveFunction* _solve = _AdvDiffMulticorrector_Solve;
+ SLE_Solver_GetResidualFunc* _getResidual = NULL;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_AdvDiffMulticorrector_New( ADVDIFFMULTICORRECTOR_PASSARGS );
+}
+
+void _AdvDiffMulticorrector_AssignFromXML( void* solver, Stg_ComponentFactory* cf, void* data ) {
+ AdvDiffMulticorrector* self = (AdvDiffMulticorrector*)solver;
+ double gamma;
+ Iteration_Index multiCorrectorIterations;
+
+ /* Construct Parent */
+ _SLE_Solver_AssignFromXML( self, cf, data );
+
+ gamma = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"gamma", 0.5 );
+ multiCorrectorIterations = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"multiCorrectorIterations", 2 );
+
+ _AdvDiffMulticorrector_Init( self, gamma, multiCorrectorIterations );
+
+ if( self->matrixSolver == PETSC_NULL ) {
+ KSPCreate( MPI_COMM_WORLD, &self->matrixSolver );
+ }
+}
+
+void _AdvDiffMulticorrector_Build( void* solver, void* data ) {
+ AdvDiffMulticorrector* self = Stg_CheckType( solver, AdvDiffMulticorrector );
+
+ _SLE_Solver_Build( self, data );
+}
+
+void _AdvDiffMulticorrector_Initialise( void* solver, void* data ) {
+ AdvDiffMulticorrector* self = (AdvDiffMulticorrector*)solver;
+
+ _SLE_Solver_Initialise( self, data );
+}
+
+void _AdvDiffMulticorrector_Execute( void* solver, void* data ) {
+ _SLE_Solver_Execute( solver, data );
+}
+
+void _AdvDiffMulticorrector_Destroy( void* solver, void* data ) {
+ _SLE_Solver_Destroy( solver, data );
+}
+
+void _AdvDiffMulticorrector_SolverSetup( void* solver, void* data ) {
+ AdvDiffMulticorrector* self = Stg_CheckType( solver, AdvDiffMulticorrector );
+ AdvectionDiffusionSLE* sle = Stg_CheckType( data, AdvectionDiffusionSLE );
+
+ __AdvDiffResidualForceTerm_UpdateLocalMemory( sle );
+
+ if ( self->matrixSolver && Stg_Class_IsInstance( sle->massMatrix, StiffnessMatrix_Type ) ) {
+ StiffnessMatrix* massMatrix = Stg_CheckType( sle->massMatrix, StiffnessMatrix );
+ KSPSetOperators( self->matrixSolver, massMatrix->matrix, massMatrix->matrix, DIFFERENT_NONZERO_PATTERN );
+ }
+}
+
+/* See Brooks, Hughes 1982 Section 4.2
+ * All equations refer to this paper if not otherwise indicated */
+void _AdvDiffMulticorrector_Solve( void* solver, void* _sle ) {
+ AdvDiffMulticorrector* self = (AdvDiffMulticorrector*) solver;
+ AdvectionDiffusionSLE* sle = (AdvectionDiffusionSLE*) _sle;
+ double dt = sle->currentDt;
+ Index iteration_I;
+ Vec deltaPhiDot;
+
+ Journal_DPrintf( sle->debug, "In func %s:\n", __func__ );
+
+ /* First apply BC's */
+
+ FeVariable_ApplyBCs( sle->phiVector->feVariable, self->context );
+ FeVariable_ApplyBCs( sle->phiDotVector->feVariable, self->context );
+
+ /* Put mesh data onto vectors */
+ SolutionVector_LoadCurrentFeVariableValuesOntoVector( sle->phiVector );
+ SolutionVector_LoadCurrentFeVariableValuesOntoVector( sle->phiDotVector );
+
+ /* Solve for predictor step */
+ AdvDiffMulticorrector_Predictors( self, sle, dt );
+
+ /* Allocate Memory For Corrector Step */
+ //Vector_Duplicate( sle->phiVector->vector, (void**)&deltaPhiDot );
+ //Vector_SetLocalSize( deltaPhiDot, Vector_GetLocalSize( sle->phiVector->vector ) );
+ VecDuplicate( sle->phiVector->vector, &deltaPhiDot );
+
+ /* Multi-corrector Steps */
+ for ( iteration_I = 0 ; iteration_I < self->multiCorrectorIterations ; iteration_I++ ) {
+ AdvDiffMulticorrector_Solution( self, sle, deltaPhiDot );
+ AdvDiffMulticorrector_Correctors( self, sle, deltaPhiDot, dt );
+
+ /* Put solutions onto meshes */
+ SolutionVector_UpdateSolutionOntoNodes( sle->phiVector );
+ SolutionVector_UpdateSolutionOntoNodes( sle->phiDotVector );
+
+ SystemLinearEquations_ZeroAllVectors( sle, NULL );
+ }
+
+ /* Clean Up */
+ //FreeObject( deltaPhiDot );
+ VecDestroy( deltaPhiDot );
+}
+
+void ViewPETScVector( Vec vec, Stream* stream ) {
+ PetscInt size;
+ PetscScalar* array;
+ unsigned entry_i;
+
+ if( !stream )
+ stream = Journal_Register( Info_Type, (Name)"tmp" );
+
+ VecGetLocalSize( vec, &size );
+ VecGetArray( vec, &array );
+
+ for( entry_i = 0; entry_i < size; entry_i++ )
+ Journal_Printf( stream, "\t%u: \t %.12g\n", entry_i, array[entry_i] );
+
+ VecRestoreArray( vec, &array );
+}
+
+/** See Eqns. 4.2.3-4 */
+void AdvDiffMulticorrector_Predictors( AdvDiffMulticorrector* self, AdvectionDiffusionSLE* sle, double dt ) {
+ double factor = dt * ( 1.0 - self->gamma );
+ Stream* debugStream = sle->debug;
+
+ Journal_DPrintf( debugStream, "In func %s:\n", __func__ );
+
+ #if DEBUG
+ if ( Stream_IsPrintableLevel( debugStream, 3 ) ) {
+ Journal_DPrintf( debugStream, "At start of %s:\n", __func__ );
+ Stream_Indent( debugStream );
+
+ Journal_PrintValue( debugStream, dt );
+ Journal_PrintValue( debugStream, self->gamma );
+ Journal_PrintValue( debugStream, factor );
+
+ Journal_DPrintf( debugStream, "Phi:\n" );
+ ViewPETScVector( sle->phiVector->vector, debugStream );
+ Journal_DPrintf( debugStream, "Phi Dot:\n" );
+ ViewPETScVector( sle->phiDotVector->vector, debugStream );
+
+ Stream_UnIndent( debugStream );
+ }
+ #endif
+
+ /* Calculate Predictor for \phi -
+ * Eq. 4.2.3: \phi_{n+1}^{(0)} = \phi_n + \Delta t(1 - \gamma)\dot \phi_n */
+ //Vector_AddScaled( sle->phiVector->vector, factor, sle->phiDotVector->vector );
+ VecAXPY( sle->phiVector->vector, factor, sle->phiDotVector->vector );
+
+ /* Calculate Predictor for \dot \phi -
+ * Eq. 4.2.4: \dot \phi_{n+1}^{(0)} = 0 */
+ //Vector_Zero( sle->phiDotVector->vector );
+ VecSet( sle->phiDotVector->vector, 0.0 );
+
+ #if DEBUG
+ if ( Stream_IsPrintableLevel( debugStream, 3 ) ) {
+ Journal_DPrintf( debugStream, "At end of %s: Phi is:\n", __func__ );
+ ViewPETScVector( sle->phiVector->vector, debugStream );
+ }
+ #endif
+}
+
+
+void AdvDiffMulticorrector_Solution( AdvDiffMulticorrector* self, AdvectionDiffusionSLE* sle, Vec deltaPhiDot ) {
+ Journal_DPrintf( sle->debug, "In func %s:\n", __func__ );
+
+ /* Calculate Residual - See Eq. 4.2.6 */
+ SystemLinearEquations_VectorSetup( sle, NULL );
+ SystemLinearEquations_MatrixSetup( sle, NULL );
+
+ /* Calculate Mass Matrix out of three options - fully explicit, fully implicit, split operators */
+ AdvDiffMulticorrector_CalculatePhiDot( self, sle, deltaPhiDot );
+
+ #if DEBUG
+ if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+ Journal_DPrintf( self->debug, "Delta Phi Dot is:\n" );
+ ViewPETScVector( deltaPhiDot, self->debug );
+ }
+ #endif
+}
+
+
+
+/* Correct \phi and \dot \phi - See Eqns. 4.2.7-8 */
+void AdvDiffMulticorrector_Correctors( AdvDiffMulticorrector* self, AdvectionDiffusionSLE* sle, Vec deltaPhiDot, double dt ) {
+ double factor = dt * self->gamma;
+
+ Journal_DPrintf( sle->debug, "In func %s:\n", __func__ );
+
+ /* Add correction to \phi - Eq. 4.2.7 */
+ //Vector_AddScaled( sle->phiVector->vector, factor, deltaPhiDot );
+ VecAXPY( sle->phiVector->vector, factor, deltaPhiDot );
+
+ /* Add correction to \dot \phi - Eq. 4.2.8 */
+ //Vector_AddScaled( sle->phiDotVector->vector, 1.0, deltaPhiDot );
+ VecAXPY( sle->phiDotVector->vector, 1.0, deltaPhiDot );
+}
+
+
+void AdvDiffMulticorrector_CalculatePhiDot( AdvDiffMulticorrector* self, AdvectionDiffusionSLE* sle, Vec deltaPhiDot ) {
+ Stg_Component* massMatrix = sle->massMatrix;
+
+ if ( Stg_Class_IsInstance( massMatrix, ForceVector_Type ) )
+ _AdvDiffMulticorrector_CalculatePhiDot_Explicit( self, sle, deltaPhiDot );
+ else if ( Stg_Class_IsInstance( massMatrix, StiffnessMatrix_Type ) )
+ _AdvDiffMulticorrector_CalculatePhiDot_Implicit( self, sle, deltaPhiDot );
+ else {
+ Journal_Firewall( False, Journal_Register( Error_Type, (Name)self->type ),
+ "Error in func '%s': Cannot understand type '%s' for mass matrix '%s'.\n",
+ __func__, massMatrix->name, massMatrix->type );
+ }
+}
+
+/* Lump all things onto diagonal of matrix - which is stored as a vector - Eq. 4.2.11 */
+void _AdvDiffMulticorrector_CalculatePhiDot_Explicit( AdvDiffMulticorrector* self, AdvectionDiffusionSLE* sle, Vec deltaPhiDot ) {
+ ForceVector* massMatrix = Stg_CheckType( sle->massMatrix, ForceVector );
+
+ /* Calculate change in \dot \phi - See Eq. 4.2.5 */
+ VecPointwiseDivide( deltaPhiDot, sle->residual->vector, massMatrix->vector );
+}
+
+void _AdvDiffMulticorrector_CalculatePhiDot_Implicit( AdvDiffMulticorrector* self, AdvectionDiffusionSLE* sle, Vec deltaPhiDot ) {
+
+ KSPSolve( self->matrixSolver, deltaPhiDot, sle->residual->vector );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/Residual.c
--- a/SLE/ProvidedSystems/AdvectionDiffusion/src/Residual.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,458 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Residual.c 985 2007-11-21 00:20:24Z MirkoVelic $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/SLE/SystemSetup/SystemSetup.h>
-#include <PICellerator/PICellerator.h>
-#include <Underworld/Underworld.h>
-
-#include "types.h"
-#include "AdvectionDiffusionSLE.h"
-#include "Residual.h"
-#include "UpwindParameter.h"
-
-#include <assert.h>
-#include <string.h>
-#include <stddef.h>
-
-/* Textual name of this class */
-const Type AdvDiffResidualForceTerm_Type = "AdvDiffResidualForceTerm";
-
-AdvDiffResidualForceTerm* AdvDiffResidualForceTerm_New(
- Name name,
- FiniteElementContext* context,
- ForceVector* forceVector,
- Swarm* integrationSwarm,
- Stg_Component* sle,
- FeVariable* velocityField,
- double defaultDiffusivity,
- Swarm* picSwarm,
- void* materials_Register,
- AdvDiffResidualForceTerm_UpwindParamFuncType upwindFuncType )
-{
- AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*) _AdvDiffResidualForceTerm_DefaultNew( name );
-
- self->isConstructed = True;
- _ForceTerm_Init( self, context, forceVector, integrationSwarm, sle );
- _AdvDiffResidualForceTerm_Init( self, velocityField, defaultDiffusivity,
- picSwarm,
- materials_Register, upwindFuncType );
-
- return self;
-}
-
-void* _AdvDiffResidualForceTerm_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(AdvDiffResidualForceTerm);
- Type type = AdvDiffResidualForceTerm_Type;
- Stg_Class_DeleteFunction* _delete = _AdvDiffResidualForceTerm_Delete;
- Stg_Class_PrintFunction* _print = _AdvDiffResidualForceTerm_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _AdvDiffResidualForceTerm_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _AdvDiffResidualForceTerm_AssignFromXML;
- Stg_Component_BuildFunction* _build = _AdvDiffResidualForceTerm_Build;
- Stg_Component_InitialiseFunction* _initialise = _AdvDiffResidualForceTerm_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AdvDiffResidualForceTerm_Execute;
- Stg_Component_DestroyFunction* _destroy = _AdvDiffResidualForceTerm_Destroy;
- ForceTerm_AssembleElementFunction* _assembleElement = _AdvDiffResidualForceTerm_AssembleElement;
- AdvDiffResidualForceTerm_UpwindParamFunction* _upwindParam = _AdvDiffResidualForceTerm_UpwindParam;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_AdvDiffResidualForceTerm_New( ADVDIFFRESIDUALFORCETERM_PASSARGS );
-}
-
-/* Creation implementation / Virtual constructor */
-AdvDiffResidualForceTerm* _AdvDiffResidualForceTerm_New( ADVDIFFRESIDUALFORCETERM_DEFARGS )
-{
- AdvDiffResidualForceTerm* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(AdvDiffResidualForceTerm) );
- /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
- /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
- and so should be set to ZERO in any children of this class. */
- nameAllocationType = NON_GLOBAL;
-
- self = (AdvDiffResidualForceTerm*) _ForceTerm_New( FORCETERM_PASSARGS );
-
- /* Virtual info */
- self->_upwindParam = _upwindParam;
-
- return self;
-}
-
-/*******************************************************************************
- The following function scans all the elements of the mesh associated with
- the residual forceterm phi to find the element with the most nodes.
- Once the maximum number of nodes is found we then may allocate memory for
- GNx etc that now live on the AdvDiffResidualForceTerm struct. This way we
- do not reallocate memory for these arrays for every element.
- *******************************************************************************/
-void __AdvDiffResidualForceTerm_UpdateLocalMemory( AdvectionDiffusionSLE* sle ){
- FeVariable* phiField = sle->phiField;
- FeMesh* phiMesh = phiField->feMesh;
- Dimension_Index dim = phiField->dim;
- Element_LocalIndex e, n_elements;
- Node_Index max_elementNodeCount;
-
- n_elements = FeMesh_GetElementLocalSize(phiMesh);//returns number of elements in a mesh
-
- /* Scan all elements in Mesh to get max node count */
- max_elementNodeCount = 0;
-
- for(e=0;e<n_elements;e++){
- ElementType *elementType = FeMesh_GetElementType( phiMesh, e );
- Node_Index elementNodeCount = elementType->nodeCount;
-
- if( elementNodeCount > max_elementNodeCount){
- max_elementNodeCount = elementNodeCount;
- }
- }
-
- sle->advDiffResidualForceTerm->GNx = Memory_Alloc_2DArray( double, dim, max_elementNodeCount, (Name)"(SUPG): Global Shape Function Derivatives" );
- sle->advDiffResidualForceTerm->phiGrad = Memory_Alloc_Array(double, dim, "(SUPG): Gradient of the Advected Scalar");
- sle->advDiffResidualForceTerm->Ni = Memory_Alloc_Array(double, max_elementNodeCount, "(SUPG): Gradient of the Advected Scalar");
- sle->advDiffResidualForceTerm->SUPGNi = Memory_Alloc_Array(double, max_elementNodeCount, "(SUPG): Upwinded Shape Function");
- sle->advDiffResidualForceTerm->incarray=IArray_New();
-}
-
-void __AdvDiffResidualForceTerm_FreeLocalMemory( AdvectionDiffusionSLE* sle ){
- Memory_Free(sle->advDiffResidualForceTerm->GNx);
- Memory_Free(sle->advDiffResidualForceTerm->phiGrad);
- Memory_Free(sle->advDiffResidualForceTerm->Ni);
- Memory_Free(sle->advDiffResidualForceTerm->SUPGNi);
-
- NewClass_Delete(sle->advDiffResidualForceTerm->incarray);
-}
-
-void _AdvDiffResidualForceTerm_Init(
- void* residual,
- FeVariable* velocityField,
- double defaultDiffusivity,
- Swarm* picSwarm,
- void* materials_Register,
- AdvDiffResidualForceTerm_UpwindParamFuncType upwindFuncType ) //WHY IS THIS LINE HERE???
-{
- AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
-
- self->velocityField = velocityField;
- self->defaultDiffusivity = defaultDiffusivity;
- self->picSwarm = picSwarm;
- self->materials_Register = materials_Register;
- self->upwindParamType = upwindFuncType;
-}
-
-void _AdvDiffResidualForceTerm_Delete( void* residual ) {
- AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
-
- _ForceTerm_Delete( self );
-}
-
-void _AdvDiffResidualForceTerm_Print( void* residual, Stream* stream ) {
- AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
-
- _ForceTerm_Print( self, stream );
-
- Journal_Printf( stream, "self->calculateUpwindParam = %s\n",
- self->_upwindParam == AdvDiffResidualForceTerm_UpwindXiExact ?
- "AdvDiffResidualForceTerm_UpwindXiExact" :
- self->_upwindParam == AdvDiffResidualForceTerm_UpwindXiDoublyAsymptoticAssumption ?
- "AdvDiffResidualForceTerm_UpwindXiDoublyAsymptoticAssumption" :
- self->_upwindParam == AdvDiffResidualForceTerm_UpwindXiCriticalAssumption ?
- "AdvDiffResidualForceTerm_UpwindXiCriticalAssumption" : "Unknown" );
-
- /* General info */
- Journal_PrintPointer( stream, self->velocityField );
- Journal_PrintDouble( stream, self->defaultDiffusivity );
-}
-
-void _AdvDiffResidualForceTerm_AssignFromXML( void* residual, Stg_ComponentFactory* cf, void* data ) {
- AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
- FeVariable* velocityField;
- Name upwindParamFuncName;
- double defaultDiffusivity;
- Materials_Register* materials_Register;
- AdvDiffResidualForceTerm_UpwindParamFuncType upwindFuncType = (AdvDiffResidualForceTerm_UpwindParamFuncType)0;
- Swarm *picSwarm;
-
- /* Construct Parent */
- _ForceTerm_AssignFromXML( self, cf, data );
-
- velocityField = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"VelocityField", FeVariable, True, data );
- upwindParamFuncName = Stg_ComponentFactory_GetString( cf, self->name, (Dictionary_Entry_Key)"UpwindXiFunction", "Exact" );
-
- if ( strcasecmp( upwindParamFuncName, "DoublyAsymptoticAssumption" ) == 0 )
- upwindFuncType = DoublyAsymptoticAssumption;
- else if ( strcasecmp( upwindParamFuncName, "CriticalAssumption" ) == 0 )
- upwindFuncType = CriticalAssumption;
- else if ( strcasecmp( upwindParamFuncName, "Exact" ) == 0 )
- upwindFuncType = Exact;
- else
- Journal_Firewall( False, Journal_Register( Error_Type, (Name)self->type ), "Cannot understand '%s'\n", upwindParamFuncName );
-
- defaultDiffusivity = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"defaultDiffusivity", 1.0 );
- picSwarm = (Swarm*)Stg_ComponentFactory_ConstructByName( cf, (Name)"picIntegrationPoints", IntegrationPointsSwarm, True, data ) ;
- materials_Register = ((PICelleratorContext*)(self->context))->materials_Register;
-
- _AdvDiffResidualForceTerm_Init( self, velocityField, defaultDiffusivity,
- picSwarm, materials_Register,
- upwindFuncType );
-}
-
-void _AdvDiffResidualForceTerm_Build( void* residual, void* data ) {
- AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
- AdvDiffResidualForceTerm_MaterialExt* materialExt;
- Material_Index material_I;
- Material* material;
- Materials_Register* materials_Register = (Materials_Register*)(self->materials_Register);
- IntegrationPointsSwarm* swarm = (IntegrationPointsSwarm*)self->picSwarm;
- MaterialPointsSwarm** materialSwarms;
- Index materialSwarm_I;
- Stg_ComponentFactory* cf;
- char* name;
-
- cf = self->context->CF;
-
- _ForceTerm_Build( self, data );
-
- Stg_Component_Build( self->velocityField, data, False );
-
- /* Sort out material extension stuff */
- self->materialExtHandle = Materials_Register_AddMaterialExtension(
- self->materials_Register,
- self->type,
- sizeof(AdvDiffResidualForceTerm_MaterialExt) );
- for ( material_I = 0 ; material_I < Materials_Register_GetCount( materials_Register ) ; material_I++) {
- material = Materials_Register_GetByIndex( materials_Register, material_I );
- materialExt = (AdvDiffResidualForceTerm_MaterialExt*)ExtensionManager_GetFunc( material->extensionMgr, material, self->materialExtHandle );
-
- materialExt->diffusivity = Stg_ComponentFactory_GetDouble( cf, material->name,
- (Dictionary_Entry_Key)"diffusivity",
- self->defaultDiffusivity );
- }
-
- /* Create Swarm Variables of each material swarm this ip swarm is mapped against */
- materialSwarms = IntegrationPointMapper_GetMaterialPointsSwarms( swarm->mapper, &(self->materialSwarmCount) );
- self->diffusivitySwarmVariables = (void**)Memory_Alloc_Array( MaterialSwarmVariable*, self->materialSwarmCount, "DiffusivityVariables" );
-
- for ( materialSwarm_I = 0; materialSwarm_I < self->materialSwarmCount; ++materialSwarm_I ) {
- name = Stg_Object_AppendSuffix( materialSwarms[materialSwarm_I], (Name)"Diffusivity" );
- self->diffusivitySwarmVariables[materialSwarm_I] = MaterialSwarmVariable_New(
- name,
- (AbstractContext*)self->context,
- materialSwarms[materialSwarm_I],
- 1,
- (Materials_Register*)self->materials_Register,
- self->materialExtHandle,
- GetOffsetOfMember( *materialExt, diffusivity ) );
- Memory_Free( name );
-
- /* Build new Swarm Variables */
- Stg_Component_Build( self->diffusivitySwarmVariables[materialSwarm_I], data, False );
- }
-}
-
-void _AdvDiffResidualForceTerm_Initialise( void* residual, void* data ) {
- AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
- Index i;
-
- _ForceTerm_Initialise( self, data );
-
- Stg_Component_Initialise( self->velocityField, data, False );
-
- for ( i = 0; i < self->materialSwarmCount; ++i ) {
- Stg_Component_Initialise( self->diffusivitySwarmVariables[i], data, False );
- }
-}
-
-void _AdvDiffResidualForceTerm_Execute( void* residual, void* data ) {
- AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
-
- _ForceTerm_Execute( self, data );
-}
-
-void _AdvDiffResidualForceTerm_Destroy( void* residual, void* data ) {
- AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
- Index i;
-
- for ( i = 0; i < self->materialSwarmCount; ++i ) {
- _Stg_Component_Delete( self->diffusivitySwarmVariables[i] );
- }
- Memory_Free( self->diffusivitySwarmVariables );
-
- _ForceTerm_Destroy( self, data );
-}
-
-void _AdvDiffResidualForceTerm_AssembleElement( void* forceTerm, ForceVector* forceVector, Element_LocalIndex lElement_I, double* elementResidual ) {
- AdvDiffResidualForceTerm* self = Stg_CheckType( forceTerm, AdvDiffResidualForceTerm );
- AdvectionDiffusionSLE* sle = Stg_CheckType( self->extraInfo, AdvectionDiffusionSLE );
- Swarm* swarm = self->picSwarm;
- Particle_Index lParticle_I;
- Particle_Index cParticle_I;
- Particle_Index cellParticleCount;
- Cell_Index cell_I;
- IntegrationPoint* particle;
- FeVariable* phiField = sle->phiField;
- Dimension_Index dim = forceVector->dim;
- double velocity[3];
- double phi, phiDot;
- double detJac;
- double* xi;
- double totalDerivative, diffusionTerm;
- double diffusivity = self->defaultDiffusivity;
- ElementType* elementType = FeMesh_GetElementType( phiField->feMesh, lElement_I );
- Node_Index elementNodeCount = elementType->nodeCount;
- Node_Index node_I;
- double factor;
-
- double** GNx;
- double* phiGrad;
- double* Ni;
- double* SUPGNi;
- double supgfactor;
- double udotu, perturbation;
- double upwindDiffusivity;
-
- GNx = self->GNx;
- phiGrad = self->phiGrad;
- Ni = self->Ni;
- SUPGNi = self->SUPGNi;
-
- upwindDiffusivity = AdvDiffResidualForceTerm_UpwindDiffusivity( self, sle, swarm, phiField->feMesh, lElement_I, dim );
-
- /* Determine number of particles in element */
- cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
- cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
-
- for ( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
- lParticle_I = swarm->cellParticleTbl[cell_I][cParticle_I];
-
- particle = (IntegrationPoint*) Swarm_ParticleAt( swarm, lParticle_I );
- xi = particle->xi;
-
- /* Evaluate Shape Functions */
- ElementType_EvaluateShapeFunctionsAt(elementType, xi, Ni);
-
- /* Calculate Global Shape Function Derivatives */
- ElementType_ShapeFunctionsGlobalDerivs(
- elementType,
- phiField->feMesh, lElement_I,
- xi, dim, &detJac, GNx );
-
- /* Calculate Velocity */
- FeVariable_InterpolateFromMeshLocalCoord( self->velocityField, phiField->feMesh, lElement_I, xi, velocity );
-
- /* Build the SUPG shape functions */
- udotu = velocity[I_AXIS]*velocity[I_AXIS] + velocity[J_AXIS]*velocity[J_AXIS];
- if(dim == 3) udotu += velocity[ K_AXIS ] * velocity[ K_AXIS ];
-
- supgfactor = upwindDiffusivity / udotu;
- for ( node_I = 0 ; node_I < elementNodeCount ; node_I++ ) {
- /* In the case of per diffusion - just build regular shape functions */
- if ( fabs(upwindDiffusivity) < SUPG_MIN_DIFFUSIVITY ) {
- SUPGNi[node_I] = Ni[node_I];
- continue;
- }
-
- perturbation = velocity[ I_AXIS ] * GNx[ I_AXIS ][ node_I ] + velocity[ J_AXIS ] * GNx[ J_AXIS ][ node_I ];
- if (dim == 3)
- perturbation = perturbation + velocity[ K_AXIS ] * GNx[ K_AXIS ][ node_I ];
-
- /* p = \frac{\bar \kappa \hat u_j w_j }{ ||u|| } - Eq. 3.2.25 */
- perturbation = supgfactor * perturbation;
-
- SUPGNi[node_I] = Ni[node_I] + perturbation;
- }
-
- /* Calculate phi on particle */
- _FeVariable_InterpolateNodeValuesToElLocalCoord( phiField, lElement_I, xi, &phi );
-
- /* Calculate Gradients of Phi */
- FeVariable_InterpolateDerivatives_WithGNx( phiField, lElement_I, GNx, phiGrad );
-
- /* Calculate time derivative of phi */
- _FeVariable_InterpolateNodeValuesToElLocalCoord( sle->phiDotField, lElement_I, xi, &phiDot );
-
- /* Calculate total derivative (i.e. Dphi/Dt = \dot \phi + u . \grad \phi) */
- totalDerivative = phiDot + StGermain_VectorDotProduct( velocity, phiGrad, dim );
-
- /* Get Diffusivity */
- diffusivity = IntegrationPointMapper_GetDoubleFromMaterial(((IntegrationPointsSwarm *)swarm)->mapper, particle, self->materialExtHandle,
-
- offsetof(AdvDiffResidualForceTerm_MaterialExt, diffusivity));
-
- /* Add to element residual */
- factor = particle->weight * detJac;
- for ( node_I = 0 ; node_I < elementNodeCount ; node_I++ ) {
- /* Calculate Diffusion Term */
- diffusionTerm = diffusivity * ( GNx[0][node_I] * phiGrad[0] + GNx[1][node_I] * phiGrad[1] );
- if (dim == 3)
- diffusionTerm += diffusivity * GNx[2][ node_I ] * phiGrad[2] ;
-
- elementResidual[ node_I ] -= factor * ( SUPGNi[ node_I ] * totalDerivative + diffusionTerm );
- }
- }
-
-}
-
-/* Virtual Function Implementations */
-double _AdvDiffResidualForceTerm_UpwindParam( void* residual, double pecletNumber ) {
- AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
-
- switch ( self->upwindParamType ) {
- case Exact:
- self->_upwindParam = AdvDiffResidualForceTerm_UpwindXiExact; break;
- case DoublyAsymptoticAssumption:
- self->_upwindParam = AdvDiffResidualForceTerm_UpwindXiDoublyAsymptoticAssumption; break;
- case CriticalAssumption:
- self->_upwindParam = AdvDiffResidualForceTerm_UpwindXiCriticalAssumption; break;
- }
-
- return AdvDiffResidualForceTerm_UpwindParam( self, pecletNumber );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/Residual.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/AdvectionDiffusion/src/Residual.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,458 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Residual.c 985 2007-11-21 00:20:24Z MirkoVelic $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include <StgFEM/SLE/SystemSetup/SystemSetup.h>
+#include <PICellerator/PICellerator.h>
+#include <Underworld/Underworld.h>
+
+#include "types.h"
+#include "AdvectionDiffusionSLE.h"
+#include "Residual.h"
+#include "UpwindParameter.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stddef.h>
+
+/* Textual name of this class */
+const Type AdvDiffResidualForceTerm_Type = "AdvDiffResidualForceTerm";
+
+AdvDiffResidualForceTerm* AdvDiffResidualForceTerm_New(
+ Name name,
+ FiniteElementContext* context,
+ ForceVector* forceVector,
+ Swarm* integrationSwarm,
+ Stg_Component* sle,
+ FeVariable* velocityField,
+ double defaultDiffusivity,
+ Swarm* picSwarm,
+ void* materials_Register,
+ AdvDiffResidualForceTerm_UpwindParamFuncType upwindFuncType )
+{
+ AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*) _AdvDiffResidualForceTerm_DefaultNew( name );
+
+ self->isConstructed = True;
+ _ForceTerm_Init( self, context, forceVector, integrationSwarm, sle );
+ _AdvDiffResidualForceTerm_Init( self, velocityField, defaultDiffusivity,
+ picSwarm,
+ materials_Register, upwindFuncType );
+
+ return self;
+}
+
+void* _AdvDiffResidualForceTerm_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(AdvDiffResidualForceTerm);
+ Type type = AdvDiffResidualForceTerm_Type;
+ Stg_Class_DeleteFunction* _delete = _AdvDiffResidualForceTerm_Delete;
+ Stg_Class_PrintFunction* _print = _AdvDiffResidualForceTerm_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _AdvDiffResidualForceTerm_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _AdvDiffResidualForceTerm_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _AdvDiffResidualForceTerm_Build;
+ Stg_Component_InitialiseFunction* _initialise = _AdvDiffResidualForceTerm_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AdvDiffResidualForceTerm_Execute;
+ Stg_Component_DestroyFunction* _destroy = _AdvDiffResidualForceTerm_Destroy;
+ ForceTerm_AssembleElementFunction* _assembleElement = _AdvDiffResidualForceTerm_AssembleElement;
+ AdvDiffResidualForceTerm_UpwindParamFunction* _upwindParam = _AdvDiffResidualForceTerm_UpwindParam;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_AdvDiffResidualForceTerm_New( ADVDIFFRESIDUALFORCETERM_PASSARGS );
+}
+
+/* Creation implementation / Virtual constructor */
+AdvDiffResidualForceTerm* _AdvDiffResidualForceTerm_New( ADVDIFFRESIDUALFORCETERM_DEFARGS )
+{
+ AdvDiffResidualForceTerm* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(AdvDiffResidualForceTerm) );
+ /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
+ /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
+ and so should be set to ZERO in any children of this class. */
+ nameAllocationType = NON_GLOBAL;
+
+ self = (AdvDiffResidualForceTerm*) _ForceTerm_New( FORCETERM_PASSARGS );
+
+ /* Virtual info */
+ self->_upwindParam = _upwindParam;
+
+ return self;
+}
+
+/*******************************************************************************
+ The following function scans all the elements of the mesh associated with
+ the residual forceterm phi to find the element with the most nodes.
+ Once the maximum number of nodes is found we then may allocate memory for
+ GNx etc that now live on the AdvDiffResidualForceTerm struct. This way we
+ do not reallocate memory for these arrays for every element.
+ *******************************************************************************/
+void __AdvDiffResidualForceTerm_UpdateLocalMemory( AdvectionDiffusionSLE* sle ){
+ FeVariable* phiField = sle->phiField;
+ FeMesh* phiMesh = phiField->feMesh;
+ Dimension_Index dim = phiField->dim;
+ Element_LocalIndex e, n_elements;
+ Node_Index max_elementNodeCount;
+
+ n_elements = FeMesh_GetElementLocalSize(phiMesh);//returns number of elements in a mesh
+
+ /* Scan all elements in Mesh to get max node count */
+ max_elementNodeCount = 0;
+
+ for(e=0;e<n_elements;e++){
+ ElementType *elementType = FeMesh_GetElementType( phiMesh, e );
+ Node_Index elementNodeCount = elementType->nodeCount;
+
+ if( elementNodeCount > max_elementNodeCount){
+ max_elementNodeCount = elementNodeCount;
+ }
+ }
+
+ sle->advDiffResidualForceTerm->GNx = Memory_Alloc_2DArray( double, dim, max_elementNodeCount, (Name)"(SUPG): Global Shape Function Derivatives" );
+ sle->advDiffResidualForceTerm->phiGrad = Memory_Alloc_Array(double, dim, "(SUPG): Gradient of the Advected Scalar");
+ sle->advDiffResidualForceTerm->Ni = Memory_Alloc_Array(double, max_elementNodeCount, "(SUPG): Gradient of the Advected Scalar");
+ sle->advDiffResidualForceTerm->SUPGNi = Memory_Alloc_Array(double, max_elementNodeCount, "(SUPG): Upwinded Shape Function");
+ sle->advDiffResidualForceTerm->incarray=IArray_New();
+}
+
+void __AdvDiffResidualForceTerm_FreeLocalMemory( AdvectionDiffusionSLE* sle ){
+ Memory_Free(sle->advDiffResidualForceTerm->GNx);
+ Memory_Free(sle->advDiffResidualForceTerm->phiGrad);
+ Memory_Free(sle->advDiffResidualForceTerm->Ni);
+ Memory_Free(sle->advDiffResidualForceTerm->SUPGNi);
+
+ NewClass_Delete(sle->advDiffResidualForceTerm->incarray);
+}
+
+void _AdvDiffResidualForceTerm_Init(
+ void* residual,
+ FeVariable* velocityField,
+ double defaultDiffusivity,
+ Swarm* picSwarm,
+ void* materials_Register,
+ AdvDiffResidualForceTerm_UpwindParamFuncType upwindFuncType ) //WHY IS THIS LINE HERE???
+{
+ AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
+
+ self->velocityField = velocityField;
+ self->defaultDiffusivity = defaultDiffusivity;
+ self->picSwarm = picSwarm;
+ self->materials_Register = materials_Register;
+ self->upwindParamType = upwindFuncType;
+}
+
+void _AdvDiffResidualForceTerm_Delete( void* residual ) {
+ AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
+
+ _ForceTerm_Delete( self );
+}
+
+void _AdvDiffResidualForceTerm_Print( void* residual, Stream* stream ) {
+ AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
+
+ _ForceTerm_Print( self, stream );
+
+ Journal_Printf( stream, "self->calculateUpwindParam = %s\n",
+ self->_upwindParam == AdvDiffResidualForceTerm_UpwindXiExact ?
+ "AdvDiffResidualForceTerm_UpwindXiExact" :
+ self->_upwindParam == AdvDiffResidualForceTerm_UpwindXiDoublyAsymptoticAssumption ?
+ "AdvDiffResidualForceTerm_UpwindXiDoublyAsymptoticAssumption" :
+ self->_upwindParam == AdvDiffResidualForceTerm_UpwindXiCriticalAssumption ?
+ "AdvDiffResidualForceTerm_UpwindXiCriticalAssumption" : "Unknown" );
+
+ /* General info */
+ Journal_PrintPointer( stream, self->velocityField );
+ Journal_PrintDouble( stream, self->defaultDiffusivity );
+}
+
+void _AdvDiffResidualForceTerm_AssignFromXML( void* residual, Stg_ComponentFactory* cf, void* data ) {
+ AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
+ FeVariable* velocityField;
+ Name upwindParamFuncName;
+ double defaultDiffusivity;
+ Materials_Register* materials_Register;
+ AdvDiffResidualForceTerm_UpwindParamFuncType upwindFuncType = (AdvDiffResidualForceTerm_UpwindParamFuncType)0;
+ Swarm *picSwarm;
+
+ /* Construct Parent */
+ _ForceTerm_AssignFromXML( self, cf, data );
+
+ velocityField = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"VelocityField", FeVariable, True, data );
+ upwindParamFuncName = Stg_ComponentFactory_GetString( cf, self->name, (Dictionary_Entry_Key)"UpwindXiFunction", "Exact" );
+
+ if ( strcasecmp( upwindParamFuncName, "DoublyAsymptoticAssumption" ) == 0 )
+ upwindFuncType = DoublyAsymptoticAssumption;
+ else if ( strcasecmp( upwindParamFuncName, "CriticalAssumption" ) == 0 )
+ upwindFuncType = CriticalAssumption;
+ else if ( strcasecmp( upwindParamFuncName, "Exact" ) == 0 )
+ upwindFuncType = Exact;
+ else
+ Journal_Firewall( False, Journal_Register( Error_Type, (Name)self->type ), "Cannot understand '%s'\n", upwindParamFuncName );
+
+ defaultDiffusivity = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"defaultDiffusivity", 1.0 );
+ picSwarm = (Swarm*)Stg_ComponentFactory_ConstructByName( cf, (Name)"picIntegrationPoints", IntegrationPointsSwarm, True, data ) ;
+ materials_Register = ((PICelleratorContext*)(self->context))->materials_Register;
+
+ _AdvDiffResidualForceTerm_Init( self, velocityField, defaultDiffusivity,
+ picSwarm, materials_Register,
+ upwindFuncType );
+}
+
+void _AdvDiffResidualForceTerm_Build( void* residual, void* data ) {
+ AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
+ AdvDiffResidualForceTerm_MaterialExt* materialExt;
+ Material_Index material_I;
+ Material* material;
+ Materials_Register* materials_Register = (Materials_Register*)(self->materials_Register);
+ IntegrationPointsSwarm* swarm = (IntegrationPointsSwarm*)self->picSwarm;
+ MaterialPointsSwarm** materialSwarms;
+ Index materialSwarm_I;
+ Stg_ComponentFactory* cf;
+ char* name;
+
+ cf = self->context->CF;
+
+ _ForceTerm_Build( self, data );
+
+ Stg_Component_Build( self->velocityField, data, False );
+
+ /* Sort out material extension stuff */
+ self->materialExtHandle = Materials_Register_AddMaterialExtension(
+ self->materials_Register,
+ self->type,
+ sizeof(AdvDiffResidualForceTerm_MaterialExt) );
+ for ( material_I = 0 ; material_I < Materials_Register_GetCount( materials_Register ) ; material_I++) {
+ material = Materials_Register_GetByIndex( materials_Register, material_I );
+ materialExt = (AdvDiffResidualForceTerm_MaterialExt*)ExtensionManager_GetFunc( material->extensionMgr, material, self->materialExtHandle );
+
+ materialExt->diffusivity = Stg_ComponentFactory_GetDouble( cf, material->name,
+ (Dictionary_Entry_Key)"diffusivity",
+ self->defaultDiffusivity );
+ }
+
+ /* Create Swarm Variables of each material swarm this ip swarm is mapped against */
+ materialSwarms = IntegrationPointMapper_GetMaterialPointsSwarms( swarm->mapper, &(self->materialSwarmCount) );
+ self->diffusivitySwarmVariables = (void**)Memory_Alloc_Array( MaterialSwarmVariable*, self->materialSwarmCount, "DiffusivityVariables" );
+
+ for ( materialSwarm_I = 0; materialSwarm_I < self->materialSwarmCount; ++materialSwarm_I ) {
+ name = Stg_Object_AppendSuffix( materialSwarms[materialSwarm_I], (Name)"Diffusivity" );
+ self->diffusivitySwarmVariables[materialSwarm_I] = MaterialSwarmVariable_New(
+ name,
+ (AbstractContext*)self->context,
+ materialSwarms[materialSwarm_I],
+ 1,
+ (Materials_Register*)self->materials_Register,
+ self->materialExtHandle,
+ GetOffsetOfMember( *materialExt, diffusivity ) );
+ Memory_Free( name );
+
+ /* Build new Swarm Variables */
+ Stg_Component_Build( self->diffusivitySwarmVariables[materialSwarm_I], data, False );
+ }
+}
+
+void _AdvDiffResidualForceTerm_Initialise( void* residual, void* data ) {
+ AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
+ Index i;
+
+ _ForceTerm_Initialise( self, data );
+
+ Stg_Component_Initialise( self->velocityField, data, False );
+
+ for ( i = 0; i < self->materialSwarmCount; ++i ) {
+ Stg_Component_Initialise( self->diffusivitySwarmVariables[i], data, False );
+ }
+}
+
+void _AdvDiffResidualForceTerm_Execute( void* residual, void* data ) {
+ AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
+
+ _ForceTerm_Execute( self, data );
+}
+
+void _AdvDiffResidualForceTerm_Destroy( void* residual, void* data ) {
+ AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
+ Index i;
+
+ for ( i = 0; i < self->materialSwarmCount; ++i ) {
+ _Stg_Component_Delete( self->diffusivitySwarmVariables[i] );
+ }
+ Memory_Free( self->diffusivitySwarmVariables );
+
+ _ForceTerm_Destroy( self, data );
+}
+
+void _AdvDiffResidualForceTerm_AssembleElement( void* forceTerm, ForceVector* forceVector, Element_LocalIndex lElement_I, double* elementResidual ) {
+ AdvDiffResidualForceTerm* self = Stg_CheckType( forceTerm, AdvDiffResidualForceTerm );
+ AdvectionDiffusionSLE* sle = Stg_CheckType( self->extraInfo, AdvectionDiffusionSLE );
+ Swarm* swarm = self->picSwarm;
+ Particle_Index lParticle_I;
+ Particle_Index cParticle_I;
+ Particle_Index cellParticleCount;
+ Cell_Index cell_I;
+ IntegrationPoint* particle;
+ FeVariable* phiField = sle->phiField;
+ Dimension_Index dim = forceVector->dim;
+ double velocity[3];
+ double phi, phiDot;
+ double detJac;
+ double* xi;
+ double totalDerivative, diffusionTerm;
+ double diffusivity = self->defaultDiffusivity;
+ ElementType* elementType = FeMesh_GetElementType( phiField->feMesh, lElement_I );
+ Node_Index elementNodeCount = elementType->nodeCount;
+ Node_Index node_I;
+ double factor;
+
+ double** GNx;
+ double* phiGrad;
+ double* Ni;
+ double* SUPGNi;
+ double supgfactor;
+ double udotu, perturbation;
+ double upwindDiffusivity;
+
+ GNx = self->GNx;
+ phiGrad = self->phiGrad;
+ Ni = self->Ni;
+ SUPGNi = self->SUPGNi;
+
+ upwindDiffusivity = AdvDiffResidualForceTerm_UpwindDiffusivity( self, sle, swarm, phiField->feMesh, lElement_I, dim );
+
+ /* Determine number of particles in element */
+ cell_I = CellLayout_MapElementIdToCellId( swarm->cellLayout, lElement_I );
+ cellParticleCount = swarm->cellParticleCountTbl[ cell_I ];
+
+ for ( cParticle_I = 0 ; cParticle_I < cellParticleCount ; cParticle_I++ ) {
+ lParticle_I = swarm->cellParticleTbl[cell_I][cParticle_I];
+
+ particle = (IntegrationPoint*) Swarm_ParticleAt( swarm, lParticle_I );
+ xi = particle->xi;
+
+ /* Evaluate Shape Functions */
+ ElementType_EvaluateShapeFunctionsAt(elementType, xi, Ni);
+
+ /* Calculate Global Shape Function Derivatives */
+ ElementType_ShapeFunctionsGlobalDerivs(
+ elementType,
+ phiField->feMesh, lElement_I,
+ xi, dim, &detJac, GNx );
+
+ /* Calculate Velocity */
+ FeVariable_InterpolateFromMeshLocalCoord( self->velocityField, phiField->feMesh, lElement_I, xi, velocity );
+
+ /* Build the SUPG shape functions */
+ udotu = velocity[I_AXIS]*velocity[I_AXIS] + velocity[J_AXIS]*velocity[J_AXIS];
+ if(dim == 3) udotu += velocity[ K_AXIS ] * velocity[ K_AXIS ];
+
+ supgfactor = upwindDiffusivity / udotu;
+ for ( node_I = 0 ; node_I < elementNodeCount ; node_I++ ) {
+ /* In the case of per diffusion - just build regular shape functions */
+ if ( fabs(upwindDiffusivity) < SUPG_MIN_DIFFUSIVITY ) {
+ SUPGNi[node_I] = Ni[node_I];
+ continue;
+ }
+
+ perturbation = velocity[ I_AXIS ] * GNx[ I_AXIS ][ node_I ] + velocity[ J_AXIS ] * GNx[ J_AXIS ][ node_I ];
+ if (dim == 3)
+ perturbation = perturbation + velocity[ K_AXIS ] * GNx[ K_AXIS ][ node_I ];
+
+ /* p = \frac{\bar \kappa \hat u_j w_j }{ ||u|| } - Eq. 3.2.25 */
+ perturbation = supgfactor * perturbation;
+
+ SUPGNi[node_I] = Ni[node_I] + perturbation;
+ }
+
+ /* Calculate phi on particle */
+ _FeVariable_InterpolateNodeValuesToElLocalCoord( phiField, lElement_I, xi, &phi );
+
+ /* Calculate Gradients of Phi */
+ FeVariable_InterpolateDerivatives_WithGNx( phiField, lElement_I, GNx, phiGrad );
+
+ /* Calculate time derivative of phi */
+ _FeVariable_InterpolateNodeValuesToElLocalCoord( sle->phiDotField, lElement_I, xi, &phiDot );
+
+ /* Calculate total derivative (i.e. Dphi/Dt = \dot \phi + u . \grad \phi) */
+ totalDerivative = phiDot + StGermain_VectorDotProduct( velocity, phiGrad, dim );
+
+ /* Get Diffusivity */
+ diffusivity = IntegrationPointMapper_GetDoubleFromMaterial(((IntegrationPointsSwarm *)swarm)->mapper, particle, self->materialExtHandle,
+
+ offsetof(AdvDiffResidualForceTerm_MaterialExt, diffusivity));
+
+ /* Add to element residual */
+ factor = particle->weight * detJac;
+ for ( node_I = 0 ; node_I < elementNodeCount ; node_I++ ) {
+ /* Calculate Diffusion Term */
+ diffusionTerm = diffusivity * ( GNx[0][node_I] * phiGrad[0] + GNx[1][node_I] * phiGrad[1] );
+ if (dim == 3)
+ diffusionTerm += diffusivity * GNx[2][ node_I ] * phiGrad[2] ;
+
+ elementResidual[ node_I ] -= factor * ( SUPGNi[ node_I ] * totalDerivative + diffusionTerm );
+ }
+ }
+
+}
+
+/* Virtual Function Implementations */
+double _AdvDiffResidualForceTerm_UpwindParam( void* residual, double pecletNumber ) {
+ AdvDiffResidualForceTerm* self = (AdvDiffResidualForceTerm*)residual;
+
+ switch ( self->upwindParamType ) {
+ case Exact:
+ self->_upwindParam = AdvDiffResidualForceTerm_UpwindXiExact; break;
+ case DoublyAsymptoticAssumption:
+ self->_upwindParam = AdvDiffResidualForceTerm_UpwindXiDoublyAsymptoticAssumption; break;
+ case CriticalAssumption:
+ self->_upwindParam = AdvDiffResidualForceTerm_UpwindXiCriticalAssumption; break;
+ }
+
+ return AdvDiffResidualForceTerm_UpwindParam( self, pecletNumber );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/Timestep.c
--- a/SLE/ProvidedSystems/AdvectionDiffusion/src/Timestep.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Timestep.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-#include "mpi.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "types.h"
-#include "Timestep.h"
-
-#include "AdvectionDiffusionSLE.h"
-#include "Residual.h"
-#include <math.h>
-#include <assert.h>
-#include <string.h>
-
-
-double AdvectionDiffusionSLE_CalculateDt( void* advectionDiffusionSLE, FiniteElementContext* context ) {
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) advectionDiffusionSLE;
- double advectionTimestep;
- double diffusionTimestep;
- double advectionTimestepGlobal;
- double diffusionTimestepGlobal;
- double timestep;
-
- Journal_DPrintf( self->debug, "In func: %s\n", __func__ );
-
- /* It would be useful to introduce a limit to the change of step in here ... to prevent timesteps
- from becoming arbitrarily large in a single step */
-
- /* Calculate Courant Number */
- advectionTimestep = AdvectionDiffusionSLE_AdvectiveTimestep( self );
- diffusionTimestep = AdvectionDiffusionSLE_DiffusiveTimestep( self );
-
- MPI_Allreduce( &advectionTimestep, &advectionTimestepGlobal, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD );
- MPI_Allreduce( &diffusionTimestep, &diffusionTimestepGlobal, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD );
-
- Journal_DPrintf( self->debug, "%s Dominating. - Advective Timestep = %g - Diffusive Timestep = %g\n",
- advectionTimestepGlobal < diffusionTimestepGlobal ? "Advection" : "Diffusion",
- advectionTimestepGlobal, diffusionTimestepGlobal);
-
- /* Calculate Time Step */
- timestep = MIN( advectionTimestepGlobal, diffusionTimestepGlobal );
-
- return timestep;
-}
-
-
-double AdvectionDiffusionSLE_DiffusiveTimestep( void* advectionDiffusionSLE ) {
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) advectionDiffusionSLE;
- double minSeparation;
- double minSeparationEachDim[3];
-
- Journal_DPrintf( self->debug, "In func: %s\n", __func__ );
-
- FeVariable_GetMinimumSeparation( self->phiField, &minSeparation, minSeparationEachDim );
-
- /* This is quite a conservative estimate */
-
- return self->courantFactor * minSeparation * minSeparation / self->maxDiffusivity;
-}
-
-
-double AdvectionDiffusionSLE_AdvectiveTimestep( void* advectionDiffusionSLE ) {
- AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) advectionDiffusionSLE;
- AdvDiffResidualForceTerm* residualForceTerm = self->advDiffResidualForceTerm;
- FeVariable* velocityField = residualForceTerm->velocityField;
- Node_LocalIndex nodeLocalCount = FeMesh_GetNodeLocalSize( self->phiField->feMesh );
- Node_LocalIndex node_I;
- Dimension_Index dim = self->dim;
- Dimension_Index dim_I;
- double timestep = HUGE_VAL;
- XYZ velocity;
- double minSeparation;
- double minSeparationEachDim[3];
- double* meshCoord;
-
- Journal_DPrintf( self->debug, "In func: %s\n", __func__ );
-
- FeVariable_GetMinimumSeparation( self->phiField, &minSeparation, minSeparationEachDim );
-
- for( node_I = 0 ; node_I < nodeLocalCount ; node_I++ ){
- meshCoord = Mesh_GetVertex( self->phiField->feMesh, node_I );
- FieldVariable_InterpolateValueAt( velocityField, meshCoord, velocity );
-
- for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
- if( velocity[ dim_I ] == 0.0 )
- continue;
- timestep = MIN( timestep, fabs( minSeparationEachDim[ dim_I ]/velocity[ dim_I ] ) );
- }
- }
-
- return self->courantFactor * timestep;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/Timestep.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/AdvectionDiffusion/src/Timestep.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,134 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Timestep.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+#include "mpi.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "types.h"
+#include "Timestep.h"
+
+#include "AdvectionDiffusionSLE.h"
+#include "Residual.h"
+#include <math.h>
+#include <assert.h>
+#include <string.h>
+
+
+double AdvectionDiffusionSLE_CalculateDt( void* advectionDiffusionSLE, FiniteElementContext* context ) {
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) advectionDiffusionSLE;
+ double advectionTimestep;
+ double diffusionTimestep;
+ double advectionTimestepGlobal;
+ double diffusionTimestepGlobal;
+ double timestep;
+
+ Journal_DPrintf( self->debug, "In func: %s\n", __func__ );
+
+ /* It would be useful to introduce a limit to the change of step in here ... to prevent timesteps
+ from becoming arbitrarily large in a single step */
+
+ /* Calculate Courant Number */
+ advectionTimestep = AdvectionDiffusionSLE_AdvectiveTimestep( self );
+ diffusionTimestep = AdvectionDiffusionSLE_DiffusiveTimestep( self );
+
+ MPI_Allreduce( &advectionTimestep, &advectionTimestepGlobal, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD );
+ MPI_Allreduce( &diffusionTimestep, &diffusionTimestepGlobal, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD );
+
+ Journal_DPrintf( self->debug, "%s Dominating. - Advective Timestep = %g - Diffusive Timestep = %g\n",
+ advectionTimestepGlobal < diffusionTimestepGlobal ? "Advection" : "Diffusion",
+ advectionTimestepGlobal, diffusionTimestepGlobal);
+
+ /* Calculate Time Step */
+ timestep = MIN( advectionTimestepGlobal, diffusionTimestepGlobal );
+
+ return timestep;
+}
+
+
+double AdvectionDiffusionSLE_DiffusiveTimestep( void* advectionDiffusionSLE ) {
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) advectionDiffusionSLE;
+ double minSeparation;
+ double minSeparationEachDim[3];
+
+ Journal_DPrintf( self->debug, "In func: %s\n", __func__ );
+
+ FeVariable_GetMinimumSeparation( self->phiField, &minSeparation, minSeparationEachDim );
+
+ /* This is quite a conservative estimate */
+
+ return self->courantFactor * minSeparation * minSeparation / self->maxDiffusivity;
+}
+
+
+double AdvectionDiffusionSLE_AdvectiveTimestep( void* advectionDiffusionSLE ) {
+ AdvectionDiffusionSLE* self = (AdvectionDiffusionSLE*) advectionDiffusionSLE;
+ AdvDiffResidualForceTerm* residualForceTerm = self->advDiffResidualForceTerm;
+ FeVariable* velocityField = residualForceTerm->velocityField;
+ Node_LocalIndex nodeLocalCount = FeMesh_GetNodeLocalSize( self->phiField->feMesh );
+ Node_LocalIndex node_I;
+ Dimension_Index dim = self->dim;
+ Dimension_Index dim_I;
+ double timestep = HUGE_VAL;
+ XYZ velocity;
+ double minSeparation;
+ double minSeparationEachDim[3];
+ double* meshCoord;
+
+ Journal_DPrintf( self->debug, "In func: %s\n", __func__ );
+
+ FeVariable_GetMinimumSeparation( self->phiField, &minSeparation, minSeparationEachDim );
+
+ for( node_I = 0 ; node_I < nodeLocalCount ; node_I++ ){
+ meshCoord = Mesh_GetVertex( self->phiField->feMesh, node_I );
+ FieldVariable_InterpolateValueAt( velocityField, meshCoord, velocity );
+
+ for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
+ if( velocity[ dim_I ] == 0.0 )
+ continue;
+ timestep = MIN( timestep, fabs( minSeparationEachDim[ dim_I ]/velocity[ dim_I ] ) );
+ }
+ }
+
+ return self->courantFactor * timestep;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/UpwindParameter.c
--- a/SLE/ProvidedSystems/AdvectionDiffusion/src/UpwindParameter.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,208 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: UpwindParameter.c 985 2007-11-21 00:20:24Z MirkoVelic $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <math.h>
-#include <assert.h>
-#include <stddef.h>
-
-#include "mpi.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include <PICellerator/PICellerator.h>
-#include <Underworld/Underworld.h>
-
-#include "types.h"
-#include "AdvectionDiffusionSLE.h"
-#include "UpwindParameter.h"
-#include "Residual.h"
-
-#define ISQRT15 0.25819888974716112567
-
-/** AdvectionDiffusion_UpwindDiffusivity - See Brooks, Hughes 1982 Section 3.3
- * All equations refer to this paper if not otherwise indicated */
-double AdvDiffResidualForceTerm_UpwindDiffusivity(
- AdvDiffResidualForceTerm* self,
- AdvectionDiffusionSLE* sle,
- Swarm* swarm,
- FeMesh* mesh,
- Element_LocalIndex lElement_I,
- Dimension_Index dim )
-{
- FeVariable* velocityField = self->velocityField;
- Coord xiElementCentre = {0.0,0.0,0.0};
- double xiUpwind;
- double velocityCentre[3];
- double pecletNumber;
- double lengthScale;
- double upwindDiffusivity;
- Dimension_Index dim_I;
- double* leastCoord;
- double* greatestCoord;
- Node_LocalIndex nodeIndex_LeastValues, nodeIndex_GreatestValues;
- unsigned nInc, *inc;
- IArray* incArray;
-
- Cell_Index cell_I;
- IntegrationPoint* particle;
- Particle_Index lParticle_I;
- double averageDiffusivity;
- Particle_InCellIndex cParticle_I;
- Particle_InCellIndex particleCount;
-
- /* Compute the average diffusivity */
- /* Find Number of Particles in Element */
- cell_I = CellLayout_MapElementIdToCellId( self->picSwarm->cellLayout, lElement_I );
- particleCount = self->picSwarm->cellParticleCountTbl[ cell_I ];
-
- /* Average diffusivity for element */
- averageDiffusivity = 0.0;
- for ( cParticle_I = 0 ; cParticle_I < particleCount ; cParticle_I++ ) {
- lParticle_I = self->picSwarm->cellParticleTbl[cell_I][cParticle_I];
- particle = (IntegrationPoint*) Swarm_ParticleAt( self->picSwarm, lParticle_I );
-
- averageDiffusivity +=
- IntegrationPointMapper_GetDoubleFromMaterial(((IntegrationPointsSwarm *)self->picSwarm)->mapper, particle, self->materialExtHandle,
- offsetof(AdvDiffResidualForceTerm_MaterialExt, diffusivity));
- }
- averageDiffusivity /= (double)particleCount;
-
- if (sle->maxDiffusivity < averageDiffusivity)
- sle->maxDiffusivity = averageDiffusivity;
-
-
-
-
-
-
- /* Change Diffusivity if it is too small */
- if ( averageDiffusivity < SUPG_MIN_DIFFUSIVITY )
- averageDiffusivity = SUPG_MIN_DIFFUSIVITY;
-
- /* Calculate Velocity At Middle of Element - See Eq. 3.3.6 */
- FeVariable_InterpolateFromMeshLocalCoord( velocityField, mesh, lElement_I, xiElementCentre, velocityCentre );
-
- /* Calculate Length Scales - See Fig 3.4 - ASSUMES BOX MESH TODO - fix */
- incArray = self->incarray;
- FeMesh_GetElementNodes( mesh, lElement_I, incArray );
- nInc = IArray_GetSize( incArray );
- inc = (unsigned*)IArray_GetPtr( incArray );
-
-
- nodeIndex_LeastValues = inc[0];
- nodeIndex_GreatestValues = (dim == 2) ? inc[3] : inc[7];
- leastCoord = Mesh_GetVertex( mesh, nodeIndex_LeastValues );
- greatestCoord = Mesh_GetVertex( mesh, nodeIndex_GreatestValues );
-
- upwindDiffusivity = 0.0;
- for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
- lengthScale = greatestCoord[ dim_I ] - leastCoord[ dim_I ];
-
- /* Calculate Peclet Number (alpha) - See Eq. 3.3.5 */
- pecletNumber = velocityCentre[ dim_I ] * lengthScale / (2.0 * averageDiffusivity);
-
- /* Calculate Upwind Local Coordinate - See Eq. 3.3.4 and (2.4.2, 3.3.1 and 3.3.2) */
- xiUpwind = AdvDiffResidualForceTerm_UpwindParam( self, pecletNumber );
-
- /* Calculate Upwind Thermal Diffusivity - See Eq. 3.3.3 */
- upwindDiffusivity += xiUpwind * velocityCentre[ dim_I ] * lengthScale;
- }
- upwindDiffusivity *= ISQRT15; /* See Eq. 3.3.11 */
-
-
- return upwindDiffusivity;
-}
-
-
-/** AdvectionDiffusion_UpwindXiExact - Brooks, Hughes 1982 equation 2.4.2
- *\f$ \bar \xi = coth( \alpha ) - \frac{1}{\alpha} \f$ */
-double AdvDiffResidualForceTerm_UpwindXiExact( void* residual, double pecletNumber ) {
- if (fabs(pecletNumber) < 1.0e-8 )
- return 0.33333333333333 * pecletNumber;
- else if (pecletNumber < -20.0)
- return -1.0 - 1.0/pecletNumber;
- else if (pecletNumber > 20.0)
- return +1.0 - 1.0/pecletNumber;
-
- return cosh( pecletNumber )/sinh( pecletNumber ) - 1.0/pecletNumber;
-}
-
-/** AdvectionDiffusion_UpwindXiDoublyAsymptoticAssumption - Brooks, Hughes 1982 equation 3.3.1
- * Simplification of \f$ \bar \xi = coth( \alpha ) - \frac{1}{\alpha} \f$ from Brooks, Hughes 1982 equation 2.4.2
- * \f[
-\bar \xi \sim \left\{ \begin{array}{rl}
- -1 &for \quad \alpha <= -3 \\
- \frac{\alpha}{3} &for \quad -3 < \alpha <= 3 \\
- +1 &for \quad \alpha > +3
- \end{array} \right.
-
-\f]*/
-double AdvDiffResidualForceTerm_UpwindXiDoublyAsymptoticAssumption( void* residual, double pecletNumber ) {
- if (pecletNumber <= -3.0)
- return -1;
- else if (pecletNumber <= 3.0)
- return 0.33333333333333 * pecletNumber;
- else
- return 1.0;
-}
-
-/** AdvectionDiffusion_UpwindXiCriticalAssumption - Brooks, Hughes 1982 equation 3.3.2
- * Simplification of \f$ \bar \xi = coth( \alpha ) - \frac{1}{\alpha} \f$ from Brooks, Hughes 1982 equation 2.4.2
- * \f[
- \bar \xi \sim \left\{ \begin{array}{rl}
- -1 - \frac{1}{\alpha} &for \quad \alpha <= -1 \\
- 0 &for \quad -1 < \alpha <= +1 \\
- +1 - \frac{1}{\alpha} &for \quad \alpha > +1
- \end{array} \right.
-\f] */
-
-double AdvDiffResidualForceTerm_UpwindXiCriticalAssumption( void* residual, double pecletNumber ) {
- if (pecletNumber <= -1.0)
- return -1.0 - 1.0/pecletNumber;
- else if (pecletNumber <= 1.0)
- return 0.0;
- else
- return 1.0 - 1.0/pecletNumber;
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/src/UpwindParameter.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/AdvectionDiffusion/src/UpwindParameter.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,208 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: UpwindParameter.c 985 2007-11-21 00:20:24Z MirkoVelic $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <math.h>
+#include <assert.h>
+#include <stddef.h>
+
+#include "mpi.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include <PICellerator/PICellerator.h>
+#include <Underworld/Underworld.h>
+
+#include "types.h"
+#include "AdvectionDiffusionSLE.h"
+#include "UpwindParameter.h"
+#include "Residual.h"
+
+#define ISQRT15 0.25819888974716112567
+
+/** AdvectionDiffusion_UpwindDiffusivity - See Brooks, Hughes 1982 Section 3.3
+ * All equations refer to this paper if not otherwise indicated */
+double AdvDiffResidualForceTerm_UpwindDiffusivity(
+ AdvDiffResidualForceTerm* self,
+ AdvectionDiffusionSLE* sle,
+ Swarm* swarm,
+ FeMesh* mesh,
+ Element_LocalIndex lElement_I,
+ Dimension_Index dim )
+{
+ FeVariable* velocityField = self->velocityField;
+ Coord xiElementCentre = {0.0,0.0,0.0};
+ double xiUpwind;
+ double velocityCentre[3];
+ double pecletNumber;
+ double lengthScale;
+ double upwindDiffusivity;
+ Dimension_Index dim_I;
+ double* leastCoord;
+ double* greatestCoord;
+ Node_LocalIndex nodeIndex_LeastValues, nodeIndex_GreatestValues;
+ unsigned nInc, *inc;
+ IArray* incArray;
+
+ Cell_Index cell_I;
+ IntegrationPoint* particle;
+ Particle_Index lParticle_I;
+ double averageDiffusivity;
+ Particle_InCellIndex cParticle_I;
+ Particle_InCellIndex particleCount;
+
+ /* Compute the average diffusivity */
+ /* Find Number of Particles in Element */
+ cell_I = CellLayout_MapElementIdToCellId( self->picSwarm->cellLayout, lElement_I );
+ particleCount = self->picSwarm->cellParticleCountTbl[ cell_I ];
+
+ /* Average diffusivity for element */
+ averageDiffusivity = 0.0;
+ for ( cParticle_I = 0 ; cParticle_I < particleCount ; cParticle_I++ ) {
+ lParticle_I = self->picSwarm->cellParticleTbl[cell_I][cParticle_I];
+ particle = (IntegrationPoint*) Swarm_ParticleAt( self->picSwarm, lParticle_I );
+
+ averageDiffusivity +=
+ IntegrationPointMapper_GetDoubleFromMaterial(((IntegrationPointsSwarm *)self->picSwarm)->mapper, particle, self->materialExtHandle,
+ offsetof(AdvDiffResidualForceTerm_MaterialExt, diffusivity));
+ }
+ averageDiffusivity /= (double)particleCount;
+
+ if (sle->maxDiffusivity < averageDiffusivity)
+ sle->maxDiffusivity = averageDiffusivity;
+
+
+
+
+
+
+ /* Change Diffusivity if it is too small */
+ if ( averageDiffusivity < SUPG_MIN_DIFFUSIVITY )
+ averageDiffusivity = SUPG_MIN_DIFFUSIVITY;
+
+ /* Calculate Velocity At Middle of Element - See Eq. 3.3.6 */
+ FeVariable_InterpolateFromMeshLocalCoord( velocityField, mesh, lElement_I, xiElementCentre, velocityCentre );
+
+ /* Calculate Length Scales - See Fig 3.4 - ASSUMES BOX MESH TODO - fix */
+ incArray = self->incarray;
+ FeMesh_GetElementNodes( mesh, lElement_I, incArray );
+ nInc = IArray_GetSize( incArray );
+ inc = (unsigned*)IArray_GetPtr( incArray );
+
+
+ nodeIndex_LeastValues = inc[0];
+ nodeIndex_GreatestValues = (dim == 2) ? inc[3] : inc[7];
+ leastCoord = Mesh_GetVertex( mesh, nodeIndex_LeastValues );
+ greatestCoord = Mesh_GetVertex( mesh, nodeIndex_GreatestValues );
+
+ upwindDiffusivity = 0.0;
+ for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
+ lengthScale = greatestCoord[ dim_I ] - leastCoord[ dim_I ];
+
+ /* Calculate Peclet Number (alpha) - See Eq. 3.3.5 */
+ pecletNumber = velocityCentre[ dim_I ] * lengthScale / (2.0 * averageDiffusivity);
+
+ /* Calculate Upwind Local Coordinate - See Eq. 3.3.4 and (2.4.2, 3.3.1 and 3.3.2) */
+ xiUpwind = AdvDiffResidualForceTerm_UpwindParam( self, pecletNumber );
+
+ /* Calculate Upwind Thermal Diffusivity - See Eq. 3.3.3 */
+ upwindDiffusivity += xiUpwind * velocityCentre[ dim_I ] * lengthScale;
+ }
+ upwindDiffusivity *= ISQRT15; /* See Eq. 3.3.11 */
+
+
+ return upwindDiffusivity;
+}
+
+
+/** AdvectionDiffusion_UpwindXiExact - Brooks, Hughes 1982 equation 2.4.2
+ *\f$ \bar \xi = coth( \alpha ) - \frac{1}{\alpha} \f$ */
+double AdvDiffResidualForceTerm_UpwindXiExact( void* residual, double pecletNumber ) {
+ if (fabs(pecletNumber) < 1.0e-8 )
+ return 0.33333333333333 * pecletNumber;
+ else if (pecletNumber < -20.0)
+ return -1.0 - 1.0/pecletNumber;
+ else if (pecletNumber > 20.0)
+ return +1.0 - 1.0/pecletNumber;
+
+ return cosh( pecletNumber )/sinh( pecletNumber ) - 1.0/pecletNumber;
+}
+
+/** AdvectionDiffusion_UpwindXiDoublyAsymptoticAssumption - Brooks, Hughes 1982 equation 3.3.1
+ * Simplification of \f$ \bar \xi = coth( \alpha ) - \frac{1}{\alpha} \f$ from Brooks, Hughes 1982 equation 2.4.2
+ * \f[
+\bar \xi \sim \left\{ \begin{array}{rl}
+ -1 &for \quad \alpha <= -3 \\
+ \frac{\alpha}{3} &for \quad -3 < \alpha <= 3 \\
+ +1 &for \quad \alpha > +3
+ \end{array} \right.
+
+\f]*/
+double AdvDiffResidualForceTerm_UpwindXiDoublyAsymptoticAssumption( void* residual, double pecletNumber ) {
+ if (pecletNumber <= -3.0)
+ return -1;
+ else if (pecletNumber <= 3.0)
+ return 0.33333333333333 * pecletNumber;
+ else
+ return 1.0;
+}
+
+/** AdvectionDiffusion_UpwindXiCriticalAssumption - Brooks, Hughes 1982 equation 3.3.2
+ * Simplification of \f$ \bar \xi = coth( \alpha ) - \frac{1}{\alpha} \f$ from Brooks, Hughes 1982 equation 2.4.2
+ * \f[
+ \bar \xi \sim \left\{ \begin{array}{rl}
+ -1 - \frac{1}{\alpha} &for \quad \alpha <= -1 \\
+ 0 &for \quad -1 < \alpha <= +1 \\
+ +1 - \frac{1}{\alpha} &for \quad \alpha > +1
+ \end{array} \right.
+\f] */
+
+double AdvDiffResidualForceTerm_UpwindXiCriticalAssumption( void* residual, double pecletNumber ) {
+ if (pecletNumber <= -1.0)
+ return -1.0 - 1.0/pecletNumber;
+ else if (pecletNumber <= 1.0)
+ return 0.0;
+ else
+ return 1.0 - 1.0/pecletNumber;
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/tests/LumpedMassMatrixSuite.c
--- a/SLE/ProvidedSystems/AdvectionDiffusion/tests/LumpedMassMatrixSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,271 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** Role:
-** Tests the LumpedMassMatrixSuite
-**
-** $Id: testTemplate.c 3462 2006-02-19 06:53:24Z WalterLandry $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "pcu/pcu.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/AdvectionDiffusion.h"
-
-#include "LumpedMassMatrixSuite.h"
-
-#define CURR_MODULE_NAME "StgFEMContext.c"
-
-typedef struct Node Node;
-typedef struct Element Element;
-
-struct Node {
- double phi;
-};
-
-struct Element {
- __FiniteElement_Element
-};
-
-struct _Particle {
- Coord coord;
-};
-
-typedef struct {
- MPI_Comm comm;
- int rank;
- int nProcs;
-} LumpedMassMatrixSuiteData;
-
-void LumpedMassMatrixSuite_quadratic(Index index, Variable_Index var_I, void* context, void* result) {
- *(double *)result = 20.0;
-}
-
-FeMesh* LumpedMassMatrixSuite_buildFeMesh( unsigned nDims, unsigned* size, double* minCrds, double* maxCrds, ExtensionManager_Register* emReg, ElementType_Register* etReg ) {
- CartesianGenerator* gen;
- FeMesh* feMesh;
- unsigned maxDecomp[3] = {0, 1, 1};
-
- gen = CartesianGenerator_New( "", NULL );
- gen->shadowDepth = 0;
- CartesianGenerator_SetDimSize( gen, nDims );
- CartesianGenerator_SetTopologyParams( gen, size, 0, NULL, maxDecomp );
- CartesianGenerator_SetGeometryParams( gen, minCrds, maxCrds );
-
- feMesh = FeMesh_New( "", NULL );
- Mesh_SetExtensionManagerRegister( feMesh, emReg );
- Mesh_SetGenerator( feMesh, gen );
- FeMesh_SetElementFamily( feMesh, "linear" );
-
- Mesh_SetTopologyDataSize( feMesh, MT_VERTEX, sizeof(Node) );
- Mesh_SetTopologyDataSize( feMesh, (MeshTopology_Dim)nDims, sizeof(Element) );
-
- Stg_Component_Build( feMesh, NULL, False );
- Stg_Component_Initialise( feMesh, NULL, False );
-
- return feMesh;
-}
-
-void LumpedMassMatrixSuite_Setup( LumpedMassMatrixSuiteData* data ) {
- Journal_Enable_AllTypedStream( False );
-
- /* MPI Initializations */
- data->comm = MPI_COMM_WORLD;
- MPI_Comm_rank( data->comm, &data->rank );
- MPI_Comm_size( data->comm, &data->nProcs );
-}
-
-void LumpedMassMatrixSuite_Teardown( LumpedMassMatrixSuiteData* data ) {
- Journal_Enable_AllTypedStream( True );
-}
-
-void LumpedMassMatrixSuite_TestLumpedMassMatrix( LumpedMassMatrixSuiteData* data ) {
- Dictionary* dictionary;
- Dictionary_Entry_Value* currBC;
- Dictionary_Entry_Value* bcList;
- unsigned nDims = 2;
- unsigned meshSize[3] = {2, 2, 0};
- unsigned nDomainVerts;
- double minCrds[3] = {0.0, 0.0, 0.0};
- double maxCrds[3] = {1.2, 1.2, 1.2};
- FeMesh* feMesh;
- Node* nodes;
- DofLayout* dofs;
- ElementType_Register* elementType_Register;
- ExtensionManager_Register* extensionMgr_Register;
- WallVC* wallVC;
- FieldVariable_Register* fV_Register;
- FeVariable* feVariable;
- Variable_Register* variableRegister;
- FiniteElementContext* context;
- Index i;
- Dimension_Index dim;
- /* Swarm Stuff */
- CellLayout* singleCellLayout;
- ParticleLayout* gaussParticleLayout;
- Swarm* swarm;
- unsigned dimExists[] = { True, True, False };
- /* Mass Matrix Stuff */
- ForceVector* massMatrix;
- Vec expectedMatrix;
- PetscViewer viewer;
- PetscTruth flg;
- LumpedMassMatrixForceTerm* massMatrixForceTerm;
- Particle_InCellIndex particlesPerDim[] = {2,2,2};
- char expected_file[PCU_PATH_MAX];
-
- /* Read input */
- dictionary = Dictionary_New();
- Dictionary_Add( dictionary, (Dictionary_Entry_Key)"outputPath", Dictionary_Entry_Value_FromString( "./output" ) );
- Dictionary_Add( dictionary, (Dictionary_Entry_Key)"rank", Dictionary_Entry_Value_FromUnsignedInt( data->rank ) );
- Dictionary_Add( dictionary, (Dictionary_Entry_Key)"numProcessors", Dictionary_Entry_Value_FromUnsignedInt( data->nProcs ) );
- Dictionary_Add( dictionary, (Dictionary_Entry_Key)"gaussParticlesX", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
- Dictionary_Add( dictionary, (Dictionary_Entry_Key)"gaussParticlesY", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
-
- bcList = Dictionary_Entry_Value_NewList();
- currBC = Dictionary_Entry_Value_NewStruct( );
- Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"name", Dictionary_Entry_Value_FromString( "phi" ) );
- Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"type", Dictionary_Entry_Value_FromString( "double" ) );
- Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"value", Dictionary_Entry_Value_FromDouble( -1.0f ) );
- Dictionary_Entry_Value_AddElement( bcList, currBC );
- currBC = Dictionary_Entry_Value_NewStruct();
- Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"wall", Dictionary_Entry_Value_FromString( "left" ) );
- Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"variables", bcList );
- Dictionary_Add( dictionary, (Dictionary_Entry_Key)"boundaryCondition", currBC );
-
- /* Create Context */
- context = FiniteElementContext_New( "context", 0,0, data->comm, dictionary );
-
- dim = context->dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "dim", 2 );
-
- /* create the layout, dof and mesh to use */
- extensionMgr_Register = ExtensionManager_Register_New();
- elementType_Register = ElementType_Register_New("elementTypeRegister");
- ElementType_Register_Add( elementType_Register, (ElementType*)ConstantElementType_New("constant") );
- ElementType_Register_Add( elementType_Register, (ElementType*)BilinearElementType_New("bilinear") );
- ElementType_Register_Add( elementType_Register, (ElementType*)TrilinearElementType_New("trilinear") );
-
- feMesh = (FeMesh*) LumpedMassMatrixSuite_buildFeMesh( nDims, meshSize, minCrds, maxCrds, extensionMgr_Register, elementType_Register );
- nDomainVerts = Mesh_GetDomainSize( feMesh, MT_VERTEX );
- nodes = (Node*)Mesh_GetTopologyData( feMesh, MT_VERTEX );
-
- /* Create variable register */
- variableRegister = Variable_Register_New();
-
- /* Create variables */
- Variable_NewScalar( "phi", (AbstractContext*)context, Variable_DataType_Double, (Index*)&nDomainVerts, NULL, (void**)&nodes, variableRegister );
-
- dofs = DofLayout_New( "dofLayout", (DomainContext*)context, variableRegister, Mesh_GetDomainSize( feMesh, MT_VERTEX ), NULL );
- for (i = 0; i < Mesh_GetDomainSize( feMesh, MT_VERTEX ); i++)
- DofLayout_AddDof_ByVarName(dofs, "phi", i);
-
- wallVC = WallVC_New( "WallVC", (AbstractContext*)context, "boundaryCondition", variableRegister, NULL, dictionary, feMesh );
-
- /* Create the finite element field variable*/
- fV_Register = FieldVariable_Register_New();
- feVariable = FeVariable_New( "phi", NULL, feMesh, NULL, dofs, wallVC, NULL, NULL, context->dim, False, False, False, fV_Register );
-
- /* Create Swarm */
- if ( 3 == dim )
- dimExists[K_AXIS] = True;
- singleCellLayout= (CellLayout*)SingleCellLayout_New( "SingleCellLayout", (AbstractContext*)context, (Bool*)dimExists, NULL, NULL );
- gaussParticleLayout = (ParticleLayout*)GaussParticleLayout_New( "GaussParticleLayout", NULL, LocalCoordSystem, True, dim, particlesPerDim );
- swarm = Swarm_New( "gaussSwarm", (AbstractContext*)context, singleCellLayout, gaussParticleLayout,
- dim, sizeof(IntegrationPoint), extensionMgr_Register, context->variable_Register, MPI_COMM_WORLD, NULL );
-
- /* Lumping of Mass Matrix */
- massMatrix = ForceVector_New( "MassMatrix", context, feVariable, dim, context->entryPoint_Register, MPI_COMM_WORLD );
- massMatrixForceTerm = LumpedMassMatrixForceTerm_New( "forceTerm", context, massMatrix, swarm );
- EP_ReplaceAll( massMatrix->assembleForceVector, ForceVector_GlobalAssembly_General );
- ForceTerm_SetAssembleElementFunction( massMatrixForceTerm, _LumpedMassMatrixForceTerm_AssembleElement_General );
-
- /* Build */
- Stg_Component_Build( feMesh, context, False );
- Variable_Register_BuildAll( variableRegister );
- Stg_Component_Build( wallVC, context, False );
- Stg_Component_Build( dofs, context, False);
- Stg_Component_Build( feVariable, context, False );
- FeEquationNumber_BuildLocationMatrix( feVariable->eqNum );
- Stg_Component_Build( singleCellLayout, context, False );
- Stg_Component_Build( gaussParticleLayout, context, False );
- Stg_Component_Build( swarm, context, False );
- Stg_Component_Build( massMatrix, context, False );
-
- /* Initialise */
- Stg_Component_Initialise( feMesh, context, False );
- Stg_Component_Initialise( feVariable, context, False );
- Stg_Component_Initialise( swarm, context, False );
- Stg_Component_Initialise( massMatrix, context, False );
-
- /* Assemble */
- if( data->rank == 0 ) {
- ForceVector_Assemble( massMatrix );
-
- PetscViewerCreate( MPI_COMM_WORLD, &viewer );
- PetscViewerSetType( viewer, PETSC_VIEWER_BINARY );
-
- pcu_filename_expected( "testLumpedMassMatrix.expected", expected_file );
- PetscViewerBinaryOpen( MPI_COMM_WORLD, expected_file, FILE_MODE_READ, &viewer );
-
- VecLoad( viewer, VECMPI, &expectedMatrix );
-
- /* Try out optimised one */
- VecSet( massMatrix->vector, 0.0 );
-
- /* Assemble */
- ForceTerm_SetAssembleElementFunction( massMatrixForceTerm, _LumpedMassMatrixForceTerm_AssembleElement_Box );
- ForceVector_Assemble( massMatrix );
-
- /* Check vector */
- VecEqual( (Vec)massMatrix->vector, expectedMatrix, &flg );
- pcu_check_true( flg );
- }
-
- /* Destroy stuff */
- _Stg_Component_Delete( massMatrix );
- _Stg_Component_Delete( massMatrixForceTerm );
- Stg_Class_Delete( fV_Register );
- _Stg_Component_Delete( wallVC );
- _Stg_Component_Delete( feMesh );
- Stg_Class_Delete( elementType_Register );
- Stg_Class_Delete( extensionMgr_Register );
- _Stg_Component_Delete( dofs );
- Stg_Class_Delete( dictionary );
-}
-
-void LumpedMassMatrixSuite( pcu_suite_t* suite ) {
- pcu_suite_setData( suite, LumpedMassMatrixSuiteData );
- pcu_suite_setFixtures( suite, LumpedMassMatrixSuite_Setup, LumpedMassMatrixSuite_Teardown );
- pcu_suite_addTest( suite, LumpedMassMatrixSuite_TestLumpedMassMatrix );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/tests/LumpedMassMatrixSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/AdvectionDiffusion/tests/LumpedMassMatrixSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,271 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** Role:
+** Tests the LumpedMassMatrixSuite
+**
+** $Id: testTemplate.c 3462 2006-02-19 06:53:24Z WalterLandry $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pcu/pcu.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/AdvectionDiffusion.h"
+
+#include "LumpedMassMatrixSuite.h"
+
+#define CURR_MODULE_NAME "StgFEMContext.c"
+
+typedef struct Node Node;
+typedef struct Element Element;
+
+struct Node {
+ double phi;
+};
+
+struct Element {
+ __FiniteElement_Element
+};
+
+struct _Particle {
+ Coord coord;
+};
+
+typedef struct {
+ MPI_Comm comm;
+ int rank;
+ int nProcs;
+} LumpedMassMatrixSuiteData;
+
+void LumpedMassMatrixSuite_quadratic(Index index, Variable_Index var_I, void* context, void* result) {
+ *(double *)result = 20.0;
+}
+
+FeMesh* LumpedMassMatrixSuite_buildFeMesh( unsigned nDims, unsigned* size, double* minCrds, double* maxCrds, ExtensionManager_Register* emReg, ElementType_Register* etReg ) {
+ CartesianGenerator* gen;
+ FeMesh* feMesh;
+ unsigned maxDecomp[3] = {0, 1, 1};
+
+ gen = CartesianGenerator_New( "", NULL );
+ gen->shadowDepth = 0;
+ CartesianGenerator_SetDimSize( gen, nDims );
+ CartesianGenerator_SetTopologyParams( gen, size, 0, NULL, maxDecomp );
+ CartesianGenerator_SetGeometryParams( gen, minCrds, maxCrds );
+
+ feMesh = FeMesh_New( "", NULL );
+ Mesh_SetExtensionManagerRegister( feMesh, emReg );
+ Mesh_SetGenerator( feMesh, gen );
+ FeMesh_SetElementFamily( feMesh, "linear" );
+
+ Mesh_SetTopologyDataSize( feMesh, MT_VERTEX, sizeof(Node) );
+ Mesh_SetTopologyDataSize( feMesh, (MeshTopology_Dim)nDims, sizeof(Element) );
+
+ Stg_Component_Build( feMesh, NULL, False );
+ Stg_Component_Initialise( feMesh, NULL, False );
+
+ return feMesh;
+}
+
+void LumpedMassMatrixSuite_Setup( LumpedMassMatrixSuiteData* data ) {
+ Journal_Enable_AllTypedStream( False );
+
+ /* MPI Initializations */
+ data->comm = MPI_COMM_WORLD;
+ MPI_Comm_rank( data->comm, &data->rank );
+ MPI_Comm_size( data->comm, &data->nProcs );
+}
+
+void LumpedMassMatrixSuite_Teardown( LumpedMassMatrixSuiteData* data ) {
+ Journal_Enable_AllTypedStream( True );
+}
+
+void LumpedMassMatrixSuite_TestLumpedMassMatrix( LumpedMassMatrixSuiteData* data ) {
+ Dictionary* dictionary;
+ Dictionary_Entry_Value* currBC;
+ Dictionary_Entry_Value* bcList;
+ unsigned nDims = 2;
+ unsigned meshSize[3] = {2, 2, 0};
+ unsigned nDomainVerts;
+ double minCrds[3] = {0.0, 0.0, 0.0};
+ double maxCrds[3] = {1.2, 1.2, 1.2};
+ FeMesh* feMesh;
+ Node* nodes;
+ DofLayout* dofs;
+ ElementType_Register* elementType_Register;
+ ExtensionManager_Register* extensionMgr_Register;
+ WallVC* wallVC;
+ FieldVariable_Register* fV_Register;
+ FeVariable* feVariable;
+ Variable_Register* variableRegister;
+ FiniteElementContext* context;
+ Index i;
+ Dimension_Index dim;
+ /* Swarm Stuff */
+ CellLayout* singleCellLayout;
+ ParticleLayout* gaussParticleLayout;
+ Swarm* swarm;
+ unsigned dimExists[] = { True, True, False };
+ /* Mass Matrix Stuff */
+ ForceVector* massMatrix;
+ Vec expectedMatrix;
+ PetscViewer viewer;
+ PetscTruth flg;
+ LumpedMassMatrixForceTerm* massMatrixForceTerm;
+ Particle_InCellIndex particlesPerDim[] = {2,2,2};
+ char expected_file[PCU_PATH_MAX];
+
+ /* Read input */
+ dictionary = Dictionary_New();
+ Dictionary_Add( dictionary, (Dictionary_Entry_Key)"outputPath", Dictionary_Entry_Value_FromString( "./output" ) );
+ Dictionary_Add( dictionary, (Dictionary_Entry_Key)"rank", Dictionary_Entry_Value_FromUnsignedInt( data->rank ) );
+ Dictionary_Add( dictionary, (Dictionary_Entry_Key)"numProcessors", Dictionary_Entry_Value_FromUnsignedInt( data->nProcs ) );
+ Dictionary_Add( dictionary, (Dictionary_Entry_Key)"gaussParticlesX", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
+ Dictionary_Add( dictionary, (Dictionary_Entry_Key)"gaussParticlesY", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
+
+ bcList = Dictionary_Entry_Value_NewList();
+ currBC = Dictionary_Entry_Value_NewStruct( );
+ Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"name", Dictionary_Entry_Value_FromString( "phi" ) );
+ Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"type", Dictionary_Entry_Value_FromString( "double" ) );
+ Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"value", Dictionary_Entry_Value_FromDouble( -1.0f ) );
+ Dictionary_Entry_Value_AddElement( bcList, currBC );
+ currBC = Dictionary_Entry_Value_NewStruct();
+ Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"wall", Dictionary_Entry_Value_FromString( "left" ) );
+ Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"variables", bcList );
+ Dictionary_Add( dictionary, (Dictionary_Entry_Key)"boundaryCondition", currBC );
+
+ /* Create Context */
+ context = FiniteElementContext_New( "context", 0,0, data->comm, dictionary );
+
+ dim = context->dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "dim", 2 );
+
+ /* create the layout, dof and mesh to use */
+ extensionMgr_Register = ExtensionManager_Register_New();
+ elementType_Register = ElementType_Register_New("elementTypeRegister");
+ ElementType_Register_Add( elementType_Register, (ElementType*)ConstantElementType_New("constant") );
+ ElementType_Register_Add( elementType_Register, (ElementType*)BilinearElementType_New("bilinear") );
+ ElementType_Register_Add( elementType_Register, (ElementType*)TrilinearElementType_New("trilinear") );
+
+ feMesh = (FeMesh*) LumpedMassMatrixSuite_buildFeMesh( nDims, meshSize, minCrds, maxCrds, extensionMgr_Register, elementType_Register );
+ nDomainVerts = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+ nodes = (Node*)Mesh_GetTopologyData( feMesh, MT_VERTEX );
+
+ /* Create variable register */
+ variableRegister = Variable_Register_New();
+
+ /* Create variables */
+ Variable_NewScalar( "phi", (AbstractContext*)context, Variable_DataType_Double, (Index*)&nDomainVerts, NULL, (void**)&nodes, variableRegister );
+
+ dofs = DofLayout_New( "dofLayout", (DomainContext*)context, variableRegister, Mesh_GetDomainSize( feMesh, MT_VERTEX ), NULL );
+ for (i = 0; i < Mesh_GetDomainSize( feMesh, MT_VERTEX ); i++)
+ DofLayout_AddDof_ByVarName(dofs, "phi", i);
+
+ wallVC = WallVC_New( "WallVC", (AbstractContext*)context, "boundaryCondition", variableRegister, NULL, dictionary, feMesh );
+
+ /* Create the finite element field variable*/
+ fV_Register = FieldVariable_Register_New();
+ feVariable = FeVariable_New( "phi", NULL, feMesh, NULL, dofs, wallVC, NULL, NULL, context->dim, False, False, False, fV_Register );
+
+ /* Create Swarm */
+ if ( 3 == dim )
+ dimExists[K_AXIS] = True;
+ singleCellLayout= (CellLayout*)SingleCellLayout_New( "SingleCellLayout", (AbstractContext*)context, (Bool*)dimExists, NULL, NULL );
+ gaussParticleLayout = (ParticleLayout*)GaussParticleLayout_New( "GaussParticleLayout", NULL, LocalCoordSystem, True, dim, particlesPerDim );
+ swarm = Swarm_New( "gaussSwarm", (AbstractContext*)context, singleCellLayout, gaussParticleLayout,
+ dim, sizeof(IntegrationPoint), extensionMgr_Register, context->variable_Register, MPI_COMM_WORLD, NULL );
+
+ /* Lumping of Mass Matrix */
+ massMatrix = ForceVector_New( "MassMatrix", context, feVariable, dim, context->entryPoint_Register, MPI_COMM_WORLD );
+ massMatrixForceTerm = LumpedMassMatrixForceTerm_New( "forceTerm", context, massMatrix, swarm );
+ EP_ReplaceAll( massMatrix->assembleForceVector, ForceVector_GlobalAssembly_General );
+ ForceTerm_SetAssembleElementFunction( massMatrixForceTerm, _LumpedMassMatrixForceTerm_AssembleElement_General );
+
+ /* Build */
+ Stg_Component_Build( feMesh, context, False );
+ Variable_Register_BuildAll( variableRegister );
+ Stg_Component_Build( wallVC, context, False );
+ Stg_Component_Build( dofs, context, False);
+ Stg_Component_Build( feVariable, context, False );
+ FeEquationNumber_BuildLocationMatrix( feVariable->eqNum );
+ Stg_Component_Build( singleCellLayout, context, False );
+ Stg_Component_Build( gaussParticleLayout, context, False );
+ Stg_Component_Build( swarm, context, False );
+ Stg_Component_Build( massMatrix, context, False );
+
+ /* Initialise */
+ Stg_Component_Initialise( feMesh, context, False );
+ Stg_Component_Initialise( feVariable, context, False );
+ Stg_Component_Initialise( swarm, context, False );
+ Stg_Component_Initialise( massMatrix, context, False );
+
+ /* Assemble */
+ if( data->rank == 0 ) {
+ ForceVector_Assemble( massMatrix );
+
+ PetscViewerCreate( MPI_COMM_WORLD, &viewer );
+ PetscViewerSetType( viewer, PETSC_VIEWER_BINARY );
+
+ pcu_filename_expected( "testLumpedMassMatrix.expected", expected_file );
+ PetscViewerBinaryOpen( MPI_COMM_WORLD, expected_file, FILE_MODE_READ, &viewer );
+
+ VecLoad( viewer, VECMPI, &expectedMatrix );
+
+ /* Try out optimised one */
+ VecSet( massMatrix->vector, 0.0 );
+
+ /* Assemble */
+ ForceTerm_SetAssembleElementFunction( massMatrixForceTerm, _LumpedMassMatrixForceTerm_AssembleElement_Box );
+ ForceVector_Assemble( massMatrix );
+
+ /* Check vector */
+ VecEqual( (Vec)massMatrix->vector, expectedMatrix, &flg );
+ pcu_check_true( flg );
+ }
+
+ /* Destroy stuff */
+ _Stg_Component_Delete( massMatrix );
+ _Stg_Component_Delete( massMatrixForceTerm );
+ Stg_Class_Delete( fV_Register );
+ _Stg_Component_Delete( wallVC );
+ _Stg_Component_Delete( feMesh );
+ Stg_Class_Delete( elementType_Register );
+ Stg_Class_Delete( extensionMgr_Register );
+ _Stg_Component_Delete( dofs );
+ Stg_Class_Delete( dictionary );
+}
+
+void LumpedMassMatrixSuite( pcu_suite_t* suite ) {
+ pcu_suite_setData( suite, LumpedMassMatrixSuiteData );
+ pcu_suite_setFixtures( suite, LumpedMassMatrixSuite_Setup, LumpedMassMatrixSuite_Teardown );
+ pcu_suite_addTest( suite, LumpedMassMatrixSuite_TestLumpedMassMatrix );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/tests/UpwindXiSuite.c
--- a/SLE/ProvidedSystems/AdvectionDiffusion/tests/UpwindXiSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** Role:
-** Tests the UpwindXiSuite
-**
-** $Id: testUpwindXi.c 3462 2006-02-19 06:53:24Z WalterLandry $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "pcu/pcu.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/AdvectionDiffusion.h"
-#include "UpwindXiSuite.h"
-
-typedef struct {
-} UpwindXiSuiteData;
-
-
-void UpwindXiSuite_Setup( UpwindXiSuiteData* data ) {
- Journal_Enable_AllTypedStream( False );
-}
-
-void UpwindXiSuite_Teardown( UpwindXiSuiteData* data ) {
-}
-
-
-void UpwindXiSuite_Test( UpwindXiSuiteData* data ) {
- Stream* dataStream;
- double minPercletNumber = -15.0;
- double maxPercletNumber = 15.0;
- double dPerceltNumber = 0.5;
- double perceltNumber;
- char expectedFile[PCU_PATH_MAX];
- int rank;
- char outputFilename[100];
-
- MPI_Comm_rank( MPI_COMM_WORLD, &rank );
- sprintf( outputFilename, "output_%2d.dat", rank );
-
- Journal_Enable_TypedStream( InfoStream_Type, True );
- dataStream = Journal_Register( Info_Type, (Name)"DataStream" );
- Stream_RedirectFile( dataStream, outputFilename );
-
- Journal_Printf( dataStream, "# File to compare code with Brooks, Hughes 1982 - Fig 3.3\n");
- Journal_Printf( dataStream, "# Integration rule for the optimal upwind scheme, doubly asymptotic approximation and critical approximation.\n");
- Journal_Printf( dataStream, "# Plot using line:\n");
- Journal_Printf( dataStream, "# plot \"%s\" using 1:2 title \"Exact\" with line, ", "output.dat" );
- Journal_Printf( dataStream, "\"%s\" using 1:3 title \"DoublyAsymptoticAssumption\" with line, ", "output.dat" );
- Journal_Printf( dataStream, "\"%s\" using 1:4 title \"CriticalAssumption\" with line\n", "output.dat" );
-
- Journal_Printf( dataStream, "# Perclet Number \t Exact \t DoublyAsymptoticAssumption \t CriticalAssumption\n" );
- for ( perceltNumber = minPercletNumber ; perceltNumber < maxPercletNumber ; perceltNumber += dPerceltNumber )
- Journal_Printf( dataStream, "%0.3g \t\t %0.3g \t\t %0.3g \t\t %0.3g\n",
- perceltNumber,
- AdvDiffResidualForceTerm_UpwindXiExact( NULL, perceltNumber),
- AdvDiffResidualForceTerm_UpwindXiDoublyAsymptoticAssumption( NULL, perceltNumber),
- AdvDiffResidualForceTerm_UpwindXiCriticalAssumption( NULL, perceltNumber) );
-
- pcu_filename_expected( "UpwindXi.expected", expectedFile );
- pcu_check_fileEq( outputFilename, expectedFile );
- remove( outputFilename );
- /*Journal_Purge( );*/
-}
-
-void UpwindXiSuite( pcu_suite_t* suite ) {
- pcu_suite_setData( suite, UpwindXiSuiteData );
- pcu_suite_setFixtures( suite, UpwindXiSuite_Setup, UpwindXiSuite_Teardown );
- pcu_suite_addTest( suite, UpwindXiSuite_Test );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/tests/UpwindXiSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/AdvectionDiffusion/tests/UpwindXiSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,102 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** Role:
+** Tests the UpwindXiSuite
+**
+** $Id: testUpwindXi.c 3462 2006-02-19 06:53:24Z WalterLandry $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pcu/pcu.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/AdvectionDiffusion.h"
+#include "UpwindXiSuite.h"
+
+typedef struct {
+} UpwindXiSuiteData;
+
+
+void UpwindXiSuite_Setup( UpwindXiSuiteData* data ) {
+ Journal_Enable_AllTypedStream( False );
+}
+
+void UpwindXiSuite_Teardown( UpwindXiSuiteData* data ) {
+}
+
+
+void UpwindXiSuite_Test( UpwindXiSuiteData* data ) {
+ Stream* dataStream;
+ double minPercletNumber = -15.0;
+ double maxPercletNumber = 15.0;
+ double dPerceltNumber = 0.5;
+ double perceltNumber;
+ char expectedFile[PCU_PATH_MAX];
+ int rank;
+ char outputFilename[100];
+
+ MPI_Comm_rank( MPI_COMM_WORLD, &rank );
+ sprintf( outputFilename, "output_%2d.dat", rank );
+
+ Journal_Enable_TypedStream( InfoStream_Type, True );
+ dataStream = Journal_Register( Info_Type, (Name)"DataStream" );
+ Stream_RedirectFile( dataStream, outputFilename );
+
+ Journal_Printf( dataStream, "# File to compare code with Brooks, Hughes 1982 - Fig 3.3\n");
+ Journal_Printf( dataStream, "# Integration rule for the optimal upwind scheme, doubly asymptotic approximation and critical approximation.\n");
+ Journal_Printf( dataStream, "# Plot using line:\n");
+ Journal_Printf( dataStream, "# plot \"%s\" using 1:2 title \"Exact\" with line, ", "output.dat" );
+ Journal_Printf( dataStream, "\"%s\" using 1:3 title \"DoublyAsymptoticAssumption\" with line, ", "output.dat" );
+ Journal_Printf( dataStream, "\"%s\" using 1:4 title \"CriticalAssumption\" with line\n", "output.dat" );
+
+ Journal_Printf( dataStream, "# Perclet Number \t Exact \t DoublyAsymptoticAssumption \t CriticalAssumption\n" );
+ for ( perceltNumber = minPercletNumber ; perceltNumber < maxPercletNumber ; perceltNumber += dPerceltNumber )
+ Journal_Printf( dataStream, "%0.3g \t\t %0.3g \t\t %0.3g \t\t %0.3g\n",
+ perceltNumber,
+ AdvDiffResidualForceTerm_UpwindXiExact( NULL, perceltNumber),
+ AdvDiffResidualForceTerm_UpwindXiDoublyAsymptoticAssumption( NULL, perceltNumber),
+ AdvDiffResidualForceTerm_UpwindXiCriticalAssumption( NULL, perceltNumber) );
+
+ pcu_filename_expected( "UpwindXi.expected", expectedFile );
+ pcu_check_fileEq( outputFilename, expectedFile );
+ remove( outputFilename );
+ /*Journal_Purge( );*/
+}
+
+void UpwindXiSuite( pcu_suite_t* suite ) {
+ pcu_suite_setData( suite, UpwindXiSuiteData );
+ pcu_suite_setFixtures( suite, UpwindXiSuite_Setup, UpwindXiSuite_Teardown );
+ pcu_suite_addTest( suite, UpwindXiSuite_Test );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/tests/oldTesting/testLumpedMassMatrix.c
--- a/SLE/ProvidedSystems/AdvectionDiffusion/tests/oldTesting/testLumpedMassMatrix.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,300 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: testLumpedMassMatrix.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/AdvectionDiffusion.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include "petsc.h"
-
-
-typedef struct Node Node;
-typedef struct Element Element;
-
-struct Node {
- double phi;
-};
-
-struct Element {
- __FiniteElement_Element
-};
-
-struct _Particle {
- Coord coord;
-};
-
-
-FeMesh* buildFeMesh( unsigned nDims, unsigned* size,
- double* minCrds, double* maxCrds,
- ExtensionManager_Register* emReg,
- ElementType_Register* etReg )
-{
- CartesianGenerator* gen;
- FeMesh* feMesh;
- unsigned maxDecomp[3] = {0, 1, 1};
-
- gen = CartesianGenerator_New( "", NULL );
- gen->shadowDepth = 0;
- CartesianGenerator_SetDimSize( gen, nDims );
- CartesianGenerator_SetTopologyParams( gen, size, 0, NULL, maxDecomp );
- CartesianGenerator_SetGeometryParams( gen, minCrds, maxCrds );
-
- feMesh = FeMesh_New( "", NULL );
- Mesh_SetExtensionManagerRegister( feMesh, emReg );
- Mesh_SetGenerator( feMesh, gen );
- FeMesh_SetElementFamily( feMesh, "linear" );
-
- Mesh_SetTopologyDataSize( feMesh, MT_VERTEX, sizeof(Node) );
- Mesh_SetTopologyDataSize( feMesh, nDims, sizeof(Element) );
-
- Stg_Component_Build( feMesh, NULL, False );
- Stg_Component_Initialise( feMesh, NULL, False );
-
- return feMesh;
-}
-
-
-int main( int argc, char* argv[] ) {
- MPI_Comm CommWorld;
- int rank;
- int numProcessors;
- int procToWatch;
- Dictionary* dictionary;
- Dictionary_Entry_Value* currBC;
- Dictionary_Entry_Value* bcList;
-
- unsigned nDims = 2;
- unsigned meshSize[3] = {2, 2, 0};
- double minCrds[3] = {0.0, 0.0, 0.0};
- double maxCrds[3] = {1.2, 1.2, 1.2};
- FeMesh* feMesh;
- unsigned nDomainVerts;
- Node* nodes;
-
- DofLayout* dofs;
- ElementType_Register* elementType_Register;
- ExtensionManager_Register* extensionMgr_Register;
- WallVC* wallVC;
- FieldVariable_Register* fV_Register;
- FeVariable* feVariable;
- Variable_Register* variableRegister;
- FiniteElementContext* context;
- Index i;
- Dimension_Index dim;
- Stream* stream;
- /* Swarm Stuff */
- CellLayout* singleCellLayout;
- ParticleLayout* gaussParticleLayout;
- Swarm* swarm;
- unsigned int dimExists[] = { True, True, False };
- /* Mass Matrix Stuff */
- ForceVector* massMatrix;
- LumpedMassMatrixForceTerm* massMatrixForceTerm;
- /* Stream Stuff */
- Stream* outputStream;
- Particle_InCellIndex particlesPerDim[] = {2,2,2};
-
- /* Initialise MPI, get world info */
- MPI_Init( &argc, &argv );
- MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld );
- MPI_Comm_size( CommWorld, &numProcessors );
- MPI_Comm_rank( CommWorld, &rank );
-
- StGermain_Init( &argc, &argv );
- StgDomain_Init( &argc, &argv );
- StgFEM_Discretisation_Init( &argc, &argv );
- //StgFEM_SLE_LinearAlgebra_Init( &argc, &argv );
- StgFEM_SLE_SystemSetup_Init( &argc, &argv );
- StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Init( &argc, &argv );
- MPI_Barrier( CommWorld ); /* Ensures copyright info always come first in output */
-
- stream = Journal_Register( Info_Type, (Name)"myStream");
-
- if( argc >= 2 ) {
- procToWatch = atoi( argv[1] );
- }
- else {
- procToWatch = 0;
- }
- if( rank == procToWatch ) printf( "Watching rank: %i\n", rank );
-
- /* Read input */
- dictionary = Dictionary_New();
- Dictionary_Add( dictionary, (Dictionary_Entry_Key)"outputPath", Dictionary_Entry_Value_FromString( "./output" ) );
- Dictionary_Add( dictionary, (Dictionary_Entry_Key)"rank", Dictionary_Entry_Value_FromUnsignedInt( rank ) );
- Dictionary_Add( dictionary, (Dictionary_Entry_Key)"numProcessors", Dictionary_Entry_Value_FromUnsignedInt( numProcessors ) );
- Dictionary_Add( dictionary, (Dictionary_Entry_Key)"gaussParticlesX", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
- Dictionary_Add( dictionary, (Dictionary_Entry_Key)"gaussParticlesY", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
-
- bcList = Dictionary_Entry_Value_NewList();
- currBC = Dictionary_Entry_Value_NewStruct( );
- Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"name", Dictionary_Entry_Value_FromString( "phi" ) );
- Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"type", Dictionary_Entry_Value_FromString( "double" ) );
- Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"value", Dictionary_Entry_Value_FromDouble( -1.0f ) );
- Dictionary_Entry_Value_AddElement( bcList, currBC );
- currBC = Dictionary_Entry_Value_NewStruct();
- Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"wall", Dictionary_Entry_Value_FromString( "left" ) );
- Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"variables", bcList );
- Dictionary_Add( dictionary, (Dictionary_Entry_Key)"boundaryCondition", currBC );
-
- /* Create Context */
- context = FiniteElementContext_New( "context", 0,0, MPI_COMM_WORLD, dictionary );
- dim = context->dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "dim", 2 );
- Journal_Enable_TypedStream( DebugStream_Type, True );
- Stream_SetLevelBranch( StgFEM_Debug, 3 );
- Stream_EnableBranch( StgFEM_Debug, True );
-
- /* create the layout, dof and mesh to use */
- extensionMgr_Register = ExtensionManager_Register_New();
- elementType_Register = ElementType_Register_New("elementTypeRegister");
- ElementType_Register_Add( elementType_Register, (ElementType*)ConstantElementType_New("constant") );
- ElementType_Register_Add( elementType_Register, (ElementType*)BilinearElementType_New("bilinear") );
- ElementType_Register_Add( elementType_Register, (ElementType*)TrilinearElementType_New("trilinear") );
-
- feMesh = buildFeMesh( nDims, meshSize, minCrds, maxCrds,
- extensionMgr_Register, elementType_Register );
- nDomainVerts = Mesh_GetDomainSize( feMesh, MT_VERTEX );
- nodes = Mesh_GetTopologyData( feMesh, MT_VERTEX );
-
- /* Create variable register */
- variableRegister = Variable_Register_New();
-
- /* Create variables */
- Variable_NewScalar(
- "phi",
- Variable_DataType_Double,
- &nDomainVerts,
- NULL,
- (void**)&nodes,
- variableRegister );
-
- dofs = DofLayout_New( "dofLayout", variableRegister, Mesh_GetDomainSize( feMesh, MT_VERTEX ), NULL );
- for (i = 0; i < Mesh_GetDomainSize( feMesh, MT_VERTEX ); i++)
- DofLayout_AddDof_ByVarName(dofs, "phi", i);
-
- wallVC = WallVC_New( "WallVC", "boundaryCondition", variableRegister, NULL, dictionary, feMesh );
-
- /* Create the finite element field variable*/
- fV_Register = FieldVariable_Register_New();
- feVariable = FeVariable_New( "phi", feMesh, NULL, dofs, wallVC, NULL, NULL, context->dim,
- False, False, False, fV_Register );
-
- /* Create Stream */
- outputStream = Journal_Register( InfoStream_Type, (Name)CURR_MODULE_NAME );
- Stream_RedirectFile( outputStream, "output/output.dat" );
-
- /* Create Swarm */
- if ( 3 == dim )
- dimExists[K_AXIS] = True;
- singleCellLayout = (CellLayout*)SingleCellLayout_New( "SingleCellLayout", dimExists, NULL, NULL );
- gaussParticleLayout = (ParticleLayout*)GaussParticleLayout_New( "GaussParticleLayout", dim, particlesPerDim );
- swarm = Swarm_New( "gaussSwarm", singleCellLayout, gaussParticleLayout, dim,
- sizeof(IntegrationPoint), context->extensionMgr_Register, context->variable_Register, MPI_COMM_WORLD, NULL );
-
- /* Lumping of Mass Matrix */
- massMatrix = ForceVector_New( "MassMatrix", feVariable, dim, context->entryPoint_Register, MPI_COMM_WORLD );
- massMatrixForceTerm = LumpedMassMatrixForceTerm_New( "forceTerm", massMatrix, swarm );
- EP_ReplaceAll( massMatrix->assembleForceVector, ForceVector_GlobalAssembly_General );
- ForceTerm_SetAssembleElementFunction( massMatrixForceTerm, _LumpedMassMatrixForceTerm_AssembleElement_General );
-
- /* Build */
- Stg_Component_Build( feMesh, context, False );
- Variable_Register_BuildAll(variableRegister);
- Stg_Component_Build( wallVC, context, False );
- Stg_Component_Build( dofs, context, False);
- Stg_Component_Build( feVariable, context, False );
- FeEquationNumber_BuildLocationMatrix( feVariable->eqNum );
- Stg_Component_Build( singleCellLayout, context, False );
- Stg_Component_Build( gaussParticleLayout, context, False );
- Stg_Component_Build( swarm, context, False );
- Stg_Component_Build( massMatrix, context, False );
-
- /* Initialise */
- Stg_Component_Initialise( feMesh, context, False );
- Stg_Component_Initialise( feVariable, context, False );
- Stg_Component_Initialise( swarm, context, False );
- Stg_Component_Initialise( massMatrix, context, False );
-
- /* Assemble */
- ForceVector_Assemble( massMatrix );
-
- /* Print out vector */
- //Vector_View( massMatrix->vector, outputStream );
-
- /* Try out optimised one */
- //Vector_Zero( massMatrix->vector );
- VecSet( massMatrix->vector, 0.0 );
-
- /* Assemble */
- ForceTerm_SetAssembleElementFunction( massMatrixForceTerm, _LumpedMassMatrixForceTerm_AssembleElement_Box );
- ForceVector_Assemble( massMatrix );
-
- /* Print out vector */
- //Vector_View( massMatrix->vector, outputStream );
-
- /* Destroy stuff */
- Stg_Class_Delete( massMatrix );
- Stg_Class_Delete( massMatrixForceTerm );
- Stg_Class_Delete( fV_Register );
- Stg_Class_Delete( wallVC );
- Stg_Class_Delete( feMesh );
- Stg_Class_Delete( elementType_Register );
- Stg_Class_Delete( extensionMgr_Register );
- Stg_Class_Delete( dofs );
- Stg_Class_Delete( dictionary );
-
- StgFEM_Discretisation_Finalise();
- StgDomain_Finalise();
- StGermain_Finalise();
-
- /* Close off MPI */
- MPI_Finalize();
-
- return 0; /* success */
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/tests/oldTesting/testLumpedMassMatrix.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/AdvectionDiffusion/tests/oldTesting/testLumpedMassMatrix.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,300 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: testLumpedMassMatrix.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/AdvectionDiffusion.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "petsc.h"
+
+
+typedef struct Node Node;
+typedef struct Element Element;
+
+struct Node {
+ double phi;
+};
+
+struct Element {
+ __FiniteElement_Element
+};
+
+struct _Particle {
+ Coord coord;
+};
+
+
+FeMesh* buildFeMesh( unsigned nDims, unsigned* size,
+ double* minCrds, double* maxCrds,
+ ExtensionManager_Register* emReg,
+ ElementType_Register* etReg )
+{
+ CartesianGenerator* gen;
+ FeMesh* feMesh;
+ unsigned maxDecomp[3] = {0, 1, 1};
+
+ gen = CartesianGenerator_New( "", NULL );
+ gen->shadowDepth = 0;
+ CartesianGenerator_SetDimSize( gen, nDims );
+ CartesianGenerator_SetTopologyParams( gen, size, 0, NULL, maxDecomp );
+ CartesianGenerator_SetGeometryParams( gen, minCrds, maxCrds );
+
+ feMesh = FeMesh_New( "", NULL );
+ Mesh_SetExtensionManagerRegister( feMesh, emReg );
+ Mesh_SetGenerator( feMesh, gen );
+ FeMesh_SetElementFamily( feMesh, "linear" );
+
+ Mesh_SetTopologyDataSize( feMesh, MT_VERTEX, sizeof(Node) );
+ Mesh_SetTopologyDataSize( feMesh, nDims, sizeof(Element) );
+
+ Stg_Component_Build( feMesh, NULL, False );
+ Stg_Component_Initialise( feMesh, NULL, False );
+
+ return feMesh;
+}
+
+
+int main( int argc, char* argv[] ) {
+ MPI_Comm CommWorld;
+ int rank;
+ int numProcessors;
+ int procToWatch;
+ Dictionary* dictionary;
+ Dictionary_Entry_Value* currBC;
+ Dictionary_Entry_Value* bcList;
+
+ unsigned nDims = 2;
+ unsigned meshSize[3] = {2, 2, 0};
+ double minCrds[3] = {0.0, 0.0, 0.0};
+ double maxCrds[3] = {1.2, 1.2, 1.2};
+ FeMesh* feMesh;
+ unsigned nDomainVerts;
+ Node* nodes;
+
+ DofLayout* dofs;
+ ElementType_Register* elementType_Register;
+ ExtensionManager_Register* extensionMgr_Register;
+ WallVC* wallVC;
+ FieldVariable_Register* fV_Register;
+ FeVariable* feVariable;
+ Variable_Register* variableRegister;
+ FiniteElementContext* context;
+ Index i;
+ Dimension_Index dim;
+ Stream* stream;
+ /* Swarm Stuff */
+ CellLayout* singleCellLayout;
+ ParticleLayout* gaussParticleLayout;
+ Swarm* swarm;
+ unsigned int dimExists[] = { True, True, False };
+ /* Mass Matrix Stuff */
+ ForceVector* massMatrix;
+ LumpedMassMatrixForceTerm* massMatrixForceTerm;
+ /* Stream Stuff */
+ Stream* outputStream;
+ Particle_InCellIndex particlesPerDim[] = {2,2,2};
+
+ /* Initialise MPI, get world info */
+ MPI_Init( &argc, &argv );
+ MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld );
+ MPI_Comm_size( CommWorld, &numProcessors );
+ MPI_Comm_rank( CommWorld, &rank );
+
+ StGermain_Init( &argc, &argv );
+ StgDomain_Init( &argc, &argv );
+ StgFEM_Discretisation_Init( &argc, &argv );
+ //StgFEM_SLE_LinearAlgebra_Init( &argc, &argv );
+ StgFEM_SLE_SystemSetup_Init( &argc, &argv );
+ StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Init( &argc, &argv );
+ MPI_Barrier( CommWorld ); /* Ensures copyright info always come first in output */
+
+ stream = Journal_Register( Info_Type, (Name)"myStream");
+
+ if( argc >= 2 ) {
+ procToWatch = atoi( argv[1] );
+ }
+ else {
+ procToWatch = 0;
+ }
+ if( rank == procToWatch ) printf( "Watching rank: %i\n", rank );
+
+ /* Read input */
+ dictionary = Dictionary_New();
+ Dictionary_Add( dictionary, (Dictionary_Entry_Key)"outputPath", Dictionary_Entry_Value_FromString( "./output" ) );
+ Dictionary_Add( dictionary, (Dictionary_Entry_Key)"rank", Dictionary_Entry_Value_FromUnsignedInt( rank ) );
+ Dictionary_Add( dictionary, (Dictionary_Entry_Key)"numProcessors", Dictionary_Entry_Value_FromUnsignedInt( numProcessors ) );
+ Dictionary_Add( dictionary, (Dictionary_Entry_Key)"gaussParticlesX", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
+ Dictionary_Add( dictionary, (Dictionary_Entry_Key)"gaussParticlesY", Dictionary_Entry_Value_FromUnsignedInt( 2 ) );
+
+ bcList = Dictionary_Entry_Value_NewList();
+ currBC = Dictionary_Entry_Value_NewStruct( );
+ Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"name", Dictionary_Entry_Value_FromString( "phi" ) );
+ Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"type", Dictionary_Entry_Value_FromString( "double" ) );
+ Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"value", Dictionary_Entry_Value_FromDouble( -1.0f ) );
+ Dictionary_Entry_Value_AddElement( bcList, currBC );
+ currBC = Dictionary_Entry_Value_NewStruct();
+ Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"wall", Dictionary_Entry_Value_FromString( "left" ) );
+ Dictionary_Entry_Value_AddMember( currBC, (Dictionary_Entry_Key)"variables", bcList );
+ Dictionary_Add( dictionary, (Dictionary_Entry_Key)"boundaryCondition", currBC );
+
+ /* Create Context */
+ context = FiniteElementContext_New( "context", 0,0, MPI_COMM_WORLD, dictionary );
+ dim = context->dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "dim", 2 );
+ Journal_Enable_TypedStream( DebugStream_Type, True );
+ Stream_SetLevelBranch( StgFEM_Debug, 3 );
+ Stream_EnableBranch( StgFEM_Debug, True );
+
+ /* create the layout, dof and mesh to use */
+ extensionMgr_Register = ExtensionManager_Register_New();
+ elementType_Register = ElementType_Register_New("elementTypeRegister");
+ ElementType_Register_Add( elementType_Register, (ElementType*)ConstantElementType_New("constant") );
+ ElementType_Register_Add( elementType_Register, (ElementType*)BilinearElementType_New("bilinear") );
+ ElementType_Register_Add( elementType_Register, (ElementType*)TrilinearElementType_New("trilinear") );
+
+ feMesh = buildFeMesh( nDims, meshSize, minCrds, maxCrds,
+ extensionMgr_Register, elementType_Register );
+ nDomainVerts = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+ nodes = Mesh_GetTopologyData( feMesh, MT_VERTEX );
+
+ /* Create variable register */
+ variableRegister = Variable_Register_New();
+
+ /* Create variables */
+ Variable_NewScalar(
+ "phi",
+ Variable_DataType_Double,
+ &nDomainVerts,
+ NULL,
+ (void**)&nodes,
+ variableRegister );
+
+ dofs = DofLayout_New( "dofLayout", variableRegister, Mesh_GetDomainSize( feMesh, MT_VERTEX ), NULL );
+ for (i = 0; i < Mesh_GetDomainSize( feMesh, MT_VERTEX ); i++)
+ DofLayout_AddDof_ByVarName(dofs, "phi", i);
+
+ wallVC = WallVC_New( "WallVC", "boundaryCondition", variableRegister, NULL, dictionary, feMesh );
+
+ /* Create the finite element field variable*/
+ fV_Register = FieldVariable_Register_New();
+ feVariable = FeVariable_New( "phi", feMesh, NULL, dofs, wallVC, NULL, NULL, context->dim,
+ False, False, False, fV_Register );
+
+ /* Create Stream */
+ outputStream = Journal_Register( InfoStream_Type, (Name)CURR_MODULE_NAME );
+ Stream_RedirectFile( outputStream, "output/output.dat" );
+
+ /* Create Swarm */
+ if ( 3 == dim )
+ dimExists[K_AXIS] = True;
+ singleCellLayout = (CellLayout*)SingleCellLayout_New( "SingleCellLayout", dimExists, NULL, NULL );
+ gaussParticleLayout = (ParticleLayout*)GaussParticleLayout_New( "GaussParticleLayout", dim, particlesPerDim );
+ swarm = Swarm_New( "gaussSwarm", singleCellLayout, gaussParticleLayout, dim,
+ sizeof(IntegrationPoint), context->extensionMgr_Register, context->variable_Register, MPI_COMM_WORLD, NULL );
+
+ /* Lumping of Mass Matrix */
+ massMatrix = ForceVector_New( "MassMatrix", feVariable, dim, context->entryPoint_Register, MPI_COMM_WORLD );
+ massMatrixForceTerm = LumpedMassMatrixForceTerm_New( "forceTerm", massMatrix, swarm );
+ EP_ReplaceAll( massMatrix->assembleForceVector, ForceVector_GlobalAssembly_General );
+ ForceTerm_SetAssembleElementFunction( massMatrixForceTerm, _LumpedMassMatrixForceTerm_AssembleElement_General );
+
+ /* Build */
+ Stg_Component_Build( feMesh, context, False );
+ Variable_Register_BuildAll(variableRegister);
+ Stg_Component_Build( wallVC, context, False );
+ Stg_Component_Build( dofs, context, False);
+ Stg_Component_Build( feVariable, context, False );
+ FeEquationNumber_BuildLocationMatrix( feVariable->eqNum );
+ Stg_Component_Build( singleCellLayout, context, False );
+ Stg_Component_Build( gaussParticleLayout, context, False );
+ Stg_Component_Build( swarm, context, False );
+ Stg_Component_Build( massMatrix, context, False );
+
+ /* Initialise */
+ Stg_Component_Initialise( feMesh, context, False );
+ Stg_Component_Initialise( feVariable, context, False );
+ Stg_Component_Initialise( swarm, context, False );
+ Stg_Component_Initialise( massMatrix, context, False );
+
+ /* Assemble */
+ ForceVector_Assemble( massMatrix );
+
+ /* Print out vector */
+ //Vector_View( massMatrix->vector, outputStream );
+
+ /* Try out optimised one */
+ //Vector_Zero( massMatrix->vector );
+ VecSet( massMatrix->vector, 0.0 );
+
+ /* Assemble */
+ ForceTerm_SetAssembleElementFunction( massMatrixForceTerm, _LumpedMassMatrixForceTerm_AssembleElement_Box );
+ ForceVector_Assemble( massMatrix );
+
+ /* Print out vector */
+ //Vector_View( massMatrix->vector, outputStream );
+
+ /* Destroy stuff */
+ Stg_Class_Delete( massMatrix );
+ Stg_Class_Delete( massMatrixForceTerm );
+ Stg_Class_Delete( fV_Register );
+ Stg_Class_Delete( wallVC );
+ Stg_Class_Delete( feMesh );
+ Stg_Class_Delete( elementType_Register );
+ Stg_Class_Delete( extensionMgr_Register );
+ Stg_Class_Delete( dofs );
+ Stg_Class_Delete( dictionary );
+
+ StgFEM_Discretisation_Finalise();
+ StgDomain_Finalise();
+ StGermain_Finalise();
+
+ /* Close off MPI */
+ MPI_Finalize();
+
+ return 0; /* success */
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/tests/oldTesting/testUpwindXi.c
--- a/SLE/ProvidedSystems/AdvectionDiffusion/tests/oldTesting/testUpwindXi.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: testUpwindXi.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/AdvectionDiffusion.h"
-
-int main( int argc, char* argv[] ) {
- Stream* dataStream;
- double minPercletNumber = -15.0;
- double maxPercletNumber = 15.0;
- double dPerceltNumber = 0.5;
- double perceltNumber;
- char* dataFileName = "./output/output.dat";
-
- MPI_Init( &argc, &argv );
- StGermain_Init( &argc, &argv );
-
- /* Create Data File */
- dataStream = Journal_Register( Info_Type, (Name)"DataStream" );
- Stream_RedirectFile( dataStream, dataFileName );
-
- Journal_Printf( dataStream, "# File to compare code with Brooks, Hughes 1982 - Fig 3.3\n");
- Journal_Printf( dataStream, "# Integration rule for the optimal upwind scheme, doubly asymptotic approximation and critical approximation.\n");
- Journal_Printf( dataStream, "# Plot using line:\n");
- Journal_Printf( dataStream, "# plot \"%s\" using 1:2 title \"Exact\" with line, ", dataFileName );
- Journal_Printf( dataStream, "\"%s\" using 1:3 title \"DoublyAsymptoticAssumption\" with line, ", dataFileName );
- Journal_Printf( dataStream, "\"%s\" using 1:4 title \"CriticalAssumption\" with line\n", dataFileName );
-
- Journal_Printf( dataStream, "# Perclet Number \t Exact \t DoublyAsymptoticAssumption \t CriticalAssumption\n" );
- for ( perceltNumber = minPercletNumber ; perceltNumber < maxPercletNumber ; perceltNumber += dPerceltNumber )
- Journal_Printf( dataStream, "%0.3g \t\t %0.3g \t\t %0.3g \t\t %0.3g\n",
- perceltNumber,
- AdvDiffResidualForceTerm_UpwindXiExact( NULL, perceltNumber),
- AdvDiffResidualForceTerm_UpwindXiDoublyAsymptoticAssumption( NULL, perceltNumber),
- AdvDiffResidualForceTerm_UpwindXiCriticalAssumption( NULL, perceltNumber) );
-
- StGermain_Finalise();
- MPI_Finalize();
-
- return EXIT_SUCCESS;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/AdvectionDiffusion/tests/oldTesting/testUpwindXi.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/AdvectionDiffusion/tests/oldTesting/testUpwindXi.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,86 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: testUpwindXi.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/AdvectionDiffusion.h"
+
+int main( int argc, char* argv[] ) {
+ Stream* dataStream;
+ double minPercletNumber = -15.0;
+ double maxPercletNumber = 15.0;
+ double dPerceltNumber = 0.5;
+ double perceltNumber;
+ char* dataFileName = "./output/output.dat";
+
+ MPI_Init( &argc, &argv );
+ StGermain_Init( &argc, &argv );
+
+ /* Create Data File */
+ dataStream = Journal_Register( Info_Type, (Name)"DataStream" );
+ Stream_RedirectFile( dataStream, dataFileName );
+
+ Journal_Printf( dataStream, "# File to compare code with Brooks, Hughes 1982 - Fig 3.3\n");
+ Journal_Printf( dataStream, "# Integration rule for the optimal upwind scheme, doubly asymptotic approximation and critical approximation.\n");
+ Journal_Printf( dataStream, "# Plot using line:\n");
+ Journal_Printf( dataStream, "# plot \"%s\" using 1:2 title \"Exact\" with line, ", dataFileName );
+ Journal_Printf( dataStream, "\"%s\" using 1:3 title \"DoublyAsymptoticAssumption\" with line, ", dataFileName );
+ Journal_Printf( dataStream, "\"%s\" using 1:4 title \"CriticalAssumption\" with line\n", dataFileName );
+
+ Journal_Printf( dataStream, "# Perclet Number \t Exact \t DoublyAsymptoticAssumption \t CriticalAssumption\n" );
+ for ( perceltNumber = minPercletNumber ; perceltNumber < maxPercletNumber ; perceltNumber += dPerceltNumber )
+ Journal_Printf( dataStream, "%0.3g \t\t %0.3g \t\t %0.3g \t\t %0.3g\n",
+ perceltNumber,
+ AdvDiffResidualForceTerm_UpwindXiExact( NULL, perceltNumber),
+ AdvDiffResidualForceTerm_UpwindXiDoublyAsymptoticAssumption( NULL, perceltNumber),
+ AdvDiffResidualForceTerm_UpwindXiCriticalAssumption( NULL, perceltNumber) );
+
+ StGermain_Finalise();
+ MPI_Finalize();
+
+ return EXIT_SUCCESS;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/Energy/src/Energy_SLE.c
--- a/SLE/ProvidedSystems/Energy/src/Energy_SLE.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Energy_SLE.c 999 2008-01-09 04:13:42Z DavidLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "types.h"
-#include "Energy_SLE.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-/* Textual name of this class */
-const Type Energy_SLE_Type = "Energy_SLE";
-
-Energy_SLE* Energy_SLE_New(
- Name name,
- SLE_Solver* solver,
- FiniteElementContext* context,
- Bool isNonLinear,
- double nonLinearTolerance,
- Iteration_Index nonLinearMaxIterations,
- Bool killNonConvergent,
- EntryPoint_Register* entryPoint_Register,
- MPI_Comm comm,
- StiffnessMatrix* stiffMat,
- SolutionVector* solutionVec,
- ForceVector* fVector )
-{
- Energy_SLE* self = (Energy_SLE*)_Energy_SLE_DefaultNew( name );
-
- self->isConstructed = True;
- _SystemLinearEquations_Init( self, solver, NULL, context, False, isNonLinear, nonLinearTolerance,
- nonLinearMaxIterations, killNonConvergent, 1, "", "", entryPoint_Register, comm );
- _Energy_SLE_Init( self, stiffMat, solutionVec, fVector );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-Energy_SLE* _Energy_SLE_New( ENERGY_SLE_DEFARGS )
-{
- Energy_SLE* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(Energy_SLE) );
- self = (Energy_SLE*) _SystemLinearEquations_New( SYSTEMLINEAREQUATIONS_PASSARGS );
-
- /* Virtual info */
- return self;
-}
-
-void _Energy_SLE_Init( void* sle, StiffnessMatrix* stiffMat, SolutionVector* solutionVec, ForceVector* fVector ) {
- Energy_SLE* self = (Energy_SLE*)sle;
-
- self->stiffMat = stiffMat;
- self->solutionVec = solutionVec;
- self->fVector = fVector;
-
- SystemLinearEquations_AddStiffnessMatrix( self, stiffMat );
- SystemLinearEquations_AddSolutionVector( self, solutionVec );
- SystemLinearEquations_AddForceVector( self, fVector );
-}
-
-void _Energy_SLE_Print( void* sle, Stream* stream ) {
- Energy_SLE* self = (Energy_SLE*)sle;
-
- /* General info */
- Journal_Printf( stream, "Energy_SLE (ptr): %p\n", self );
- _SystemLinearEquations_Print( self, stream );
-
- Journal_PrintString( stream, self->stiffMat->name );
- Journal_PrintString( stream, self->solutionVec->name );
- Journal_PrintString( stream, self->fVector->name );
-
- Stg_Class_Print( self->solver, stream );
-}
-
-void* _Energy_SLE_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(Energy_SLE);
- Type type = Energy_SLE_Type;
- Stg_Class_DeleteFunction* _delete = _SystemLinearEquations_Delete;
- Stg_Class_PrintFunction* _print = _Energy_SLE_Print;
- Stg_Class_CopyFunction* _copy = _SystemLinearEquations_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _Energy_SLE_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _Energy_SLE_AssignFromXML;
- Stg_Component_BuildFunction* _build = _SystemLinearEquations_Build;
- Stg_Component_InitialiseFunction* _initialise = _SystemLinearEquations_Initialise;
- Stg_Component_ExecuteFunction* _execute = _SystemLinearEquations_Execute;
- Stg_Component_DestroyFunction* _destroy = _SystemLinearEquations_Destroy;
- SystemLinearEquations_LM_SetupFunction* _LM_Setup = _SystemLinearEquations_LM_Setup;
- SystemLinearEquations_MatrixSetupFunction* _matrixSetup = _SystemLinearEquations_MatrixSetup;
- SystemLinearEquations_VectorSetupFunction* _vectorSetup = _SystemLinearEquations_VectorSetup;
- SystemLinearEquations_UpdateSolutionOntoNodesFunc* _updateSolutionOntoNodes = _SystemLinearEquations_UpdateSolutionOntoNodes;
- SystemLinearEquations_MG_SelectStiffMatsFunc* _mgSelectStiffMats = _SystemLinearEquations_MG_SelectStiffMats;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_Energy_SLE_New( ENERGY_SLE_PASSARGS );
-}
-
-void _Energy_SLE_AssignFromXML( void* sle, Stg_ComponentFactory* cf, void* data ){
- Energy_SLE* self = (Energy_SLE*)sle;
- StiffnessMatrix* stiffMat;
- SolutionVector* solutionVec;
- ForceVector* fVector;
-
- /* Construct Parent */
- _SystemLinearEquations_AssignFromXML( self, cf, data );
-
- stiffMat = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)StiffnessMatrix_Type, StiffnessMatrix, True, data ) ;
- solutionVec = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)SolutionVector_Type, SolutionVector, True, data ) ;
- fVector = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)ForceVector_Type, ForceVector, True, data ) ;
-
- _Energy_SLE_Init( self, stiffMat, solutionVec, fVector );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/Energy/src/Energy_SLE.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/Energy/src/Energy_SLE.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,162 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Energy_SLE.c 999 2008-01-09 04:13:42Z DavidLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "types.h"
+#include "Energy_SLE.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+/* Textual name of this class */
+const Type Energy_SLE_Type = "Energy_SLE";
+
+Energy_SLE* Energy_SLE_New(
+ Name name,
+ SLE_Solver* solver,
+ FiniteElementContext* context,
+ Bool isNonLinear,
+ double nonLinearTolerance,
+ Iteration_Index nonLinearMaxIterations,
+ Bool killNonConvergent,
+ EntryPoint_Register* entryPoint_Register,
+ MPI_Comm comm,
+ StiffnessMatrix* stiffMat,
+ SolutionVector* solutionVec,
+ ForceVector* fVector )
+{
+ Energy_SLE* self = (Energy_SLE*)_Energy_SLE_DefaultNew( name );
+
+ self->isConstructed = True;
+ _SystemLinearEquations_Init( self, solver, NULL, context, False, isNonLinear, nonLinearTolerance,
+ nonLinearMaxIterations, killNonConvergent, 1, "", "", entryPoint_Register, comm );
+ _Energy_SLE_Init( self, stiffMat, solutionVec, fVector );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+Energy_SLE* _Energy_SLE_New( ENERGY_SLE_DEFARGS )
+{
+ Energy_SLE* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(Energy_SLE) );
+ self = (Energy_SLE*) _SystemLinearEquations_New( SYSTEMLINEAREQUATIONS_PASSARGS );
+
+ /* Virtual info */
+ return self;
+}
+
+void _Energy_SLE_Init( void* sle, StiffnessMatrix* stiffMat, SolutionVector* solutionVec, ForceVector* fVector ) {
+ Energy_SLE* self = (Energy_SLE*)sle;
+
+ self->stiffMat = stiffMat;
+ self->solutionVec = solutionVec;
+ self->fVector = fVector;
+
+ SystemLinearEquations_AddStiffnessMatrix( self, stiffMat );
+ SystemLinearEquations_AddSolutionVector( self, solutionVec );
+ SystemLinearEquations_AddForceVector( self, fVector );
+}
+
+void _Energy_SLE_Print( void* sle, Stream* stream ) {
+ Energy_SLE* self = (Energy_SLE*)sle;
+
+ /* General info */
+ Journal_Printf( stream, "Energy_SLE (ptr): %p\n", self );
+ _SystemLinearEquations_Print( self, stream );
+
+ Journal_PrintString( stream, self->stiffMat->name );
+ Journal_PrintString( stream, self->solutionVec->name );
+ Journal_PrintString( stream, self->fVector->name );
+
+ Stg_Class_Print( self->solver, stream );
+}
+
+void* _Energy_SLE_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(Energy_SLE);
+ Type type = Energy_SLE_Type;
+ Stg_Class_DeleteFunction* _delete = _SystemLinearEquations_Delete;
+ Stg_Class_PrintFunction* _print = _Energy_SLE_Print;
+ Stg_Class_CopyFunction* _copy = _SystemLinearEquations_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _Energy_SLE_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _Energy_SLE_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _SystemLinearEquations_Build;
+ Stg_Component_InitialiseFunction* _initialise = _SystemLinearEquations_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _SystemLinearEquations_Execute;
+ Stg_Component_DestroyFunction* _destroy = _SystemLinearEquations_Destroy;
+ SystemLinearEquations_LM_SetupFunction* _LM_Setup = _SystemLinearEquations_LM_Setup;
+ SystemLinearEquations_MatrixSetupFunction* _matrixSetup = _SystemLinearEquations_MatrixSetup;
+ SystemLinearEquations_VectorSetupFunction* _vectorSetup = _SystemLinearEquations_VectorSetup;
+ SystemLinearEquations_UpdateSolutionOntoNodesFunc* _updateSolutionOntoNodes = _SystemLinearEquations_UpdateSolutionOntoNodes;
+ SystemLinearEquations_MG_SelectStiffMatsFunc* _mgSelectStiffMats = _SystemLinearEquations_MG_SelectStiffMats;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_Energy_SLE_New( ENERGY_SLE_PASSARGS );
+}
+
+void _Energy_SLE_AssignFromXML( void* sle, Stg_ComponentFactory* cf, void* data ){
+ Energy_SLE* self = (Energy_SLE*)sle;
+ StiffnessMatrix* stiffMat;
+ SolutionVector* solutionVec;
+ ForceVector* fVector;
+
+ /* Construct Parent */
+ _SystemLinearEquations_AssignFromXML( self, cf, data );
+
+ stiffMat = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)StiffnessMatrix_Type, StiffnessMatrix, True, data ) ;
+ solutionVec = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)SolutionVector_Type, SolutionVector, True, data ) ;
+ fVector = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)ForceVector_Type, ForceVector, True, data ) ;
+
+ _Energy_SLE_Init( self, stiffMat, solutionVec, fVector );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/Energy/src/Energy_SLE_Solver.c
--- a/SLE/ProvidedSystems/Energy/src/Energy_SLE_Solver.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,299 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Energy_SLE_Solver.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "types.h"
-#include "Energy_SLE_Solver.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-/* Textual name of this class */
-const Type Energy_SLE_Solver_Type = "Energy_SLE_Solver";
-
-PetscTruth Energy_SLE_HasNullSpace( Mat A );
-
-void* Energy_SLE_Solver_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(Energy_SLE_Solver);
- Type type = Energy_SLE_Solver_Type;
- Stg_Class_DeleteFunction* _delete = _Energy_SLE_Solver_Delete;
- Stg_Class_PrintFunction* _print = _Energy_SLE_Solver_Print;
- Stg_Class_CopyFunction* _copy = _Energy_SLE_Solver_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = Energy_SLE_Solver_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _Energy_SLE_Solver_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Energy_SLE_Solver_Build;
- Stg_Component_InitialiseFunction* _initialise = _Energy_SLE_Solver_Initialise;
- Stg_Component_ExecuteFunction* _execute = _SLE_Solver_Execute;
- Stg_Component_DestroyFunction* _destroy = _SLE_Solver_Destroy;
- SLE_Solver_SolverSetupFunction* _solverSetup = _Energy_SLE_Solver_SolverSetup;
- SLE_Solver_SolveFunction* _solve = _Energy_SLE_Solver_Solve;
- SLE_Solver_GetResidualFunc* _getResidual = _Energy_SLE_GetResidual;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _Energy_SLE_Solver_New( ENERGY_SLE_SOLVER_PASSARGS );
-}
-
-Energy_SLE_Solver* Energy_SLE_Solver_New( Name name, Bool useStatSolve, int statReps ) {
- Energy_SLE_Solver* self = (Energy_SLE_Solver*) Energy_SLE_Solver_DefaultNew( name );
-
- Energy_SLE_Solver_InitAll( self, useStatSolve, statReps ) ;
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-Energy_SLE_Solver* _Energy_SLE_Solver_New( ENERGY_SLE_SOLVER_DEFARGS )
-{
- Energy_SLE_Solver* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(Energy_SLE_Solver) );
- self = (Energy_SLE_Solver*) _SLE_Solver_New( SLE_SOLVER_PASSARGS );
-
- /* Virtual info */
- return self;
-}
-
-/* Initialisation implementation */
-void _Energy_SLE_Solver_Init( Energy_SLE_Solver* self ) {
- self->isConstructed = True;
- self->residual = NULL;
- //self->matrixSolver = NULL;
- self->matrixSolver = PETSC_NULL;
-}
-void Energy_SLE_Solver_InitAll( Energy_SLE_Solver* solver, Bool useStatSolve, int statReps ) {
- Energy_SLE_Solver* self = (Energy_SLE_Solver*)solver;
-
- SLE_Solver_InitAll( self, useStatSolve, statReps );
-}
-
-void _Energy_SLE_Solver_Delete( void* sle ) {
- Energy_SLE_Solver* self = (Energy_SLE_Solver*)sle;
-
- //FreeObject( self->matrixSolver );
- KSPDestroy( self->matrixSolver );
-
- if( self->residual != PETSC_NULL ) {
- //FreeObject( self->residual );
- VecDestroy( self->residual );
- }
-}
-
-void _Energy_SLE_Solver_Print( void* solver, Stream* stream ) {
- Energy_SLE_Solver* self = (Energy_SLE_Solver*)solver;
-
- /* Set the Journal for printing informations */
- Stream* standard_SLE_SolverStream = stream;
-
- /* General info */
- Journal_Printf( standard_SLE_SolverStream, "Energy_SLE_Solver (ptr): %p\n", self );
-
- /* other info */
- Journal_Printf( standard_SLE_SolverStream, "\tmatrixSolver (ptr): %p", self->matrixSolver );
-}
-
-
-void* _Energy_SLE_Solver_Copy( const void* standardSleSolver, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- Energy_SLE_Solver* self = (Energy_SLE_Solver*)standardSleSolver;
- Energy_SLE_Solver* newEnergySleSolver;
-
- newEnergySleSolver = (Energy_SLE_Solver*)_SLE_Solver_Copy( self, dest, deep, nameExt, ptrMap );
-
- newEnergySleSolver->matrixSolver = self->matrixSolver;
-
- return (void*)newEnergySleSolver;
-}
-
-void _Energy_SLE_Solver_AssignFromXML( void* sleSolver, Stg_ComponentFactory* cf, void* data ) {
- Energy_SLE_Solver *self = (Energy_SLE_Solver*)sleSolver;
-
- assert( self && Stg_CheckType( self, Energy_SLE_Solver ) );
- assert( cf && Stg_CheckType( cf, Stg_ComponentFactory ) );
-
- _SLE_Solver_AssignFromXML( self, cf, data );
-}
-
-/* Build */
-void _Energy_SLE_Solver_Build( void* sleSolver, void* standardSLE ) {
- Energy_SLE_Solver* self = (Energy_SLE_Solver*)sleSolver;
- SystemLinearEquations* sle = (SystemLinearEquations*) standardSLE;
- StiffnessMatrix* stiffMat = (StiffnessMatrix*)sle->stiffnessMatrices->data[0];
-
- Journal_DPrintf( self->debug, "In %s()\n", __func__ );
- Stream_IndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
- Journal_DPrintf( self->debug, "building a standard L.A. solver for the \"%s\" matrix.\n", stiffMat->name );
-
- Stg_Component_Build( stiffMat, standardSLE, False );
-
- if( self->matrixSolver == PETSC_NULL )
- KSPCreate( sle->comm, &self->matrixSolver );
-
- Stream_UnIndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
-}
-
-
-void _Energy_SLE_Solver_Initialise( void* sleSolver, void* standardSLE ) {
- Energy_SLE_Solver* self = (Energy_SLE_Solver*)sleSolver;
- SystemLinearEquations* sle = (SystemLinearEquations*) standardSLE;
-
- /* Initialise parent. */
- _SLE_Solver_Initialise( self, sle );
-}
-
-void _Energy_SLE_Solver_Execute( void* sleSolver, void* data ) {
-}
-
-void _Energy_SLE_Solver_Destroy( void* sleSolver, void* data ) {
-}
-
-void _Energy_SLE_Solver_SolverSetup( void* sleSolver, void* standardSLE ) {
- Energy_SLE_Solver* self = (Energy_SLE_Solver*)sleSolver;
- SystemLinearEquations* sle = (SystemLinearEquations*) standardSLE;
- StiffnessMatrix* stiffMat = (StiffnessMatrix*)sle->stiffnessMatrices->data[0];
-
- Journal_DPrintf( self->debug, "In %s()\n", __func__ );
- Stream_IndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
-
- Journal_DPrintf( self->debug, "Initialising the L.A. solver for the \"%s\" matrix.\n", stiffMat->name );
- KSPSetOperators( self->matrixSolver, stiffMat->matrix, stiffMat->matrix, DIFFERENT_NONZERO_PATTERN );
- Stream_UnIndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
-
- if( self->maxIterations > 0 ) {
- KSPSetTolerances( self->matrixSolver, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, self->maxIterations );
- }
-
- VecDuplicate( ((ForceVector**)sle->forceVectors->data)[0]->vector, &self->residual );
-}
-
-
-void _Energy_SLE_Solver_Solve( void* sleSolver, void* standardSLE ) {
- Energy_SLE_Solver* self = (Energy_SLE_Solver*)sleSolver;
- SystemLinearEquations* sle = (SystemLinearEquations*) standardSLE;
- Iteration_Index iterations;
- PetscTruth isNull;
- MatNullSpace nsp;
-
-
- Journal_DPrintf( self->debug, "In %s - for standard SLE solver\n", __func__ );
- Stream_IndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
-
- if ( (sle->stiffnessMatrices->count > 1 ) ||
- (sle->forceVectors->count > 1 ) )
- {
- Stream* warning = Stream_RegisterChild( StgFEM_Warning, self->type );
- Journal_Printf( warning, "Warning: Energy solver unable to solve more that one matrix/vector.\n" );
- }
-
- if ( sle->solutionVectors->count > 1 ) {
- Stream* warning = Stream_RegisterChild( StgFEM_Warning, self->type );
- Journal_Printf( warning, "Warning: More than 1 solution vector provided to standard sle. Ignoring second and subsequent"
- " solution vectors.\n" );
- }
-
- isNull = Energy_SLE_HasNullSpace(((StiffnessMatrix**)sle->stiffnessMatrices->data)[0]->matrix);
- if(isNull) {
- MatNullSpaceCreate(PETSC_COMM_WORLD, PETSC_TRUE, 0, PETSC_NULL, &nsp);
- KSPSetNullSpace(self->matrixSolver, nsp);
- }
-
- KSPSolve( self->matrixSolver,
- ((ForceVector*) sle->forceVectors->data[0])->vector,
- ((SolutionVector*) sle->solutionVectors->data[0])->vector );
- KSPGetIterationNumber( self->matrixSolver, (PetscInt*)(&iterations) );
-
- Journal_DPrintf( self->debug, "Solved after %u iterations.\n", iterations );
- Stream_UnIndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
-
- /* calculate the residual */
- /* TODO: need to make this optional */
- MatMult( ((StiffnessMatrix**)sle->stiffnessMatrices->data)[0]->matrix,
- ((SolutionVector**)sle->solutionVectors->data)[0]->vector,
- self->residual );
- VecAYPX( self->residual, -1.0, ((ForceVector**)sle->forceVectors->data)[0]->vector );
-
- if(isNull)
- MatNullSpaceDestroy(nsp);
-}
-
-
-Vec _Energy_SLE_GetResidual( void* sleSolver, Index fv_I ) {
- Energy_SLE_Solver* self = (Energy_SLE_Solver*)sleSolver;
-
- return self->residual;
-}
-
-PetscTruth Energy_SLE_HasNullSpace( Mat A ) {
- PetscInt N;
- PetscScalar sum;
- PetscReal nrm;
- PetscTruth isNull;
- Vec r, l;
-
- MatGetVecs(A, &r, &l); /* l = A r */
-
- VecGetSize(r, &N);
- sum = 1.0/(PetscScalar)N;
- VecSet(r, sum);
-
- MatMult(A, r, l); /* {l} = [A] {r} */
-
- VecNorm(l, NORM_2, &nrm);
- if(nrm < 1.e-7)
- isNull = PETSC_TRUE;
- else
- isNull = PETSC_FALSE;
-
- VecDestroy(l);
- VecDestroy(r);
-
- return isNull;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/Energy/src/Energy_SLE_Solver.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/Energy/src/Energy_SLE_Solver.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,299 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Energy_SLE_Solver.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "types.h"
+#include "Energy_SLE_Solver.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+/* Textual name of this class */
+const Type Energy_SLE_Solver_Type = "Energy_SLE_Solver";
+
+PetscTruth Energy_SLE_HasNullSpace( Mat A );
+
+void* Energy_SLE_Solver_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(Energy_SLE_Solver);
+ Type type = Energy_SLE_Solver_Type;
+ Stg_Class_DeleteFunction* _delete = _Energy_SLE_Solver_Delete;
+ Stg_Class_PrintFunction* _print = _Energy_SLE_Solver_Print;
+ Stg_Class_CopyFunction* _copy = _Energy_SLE_Solver_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = Energy_SLE_Solver_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _Energy_SLE_Solver_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Energy_SLE_Solver_Build;
+ Stg_Component_InitialiseFunction* _initialise = _Energy_SLE_Solver_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _SLE_Solver_Execute;
+ Stg_Component_DestroyFunction* _destroy = _SLE_Solver_Destroy;
+ SLE_Solver_SolverSetupFunction* _solverSetup = _Energy_SLE_Solver_SolverSetup;
+ SLE_Solver_SolveFunction* _solve = _Energy_SLE_Solver_Solve;
+ SLE_Solver_GetResidualFunc* _getResidual = _Energy_SLE_GetResidual;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _Energy_SLE_Solver_New( ENERGY_SLE_SOLVER_PASSARGS );
+}
+
+Energy_SLE_Solver* Energy_SLE_Solver_New( Name name, Bool useStatSolve, int statReps ) {
+ Energy_SLE_Solver* self = (Energy_SLE_Solver*) Energy_SLE_Solver_DefaultNew( name );
+
+ Energy_SLE_Solver_InitAll( self, useStatSolve, statReps ) ;
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+Energy_SLE_Solver* _Energy_SLE_Solver_New( ENERGY_SLE_SOLVER_DEFARGS )
+{
+ Energy_SLE_Solver* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(Energy_SLE_Solver) );
+ self = (Energy_SLE_Solver*) _SLE_Solver_New( SLE_SOLVER_PASSARGS );
+
+ /* Virtual info */
+ return self;
+}
+
+/* Initialisation implementation */
+void _Energy_SLE_Solver_Init( Energy_SLE_Solver* self ) {
+ self->isConstructed = True;
+ self->residual = NULL;
+ //self->matrixSolver = NULL;
+ self->matrixSolver = PETSC_NULL;
+}
+void Energy_SLE_Solver_InitAll( Energy_SLE_Solver* solver, Bool useStatSolve, int statReps ) {
+ Energy_SLE_Solver* self = (Energy_SLE_Solver*)solver;
+
+ SLE_Solver_InitAll( self, useStatSolve, statReps );
+}
+
+void _Energy_SLE_Solver_Delete( void* sle ) {
+ Energy_SLE_Solver* self = (Energy_SLE_Solver*)sle;
+
+ //FreeObject( self->matrixSolver );
+ KSPDestroy( self->matrixSolver );
+
+ if( self->residual != PETSC_NULL ) {
+ //FreeObject( self->residual );
+ VecDestroy( self->residual );
+ }
+}
+
+void _Energy_SLE_Solver_Print( void* solver, Stream* stream ) {
+ Energy_SLE_Solver* self = (Energy_SLE_Solver*)solver;
+
+ /* Set the Journal for printing informations */
+ Stream* standard_SLE_SolverStream = stream;
+
+ /* General info */
+ Journal_Printf( standard_SLE_SolverStream, "Energy_SLE_Solver (ptr): %p\n", self );
+
+ /* other info */
+ Journal_Printf( standard_SLE_SolverStream, "\tmatrixSolver (ptr): %p", self->matrixSolver );
+}
+
+
+void* _Energy_SLE_Solver_Copy( const void* standardSleSolver, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ Energy_SLE_Solver* self = (Energy_SLE_Solver*)standardSleSolver;
+ Energy_SLE_Solver* newEnergySleSolver;
+
+ newEnergySleSolver = (Energy_SLE_Solver*)_SLE_Solver_Copy( self, dest, deep, nameExt, ptrMap );
+
+ newEnergySleSolver->matrixSolver = self->matrixSolver;
+
+ return (void*)newEnergySleSolver;
+}
+
+void _Energy_SLE_Solver_AssignFromXML( void* sleSolver, Stg_ComponentFactory* cf, void* data ) {
+ Energy_SLE_Solver *self = (Energy_SLE_Solver*)sleSolver;
+
+ assert( self && Stg_CheckType( self, Energy_SLE_Solver ) );
+ assert( cf && Stg_CheckType( cf, Stg_ComponentFactory ) );
+
+ _SLE_Solver_AssignFromXML( self, cf, data );
+}
+
+/* Build */
+void _Energy_SLE_Solver_Build( void* sleSolver, void* standardSLE ) {
+ Energy_SLE_Solver* self = (Energy_SLE_Solver*)sleSolver;
+ SystemLinearEquations* sle = (SystemLinearEquations*) standardSLE;
+ StiffnessMatrix* stiffMat = (StiffnessMatrix*)sle->stiffnessMatrices->data[0];
+
+ Journal_DPrintf( self->debug, "In %s()\n", __func__ );
+ Stream_IndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
+ Journal_DPrintf( self->debug, "building a standard L.A. solver for the \"%s\" matrix.\n", stiffMat->name );
+
+ Stg_Component_Build( stiffMat, standardSLE, False );
+
+ if( self->matrixSolver == PETSC_NULL )
+ KSPCreate( sle->comm, &self->matrixSolver );
+
+ Stream_UnIndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
+}
+
+
+void _Energy_SLE_Solver_Initialise( void* sleSolver, void* standardSLE ) {
+ Energy_SLE_Solver* self = (Energy_SLE_Solver*)sleSolver;
+ SystemLinearEquations* sle = (SystemLinearEquations*) standardSLE;
+
+ /* Initialise parent. */
+ _SLE_Solver_Initialise( self, sle );
+}
+
+void _Energy_SLE_Solver_Execute( void* sleSolver, void* data ) {
+}
+
+void _Energy_SLE_Solver_Destroy( void* sleSolver, void* data ) {
+}
+
+void _Energy_SLE_Solver_SolverSetup( void* sleSolver, void* standardSLE ) {
+ Energy_SLE_Solver* self = (Energy_SLE_Solver*)sleSolver;
+ SystemLinearEquations* sle = (SystemLinearEquations*) standardSLE;
+ StiffnessMatrix* stiffMat = (StiffnessMatrix*)sle->stiffnessMatrices->data[0];
+
+ Journal_DPrintf( self->debug, "In %s()\n", __func__ );
+ Stream_IndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
+
+ Journal_DPrintf( self->debug, "Initialising the L.A. solver for the \"%s\" matrix.\n", stiffMat->name );
+ KSPSetOperators( self->matrixSolver, stiffMat->matrix, stiffMat->matrix, DIFFERENT_NONZERO_PATTERN );
+ Stream_UnIndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
+
+ if( self->maxIterations > 0 ) {
+ KSPSetTolerances( self->matrixSolver, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, self->maxIterations );
+ }
+
+ VecDuplicate( ((ForceVector**)sle->forceVectors->data)[0]->vector, &self->residual );
+}
+
+
+void _Energy_SLE_Solver_Solve( void* sleSolver, void* standardSLE ) {
+ Energy_SLE_Solver* self = (Energy_SLE_Solver*)sleSolver;
+ SystemLinearEquations* sle = (SystemLinearEquations*) standardSLE;
+ Iteration_Index iterations;
+ PetscTruth isNull;
+ MatNullSpace nsp;
+
+
+ Journal_DPrintf( self->debug, "In %s - for standard SLE solver\n", __func__ );
+ Stream_IndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
+
+ if ( (sle->stiffnessMatrices->count > 1 ) ||
+ (sle->forceVectors->count > 1 ) )
+ {
+ Stream* warning = Stream_RegisterChild( StgFEM_Warning, self->type );
+ Journal_Printf( warning, "Warning: Energy solver unable to solve more that one matrix/vector.\n" );
+ }
+
+ if ( sle->solutionVectors->count > 1 ) {
+ Stream* warning = Stream_RegisterChild( StgFEM_Warning, self->type );
+ Journal_Printf( warning, "Warning: More than 1 solution vector provided to standard sle. Ignoring second and subsequent"
+ " solution vectors.\n" );
+ }
+
+ isNull = Energy_SLE_HasNullSpace(((StiffnessMatrix**)sle->stiffnessMatrices->data)[0]->matrix);
+ if(isNull) {
+ MatNullSpaceCreate(PETSC_COMM_WORLD, PETSC_TRUE, 0, PETSC_NULL, &nsp);
+ KSPSetNullSpace(self->matrixSolver, nsp);
+ }
+
+ KSPSolve( self->matrixSolver,
+ ((ForceVector*) sle->forceVectors->data[0])->vector,
+ ((SolutionVector*) sle->solutionVectors->data[0])->vector );
+ KSPGetIterationNumber( self->matrixSolver, (PetscInt*)(&iterations) );
+
+ Journal_DPrintf( self->debug, "Solved after %u iterations.\n", iterations );
+ Stream_UnIndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
+
+ /* calculate the residual */
+ /* TODO: need to make this optional */
+ MatMult( ((StiffnessMatrix**)sle->stiffnessMatrices->data)[0]->matrix,
+ ((SolutionVector**)sle->solutionVectors->data)[0]->vector,
+ self->residual );
+ VecAYPX( self->residual, -1.0, ((ForceVector**)sle->forceVectors->data)[0]->vector );
+
+ if(isNull)
+ MatNullSpaceDestroy(nsp);
+}
+
+
+Vec _Energy_SLE_GetResidual( void* sleSolver, Index fv_I ) {
+ Energy_SLE_Solver* self = (Energy_SLE_Solver*)sleSolver;
+
+ return self->residual;
+}
+
+PetscTruth Energy_SLE_HasNullSpace( Mat A ) {
+ PetscInt N;
+ PetscScalar sum;
+ PetscReal nrm;
+ PetscTruth isNull;
+ Vec r, l;
+
+ MatGetVecs(A, &r, &l); /* l = A r */
+
+ VecGetSize(r, &N);
+ sum = 1.0/(PetscScalar)N;
+ VecSet(r, sum);
+
+ MatMult(A, r, l); /* {l} = [A] {r} */
+
+ VecNorm(l, NORM_2, &nrm);
+ if(nrm < 1.e-7)
+ isNull = PETSC_TRUE;
+ else
+ isNull = PETSC_FALSE;
+
+ VecDestroy(l);
+ VecDestroy(r);
+
+ return isNull;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/Energy/src/Finalise.c
--- a/SLE/ProvidedSystems/Energy/src/Finalise.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "types.h"
-#include "Finalise.h"
-
-#include <stdio.h>
-
-Bool StgFEM_SLE_ProvidedSystems_Energy_Finalise( void ) {
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- Stream_IndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
- Stream_UnIndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/Energy/src/Finalise.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/Energy/src/Finalise.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,60 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "types.h"
+#include "Finalise.h"
+
+#include <stdio.h>
+
+Bool StgFEM_SLE_ProvidedSystems_Energy_Finalise( void ) {
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ Stream_IndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
+ Stream_UnIndentBranch( StgFEM_SLE_ProvidedSystems_Energy_Debug );
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/Energy/src/Init.c
--- a/SLE/ProvidedSystems/Energy/src/Init.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "types.h"
-#include "Init.h"
-
-#include "Energy_SLE_Solver.h"
-#include "Energy_SLE.h"
-#include <stdio.h>
-
-Stream* StgFEM_SLE_ProvidedSystems_Energy_Debug = NULL;
-
-/** Initialises the Linear Algebra package, then any init for this package
-such as streams etc */
-Bool StgFEM_SLE_ProvidedSystems_Energy_Init( int* argc, char** argv[] ) {
-
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- /* initialise this level's streams */
- StgFEM_SLE_ProvidedSystems_Energy_Debug = Stream_RegisterChild( StgFEM_SLE_Debug, "ProvidedSystems_Energy" );
-
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), Energy_SLE_Solver_Type , (Name)"0", Energy_SLE_Solver_DefaultNew );
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ), Energy_SLE_Type , "0", _Energy_SLE_DefaultNew );
-
- RegisterParent( Energy_SLE_Type, SystemLinearEquations_Type );
- RegisterParent( Energy_SLE_Solver_Type, SLE_Solver_Type );
-
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/Energy/src/Init.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/Energy/src/Init.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,74 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "types.h"
+#include "Init.h"
+
+#include "Energy_SLE_Solver.h"
+#include "Energy_SLE.h"
+#include <stdio.h>
+
+Stream* StgFEM_SLE_ProvidedSystems_Energy_Debug = NULL;
+
+/** Initialises the Linear Algebra package, then any init for this package
+such as streams etc */
+Bool StgFEM_SLE_ProvidedSystems_Energy_Init( int* argc, char** argv[] ) {
+
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ /* initialise this level's streams */
+ StgFEM_SLE_ProvidedSystems_Energy_Debug = Stream_RegisterChild( StgFEM_SLE_Debug, "ProvidedSystems_Energy" );
+
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), Energy_SLE_Solver_Type , (Name)"0", Energy_SLE_Solver_DefaultNew );
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ), Energy_SLE_Type , "0", _Energy_SLE_DefaultNew );
+
+ RegisterParent( Energy_SLE_Type, SystemLinearEquations_Type );
+ RegisterParent( Energy_SLE_Solver_Type, SLE_Solver_Type );
+
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/Finalise.c
--- a/SLE/ProvidedSystems/StokesFlow/src/Finalise.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "types.h"
-#include "Finalise.h"
-
-#include <stdio.h>
-
-Bool StgFEM_SLE_ProvidedSystems_StokesFlow_Finalise( void ) {
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- Stream_IndentBranch( StgFEM_SLE_ProvidedSystems_StokesFlow_Debug );
- Stream_UnIndentBranch( StgFEM_SLE_ProvidedSystems_StokesFlow_Debug );
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/Finalise.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/StokesFlow/src/Finalise.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,60 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "types.h"
+#include "Finalise.h"
+
+#include <stdio.h>
+
+Bool StgFEM_SLE_ProvidedSystems_StokesFlow_Finalise( void ) {
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ Stream_IndentBranch( StgFEM_SLE_ProvidedSystems_StokesFlow_Debug );
+ Stream_UnIndentBranch( StgFEM_SLE_ProvidedSystems_StokesFlow_Debug );
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/Init.c
--- a/SLE/ProvidedSystems/StokesFlow/src/Init.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-
-#include "StokesFlow.h"
-
-#include <stdio.h>
-
-Stream* StgFEM_SLE_ProvidedSystems_StokesFlow_Debug = NULL;
-
-/** Initialises the Linear Algebra package, then any init for this package
-such as streams etc */
-Bool StgFEM_SLE_ProvidedSystems_StokesFlow_Init( int* argc, char** argv[] ) {
-
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- /* initialise this level's streams */
- StgFEM_SLE_ProvidedSystems_StokesFlow_Debug = Stream_RegisterChild( StgFEM_SLE_Debug,
- "ProvidedSystems_StokesFlow" );
-
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), Stokes_SLE_Type , (Name)"0", _Stokes_SLE_DefaultNew );
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ), Stokes_SLE_UzawaSolver_Type , "0", _Stokes_SLE_UzawaSolver_DefaultNew );
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), Stokes_SLE_PenaltySolver_Type , (Name)"0", Stokes_SLE_PenaltySolver_DefaultNew );
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ), UzawaPreconditionerTerm_Type , "0", _UzawaPreconditionerTerm_DefaultNew );
-
- RegisterParent( Stokes_SLE_Type, SystemLinearEquations_Type );
- RegisterParent( Stokes_SLE_PenaltySolver_Type, SLE_Solver_Type );
- RegisterParent( Stokes_SLE_UzawaSolver_Type, SLE_Solver_Type );
- RegisterParent( UzawaPreconditionerTerm_Type, StiffnessMatrixTerm_Type );
-
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/Init.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/StokesFlow/src/Init.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,77 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+
+#include "StokesFlow.h"
+
+#include <stdio.h>
+
+Stream* StgFEM_SLE_ProvidedSystems_StokesFlow_Debug = NULL;
+
+/** Initialises the Linear Algebra package, then any init for this package
+such as streams etc */
+Bool StgFEM_SLE_ProvidedSystems_StokesFlow_Init( int* argc, char** argv[] ) {
+
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ /* initialise this level's streams */
+ StgFEM_SLE_ProvidedSystems_StokesFlow_Debug = Stream_RegisterChild( StgFEM_SLE_Debug,
+ "ProvidedSystems_StokesFlow" );
+
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), Stokes_SLE_Type , (Name)"0", _Stokes_SLE_DefaultNew );
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ), Stokes_SLE_UzawaSolver_Type , "0", _Stokes_SLE_UzawaSolver_DefaultNew );
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), Stokes_SLE_PenaltySolver_Type , (Name)"0", Stokes_SLE_PenaltySolver_DefaultNew );
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ), UzawaPreconditionerTerm_Type , "0", _UzawaPreconditionerTerm_DefaultNew );
+
+ RegisterParent( Stokes_SLE_Type, SystemLinearEquations_Type );
+ RegisterParent( Stokes_SLE_PenaltySolver_Type, SLE_Solver_Type );
+ RegisterParent( Stokes_SLE_UzawaSolver_Type, SLE_Solver_Type );
+ RegisterParent( UzawaPreconditionerTerm_Type, StiffnessMatrixTerm_Type );
+
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE.c
--- a/SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,239 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Stokes_SLE.c 999 2008-01-09 04:13:42Z DavidLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "types.h"
-#include "Stokes_SLE.h"
-#include "UpdateDt.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-/* Textual name of this class */
-const Type Stokes_SLE_Type = "Stokes_SLE";
-
-Stokes_SLE* Stokes_SLE_New(
- Name name,
- SLE_Solver* solver,
- FiniteElementContext* context,
- Bool isNonLinear,
- double nonLinearTolerance,
- Iteration_Index nonLinearMaxIterations,
- Bool killNonConvergent,
- EntryPoint_Register* entryPoint_Register,
- MPI_Comm comm,
- StiffnessMatrix* kStiffMat,
- StiffnessMatrix* gStiffMat,
- StiffnessMatrix* dStiffMat,
- StiffnessMatrix* cStiffMat,
- SolutionVector* uSolnVec,
- SolutionVector* pSolnVec,
- ForceVector* fForceVec,
- ForceVector* hForceVec )
-{
- Stokes_SLE* self = (Stokes_SLE*) _Stokes_SLE_DefaultNew( name );
-
- self->isConstructed = True;
- _SystemLinearEquations_Init( self, solver, NULL, context, False, isNonLinear,
- nonLinearTolerance, nonLinearMaxIterations, killNonConvergent, 1, "", "", entryPoint_Register, comm );
- _Stokes_SLE_Init( self, kStiffMat, gStiffMat, dStiffMat, cStiffMat, uSolnVec, pSolnVec, fForceVec, hForceVec );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-Stokes_SLE* _Stokes_SLE_New( STOKES_SLE_DEFARGS )
-{
- Stokes_SLE* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(Stokes_SLE) );
- self = (Stokes_SLE*) _SystemLinearEquations_New( SYSTEMLINEAREQUATIONS_PASSARGS );
-
- /* Virtual info */
-
- return self;
-}
-
-void _Stokes_SLE_Init(
- void* sle,
- StiffnessMatrix* kStiffMat,
- StiffnessMatrix* gStiffMat,
- StiffnessMatrix* dStiffMat,
- StiffnessMatrix* cStiffMat,
- SolutionVector* uSolnVec,
- SolutionVector* pSolnVec,
- ForceVector* fForceVec,
- ForceVector* hForceVec )
-{
- Stokes_SLE* self = (Stokes_SLE*)sle;
-
- self->kStiffMat = kStiffMat;
- self->gStiffMat = gStiffMat;
- self->dStiffMat = dStiffMat;
- self->cStiffMat = cStiffMat;
- self->uSolnVec = uSolnVec;
- self->pSolnVec = pSolnVec;
- self->fForceVec = fForceVec;
- self->hForceVec = hForceVec;
-
- /* add the vecs and matrices to the Base SLE class's dynamic lists, so they can be
- initialised and built properly */
- SystemLinearEquations_AddStiffnessMatrix( self, kStiffMat );
- SystemLinearEquations_AddStiffnessMatrix( self, gStiffMat );
-
- if ( dStiffMat )
- SystemLinearEquations_AddStiffnessMatrix( self, dStiffMat );
- if ( cStiffMat )
- SystemLinearEquations_AddStiffnessMatrix( self, cStiffMat );
-
- SystemLinearEquations_AddSolutionVector( self, uSolnVec );
- SystemLinearEquations_AddSolutionVector( self, pSolnVec );
- SystemLinearEquations_AddForceVector( self, fForceVec );
- SystemLinearEquations_AddForceVector( self, hForceVec );
-
- /* Put timestep function onto entry point */
- if ( self->context )
- EP_AppendClassHook( self->context->calcDtEP, Stokes_SLE_UpdateDt, self );
-}
-
-void _Stokes_SLE_Print( void* sle, Stream* stream ) {
- Stokes_SLE* self = (Stokes_SLE*)sle;
- /* Set the Journal for printing informations */
-
- /* General info */
- Journal_Printf( stream, "Stokes_SLE (ptr): %p\n", self );
- _SystemLinearEquations_Print( self, stream );
-
- Journal_Printf( stream, "Name of discrete stress tensor (K) matrix = \"%s\" \n",self->kStiffMat->name );
- Journal_Printf( stream, "Name of discrete gradient (G) matrix = \"%s\" \n",self->gStiffMat->name );
- if (self->dStiffMat) {
- Journal_Printf( stream, "Name of discrete divergence (D) matrix = \"%s\" \n",self->dStiffMat->name );
- }
- else {
- Journal_Printf( stream, "No discrete divergence (D) matrix set up (Symmetric geometry).\n" );
- }
- if (self->cStiffMat) {
- Journal_Printf( stream, "Name of compressibility (C) matrix = \"%s\" \n",self->cStiffMat->name );
- }
- else {
- Journal_Printf( stream, "No compressibility (C) matrix set up (incompressible fluids)\n" );
- }
- Journal_Printf( stream, "Name of velocity (u) vector = \"%s\" \n",self->uSolnVec->name );
- Journal_Printf( stream, "Name of pressure (p) vector = \"%s\" \n",self->pSolnVec->name );
-
- Stg_Class_Print( self->solver, stream );
-}
-
-void* _Stokes_SLE_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(Stokes_SLE);
- Type type = Stokes_SLE_Type;
- Stg_Class_DeleteFunction* _delete = _SystemLinearEquations_Delete;
- Stg_Class_PrintFunction* _print = _Stokes_SLE_Print;
- Stg_Class_CopyFunction* _copy = _SystemLinearEquations_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _Stokes_SLE_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _Stokes_SLE_AssignFromXML;
- Stg_Component_BuildFunction* _build = _SystemLinearEquations_Build;
- Stg_Component_InitialiseFunction* _initialise = _SystemLinearEquations_Initialise;
- Stg_Component_ExecuteFunction* _execute = _SystemLinearEquations_Execute;
- Stg_Component_DestroyFunction* _destroy = _SystemLinearEquations_Destroy;
- SystemLinearEquations_LM_SetupFunction* _LM_Setup = _SystemLinearEquations_LM_Setup;
- SystemLinearEquations_MatrixSetupFunction* _matrixSetup = _SystemLinearEquations_MatrixSetup;
- SystemLinearEquations_VectorSetupFunction* _vectorSetup = _SystemLinearEquations_VectorSetup;
- SystemLinearEquations_UpdateSolutionOntoNodesFunc* _updateSolutionOntoNodes = _SystemLinearEquations_UpdateSolutionOntoNodes;
- SystemLinearEquations_MG_SelectStiffMatsFunc* _mgSelectStiffMats = _Stokes_SLE_MG_SelectStiffMats;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_Stokes_SLE_New( STOKES_SLE_PASSARGS );
-}
-
-void _Stokes_SLE_AssignFromXML( void* sle, Stg_ComponentFactory* cf, void* data ) {
- Stokes_SLE* self = (Stokes_SLE*)sle;
- StiffnessMatrix* kStiffMat;
- StiffnessMatrix* gStiffMat;
- StiffnessMatrix* dStiffMat;
- StiffnessMatrix* cStiffMat;
- SolutionVector* uSolnVec;
- SolutionVector* pSolnVec;
- ForceVector* fForceVec;
- ForceVector* hForceVec;
-
- /* Construct Parent */
- _SystemLinearEquations_AssignFromXML( self, cf, data );
-
- kStiffMat = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"StressTensorMatrix", StiffnessMatrix, True, data );
- gStiffMat = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"GradientMatrix", StiffnessMatrix, True, data );
- dStiffMat = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"DivergenceMatrix", StiffnessMatrix, False, data );
- cStiffMat = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"CompressibilityMatrix", StiffnessMatrix, False, data );
-
- uSolnVec = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"VelocityVector", SolutionVector, True, data );
- pSolnVec = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"PressureVector", SolutionVector, True, data );
-
- fForceVec = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ForceVector", ForceVector, True, data );
- hForceVec = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ContinuityForceVector", ForceVector, True, data );
-
- _Stokes_SLE_Init( self, kStiffMat, gStiffMat, dStiffMat, cStiffMat, uSolnVec, pSolnVec, fForceVec, hForceVec );
-}
-
-
-void _Stokes_SLE_MG_SelectStiffMats( void* _sle, unsigned* nSMs, StiffnessMatrix*** sms ) {
- Stokes_SLE* self = (Stokes_SLE*)_sle;
-
- /*
- ** In this implementation, only the velocity matrix will have MG applied.
- */
-
- *nSMs = 1;
- *sms = Memory_Alloc_Array( StiffnessMatrix*, 1, "Stokes_SLE" );
- (*sms)[0] = self->kStiffMat;
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,239 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Stokes_SLE.c 999 2008-01-09 04:13:42Z DavidLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "types.h"
+#include "Stokes_SLE.h"
+#include "UpdateDt.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+/* Textual name of this class */
+const Type Stokes_SLE_Type = "Stokes_SLE";
+
+Stokes_SLE* Stokes_SLE_New(
+ Name name,
+ SLE_Solver* solver,
+ FiniteElementContext* context,
+ Bool isNonLinear,
+ double nonLinearTolerance,
+ Iteration_Index nonLinearMaxIterations,
+ Bool killNonConvergent,
+ EntryPoint_Register* entryPoint_Register,
+ MPI_Comm comm,
+ StiffnessMatrix* kStiffMat,
+ StiffnessMatrix* gStiffMat,
+ StiffnessMatrix* dStiffMat,
+ StiffnessMatrix* cStiffMat,
+ SolutionVector* uSolnVec,
+ SolutionVector* pSolnVec,
+ ForceVector* fForceVec,
+ ForceVector* hForceVec )
+{
+ Stokes_SLE* self = (Stokes_SLE*) _Stokes_SLE_DefaultNew( name );
+
+ self->isConstructed = True;
+ _SystemLinearEquations_Init( self, solver, NULL, context, False, isNonLinear,
+ nonLinearTolerance, nonLinearMaxIterations, killNonConvergent, 1, "", "", entryPoint_Register, comm );
+ _Stokes_SLE_Init( self, kStiffMat, gStiffMat, dStiffMat, cStiffMat, uSolnVec, pSolnVec, fForceVec, hForceVec );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+Stokes_SLE* _Stokes_SLE_New( STOKES_SLE_DEFARGS )
+{
+ Stokes_SLE* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(Stokes_SLE) );
+ self = (Stokes_SLE*) _SystemLinearEquations_New( SYSTEMLINEAREQUATIONS_PASSARGS );
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _Stokes_SLE_Init(
+ void* sle,
+ StiffnessMatrix* kStiffMat,
+ StiffnessMatrix* gStiffMat,
+ StiffnessMatrix* dStiffMat,
+ StiffnessMatrix* cStiffMat,
+ SolutionVector* uSolnVec,
+ SolutionVector* pSolnVec,
+ ForceVector* fForceVec,
+ ForceVector* hForceVec )
+{
+ Stokes_SLE* self = (Stokes_SLE*)sle;
+
+ self->kStiffMat = kStiffMat;
+ self->gStiffMat = gStiffMat;
+ self->dStiffMat = dStiffMat;
+ self->cStiffMat = cStiffMat;
+ self->uSolnVec = uSolnVec;
+ self->pSolnVec = pSolnVec;
+ self->fForceVec = fForceVec;
+ self->hForceVec = hForceVec;
+
+ /* add the vecs and matrices to the Base SLE class's dynamic lists, so they can be
+ initialised and built properly */
+ SystemLinearEquations_AddStiffnessMatrix( self, kStiffMat );
+ SystemLinearEquations_AddStiffnessMatrix( self, gStiffMat );
+
+ if ( dStiffMat )
+ SystemLinearEquations_AddStiffnessMatrix( self, dStiffMat );
+ if ( cStiffMat )
+ SystemLinearEquations_AddStiffnessMatrix( self, cStiffMat );
+
+ SystemLinearEquations_AddSolutionVector( self, uSolnVec );
+ SystemLinearEquations_AddSolutionVector( self, pSolnVec );
+ SystemLinearEquations_AddForceVector( self, fForceVec );
+ SystemLinearEquations_AddForceVector( self, hForceVec );
+
+ /* Put timestep function onto entry point */
+ if ( self->context )
+ EP_AppendClassHook( self->context->calcDtEP, Stokes_SLE_UpdateDt, self );
+}
+
+void _Stokes_SLE_Print( void* sle, Stream* stream ) {
+ Stokes_SLE* self = (Stokes_SLE*)sle;
+ /* Set the Journal for printing informations */
+
+ /* General info */
+ Journal_Printf( stream, "Stokes_SLE (ptr): %p\n", self );
+ _SystemLinearEquations_Print( self, stream );
+
+ Journal_Printf( stream, "Name of discrete stress tensor (K) matrix = \"%s\" \n",self->kStiffMat->name );
+ Journal_Printf( stream, "Name of discrete gradient (G) matrix = \"%s\" \n",self->gStiffMat->name );
+ if (self->dStiffMat) {
+ Journal_Printf( stream, "Name of discrete divergence (D) matrix = \"%s\" \n",self->dStiffMat->name );
+ }
+ else {
+ Journal_Printf( stream, "No discrete divergence (D) matrix set up (Symmetric geometry).\n" );
+ }
+ if (self->cStiffMat) {
+ Journal_Printf( stream, "Name of compressibility (C) matrix = \"%s\" \n",self->cStiffMat->name );
+ }
+ else {
+ Journal_Printf( stream, "No compressibility (C) matrix set up (incompressible fluids)\n" );
+ }
+ Journal_Printf( stream, "Name of velocity (u) vector = \"%s\" \n",self->uSolnVec->name );
+ Journal_Printf( stream, "Name of pressure (p) vector = \"%s\" \n",self->pSolnVec->name );
+
+ Stg_Class_Print( self->solver, stream );
+}
+
+void* _Stokes_SLE_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(Stokes_SLE);
+ Type type = Stokes_SLE_Type;
+ Stg_Class_DeleteFunction* _delete = _SystemLinearEquations_Delete;
+ Stg_Class_PrintFunction* _print = _Stokes_SLE_Print;
+ Stg_Class_CopyFunction* _copy = _SystemLinearEquations_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _Stokes_SLE_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _Stokes_SLE_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _SystemLinearEquations_Build;
+ Stg_Component_InitialiseFunction* _initialise = _SystemLinearEquations_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _SystemLinearEquations_Execute;
+ Stg_Component_DestroyFunction* _destroy = _SystemLinearEquations_Destroy;
+ SystemLinearEquations_LM_SetupFunction* _LM_Setup = _SystemLinearEquations_LM_Setup;
+ SystemLinearEquations_MatrixSetupFunction* _matrixSetup = _SystemLinearEquations_MatrixSetup;
+ SystemLinearEquations_VectorSetupFunction* _vectorSetup = _SystemLinearEquations_VectorSetup;
+ SystemLinearEquations_UpdateSolutionOntoNodesFunc* _updateSolutionOntoNodes = _SystemLinearEquations_UpdateSolutionOntoNodes;
+ SystemLinearEquations_MG_SelectStiffMatsFunc* _mgSelectStiffMats = _Stokes_SLE_MG_SelectStiffMats;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_Stokes_SLE_New( STOKES_SLE_PASSARGS );
+}
+
+void _Stokes_SLE_AssignFromXML( void* sle, Stg_ComponentFactory* cf, void* data ) {
+ Stokes_SLE* self = (Stokes_SLE*)sle;
+ StiffnessMatrix* kStiffMat;
+ StiffnessMatrix* gStiffMat;
+ StiffnessMatrix* dStiffMat;
+ StiffnessMatrix* cStiffMat;
+ SolutionVector* uSolnVec;
+ SolutionVector* pSolnVec;
+ ForceVector* fForceVec;
+ ForceVector* hForceVec;
+
+ /* Construct Parent */
+ _SystemLinearEquations_AssignFromXML( self, cf, data );
+
+ kStiffMat = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"StressTensorMatrix", StiffnessMatrix, True, data );
+ gStiffMat = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"GradientMatrix", StiffnessMatrix, True, data );
+ dStiffMat = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"DivergenceMatrix", StiffnessMatrix, False, data );
+ cStiffMat = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"CompressibilityMatrix", StiffnessMatrix, False, data );
+
+ uSolnVec = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"VelocityVector", SolutionVector, True, data );
+ pSolnVec = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"PressureVector", SolutionVector, True, data );
+
+ fForceVec = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ForceVector", ForceVector, True, data );
+ hForceVec = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ContinuityForceVector", ForceVector, True, data );
+
+ _Stokes_SLE_Init( self, kStiffMat, gStiffMat, dStiffMat, cStiffMat, uSolnVec, pSolnVec, fForceVec, hForceVec );
+}
+
+
+void _Stokes_SLE_MG_SelectStiffMats( void* _sle, unsigned* nSMs, StiffnessMatrix*** sms ) {
+ Stokes_SLE* self = (Stokes_SLE*)_sle;
+
+ /*
+ ** In this implementation, only the velocity matrix will have MG applied.
+ */
+
+ *nSMs = 1;
+ *sms = Memory_Alloc_Array( StiffnessMatrix*, 1, "Stokes_SLE" );
+ (*sms)[0] = self->kStiffMat;
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_PenaltySolver.c
--- a/SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_PenaltySolver.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,304 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Stokes_SLE_PenaltySolver.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "types.h"
-#include "Stokes_SLE_PenaltySolver.h"
-
-#include <assert.h>
-#include <string.h>
-
-#include "Stokes_SLE.h"
-
-const Type Stokes_SLE_PenaltySolver_Type = "Stokes_SLE_PenaltySolver";
-
-void* Stokes_SLE_PenaltySolver_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(Stokes_SLE_PenaltySolver);
- Type type = Stokes_SLE_PenaltySolver_Type;
- Stg_Class_DeleteFunction* _delete = _Stokes_SLE_PenaltySolver_Delete;
- Stg_Class_PrintFunction* _print = _Stokes_SLE_PenaltySolver_Print;
- Stg_Class_CopyFunction* _copy = _Stokes_SLE_PenaltySolver_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = Stokes_SLE_PenaltySolver_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _Stokes_SLE_PenaltySolver_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Stokes_SLE_PenaltySolver_Build;
- Stg_Component_InitialiseFunction* _initialise = _SLE_Solver_Initialise;
- Stg_Component_ExecuteFunction* _execute = _SLE_Solver_Execute;
- Stg_Component_DestroyFunction* _destroy = _SLE_Solver_Destroy;
- SLE_Solver_SolverSetupFunction* _solverSetup = _Stokes_SLE_PenaltySolver_SolverSetup;
- SLE_Solver_SolveFunction* _solve = _Stokes_SLE_PenaltySolver_Solve;
- SLE_Solver_GetResidualFunc* _getResidual = _Stokes_SLE_PenaltySolver_GetResidual;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _Stokes_SLE_PenaltySolver_New( STOKES_SLE_PENALTYSOLVER_PASSARGS );
-}
-
-Stokes_SLE_PenaltySolver* Stokes_SLE_PenaltySolver_New(
- Name name,
- Bool useStatSolve,
- int statReps )
-{
- Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*) Stokes_SLE_PenaltySolver_DefaultNew( name );
-
- Stokes_SLE_PenaltySolver_InitAll( self, useStatSolve, statReps );
-
- return self;
-}
-
-
-/* Creation implementation / Virtual constructor */
-Stokes_SLE_PenaltySolver* _Stokes_SLE_PenaltySolver_New( STOKES_SLE_PENALTYSOLVER_DEFARGS )
-{
- Stokes_SLE_PenaltySolver* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(Stokes_SLE_PenaltySolver) );
- self = (Stokes_SLE_PenaltySolver*) _SLE_Solver_New( SLE_SOLVER_PASSARGS );
-
- /* Virtual info */
- return self;
-}
-
-
-void _Stokes_SLE_PenaltySolver_Init( void* solver ) {
- Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver;
-
- self->isConstructed = True;
-}
-
-void Stokes_SLE_PenaltySolver_InitAll(
- void* solver,
- Bool useStatSolve,
- int statReps )
-{
- Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver;
-
- SLE_Solver_InitAll( self, useStatSolve, statReps );
- _Stokes_SLE_PenaltySolver_Init( self );
-}
-
-
-void _Stokes_SLE_PenaltySolver_Delete( void* solver ) {
- Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver;
-
- Journal_DPrintf( self->debug, "In: %s \n", __func__);
-
- Stream_IndentBranch( StgFEM_Debug );
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _Stokes_SLE_PenaltySolver_Print( void* solver, Stream* stream ) {
- Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver;
-
- _SLE_Solver_Print( self, stream );
-}
-
-
-void* _Stokes_SLE_PenaltySolver_Copy( const void* stokesSlePenaltySolver, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)stokesSlePenaltySolver;
- Stokes_SLE_PenaltySolver* newStokesSlePenaltySolver;
-
- newStokesSlePenaltySolver = (Stokes_SLE_PenaltySolver*)_SLE_Solver_Copy( self, dest, deep, nameExt, ptrMap );
-
- return (void*) newStokesSlePenaltySolver;
-}
-
-
-void _Stokes_SLE_PenaltySolver_Build( void* solver, void* stokesSLE ) {
- Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-void _Stokes_SLE_PenaltySolver_AssignFromXML( void* solver, Stg_ComponentFactory* cf, void* data ) {
- Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*) solver;
-
- _SLE_Solver_AssignFromXML( self, cf, data );
-
- _Stokes_SLE_PenaltySolver_Init( self );
-}
-
-void _Stokes_SLE_PenaltySolver_Execute( void* solver, void* data ) {
-}
-
-void _Stokes_SLE_PenaltySolver_Destroy( void* solver, void* data ) {
-}
-
-void _Stokes_SLE_PenaltySolver_Initialise( void* solver, void* stokesSLE ) {
- Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*) solver;
- Stokes_SLE* sle = (Stokes_SLE*) stokesSLE;
-
- /* Initialise Parent */
- _SLE_Solver_Initialise( self, sle );
-}
-
-/* SolverSetup */
-void _Stokes_SLE_PenaltySolver_SolverSetup( void* solver, void* stokesSLE ) {
- Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*) solver;
-
- Journal_DPrintf( self->debug, "In %s:\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _Stokes_SLE_PenaltySolver_Solve( void* solver,void* stokesSLE ) {
- Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver;
- Stokes_SLE* sle = (Stokes_SLE*)stokesSLE;
- /* Create shortcuts to stuff needed on sle */
- Mat kMatrix = sle->kStiffMat->matrix;
- Mat gradMat = sle->gStiffMat->matrix;
- Mat divMat = NULL;
- Mat C_Mat = sle->cStiffMat->matrix;
- Vec uVec = sle->uSolnVec->vector;
- Vec pVec = sle->pSolnVec->vector;
- Vec fVec = sle->fForceVec->vector;
- Vec hVec = sle->hForceVec->vector;
- Vec hTempVec;
- Vec fTempVec;
- Mat GTrans;
- KSP sles_v;
- double negOne=-1.0;
- double one=1.0;
- Mat kHat;
- Mat C_InvMat;
- Vec diagC;
- PC pc;
-
- Journal_DPrintf( self->debug, "In %s():\n", __func__ );
-
- VecDuplicate( hVec, &hTempVec );
- VecDuplicate( fVec, &fTempVec );
- VecDuplicate( pVec, &diagC );
-
- if( sle->dStiffMat == NULL ) {
- Journal_DPrintf( self->debug, "Div matrix == NULL : Problem is assumed to be symmetric. ie Div = GTrans \n");
-#if( PETSC_VERSION_MAJOR <= 2 )
- MatTranspose( gradMat, >rans );
-#else
- MatTranspose( gradMat, MAT_INITIAL_MATRIX, >rans );
-#endif
- divMat = GTrans;
- }
- else {
- /* make a copy we can play with */
- MatCreate( sle->comm, >rans );
- MatCopy( sle->dStiffMat->matrix, GTrans, DIFFERENT_NONZERO_PATTERN );
- divMat = GTrans;
- }
-
- /* Create CInv */
- MatGetDiagonal( C_Mat, diagC );
- VecReciprocal( diagC );
- MatDiagonalSet( C_Mat, diagC, INSERT_VALUES );
- C_InvMat = C_Mat; /* Use pointer CInv since C has been inverted */
-
- /* Build RHS : rhs = f - GCInv h */
- MatMult( C_InvMat, hVec, hTempVec );
- VecScale( hTempVec, negOne );
- MatMultAdd( gradMat, hTempVec, fVec, fTempVec );
-
- /* Build G CInv GTrans */
-/* MatTranspose( gradMat, >rans ); */
-/* since CInv is diagonal we can just scale mat entries by the diag vector */
- MatDiagonalScale( divMat, diagC, PETSC_NULL ); /* Div = CInve Div */
- /* MatMatMult_any( &tmpMat, C, *divMat ); */ /* tmpMat = CInv Div */
-
-
- Journal_DPrintf( self->debug, "UpdivMat mat mat mult \n");
- MatPtAP( gradMat, divMat, MAT_INITIAL_MATRIX, 1.0, &kHat );
- Journal_DPrintf( self->debug, "done mult \n");
- MatScale( kHat, -1 );
- MatAXPY( kHat, one, kMatrix, SAME_NONZERO_PATTERN );
-
- /* Setup solver context and make sure that it uses a direct solver */
- KSPCreate( sle->comm, &sles_v );
- KSPSetOperators( sles_v, kHat, kHat, DIFFERENT_NONZERO_PATTERN );
- KSPSetType( sles_v, KSPPREONLY );
- KSPGetPC( sles_v, &pc );
- PCSetType( pc, PCLU );
-
- KSPSolve( sles_v, fTempVec, uVec );
-
- /* Recover p */
- if( sle->dStiffMat == NULL ) {
-/* since Div was modified when C is diagonal, re build the transpose */
-#if( PETSC_VERSION_MAJOR <= 2 )
- MatTranspose( gradMat, >rans );
-#else
- MatTranspose( gradMat, MAT_INITIAL_MATRIX, >rans );
-#endif
- divMat = GTrans;
- }
- else {
-/* never modified Div_null so set divMat to point back to it */
- divMat = sle->dStiffMat->matrix;
- }
- MatMult( divMat, uVec, hTempVec ); /* hTemp = Div v */
- VecAXPY( hVec, negOne, hTempVec ); /* hTemp = H - hTemp : hTemp = H - Div v */
- MatMult( C_InvMat, hTempVec, pVec ); /* p = CInv hTemp : p = CInv ( H - Div v ) */
-
- if( kHat != PETSC_NULL ) MatDestroy( kHat );
- if( fTempVec != PETSC_NULL ) VecDestroy( fTempVec );
- if( hTempVec != PETSC_NULL ) VecDestroy( hTempVec );
- if( diagC != PETSC_NULL ) VecDestroy( diagC );
- if( sles_v != PETSC_NULL ) KSPDestroy( sles_v );
- if( GTrans != PETSC_NULL ) MatDestroy( GTrans );
-}
-
-
-Vec _Stokes_SLE_PenaltySolver_GetResidual( void* solver, Index fv_I ) {
-/* TODO */
- return NULL;
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_PenaltySolver.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_PenaltySolver.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,304 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Stokes_SLE_PenaltySolver.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "types.h"
+#include "Stokes_SLE_PenaltySolver.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "Stokes_SLE.h"
+
+const Type Stokes_SLE_PenaltySolver_Type = "Stokes_SLE_PenaltySolver";
+
+void* Stokes_SLE_PenaltySolver_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(Stokes_SLE_PenaltySolver);
+ Type type = Stokes_SLE_PenaltySolver_Type;
+ Stg_Class_DeleteFunction* _delete = _Stokes_SLE_PenaltySolver_Delete;
+ Stg_Class_PrintFunction* _print = _Stokes_SLE_PenaltySolver_Print;
+ Stg_Class_CopyFunction* _copy = _Stokes_SLE_PenaltySolver_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = Stokes_SLE_PenaltySolver_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _Stokes_SLE_PenaltySolver_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Stokes_SLE_PenaltySolver_Build;
+ Stg_Component_InitialiseFunction* _initialise = _SLE_Solver_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _SLE_Solver_Execute;
+ Stg_Component_DestroyFunction* _destroy = _SLE_Solver_Destroy;
+ SLE_Solver_SolverSetupFunction* _solverSetup = _Stokes_SLE_PenaltySolver_SolverSetup;
+ SLE_Solver_SolveFunction* _solve = _Stokes_SLE_PenaltySolver_Solve;
+ SLE_Solver_GetResidualFunc* _getResidual = _Stokes_SLE_PenaltySolver_GetResidual;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _Stokes_SLE_PenaltySolver_New( STOKES_SLE_PENALTYSOLVER_PASSARGS );
+}
+
+Stokes_SLE_PenaltySolver* Stokes_SLE_PenaltySolver_New(
+ Name name,
+ Bool useStatSolve,
+ int statReps )
+{
+ Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*) Stokes_SLE_PenaltySolver_DefaultNew( name );
+
+ Stokes_SLE_PenaltySolver_InitAll( self, useStatSolve, statReps );
+
+ return self;
+}
+
+
+/* Creation implementation / Virtual constructor */
+Stokes_SLE_PenaltySolver* _Stokes_SLE_PenaltySolver_New( STOKES_SLE_PENALTYSOLVER_DEFARGS )
+{
+ Stokes_SLE_PenaltySolver* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(Stokes_SLE_PenaltySolver) );
+ self = (Stokes_SLE_PenaltySolver*) _SLE_Solver_New( SLE_SOLVER_PASSARGS );
+
+ /* Virtual info */
+ return self;
+}
+
+
+void _Stokes_SLE_PenaltySolver_Init( void* solver ) {
+ Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver;
+
+ self->isConstructed = True;
+}
+
+void Stokes_SLE_PenaltySolver_InitAll(
+ void* solver,
+ Bool useStatSolve,
+ int statReps )
+{
+ Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver;
+
+ SLE_Solver_InitAll( self, useStatSolve, statReps );
+ _Stokes_SLE_PenaltySolver_Init( self );
+}
+
+
+void _Stokes_SLE_PenaltySolver_Delete( void* solver ) {
+ Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver;
+
+ Journal_DPrintf( self->debug, "In: %s \n", __func__);
+
+ Stream_IndentBranch( StgFEM_Debug );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _Stokes_SLE_PenaltySolver_Print( void* solver, Stream* stream ) {
+ Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver;
+
+ _SLE_Solver_Print( self, stream );
+}
+
+
+void* _Stokes_SLE_PenaltySolver_Copy( const void* stokesSlePenaltySolver, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)stokesSlePenaltySolver;
+ Stokes_SLE_PenaltySolver* newStokesSlePenaltySolver;
+
+ newStokesSlePenaltySolver = (Stokes_SLE_PenaltySolver*)_SLE_Solver_Copy( self, dest, deep, nameExt, ptrMap );
+
+ return (void*) newStokesSlePenaltySolver;
+}
+
+
+void _Stokes_SLE_PenaltySolver_Build( void* solver, void* stokesSLE ) {
+ Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+void _Stokes_SLE_PenaltySolver_AssignFromXML( void* solver, Stg_ComponentFactory* cf, void* data ) {
+ Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*) solver;
+
+ _SLE_Solver_AssignFromXML( self, cf, data );
+
+ _Stokes_SLE_PenaltySolver_Init( self );
+}
+
+void _Stokes_SLE_PenaltySolver_Execute( void* solver, void* data ) {
+}
+
+void _Stokes_SLE_PenaltySolver_Destroy( void* solver, void* data ) {
+}
+
+void _Stokes_SLE_PenaltySolver_Initialise( void* solver, void* stokesSLE ) {
+ Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*) solver;
+ Stokes_SLE* sle = (Stokes_SLE*) stokesSLE;
+
+ /* Initialise Parent */
+ _SLE_Solver_Initialise( self, sle );
+}
+
+/* SolverSetup */
+void _Stokes_SLE_PenaltySolver_SolverSetup( void* solver, void* stokesSLE ) {
+ Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*) solver;
+
+ Journal_DPrintf( self->debug, "In %s:\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _Stokes_SLE_PenaltySolver_Solve( void* solver,void* stokesSLE ) {
+ Stokes_SLE_PenaltySolver* self = (Stokes_SLE_PenaltySolver*)solver;
+ Stokes_SLE* sle = (Stokes_SLE*)stokesSLE;
+ /* Create shortcuts to stuff needed on sle */
+ Mat kMatrix = sle->kStiffMat->matrix;
+ Mat gradMat = sle->gStiffMat->matrix;
+ Mat divMat = NULL;
+ Mat C_Mat = sle->cStiffMat->matrix;
+ Vec uVec = sle->uSolnVec->vector;
+ Vec pVec = sle->pSolnVec->vector;
+ Vec fVec = sle->fForceVec->vector;
+ Vec hVec = sle->hForceVec->vector;
+ Vec hTempVec;
+ Vec fTempVec;
+ Mat GTrans;
+ KSP sles_v;
+ double negOne=-1.0;
+ double one=1.0;
+ Mat kHat;
+ Mat C_InvMat;
+ Vec diagC;
+ PC pc;
+
+ Journal_DPrintf( self->debug, "In %s():\n", __func__ );
+
+ VecDuplicate( hVec, &hTempVec );
+ VecDuplicate( fVec, &fTempVec );
+ VecDuplicate( pVec, &diagC );
+
+ if( sle->dStiffMat == NULL ) {
+ Journal_DPrintf( self->debug, "Div matrix == NULL : Problem is assumed to be symmetric. ie Div = GTrans \n");
+#if( PETSC_VERSION_MAJOR <= 2 )
+ MatTranspose( gradMat, >rans );
+#else
+ MatTranspose( gradMat, MAT_INITIAL_MATRIX, >rans );
+#endif
+ divMat = GTrans;
+ }
+ else {
+ /* make a copy we can play with */
+ MatCreate( sle->comm, >rans );
+ MatCopy( sle->dStiffMat->matrix, GTrans, DIFFERENT_NONZERO_PATTERN );
+ divMat = GTrans;
+ }
+
+ /* Create CInv */
+ MatGetDiagonal( C_Mat, diagC );
+ VecReciprocal( diagC );
+ MatDiagonalSet( C_Mat, diagC, INSERT_VALUES );
+ C_InvMat = C_Mat; /* Use pointer CInv since C has been inverted */
+
+ /* Build RHS : rhs = f - GCInv h */
+ MatMult( C_InvMat, hVec, hTempVec );
+ VecScale( hTempVec, negOne );
+ MatMultAdd( gradMat, hTempVec, fVec, fTempVec );
+
+ /* Build G CInv GTrans */
+/* MatTranspose( gradMat, >rans ); */
+/* since CInv is diagonal we can just scale mat entries by the diag vector */
+ MatDiagonalScale( divMat, diagC, PETSC_NULL ); /* Div = CInve Div */
+ /* MatMatMult_any( &tmpMat, C, *divMat ); */ /* tmpMat = CInv Div */
+
+
+ Journal_DPrintf( self->debug, "UpdivMat mat mat mult \n");
+ MatPtAP( gradMat, divMat, MAT_INITIAL_MATRIX, 1.0, &kHat );
+ Journal_DPrintf( self->debug, "done mult \n");
+ MatScale( kHat, -1 );
+ MatAXPY( kHat, one, kMatrix, SAME_NONZERO_PATTERN );
+
+ /* Setup solver context and make sure that it uses a direct solver */
+ KSPCreate( sle->comm, &sles_v );
+ KSPSetOperators( sles_v, kHat, kHat, DIFFERENT_NONZERO_PATTERN );
+ KSPSetType( sles_v, KSPPREONLY );
+ KSPGetPC( sles_v, &pc );
+ PCSetType( pc, PCLU );
+
+ KSPSolve( sles_v, fTempVec, uVec );
+
+ /* Recover p */
+ if( sle->dStiffMat == NULL ) {
+/* since Div was modified when C is diagonal, re build the transpose */
+#if( PETSC_VERSION_MAJOR <= 2 )
+ MatTranspose( gradMat, >rans );
+#else
+ MatTranspose( gradMat, MAT_INITIAL_MATRIX, >rans );
+#endif
+ divMat = GTrans;
+ }
+ else {
+/* never modified Div_null so set divMat to point back to it */
+ divMat = sle->dStiffMat->matrix;
+ }
+ MatMult( divMat, uVec, hTempVec ); /* hTemp = Div v */
+ VecAXPY( hVec, negOne, hTempVec ); /* hTemp = H - hTemp : hTemp = H - Div v */
+ MatMult( C_InvMat, hTempVec, pVec ); /* p = CInv hTemp : p = CInv ( H - Div v ) */
+
+ if( kHat != PETSC_NULL ) MatDestroy( kHat );
+ if( fTempVec != PETSC_NULL ) VecDestroy( fTempVec );
+ if( hTempVec != PETSC_NULL ) VecDestroy( hTempVec );
+ if( diagC != PETSC_NULL ) VecDestroy( diagC );
+ if( sles_v != PETSC_NULL ) KSPDestroy( sles_v );
+ if( GTrans != PETSC_NULL ) MatDestroy( GTrans );
+}
+
+
+Vec _Stokes_SLE_PenaltySolver_GetResidual( void* solver, Index fv_I ) {
+/* TODO */
+ return NULL;
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_UzawaSolver.c
--- a/SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_UzawaSolver.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1048 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Stokes_SLE_UzawaSolver.c 1199 2008-08-08 04:03:32Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "types.h"
-#include "Stokes_SLE_UzawaSolver.h"
-
-#include <assert.h>
-#include <string.h>
-
-#include "Stokes_SLE.h"
-
-/* Macro to checking number integrity - i.e. checks if number is infinite or "not a number" */
-#define isGoodNumber( number ) \
- ( (! isnan( number ) ) && ( ! isinf( number ) ) )
-
-const Type Stokes_SLE_UzawaSolver_Type = "Stokes_SLE_UzawaSolver";
-
-void* _Stokes_SLE_UzawaSolver_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(Stokes_SLE_UzawaSolver);
- Type type = Stokes_SLE_UzawaSolver_Type;
- Stg_Class_DeleteFunction* _delete = _Stokes_SLE_UzawaSolver_Delete;
- Stg_Class_PrintFunction* _print = _Stokes_SLE_UzawaSolver_Print;
- Stg_Class_CopyFunction* _copy = _Stokes_SLE_UzawaSolver_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _Stokes_SLE_UzawaSolver_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _Stokes_SLE_UzawaSolver_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Stokes_SLE_UzawaSolver_Build;
- Stg_Component_InitialiseFunction* _initialise = _Stokes_SLE_UzawaSolver_Initialise;
- Stg_Component_ExecuteFunction* _execute = _SLE_Solver_Execute;
- Stg_Component_DestroyFunction* _destroy = _Stokes_SLE_UzawaSolver_Destroy;
- SLE_Solver_SolverSetupFunction* _solverSetup = _Stokes_SLE_UzawaSolver_SolverSetup;
- SLE_Solver_SolveFunction* _solve = _Stokes_SLE_UzawaSolver_Solve;
- SLE_Solver_GetResidualFunc* _getResidual = _Stokes_SLE_UzawaSolver_GetResidual;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _Stokes_SLE_UzawaSolver_New( STOKES_SLE_UZAWASOLVER_PASSARGS );
-}
-
-Stokes_SLE_UzawaSolver* Stokes_SLE_UzawaSolver_New(
- Name name,
- Bool useStatSolve,
- int statReps,
- StiffnessMatrix* preconditioner,
- Iteration_Index maxUzawaIterations,
- Iteration_Index minUzawaIterations,
- double tolerance,
- Bool useAbsoluteTolerance,
- Bool monitor )
-{
- Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)_Stokes_SLE_UzawaSolver_DefaultNew( name );
-
- Stokes_SLE_UzawaSolver_InitAll( self, useStatSolve, statReps, preconditioner, maxUzawaIterations, minUzawaIterations, tolerance, useAbsoluteTolerance, monitor );
-
- return self;
-}
-
-
-/* Creation implementation / Virtual constructor */
-Stokes_SLE_UzawaSolver* _Stokes_SLE_UzawaSolver_New( STOKES_SLE_UZAWASOLVER_DEFARGS )
-{
- Stokes_SLE_UzawaSolver* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(Stokes_SLE_UzawaSolver) );
- self = (Stokes_SLE_UzawaSolver*) _SLE_Solver_New( SLE_SOLVER_PASSARGS );
-
- self->_formResidual = _Stokes_SLE_UzawaSolver_FormResidual;
- self->_getRhs = _Stokes_SLE_UzawaSolver_GetRhs;
- self->_getSolution = _Stokes_SLE_UzawaSolver_GetSolution;
-
- /* Virtual info */
- return self;
-}
-
-
-void _Stokes_SLE_UzawaSolver_Init(
- Stokes_SLE_UzawaSolver* self,
- StiffnessMatrix* preconditioner,
- Iteration_Index maxUzawaIterations,
- Iteration_Index minUzawaIterations,
- double tolerance,
- Bool useAbsoluteTolerance,
- Bool monitor )
-{
- self->isConstructed = True;
- self->tolerance = tolerance;
- self->maxUzawaIterations = maxUzawaIterations;
- self->minUzawaIterations = minUzawaIterations;
- self->preconditioner = preconditioner;
- self->useAbsoluteTolerance = useAbsoluteTolerance;
- self->monitor = monitor;
-}
-
-void Stokes_SLE_UzawaSolver_InitAll(
- void* solver,
- Bool useStatSolve,
- int statReps,
- StiffnessMatrix* preconditioner,
- Iteration_Index maxUzawaIterations,
- Iteration_Index minUzawaIterations,
- double tolerance,
- Bool useAbsoluteTolerance,
- Bool monitor )
-{
- Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)solver;
-
- SLE_Solver_InitAll( self, useStatSolve, statReps );
- _Stokes_SLE_UzawaSolver_Init( self, preconditioner, maxUzawaIterations, minUzawaIterations, tolerance, useAbsoluteTolerance, monitor );
-}
-
-void _Stokes_SLE_UzawaSolver_Delete( void* solver ) {
- Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)solver;
-
- _SLE_Solver_Delete( self );
-
-}
-
-
-void _Stokes_SLE_UzawaSolver_Print( void* solver, Stream* stream ) {
- Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)solver;
-
- _SLE_Solver_Print( self, stream );
-
- Journal_PrintValue( stream, self->tolerance );
- Journal_PrintValue( stream, self->maxUzawaIterations );
- Journal_PrintValue( stream, self->minUzawaIterations );
-}
-
-
-void* _Stokes_SLE_UzawaSolver_Copy( const void* stokesSleUzawaSolver, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)stokesSleUzawaSolver;
- Stokes_SLE_UzawaSolver* newStokesSleUzawaSolver;
-
- newStokesSleUzawaSolver = (Stokes_SLE_UzawaSolver*)_SLE_Solver_Copy( self, dest, deep, nameExt, ptrMap );
-
- newStokesSleUzawaSolver->velSolver = self->velSolver;
- newStokesSleUzawaSolver->pcSolver = self->pcSolver;
- newStokesSleUzawaSolver->preconditioner = self->preconditioner;
- newStokesSleUzawaSolver->pTempVec = self->pTempVec;
- newStokesSleUzawaSolver->rVec = self->rVec;
- newStokesSleUzawaSolver->sVec = self->sVec;
- newStokesSleUzawaSolver->fTempVec = self->fTempVec;
- newStokesSleUzawaSolver->vStarVec = self->vStarVec;
- newStokesSleUzawaSolver->tolerance = self->tolerance;
- newStokesSleUzawaSolver->maxUzawaIterations = self->maxUzawaIterations;
- newStokesSleUzawaSolver->minUzawaIterations = self->minUzawaIterations;
- newStokesSleUzawaSolver->useAbsoluteTolerance = self->useAbsoluteTolerance;
- newStokesSleUzawaSolver->monitor = self->monitor;
-
- return (void*) newStokesSleUzawaSolver;
-}
-
-
-void _Stokes_SLE_UzawaSolver_Build( void* solver, void* stokesSLE ) {
- Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)solver;
- Stokes_SLE* sle = (Stokes_SLE*)stokesSLE;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- Journal_DPrintfL( self->debug, 2, "building a standard solver for the velocity system.\n" );
- KSPCreate( sle->comm, &self->velSolver );
-
- /* Build Preconditioner */
- if ( self->preconditioner ) {
- Stg_Component_Build( self->preconditioner, stokesSLE, False );
- SystemLinearEquations_AddStiffnessMatrix( sle, self->preconditioner );
-
- Journal_DPrintfL( self->debug, 2, "build a standard solver for the preconditioner system.\n" );
- KSPCreate( sle->comm, &self->pcSolver );
- }
- else
- self->pcSolver = PETSC_NULL;
-
- if( self->pTempVec != PETSC_NULL ) VecDestroy( self->pTempVec );
- if( self->rVec != PETSC_NULL ) VecDestroy( self->rVec );
- if( self->sVec != PETSC_NULL ) VecDestroy( self->sVec );
- if( self->fTempVec != PETSC_NULL ) VecDestroy( self->fTempVec );
- if( self->vStarVec != PETSC_NULL ) VecDestroy( self->vStarVec );
-
- Journal_DPrintfL( self->debug, 2, "Allocate the auxillary vectors pTemp, r, s, fTemp and vStar.\n" );
- VecDuplicate( sle->pSolnVec->vector, &self->pTempVec );
- VecDuplicate( sle->pSolnVec->vector, &self->rVec );
- VecDuplicate( sle->pSolnVec->vector, &self->sVec );
-
- VecDuplicate( sle->fForceVec->vector, &self->fTempVec );
- VecDuplicate( sle->fForceVec->vector, &self->vStarVec );
-
- /* Need by the Picard nonlinear solver */
-// Vector_Duplicate( sle->pTempVec->vector, (void**)&self->f_hat );
-// Vector_SetLocalSize( self->vf_hat, Vector_GetLocalSize( sle->pTempVec->vector ) );
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-void _Stokes_SLE_UzawaSolver_AssignFromXML( void* solver, Stg_ComponentFactory* cf, void* data ) {
- Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*) solver;
- double tolerance;
- Iteration_Index maxUzawaIterations, minUzawaIterations;
- StiffnessMatrix* preconditioner;
- Bool useAbsoluteTolerance;
- Bool monitor;
-
- _SLE_Solver_AssignFromXML( self, cf, data );
-
- tolerance = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"tolerance", 1.0e-5 );
- maxUzawaIterations = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"maxIterations", 1000 );
- minUzawaIterations = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"minIterations", 1 );
- useAbsoluteTolerance = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"useAbsoluteTolerance", False );
- monitor = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"monitor", False );
-
- preconditioner = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Preconditioner", StiffnessMatrix, False, data );
-
- _Stokes_SLE_UzawaSolver_Init( self, preconditioner, maxUzawaIterations, minUzawaIterations, tolerance, useAbsoluteTolerance, monitor );
-
- if( self->velSolver == PETSC_NULL ) {
- KSPCreate( MPI_COMM_WORLD, &self->velSolver );
- }
-}
-
-void _Stokes_SLE_UzawaSolver_Execute( void* solver, void* data ) {
-}
-
-void _Stokes_SLE_UzawaSolver_Destroy( void* solver, void* data ) {
- Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*) solver;
- Journal_DPrintf( self->debug, "In: %s \n", __func__);
-
- Stream_IndentBranch( StgFEM_Debug );
- Journal_DPrintfL( self->debug, 2, "Destroying Solver contexts.\n" );
- KSPDestroy( self->velSolver );
- KSPDestroy( self->pcSolver );
-
- Journal_DPrintfL( self->debug, 2, "Destroying temporary solver vectors.\n" );
- if( self->pTempVec != PETSC_NULL ) VecDestroy( self->pTempVec );
- if( self->rVec != PETSC_NULL ) VecDestroy( self->rVec );
- if( self->sVec != PETSC_NULL ) VecDestroy( self->sVec );
- if( self->fTempVec != PETSC_NULL ) VecDestroy( self->fTempVec );
- if( self->vStarVec != PETSC_NULL ) VecDestroy( self->vStarVec );
- Stream_UnIndentBranch( StgFEM_Debug );
- _SLE_Solver_Destroy( self, data );
-
-}
-
-void _Stokes_SLE_UzawaSolver_Initialise( void* solver, void* stokesSLE ) {
- Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*) solver;
- Stokes_SLE* sle = (Stokes_SLE*) stokesSLE;
-
- /* Initialise Parent */
- _SLE_Solver_Initialise( self, sle );
-
- if ( sle->context && (True == sle->context->loadFromCheckPoint) ) {
- /* The previous timestep's velocity solution will be helpful in iterating to a better
- solution faster - and thus make restarting from checkpoint more repeatable compared
- to original non-restart solution */
- SolutionVector_LoadCurrentFeVariableValuesOntoVector( sle->uSolnVec );
- SolutionVector_LoadCurrentFeVariableValuesOntoVector( sle->pSolnVec );
- }
-
-}
-
-/* SolverSetup */
-
-void _Stokes_SLE_UzawaSolver_SolverSetup( void* solver, void* stokesSLE ) {
- Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*) solver;
- Stokes_SLE* sle = (Stokes_SLE*) stokesSLE;
-
- Journal_DPrintf( self->debug, "In %s:\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- Journal_DPrintfL( self->debug, 1, "Setting up MatrixSolver for the velocity eqn.\n" );
- KSPSetOperators( self->velSolver, sle->kStiffMat->matrix, sle->kStiffMat->matrix, DIFFERENT_NONZERO_PATTERN );
- KSPSetFromOptions( self->velSolver );
-
- if( self->pcSolver ) {
- Journal_DPrintfL( self->debug, 1, "Setting up MatrixSolver for the Preconditioner.\n" );
- KSPSetOperators( self->pcSolver, self->preconditioner->matrix, self->preconditioner->matrix, DIFFERENT_NONZERO_PATTERN );
- KSPSetFromOptions( self->pcSolver );
- }
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-Bool _check_if_constant_nullsp_present( Stokes_SLE_UzawaSolver* self, Mat K, Mat G, Mat M, Vec t1, Vec ustar, Vec r, Vec l, KSP ksp )
-{
- PetscInt N;
- PetscScalar sum;
- PetscReal nrm;
- Bool nullsp_present;
-
- VecGetSize(l,&N);
- sum = 1.0/N;
- VecSet(l,sum);
-
- /* [S] {l} = {r} */
- MatMult( G,l, t1 );
- KSPSolve( ksp, t1, ustar );
- MatMultTranspose( G, ustar, r );
- if ( M ) {
- VecScale( r, -1.0 );
- MatMultAdd( M,l, r, r );
- VecScale( r, -1.0 );
- }
-
- VecNorm(r,NORM_2,&nrm);
- if (nrm < 1.e-7) {
- Journal_PrintfL( self->info, 1, "Constant null space detected, " );
- nullsp_present = True;
- }
- else {
- Journal_PrintfL( self->info, 1, "Constant null space not present, " );
- nullsp_present = False;
- }
- Journal_PrintfL( self->info, 1, "|| [S]{1} || = %G\n", nrm );
-
-
- return nullsp_present;
-}
-
-void _remove_constant_nullsp( Vec v )
-{
- PetscInt N;
- PetscScalar sum;
-
- VecGetSize( v, &N );
- if( N > 0 ) {
- VecSum( v, &sum );
- sum = sum/( -1.0*N );
- VecShift( v, sum );
- }
-}
-
-/* from the depreciated Vector class */
-void _SLE_VectorView( Vec v, Stream* stream ) {
- unsigned entry_i;
- PetscInt size;
- PetscScalar* array;
-
- VecGetSize( v, &size );
- VecGetArray( v, &array );
-
- Journal_Printf( stream, "%p = [", v );
- for( entry_i = 0; entry_i < size; entry_i++ )
- Journal_Printf( stream, "\t%u: \t %.12g\n", entry_i, array[entry_i] );
- Journal_Printf( stream, "];\n" );
-
- VecRestoreArray( v, &array );
-}
-
-void _Stokes_SLE_UzawaSolver_Solve( void* solver, void* stokesSLE ) {
- Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)solver;
- Stokes_SLE* sle = (Stokes_SLE*)stokesSLE;
-
- /* Create shortcuts to stuff needed on sle */
- Mat K_Mat = sle->kStiffMat->matrix;
- Mat G_Mat = sle->gStiffMat->matrix;
- Mat D_Mat = NULL;
- Mat M_Mat = NULL;
- Vec uVec = sle->uSolnVec->vector;
- Vec qVec = sle->pSolnVec->vector;
- Vec fVec = sle->fForceVec->vector;
- Vec hVec = sle->hForceVec->vector;
-
- /* Create shortcuts to solver related stuff */
- Vec qTempVec = self->pTempVec;
- Vec rVec = self->rVec;
- Vec sVec = self->sVec;
- Vec fTempVec = self->fTempVec;
- Vec vStarVec = self->vStarVec;
- KSP velSolver = self->velSolver; /* Inner velocity solver */
- KSP pcSolver = self->pcSolver; /* Preconditioner */
-
- Iteration_Index maxIterations = self->maxUzawaIterations;
- Iteration_Index minIterations = self->minUzawaIterations;
- Iteration_Index iteration_I = 0;
- Iteration_Index outputInterval = 1;
-
- double zdotr_current = 0.0;
- double zdotr_previous = 1.0;
- double sdotGTrans_v;
- double alpha, beta;
- double absResidual;
- double relResidual;
- double* chosenResidual; /* We can opt to use either the absolute or relative residual in termination condition */
- double uzawaRhsScale;
- double divU;
- double weightedResidual;
- double weightedVelocityScale;
- double momentumEquationResidual;
-
- Iteration_Index innerLoopIterations;
- Stream* errorStream = Journal_Register( Error_Type, (Name)Stokes_SLE_UzawaSolver_Type );
-
- PetscInt fVecSize, qTempVecSize, uVecSize, qVecSize;
- PetscScalar fVecNorm, qTempVecNorm, uVecNorm, rVecNorm, fTempVecNorm, uVecNormInf, qVecNorm, qVecNormInf;
-
- double qGlobalProblemScale;
- double qReciprocalGlobalProblemScale;
- int init_info_stream_rank;
- PetscScalar p_sum;
- /* Bool nullsp_present; */
- Bool uzawa_summary;
- double time,t0,rnorm0;
-
- VecGetSize( qTempVec, &qTempVecSize );
- qGlobalProblemScale = sqrt( (double) qTempVecSize );
- qReciprocalGlobalProblemScale = 1.0 / qGlobalProblemScale;
- init_info_stream_rank = Stream_GetPrintingRank( self->info );
- Stream_SetPrintingRank( self->info, 0 );
-
- /* DEFINITIONS:
- See accompanying documentation
- u - the displacement / velocity solution (to which constraints are applied)
- q - the pressure-like variable which constrains the divergence displacement / velocity (= pressure for incompressible)
- F - standard FE force vector
- Fhat - Uzawa RHS = K^{-1} G F - h
- K - standard FE stiffness matrix
- Khat - Uzawa transformed stiffness matrix = G^T K^{-1} G
- G matrix - discrete gradient operator
- D matrix - discrete divergence operator = G^T for this particular algorithm
- C matrix - Mass matrix (M) for compressibility
-
- LM & DAM
- */
-
- /* CHOICE OF RESIDUAL:
- we may opt to converge on the absolute value (self->useAbsoluteTolerance == True ... default)
- or the relative value of the residual (self->useAbsoluteTolerance == False)
- (another possibility would be always to improve the residual by a given tolerance)
- The Moresi & Solomatov (Phys Fluids, 1995) approach is to use the relative tolerance
- */
-
- VecNorm( fVec, NORM_2, &fVecNorm );
- VecGetSize( fVec, &fVecSize );
- if ( fVecNorm / sqrt( (double)fVecSize ) <= 1e-99 ) {
- Journal_Printf( errorStream,
- "Error in func %s: The momentum force vector \"%s\" is zero. "
- "The force vector should be non-zero either because of your chosen boundary "
- "conditions, or because of the element force vector assembly. You have %d "
- "element force vectors attached.\n",
- __func__, sle->fForceVec->name, sle->fForceVec->assembleForceVector->hooks->count );
- if ( sle->fForceVec->assembleForceVector->hooks->count > 0 ) {
- Journal_Printf( errorStream, "You used the following force vector assembly terms:\n" );
- EntryPoint_PrintConcise( sle->fForceVec->assembleForceVector, errorStream );
-/* TODO : need to print the elementForceVector assembly, not the global guy!! */
- }
- Journal_Printf( errorStream,
- "Please check values for building the force vector.\n" );
- Journal_Firewall( 0, errorStream, "Exiting.\n" );
- }
-
-
- Journal_DPrintf( self->debug, "In %s:\n", __func__ );
- Journal_RPrintfL( self->debug, 2, "Conjugate Gradient Uzawa solver with:\n");
-
- Stream_IndentBranch( StgFEM_Debug );
-
- Journal_RPrintfL( self->debug, 2, "Compressibility %s\n", (sle->cStiffMat)? "on" : "off");
- Journal_RPrintfL( self->debug, 2, "Preconditioning %s\n", (pcSolver)? "on" : "off" );
-
-
-
- if ( sle->cStiffMat ) {
- Journal_DPrintfL( self->debug, 2, "(compressibility active)\n" );
- M_Mat = sle->cStiffMat->matrix;
- }
- else {
- Journal_DPrintfL( self->debug, 2, "(compressibility inactive)\n" );
- }
- if ( sle->dStiffMat ) {
- Journal_DPrintfL( self->debug, 2, "(asymmetric geometry: handling D Matrix [incorrectly - will be ignored])\n" );
- D_Mat = sle->dStiffMat->matrix;
- }
- else {
- Journal_DPrintfL( self->debug, 2, "(No D -> symmetric geometry: D = Gt)\n" );
- }
-
- #if DEBUG
- if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
- Journal_DPrintf( self->debug, "Matrices and Vectors to solve are:\n" );
- Journal_DPrintf( self->debug, "K Matrix:\n" );
- /* No nice way of viewing Matrices, so commented out as incompatible with
- * new 3D decomp at present --Kathleen Humble 30-04-07
- * Matrix_View( sle->kStiffMat->matrix, self->debug ); */
- Journal_DPrintf( self->debug, "G Matrix:\n" );
- if ( D_Mat ) {
- Journal_DPrintf( self->debug, "D Matrix:\n" );
- }
- if ( M_Mat ) {
- Journal_DPrintf( self->debug, "M Matrix:\n" );
- }
- Journal_DPrintf( self->debug, "Z (preconditioner) Matrix:\n" );
- Journal_DPrintf( self->debug, "f Vector:\n" );
- _SLE_VectorView( fVec, self->debug );
- Journal_DPrintf( self->debug, "h Vector:\n" );
- _SLE_VectorView( hVec, self->debug );
- }
- #endif
-
- /* STEP 1: Estimate the magnitude of the RHS for the transformed problem
- we compute (usually to lower accuracy than elsewhere) the RHS (Fhat - h)
- and store the result in qTempVec.
- LM & DAM
- */
-
- Journal_DPrintfL( self->debug, 2, "Building Fhat - h.\n" );
-
- KSPSetTolerances( velSolver, self->tolerance, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT );
- KSPSolve( velSolver, fVec, vStarVec );
- KSPGetIterationNumber( velSolver, (PetscInt*)(&innerLoopIterations) );
-
- Journal_DPrintfL( self->debug, 2, "Fhat inner solution: Number of iterations: %d\n", innerLoopIterations );
-
- if ( D_Mat ) {
- MatMult( D_Mat, vStarVec, qTempVec );
- }
- else {
- MatMultTranspose( G_Mat, vStarVec, qTempVec );
- }
- VecAXPY( qTempVec, -1.0, hVec );
-
- /* WARNING:
- If D != G^T then the resulting \hat{K} is not likely to be symmetric, positive definite as
- required by this implementation of the Uzawa iteration. This next piece of code
- is VERY unlikely to work properly so it's in the sin bin for the time being - LM.
-
- if ( D_Mat ) {
- MatrixMultiply( D_Mat, vStarVec, qTempVec );
- }
- else {
- MatrixTransposeMultiply( G_Mat, vStarVec, qTempVec );
- }
- LM & DAM
- */
-
-
- /* STEP 2: The problem scaling - optionally normalize the uzawa residual by the magnitude of the RHS (use a relative tolerance)
- For the inner velocity solver, Citcom uses a relative tolerance equal to that used for the Uzawa iteration as a whole
- LM & DAM
- */
-
- if (self->useAbsoluteTolerance) {
- chosenResidual = &absResidual;
- Journal_PrintfL( self->info, 2, "Absolute residual < %g for Uzawa stopping condition\n", self->tolerance);
- /* We should calculate the effective relative tolerance and insert that here !! */
- KSPSetTolerances( velSolver, 0.1 * self->tolerance, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT );
- }
- else { /* The CITCOM compatible choice */
- chosenResidual = &relResidual;
- Journal_PrintfL( self->info, 2, "Relative residual < %g for Uzawa stopping condition\n", self->tolerance);
- KSPSetTolerances( velSolver, 0.1 * self->tolerance, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT );
- }
-
- Journal_DPrintfL( self->debug, 2, "Determining scaling factor for residual:\n" );
- VecNorm( qTempVec, NORM_2, &qTempVecNorm );
- uzawaRhsScale = ((double)qTempVecNorm) * qReciprocalGlobalProblemScale;
-
- Journal_DPrintfL( self->debug, 2, "uzawaRhsScale = %f\n", uzawaRhsScale );
- Journal_Firewall( isGoodNumber( uzawaRhsScale ), errorStream,
- "Error in func '%s' for %s '%s' - uzawaRhsScale has illegal value '%g'.\n", __func__, self->type, self->name, uzawaRhsScale );
-
- /* STEP 3: Calculate initial residual for transformed equation (\hat{F} - h - \hat{K} q_0)
- Compute the solution to K u_0 = F - G q_0 (u_0 unknown)
- Then G^T u* = \hat{F} - \hat{K} q_0
- u_0 is also the initial velocity solution to which the constraint is applied by the subsequent iteration
- LM & DAM
- */
-
- Journal_DPrintfL( self->debug, 2, "Solving for transformed Uzawa RHS.\n" );
-
- VecCopy( fVec, fTempVec );
- VecScale( fTempVec, -1.0 );
- MatMultAdd( G_Mat, qVec, fTempVec, fTempVec );
- VecScale( fTempVec, -1.0 );
- KSPSolve( velSolver, fTempVec, uVec );
-
- /* Handling for NON-SYMMETRIC: relegated to sin bin (see comment above) LM & DAM */
- if ( D_Mat ) {
- MatMult( D_Mat, uVec, rVec );
- }
- else {
- MatMultTranspose( G_Mat, uVec, rVec );
- }
- VecNorm( rVec, NORM_2, &rnorm0 );
- VecNorm( uVec, NORM_2, &uVecNorm );
- divU = rnorm0 / uVecNorm;
-
- Journal_PrintfL( self->info, 2, "Initial l2Norm( Div u ) / l2Norm( u ) = %f \n", divU);
-
- Journal_Firewall( isGoodNumber( divU ), errorStream,
- "Error in func '%s' for %s '%s' - l2Norm( Div u ) has illegal value '%g'.\n",
- __func__, self->type, self->name, divU );
-
-
- Journal_DPrintfL( self->debug, 2, "Adding compressibility and prescribed divergence terms.\n" );
-
- if ( M_Mat ) {
- MatMultAdd( M_Mat, qVec, rVec, rVec );
- }
- VecAXPY( rVec, -1.0, hVec );
-
- /* Check for existence of constant null space */
-#if 0
- nullsp_present = _check_if_constant_nullsp_present( self, K_Mat,G_Mat,M_Mat, fTempVec,vStarVec,qTempVec,sVec, velSolver );
-#endif
-
- /* STEP 4: Preconditioned conjugate gradient iteration loop */
-
- Journal_DPrintfL( self->debug, 1, "Beginning main Uzawa conjugate gradient loop:\n" );
-
- iteration_I = 0;
-
- /* outer_it, residual, time */
- uzawa_summary = self->monitor;
- time = 0.0;
- t0 = MPI_Wtime();
-// Journal_PrintfL( self->info, 1, " |r0| = %.8e \n", rnorm0 );
-
- do{
- Journal_DPrintfL( self->debug, 2, "Beginning solve '%u'.\n", iteration_I );
- Stream_IndentBranch( StgFEM_Debug );
-
- /* STEP 4.1: Preconditioner
- Solve:
- Q_\hat{K} z_1 = r_1
- Q_\hat{K} is an approximation to \hat{K} which is simple / trivial / quick to invert
- LM & DAM
- */
-
- if ( pcSolver ) {
- KSPSolve( pcSolver, rVec, qTempVec );
- }
- else {
- VecCopy( rVec, qTempVec );
- }
-
- /* Remove the constant null space, but only if NOT compressible */
-#if 0
- if( nullsp_present == True ) {
- _remove_constant_nullsp( qTempVec );
- }
-#endif
-
- /* STEP 4.2: Calculate s_I, the pressure search direction
- z_{I-1} . r_{I-1}
- \beta = (z_{I-1} . r_{I-1}) / (z_{I-2} . r_{I-2})
- \beta = 0 for the first iteration
- s_I = z_(I-1) + \beta * s_(I-1)
- LM & DAM
- */
-
- VecDot( qTempVec, rVec, &zdotr_current );
-
- VecNorm( qTempVec, NORM_2, &qTempVecNorm );
- VecNorm( rVec, NORM_2, &rVecNorm );
- Journal_DPrintfL( self->debug, 2, "l2Norm (qTempVec) %g; (rVec) %g \n",
- qTempVecNorm * qReciprocalGlobalProblemScale,
- rVecNorm * qReciprocalGlobalProblemScale );
-
- if ( iteration_I == 0 ) {
- VecCopy( qTempVec, sVec );
- }
- else {
- beta = zdotr_current/zdotr_previous;
- VecAYPX( sVec, beta, qTempVec );
- }
-
- /* STEP 4.3: Velocity search direction corresponding to s_I is found by solving
- K u* = G s_I
- LM & DAM
- */
-
- MatMult( G_Mat, sVec, fTempVec );
-
- Journal_DPrintfL( self->debug, 2, "Uzawa inner iteration step\n");
-
- //START OF INNER ITERATIONS!!!!
- /*get initial wall time for inner loop*/
- self->inneritsinitialtime = MPI_Wtime();
- KSPSolve( velSolver, fTempVec, vStarVec );
- /*get end wall time for inner loop*/
- self->inneritsendtime = MPI_Wtime();
-
- /* add time to total time inner its: */
- self->totalinneritstime = self->totalinneritstime + (-self->inneritsinitialtime + self->inneritsendtime);
- /* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */
- self->inneritsinitialtime = 0;
- self->inneritsendtime = 0;
-
- KSPGetIterationNumber( velSolver, (PetscInt*)(&innerLoopIterations) );
- /* add the inner loop iterations to the total inner iterations */
- self->totalnuminnerits = self->totalnuminnerits + innerLoopIterations;
-
- Journal_DPrintfL( self->debug, 2, "Completed Uzawa inner iteration in '%u' iterations \n", innerLoopIterations );
-
- /* STEP 4.4: Calculate the step size ( \alpha = z_{I-1} . r_{I-1} / (s_I . \hat{K} s_I) )
- \hat{K} s_I = G^T u* - M s_I (u* from step 4.3)
- LM & DAM
- */
-
- if ( D_Mat ) {
- MatMult( D_Mat, vStarVec, qTempVec );
- }
- else {
- MatMultTranspose( G_Mat, vStarVec, qTempVec );
- }
-
- /* Handling for NON-SYMMETRIC: relegated to sin bin (see comment above)
-
- if ( D_Mat ) {
- MatrixMultiply( D_Mat, vStarVec, qTempVec );
- }
- else {
- MatrixTransposeMultiply( G_Mat, vStarVec, qTempVec );
- }
- LM & DAM
- */
-
- if ( M_Mat ) {
- Journal_DPrintfL( self->debug, 2, "Correcting for Compressibility\n" );
- VecScale( qTempVec, -1.0 );
- MatMultAdd( M_Mat, sVec, qTempVec, qTempVec );
- VecScale( qTempVec, -1.0 );
- }
-
- VecDot( sVec, qTempVec, &sdotGTrans_v );
-
- alpha = zdotr_current/sdotGTrans_v;
-
- /* STEP 4.5: Update pressure, velocity and value of residual
- by \alpha times corresponding search direction
- LM & DAM
- */
-
- Journal_DPrintfL( self->debug, 2, "zdotr_current = %g \n", zdotr_current);
- Journal_DPrintfL( self->debug, 2, "sdotGTrans_v = %g \n", sdotGTrans_v);
- Journal_DPrintfL( self->debug, 2, "alpha = %g \n", alpha);
-
- Journal_Firewall(
- isGoodNumber( zdotr_current ) && isGoodNumber( sdotGTrans_v ) && isGoodNumber( alpha ),
- errorStream,
- "Error in func '%s' for %s '%s' - zdotr_current, sdotGTrans_v or alpha has an illegal value: '%g','%g' or '%g'\n",
- __func__, self->type, self->name, zdotr_current, sdotGTrans_v, alpha );
-
- VecAXPY( qVec, alpha, sVec );
- VecAXPY( uVec, -alpha, vStarVec );
- VecAXPY( rVec, -alpha, qTempVec );
-
- /* STEP 4.6: store the value of z_{I-1} . r_{I-1} for the next iteration
- LM & DAM
- */
-
- zdotr_previous = zdotr_current;
-
- VecNorm( rVec, NORM_2, &rVecNorm );
- absResidual = rVecNorm * qReciprocalGlobalProblemScale;
- relResidual = absResidual / uzawaRhsScale;
-
- Stream_UnIndentBranch( StgFEM_Debug );
-
- if( iteration_I % outputInterval == 0 ) {
- Journal_PrintfL( self->info, 2, "\tLoop = %u, absResidual = %.8e, relResidual = %.8e\n",
- iteration_I, absResidual, relResidual );
- }
-
- Journal_Firewall( isGoodNumber( absResidual ), errorStream,
- "Error in func '%s' for %s '%s' - absResidual has an illegal value: '%g'\n",
- __func__, self->type, self->name, absResidual );
-
- Journal_Firewall( iteration_I < maxIterations,
- errorStream, "In func %s: Reached maximum number of iterations %u without converging; absResidual = %.5g, relResidual = %.5g \n",
- __func__, iteration_I, absResidual, relResidual );
-
-/* TODO: test for small change in 10 iterations and if so restart? */
-
- time = MPI_Wtime()-t0;
- if (uzawa_summary) {
- Journal_PrintfL( self->info, 1, " %1.4d uzawa residual norm %12.13e, cpu time %5.5e\n", iteration_I+1,*chosenResidual,time );
- }
-
- iteration_I++;
- //END OF OUTER ITERATION LOOP!!!
- /*get wall time for end of outer loop*/
- self->outeritsendtime = MPI_Wtime();
- /* add time to total time inner its: */
- self->totalouteritstime = self->totalouteritstime + (-self->outeritsinitialtime + self->outeritsendtime);
- /* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */
- self->outeritsinitialtime = 0;
- self->outeritsendtime = 0;
- /* add the outer loop iterations to the total outer iterations */
- self->totalnumouterits++;
- } while ( (*chosenResidual > self->tolerance) || (iteration_I<minIterations) );
-// } while ( *chosenResidual > self->tolerance );
-
- Journal_DPrintfL( self->debug, 1, "Pressure solution converged. Exiting uzawa \n ");
-
- /* STEP 5: Check all the relevant residuals and report back */
-
- if (Stream_IsEnable( self->info ) ) {
-
- /* This information should be in an info stream */
- Journal_PrintfL( self->info, 1, "Summary:\n");
- Journal_PrintfL( self->info, 1, " Uzawa its. = %04d , Uzawa residual = %12.13e\n", iteration_I, relResidual );
- MatMultTranspose( G_Mat, uVec, rVec );
- VecNorm( rVec, NORM_2, &rVecNorm );
- VecNorm( uVec, NORM_2, &uVecNorm );
- divU = rVecNorm / uVecNorm;
- Journal_PrintfL( self->info, 1, " |G^T u|/|u| = %.8e\n", divU);
-
- /* Residual for the momentum equation
- Compute r = || F - Ku - Gp || / || F ||
- */
-
- MatMult( G_Mat, qVec, vStarVec );
- MatMultAdd( K_Mat, uVec, vStarVec, fTempVec );
- VecAYPX( fTempVec, -1.0, fVec );
-
- VecNorm( fTempVec, NORM_2, &fTempVecNorm );
- VecNorm( fVec, NORM_2, &fVecNorm );
- momentumEquationResidual = fTempVecNorm / fVecNorm;
- Journal_PrintfL( self->info, 1, " |f - K u - G p|/|f| = %.8e\n", momentumEquationResidual );
- Journal_Firewall( isGoodNumber( momentumEquationResidual ), errorStream,
- "Bad residual for the momentum equation (|| F - Ku - Gp || / || F || = %g):\n"
- "\tCheck to see if forcing term is zero or nan - \n\t|| F - Ku - Gp || = %g \n\t|| F || = %g.\n",
- momentumEquationResidual,
- fTempVecNorm, fVecNorm );
-
- /* "Preconditioned" residual for the momentum equation
- r_{w} = || Q_{K}(r) || / || Q_{K}(F)
- fTempVec contains the residual but is overwritten once used
- vStarVec is used to hold the diagonal preconditioner Q_{K}
- */
-
- MatGetDiagonal( K_Mat, vStarVec );
- VecReciprocal( vStarVec );
- VecPointwiseMult( vStarVec, fTempVec, fTempVec );
- VecNorm( fTempVec, NORM_2, &weightedResidual );
- VecPointwiseMult( vStarVec, fVec, fTempVec );
- VecNorm( fTempVec, NORM_2, &weightedVelocityScale );
-
- Journal_PrintfL( self->info, 1, " |f - K u - G p|_w/|f|_w = %.8e\n", weightedResidual / weightedVelocityScale );
-
- /* Report back on the solution - velocity and pressure
- Note - correction for dof in Vrms ??
- */
-
- VecNorm( uVec, NORM_INFINITY, &uVecNormInf );
- VecNorm( uVec, NORM_2, &uVecNorm );
- VecGetSize( uVec, &uVecSize );
- VecNorm( qVec, NORM_INFINITY, &qVecNormInf );
- VecNorm( qVec, NORM_2, &qVecNorm );
- VecGetSize( qVec, &qVecSize );
- Journal_PrintfL( self->info, 1, " |u|_{\\infty} = %.8e , u_rms = %.8e\n",
- uVecNormInf, uVecNorm / sqrt( (double)uVecSize ) );
- Journal_PrintfL( self->info, 1, " |p|_{\\infty} = %.8e , p_rms = %.8e\n",
- qVecNormInf, qVecNorm / sqrt( (double)qVecSize ) );
-
- { PetscInt lmin,lmax;
- PetscReal min,max;
- VecMax( uVec, &lmax, &max );
- VecMin( uVec, &lmin, &min );
- Journal_PrintfL( self->info, 1, " min/max(u) = %.8e [%d] / %.8e [%d]\n",min,lmin,max,lmax);
- VecMax( qVec, &lmax, &max );
- VecMin( qVec, &lmin, &min );
- Journal_PrintfL( self->info, 1, " min/max(p) = %.8e [%d] / %.8e [%d]\n",min,lmin,max,lmax);
- }
- VecSum( qVec, &p_sum );
- Journal_PrintfL( self->info, 1, " \\sum_i p_i = %.8e \n", p_sum );
-
- } /* journal stream enabled */
-
- #if DEBUG
- if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
- Journal_DPrintf( self->debug, "Velocity solution:\n" );
- _SLE_VectorView( uVec, self->debug );
- Journal_DPrintf( self->debug, "Pressure solution:\n" );
- _SLE_VectorView( qVec, self->debug );
- }
- #endif
- Stream_UnIndentBranch( StgFEM_Debug );
-
- Stream_SetPrintingRank( self->info, init_info_stream_rank );
- /* Now gather up data for printing out to FrequentOutput file: */
-
-
- /*!!! if non-linear need to divide by number of nonlinear iterations and we do this in SystemLinearEquations */
- if((sle->isNonLinear != True)){
- self->avgnuminnerits = self->totalnuminnerits/self->totalnumouterits;
- self->avgnumouterits = self->totalnumouterits;
- self->avgtimeouterits = (self->totalouteritstime - self->totalinneritstime)/self->totalnumouterits;
- self->avgtimeinnerits = self->totalinneritstime/self->totalnuminnerits;
- }
-}
-
-void _Stokes_SLE_UzawaSolver_GetSolution( void *stokesSLE, void *solver, Vec *x )
-{
- Stokes_SLE *sle = (Stokes_SLE*)stokesSLE;
- Vec p = sle->pSolnVec->vector;
-
- (*x) = p;
-}
-
-
-#undef __FUNCT__
-#define __FUNCT__ "_Stokes_SLE_UzawaSolver_GetRhs"
-void _Stokes_SLE_UzawaSolver_GetRhs( void *stokesSLE, void *solver, Vec rhs )
-{
- Stokes_SLE_UzawaSolver *self = (Stokes_SLE_UzawaSolver*)solver;
- Stokes_SLE *sle = (Stokes_SLE*)stokesSLE;
- /* stg linear algebra */
- KSP A11_solver = self->velSolver;
- Mat A12 = sle->gStiffMat->matrix;
- Vec b1 = sle->fForceVec->vector;
- Vec b2 = sle->hForceVec->vector;
- Vec u_star = self->vStarVec;
-
- /* petsc variables */
- KSP ksp_A11;
-
- /* check operations will be valid */
- if (sle->dStiffMat!=NULL) { SETERRABORT( sle->comm, PETSC_ERR_SUP, "A21 must be NULL" ); }
- if (A11_solver==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "vel_solver is NULL" ); }
- if (A12==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "A12 is NULL" ); }
- if (b1==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "b1 is NULL" ); }
- if (b2==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "b2 is NULL" ); }
- if (u_star==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "u* is NULL" ); }
-
- /* Extract petsc objects */
- ksp_A11 = A11_solver;
-
- /* compute rhs = A12^T A11^{-1} b1 - b2 */
- KSPSolve( ksp_A11, b1, u_star ); /* u* = A11^{-1} b1 */
- MatMultTranspose( A12, u_star, rhs ); /* b2 = A12^T u* */
- VecAXPY( rhs, -1.0, b2 ); /* rhs <- rhs - b2 */
-}
-
-
-/* Computes r = f_hat - S p */
-#undef __FUNCT__
-#define __FUNCT__ "_Stokes_SLE_UzawaSolver_FormResidual"
-void _Stokes_SLE_UzawaSolver_FormResidual( void *stokesSLE, void *solver, Vec r )
-{
- Stokes_SLE_UzawaSolver *self = (Stokes_SLE_UzawaSolver*)solver;
- Stokes_SLE *sle = (Stokes_SLE*)stokesSLE;
- /* stg linear algebra objects */
- Mat A12 = sle->gStiffMat->matrix;
- Mat A22 = NULL;
- Vec x2 = sle->pSolnVec->vector;
- Vec f_star = self->fTempVec;
- Vec u_star = self->vStarVec;
- Vec q_star = self->pTempVec;
- KSP A11_solver = self->velSolver;
-
- /* petsc objects */
- KSP ksp_A11;
- PetscInt r_N, x2_N;
-
- /* check operations will be valid */
- if (A11_solver==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "vel_solver is NULL" ); }
- if (sle->dStiffMat!=NULL) { SETERRABORT( sle->comm, PETSC_ERR_SUP, "A21 must be NULL" ); }
- if (A12==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "A12 is NULL" ); }
- if (x2==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "x2 is NULL" ); }
- if (u_star==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "u* is NULL" ); }
- if (f_star==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "f* is NULL" ); }
- if (q_star==NULL) { SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "q* is NULL" ); }
-
- A22 = PETSC_NULL;
- if (sle->cStiffMat!=NULL) {
- A22 = sle->cStiffMat->matrix;
- }
-
-
- /* Extract petsc objects */
- ksp_A11 = A11_solver;
-
- /* Check sizes match */
- VecGetSize( r, &r_N );
- VecGetSize( x2, &x2_N );
- if (r_N!=x2_N) {
- SETERRABORT( sle->comm, PETSC_ERR_ARG_SIZ, "Solution vector for pressure is not compatible with residual vector" );
- }
-
- /* r = f_hat - (G^T K^{-1} G - M) p */
- _Stokes_SLE_UzawaSolver_GetRhs( stokesSLE, solver, r ); /* r <- f_hat */
-
- /* correct for non zero A22 */
- if (A22!=PETSC_NULL) {
- MatMultAdd( A22, x2, r, r ); /* r <- r + A22 p */
- }
-
- /* make correction r <- r - G^T K^{-1} G */
- MatMult( A12, x2, f_star ); /* f* <- A12 x2 */
- KSPSolve( ksp_A11, f_star, u_star ); /* u* <- A11^{-1} f* */
- MatMultTranspose( A12, u_star, q_star ); /* q* <- A12 u* */
-
- VecAXPY( r, -1.0, q_star ); /* r <- r - q* */
-}
-
-Vec _Stokes_SLE_UzawaSolver_GetResidual( void* solver, Index fv_I ) {
- return NULL;
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_UzawaSolver.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_UzawaSolver.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,1048 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Stokes_SLE_UzawaSolver.c 1199 2008-08-08 04:03:32Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "types.h"
+#include "Stokes_SLE_UzawaSolver.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "Stokes_SLE.h"
+
+/* Macro to checking number integrity - i.e. checks if number is infinite or "not a number" */
+#define isGoodNumber( number ) \
+ ( (! isnan( number ) ) && ( ! isinf( number ) ) )
+
+const Type Stokes_SLE_UzawaSolver_Type = "Stokes_SLE_UzawaSolver";
+
+void* _Stokes_SLE_UzawaSolver_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(Stokes_SLE_UzawaSolver);
+ Type type = Stokes_SLE_UzawaSolver_Type;
+ Stg_Class_DeleteFunction* _delete = _Stokes_SLE_UzawaSolver_Delete;
+ Stg_Class_PrintFunction* _print = _Stokes_SLE_UzawaSolver_Print;
+ Stg_Class_CopyFunction* _copy = _Stokes_SLE_UzawaSolver_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _Stokes_SLE_UzawaSolver_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _Stokes_SLE_UzawaSolver_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Stokes_SLE_UzawaSolver_Build;
+ Stg_Component_InitialiseFunction* _initialise = _Stokes_SLE_UzawaSolver_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _SLE_Solver_Execute;
+ Stg_Component_DestroyFunction* _destroy = _Stokes_SLE_UzawaSolver_Destroy;
+ SLE_Solver_SolverSetupFunction* _solverSetup = _Stokes_SLE_UzawaSolver_SolverSetup;
+ SLE_Solver_SolveFunction* _solve = _Stokes_SLE_UzawaSolver_Solve;
+ SLE_Solver_GetResidualFunc* _getResidual = _Stokes_SLE_UzawaSolver_GetResidual;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _Stokes_SLE_UzawaSolver_New( STOKES_SLE_UZAWASOLVER_PASSARGS );
+}
+
+Stokes_SLE_UzawaSolver* Stokes_SLE_UzawaSolver_New(
+ Name name,
+ Bool useStatSolve,
+ int statReps,
+ StiffnessMatrix* preconditioner,
+ Iteration_Index maxUzawaIterations,
+ Iteration_Index minUzawaIterations,
+ double tolerance,
+ Bool useAbsoluteTolerance,
+ Bool monitor )
+{
+ Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)_Stokes_SLE_UzawaSolver_DefaultNew( name );
+
+ Stokes_SLE_UzawaSolver_InitAll( self, useStatSolve, statReps, preconditioner, maxUzawaIterations, minUzawaIterations, tolerance, useAbsoluteTolerance, monitor );
+
+ return self;
+}
+
+
+/* Creation implementation / Virtual constructor */
+Stokes_SLE_UzawaSolver* _Stokes_SLE_UzawaSolver_New( STOKES_SLE_UZAWASOLVER_DEFARGS )
+{
+ Stokes_SLE_UzawaSolver* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(Stokes_SLE_UzawaSolver) );
+ self = (Stokes_SLE_UzawaSolver*) _SLE_Solver_New( SLE_SOLVER_PASSARGS );
+
+ self->_formResidual = _Stokes_SLE_UzawaSolver_FormResidual;
+ self->_getRhs = _Stokes_SLE_UzawaSolver_GetRhs;
+ self->_getSolution = _Stokes_SLE_UzawaSolver_GetSolution;
+
+ /* Virtual info */
+ return self;
+}
+
+
+void _Stokes_SLE_UzawaSolver_Init(
+ Stokes_SLE_UzawaSolver* self,
+ StiffnessMatrix* preconditioner,
+ Iteration_Index maxUzawaIterations,
+ Iteration_Index minUzawaIterations,
+ double tolerance,
+ Bool useAbsoluteTolerance,
+ Bool monitor )
+{
+ self->isConstructed = True;
+ self->tolerance = tolerance;
+ self->maxUzawaIterations = maxUzawaIterations;
+ self->minUzawaIterations = minUzawaIterations;
+ self->preconditioner = preconditioner;
+ self->useAbsoluteTolerance = useAbsoluteTolerance;
+ self->monitor = monitor;
+}
+
+void Stokes_SLE_UzawaSolver_InitAll(
+ void* solver,
+ Bool useStatSolve,
+ int statReps,
+ StiffnessMatrix* preconditioner,
+ Iteration_Index maxUzawaIterations,
+ Iteration_Index minUzawaIterations,
+ double tolerance,
+ Bool useAbsoluteTolerance,
+ Bool monitor )
+{
+ Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)solver;
+
+ SLE_Solver_InitAll( self, useStatSolve, statReps );
+ _Stokes_SLE_UzawaSolver_Init( self, preconditioner, maxUzawaIterations, minUzawaIterations, tolerance, useAbsoluteTolerance, monitor );
+}
+
+void _Stokes_SLE_UzawaSolver_Delete( void* solver ) {
+ Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)solver;
+
+ _SLE_Solver_Delete( self );
+
+}
+
+
+void _Stokes_SLE_UzawaSolver_Print( void* solver, Stream* stream ) {
+ Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)solver;
+
+ _SLE_Solver_Print( self, stream );
+
+ Journal_PrintValue( stream, self->tolerance );
+ Journal_PrintValue( stream, self->maxUzawaIterations );
+ Journal_PrintValue( stream, self->minUzawaIterations );
+}
+
+
+void* _Stokes_SLE_UzawaSolver_Copy( const void* stokesSleUzawaSolver, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)stokesSleUzawaSolver;
+ Stokes_SLE_UzawaSolver* newStokesSleUzawaSolver;
+
+ newStokesSleUzawaSolver = (Stokes_SLE_UzawaSolver*)_SLE_Solver_Copy( self, dest, deep, nameExt, ptrMap );
+
+ newStokesSleUzawaSolver->velSolver = self->velSolver;
+ newStokesSleUzawaSolver->pcSolver = self->pcSolver;
+ newStokesSleUzawaSolver->preconditioner = self->preconditioner;
+ newStokesSleUzawaSolver->pTempVec = self->pTempVec;
+ newStokesSleUzawaSolver->rVec = self->rVec;
+ newStokesSleUzawaSolver->sVec = self->sVec;
+ newStokesSleUzawaSolver->fTempVec = self->fTempVec;
+ newStokesSleUzawaSolver->vStarVec = self->vStarVec;
+ newStokesSleUzawaSolver->tolerance = self->tolerance;
+ newStokesSleUzawaSolver->maxUzawaIterations = self->maxUzawaIterations;
+ newStokesSleUzawaSolver->minUzawaIterations = self->minUzawaIterations;
+ newStokesSleUzawaSolver->useAbsoluteTolerance = self->useAbsoluteTolerance;
+ newStokesSleUzawaSolver->monitor = self->monitor;
+
+ return (void*) newStokesSleUzawaSolver;
+}
+
+
+void _Stokes_SLE_UzawaSolver_Build( void* solver, void* stokesSLE ) {
+ Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)solver;
+ Stokes_SLE* sle = (Stokes_SLE*)stokesSLE;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ Journal_DPrintfL( self->debug, 2, "building a standard solver for the velocity system.\n" );
+ KSPCreate( sle->comm, &self->velSolver );
+
+ /* Build Preconditioner */
+ if ( self->preconditioner ) {
+ Stg_Component_Build( self->preconditioner, stokesSLE, False );
+ SystemLinearEquations_AddStiffnessMatrix( sle, self->preconditioner );
+
+ Journal_DPrintfL( self->debug, 2, "build a standard solver for the preconditioner system.\n" );
+ KSPCreate( sle->comm, &self->pcSolver );
+ }
+ else
+ self->pcSolver = PETSC_NULL;
+
+ if( self->pTempVec != PETSC_NULL ) VecDestroy( self->pTempVec );
+ if( self->rVec != PETSC_NULL ) VecDestroy( self->rVec );
+ if( self->sVec != PETSC_NULL ) VecDestroy( self->sVec );
+ if( self->fTempVec != PETSC_NULL ) VecDestroy( self->fTempVec );
+ if( self->vStarVec != PETSC_NULL ) VecDestroy( self->vStarVec );
+
+ Journal_DPrintfL( self->debug, 2, "Allocate the auxillary vectors pTemp, r, s, fTemp and vStar.\n" );
+ VecDuplicate( sle->pSolnVec->vector, &self->pTempVec );
+ VecDuplicate( sle->pSolnVec->vector, &self->rVec );
+ VecDuplicate( sle->pSolnVec->vector, &self->sVec );
+
+ VecDuplicate( sle->fForceVec->vector, &self->fTempVec );
+ VecDuplicate( sle->fForceVec->vector, &self->vStarVec );
+
+ /* Need by the Picard nonlinear solver */
+// Vector_Duplicate( sle->pTempVec->vector, (void**)&self->f_hat );
+// Vector_SetLocalSize( self->vf_hat, Vector_GetLocalSize( sle->pTempVec->vector ) );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+void _Stokes_SLE_UzawaSolver_AssignFromXML( void* solver, Stg_ComponentFactory* cf, void* data ) {
+ Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*) solver;
+ double tolerance;
+ Iteration_Index maxUzawaIterations, minUzawaIterations;
+ StiffnessMatrix* preconditioner;
+ Bool useAbsoluteTolerance;
+ Bool monitor;
+
+ _SLE_Solver_AssignFromXML( self, cf, data );
+
+ tolerance = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"tolerance", 1.0e-5 );
+ maxUzawaIterations = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"maxIterations", 1000 );
+ minUzawaIterations = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"minIterations", 1 );
+ useAbsoluteTolerance = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"useAbsoluteTolerance", False );
+ monitor = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"monitor", False );
+
+ preconditioner = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Preconditioner", StiffnessMatrix, False, data );
+
+ _Stokes_SLE_UzawaSolver_Init( self, preconditioner, maxUzawaIterations, minUzawaIterations, tolerance, useAbsoluteTolerance, monitor );
+
+ if( self->velSolver == PETSC_NULL ) {
+ KSPCreate( MPI_COMM_WORLD, &self->velSolver );
+ }
+}
+
+void _Stokes_SLE_UzawaSolver_Execute( void* solver, void* data ) {
+}
+
+void _Stokes_SLE_UzawaSolver_Destroy( void* solver, void* data ) {
+ Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*) solver;
+ Journal_DPrintf( self->debug, "In: %s \n", __func__);
+
+ Stream_IndentBranch( StgFEM_Debug );
+ Journal_DPrintfL( self->debug, 2, "Destroying Solver contexts.\n" );
+ KSPDestroy( self->velSolver );
+ KSPDestroy( self->pcSolver );
+
+ Journal_DPrintfL( self->debug, 2, "Destroying temporary solver vectors.\n" );
+ if( self->pTempVec != PETSC_NULL ) VecDestroy( self->pTempVec );
+ if( self->rVec != PETSC_NULL ) VecDestroy( self->rVec );
+ if( self->sVec != PETSC_NULL ) VecDestroy( self->sVec );
+ if( self->fTempVec != PETSC_NULL ) VecDestroy( self->fTempVec );
+ if( self->vStarVec != PETSC_NULL ) VecDestroy( self->vStarVec );
+ Stream_UnIndentBranch( StgFEM_Debug );
+ _SLE_Solver_Destroy( self, data );
+
+}
+
+void _Stokes_SLE_UzawaSolver_Initialise( void* solver, void* stokesSLE ) {
+ Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*) solver;
+ Stokes_SLE* sle = (Stokes_SLE*) stokesSLE;
+
+ /* Initialise Parent */
+ _SLE_Solver_Initialise( self, sle );
+
+ if ( sle->context && (True == sle->context->loadFromCheckPoint) ) {
+ /* The previous timestep's velocity solution will be helpful in iterating to a better
+ solution faster - and thus make restarting from checkpoint more repeatable compared
+ to original non-restart solution */
+ SolutionVector_LoadCurrentFeVariableValuesOntoVector( sle->uSolnVec );
+ SolutionVector_LoadCurrentFeVariableValuesOntoVector( sle->pSolnVec );
+ }
+
+}
+
+/* SolverSetup */
+
+void _Stokes_SLE_UzawaSolver_SolverSetup( void* solver, void* stokesSLE ) {
+ Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*) solver;
+ Stokes_SLE* sle = (Stokes_SLE*) stokesSLE;
+
+ Journal_DPrintf( self->debug, "In %s:\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ Journal_DPrintfL( self->debug, 1, "Setting up MatrixSolver for the velocity eqn.\n" );
+ KSPSetOperators( self->velSolver, sle->kStiffMat->matrix, sle->kStiffMat->matrix, DIFFERENT_NONZERO_PATTERN );
+ KSPSetFromOptions( self->velSolver );
+
+ if( self->pcSolver ) {
+ Journal_DPrintfL( self->debug, 1, "Setting up MatrixSolver for the Preconditioner.\n" );
+ KSPSetOperators( self->pcSolver, self->preconditioner->matrix, self->preconditioner->matrix, DIFFERENT_NONZERO_PATTERN );
+ KSPSetFromOptions( self->pcSolver );
+ }
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+Bool _check_if_constant_nullsp_present( Stokes_SLE_UzawaSolver* self, Mat K, Mat G, Mat M, Vec t1, Vec ustar, Vec r, Vec l, KSP ksp )
+{
+ PetscInt N;
+ PetscScalar sum;
+ PetscReal nrm;
+ Bool nullsp_present;
+
+ VecGetSize(l,&N);
+ sum = 1.0/N;
+ VecSet(l,sum);
+
+ /* [S] {l} = {r} */
+ MatMult( G,l, t1 );
+ KSPSolve( ksp, t1, ustar );
+ MatMultTranspose( G, ustar, r );
+ if ( M ) {
+ VecScale( r, -1.0 );
+ MatMultAdd( M,l, r, r );
+ VecScale( r, -1.0 );
+ }
+
+ VecNorm(r,NORM_2,&nrm);
+ if (nrm < 1.e-7) {
+ Journal_PrintfL( self->info, 1, "Constant null space detected, " );
+ nullsp_present = True;
+ }
+ else {
+ Journal_PrintfL( self->info, 1, "Constant null space not present, " );
+ nullsp_present = False;
+ }
+ Journal_PrintfL( self->info, 1, "|| [S]{1} || = %G\n", nrm );
+
+
+ return nullsp_present;
+}
+
+void _remove_constant_nullsp( Vec v )
+{
+ PetscInt N;
+ PetscScalar sum;
+
+ VecGetSize( v, &N );
+ if( N > 0 ) {
+ VecSum( v, &sum );
+ sum = sum/( -1.0*N );
+ VecShift( v, sum );
+ }
+}
+
+/* from the depreciated Vector class */
+void _SLE_VectorView( Vec v, Stream* stream ) {
+ unsigned entry_i;
+ PetscInt size;
+ PetscScalar* array;
+
+ VecGetSize( v, &size );
+ VecGetArray( v, &array );
+
+ Journal_Printf( stream, "%p = [", v );
+ for( entry_i = 0; entry_i < size; entry_i++ )
+ Journal_Printf( stream, "\t%u: \t %.12g\n", entry_i, array[entry_i] );
+ Journal_Printf( stream, "];\n" );
+
+ VecRestoreArray( v, &array );
+}
+
+void _Stokes_SLE_UzawaSolver_Solve( void* solver, void* stokesSLE ) {
+ Stokes_SLE_UzawaSolver* self = (Stokes_SLE_UzawaSolver*)solver;
+ Stokes_SLE* sle = (Stokes_SLE*)stokesSLE;
+
+ /* Create shortcuts to stuff needed on sle */
+ Mat K_Mat = sle->kStiffMat->matrix;
+ Mat G_Mat = sle->gStiffMat->matrix;
+ Mat D_Mat = NULL;
+ Mat M_Mat = NULL;
+ Vec uVec = sle->uSolnVec->vector;
+ Vec qVec = sle->pSolnVec->vector;
+ Vec fVec = sle->fForceVec->vector;
+ Vec hVec = sle->hForceVec->vector;
+
+ /* Create shortcuts to solver related stuff */
+ Vec qTempVec = self->pTempVec;
+ Vec rVec = self->rVec;
+ Vec sVec = self->sVec;
+ Vec fTempVec = self->fTempVec;
+ Vec vStarVec = self->vStarVec;
+ KSP velSolver = self->velSolver; /* Inner velocity solver */
+ KSP pcSolver = self->pcSolver; /* Preconditioner */
+
+ Iteration_Index maxIterations = self->maxUzawaIterations;
+ Iteration_Index minIterations = self->minUzawaIterations;
+ Iteration_Index iteration_I = 0;
+ Iteration_Index outputInterval = 1;
+
+ double zdotr_current = 0.0;
+ double zdotr_previous = 1.0;
+ double sdotGTrans_v;
+ double alpha, beta;
+ double absResidual;
+ double relResidual;
+ double* chosenResidual; /* We can opt to use either the absolute or relative residual in termination condition */
+ double uzawaRhsScale;
+ double divU;
+ double weightedResidual;
+ double weightedVelocityScale;
+ double momentumEquationResidual;
+
+ Iteration_Index innerLoopIterations;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)Stokes_SLE_UzawaSolver_Type );
+
+ PetscInt fVecSize, qTempVecSize, uVecSize, qVecSize;
+ PetscScalar fVecNorm, qTempVecNorm, uVecNorm, rVecNorm, fTempVecNorm, uVecNormInf, qVecNorm, qVecNormInf;
+
+ double qGlobalProblemScale;
+ double qReciprocalGlobalProblemScale;
+ int init_info_stream_rank;
+ PetscScalar p_sum;
+ /* Bool nullsp_present; */
+ Bool uzawa_summary;
+ double time,t0,rnorm0;
+
+ VecGetSize( qTempVec, &qTempVecSize );
+ qGlobalProblemScale = sqrt( (double) qTempVecSize );
+ qReciprocalGlobalProblemScale = 1.0 / qGlobalProblemScale;
+ init_info_stream_rank = Stream_GetPrintingRank( self->info );
+ Stream_SetPrintingRank( self->info, 0 );
+
+ /* DEFINITIONS:
+ See accompanying documentation
+ u - the displacement / velocity solution (to which constraints are applied)
+ q - the pressure-like variable which constrains the divergence displacement / velocity (= pressure for incompressible)
+ F - standard FE force vector
+ Fhat - Uzawa RHS = K^{-1} G F - h
+ K - standard FE stiffness matrix
+ Khat - Uzawa transformed stiffness matrix = G^T K^{-1} G
+ G matrix - discrete gradient operator
+ D matrix - discrete divergence operator = G^T for this particular algorithm
+ C matrix - Mass matrix (M) for compressibility
+
+ LM & DAM
+ */
+
+ /* CHOICE OF RESIDUAL:
+ we may opt to converge on the absolute value (self->useAbsoluteTolerance == True ... default)
+ or the relative value of the residual (self->useAbsoluteTolerance == False)
+ (another possibility would be always to improve the residual by a given tolerance)
+ The Moresi & Solomatov (Phys Fluids, 1995) approach is to use the relative tolerance
+ */
+
+ VecNorm( fVec, NORM_2, &fVecNorm );
+ VecGetSize( fVec, &fVecSize );
+ if ( fVecNorm / sqrt( (double)fVecSize ) <= 1e-99 ) {
+ Journal_Printf( errorStream,
+ "Error in func %s: The momentum force vector \"%s\" is zero. "
+ "The force vector should be non-zero either because of your chosen boundary "
+ "conditions, or because of the element force vector assembly. You have %d "
+ "element force vectors attached.\n",
+ __func__, sle->fForceVec->name, sle->fForceVec->assembleForceVector->hooks->count );
+ if ( sle->fForceVec->assembleForceVector->hooks->count > 0 ) {
+ Journal_Printf( errorStream, "You used the following force vector assembly terms:\n" );
+ EntryPoint_PrintConcise( sle->fForceVec->assembleForceVector, errorStream );
+/* TODO : need to print the elementForceVector assembly, not the global guy!! */
+ }
+ Journal_Printf( errorStream,
+ "Please check values for building the force vector.\n" );
+ Journal_Firewall( 0, errorStream, "Exiting.\n" );
+ }
+
+
+ Journal_DPrintf( self->debug, "In %s:\n", __func__ );
+ Journal_RPrintfL( self->debug, 2, "Conjugate Gradient Uzawa solver with:\n");
+
+ Stream_IndentBranch( StgFEM_Debug );
+
+ Journal_RPrintfL( self->debug, 2, "Compressibility %s\n", (sle->cStiffMat)? "on" : "off");
+ Journal_RPrintfL( self->debug, 2, "Preconditioning %s\n", (pcSolver)? "on" : "off" );
+
+
+
+ if ( sle->cStiffMat ) {
+ Journal_DPrintfL( self->debug, 2, "(compressibility active)\n" );
+ M_Mat = sle->cStiffMat->matrix;
+ }
+ else {
+ Journal_DPrintfL( self->debug, 2, "(compressibility inactive)\n" );
+ }
+ if ( sle->dStiffMat ) {
+ Journal_DPrintfL( self->debug, 2, "(asymmetric geometry: handling D Matrix [incorrectly - will be ignored])\n" );
+ D_Mat = sle->dStiffMat->matrix;
+ }
+ else {
+ Journal_DPrintfL( self->debug, 2, "(No D -> symmetric geometry: D = Gt)\n" );
+ }
+
+ #if DEBUG
+ if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+ Journal_DPrintf( self->debug, "Matrices and Vectors to solve are:\n" );
+ Journal_DPrintf( self->debug, "K Matrix:\n" );
+ /* No nice way of viewing Matrices, so commented out as incompatible with
+ * new 3D decomp at present --Kathleen Humble 30-04-07
+ * Matrix_View( sle->kStiffMat->matrix, self->debug ); */
+ Journal_DPrintf( self->debug, "G Matrix:\n" );
+ if ( D_Mat ) {
+ Journal_DPrintf( self->debug, "D Matrix:\n" );
+ }
+ if ( M_Mat ) {
+ Journal_DPrintf( self->debug, "M Matrix:\n" );
+ }
+ Journal_DPrintf( self->debug, "Z (preconditioner) Matrix:\n" );
+ Journal_DPrintf( self->debug, "f Vector:\n" );
+ _SLE_VectorView( fVec, self->debug );
+ Journal_DPrintf( self->debug, "h Vector:\n" );
+ _SLE_VectorView( hVec, self->debug );
+ }
+ #endif
+
+ /* STEP 1: Estimate the magnitude of the RHS for the transformed problem
+ we compute (usually to lower accuracy than elsewhere) the RHS (Fhat - h)
+ and store the result in qTempVec.
+ LM & DAM
+ */
+
+ Journal_DPrintfL( self->debug, 2, "Building Fhat - h.\n" );
+
+ KSPSetTolerances( velSolver, self->tolerance, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT );
+ KSPSolve( velSolver, fVec, vStarVec );
+ KSPGetIterationNumber( velSolver, (PetscInt*)(&innerLoopIterations) );
+
+ Journal_DPrintfL( self->debug, 2, "Fhat inner solution: Number of iterations: %d\n", innerLoopIterations );
+
+ if ( D_Mat ) {
+ MatMult( D_Mat, vStarVec, qTempVec );
+ }
+ else {
+ MatMultTranspose( G_Mat, vStarVec, qTempVec );
+ }
+ VecAXPY( qTempVec, -1.0, hVec );
+
+ /* WARNING:
+ If D != G^T then the resulting \hat{K} is not likely to be symmetric, positive definite as
+ required by this implementation of the Uzawa iteration. This next piece of code
+ is VERY unlikely to work properly so it's in the sin bin for the time being - LM.
+
+ if ( D_Mat ) {
+ MatrixMultiply( D_Mat, vStarVec, qTempVec );
+ }
+ else {
+ MatrixTransposeMultiply( G_Mat, vStarVec, qTempVec );
+ }
+ LM & DAM
+ */
+
+
+ /* STEP 2: The problem scaling - optionally normalize the uzawa residual by the magnitude of the RHS (use a relative tolerance)
+ For the inner velocity solver, Citcom uses a relative tolerance equal to that used for the Uzawa iteration as a whole
+ LM & DAM
+ */
+
+ if (self->useAbsoluteTolerance) {
+ chosenResidual = &absResidual;
+ Journal_PrintfL( self->info, 2, "Absolute residual < %g for Uzawa stopping condition\n", self->tolerance);
+ /* We should calculate the effective relative tolerance and insert that here !! */
+ KSPSetTolerances( velSolver, 0.1 * self->tolerance, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT );
+ }
+ else { /* The CITCOM compatible choice */
+ chosenResidual = &relResidual;
+ Journal_PrintfL( self->info, 2, "Relative residual < %g for Uzawa stopping condition\n", self->tolerance);
+ KSPSetTolerances( velSolver, 0.1 * self->tolerance, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT );
+ }
+
+ Journal_DPrintfL( self->debug, 2, "Determining scaling factor for residual:\n" );
+ VecNorm( qTempVec, NORM_2, &qTempVecNorm );
+ uzawaRhsScale = ((double)qTempVecNorm) * qReciprocalGlobalProblemScale;
+
+ Journal_DPrintfL( self->debug, 2, "uzawaRhsScale = %f\n", uzawaRhsScale );
+ Journal_Firewall( isGoodNumber( uzawaRhsScale ), errorStream,
+ "Error in func '%s' for %s '%s' - uzawaRhsScale has illegal value '%g'.\n", __func__, self->type, self->name, uzawaRhsScale );
+
+ /* STEP 3: Calculate initial residual for transformed equation (\hat{F} - h - \hat{K} q_0)
+ Compute the solution to K u_0 = F - G q_0 (u_0 unknown)
+ Then G^T u* = \hat{F} - \hat{K} q_0
+ u_0 is also the initial velocity solution to which the constraint is applied by the subsequent iteration
+ LM & DAM
+ */
+
+ Journal_DPrintfL( self->debug, 2, "Solving for transformed Uzawa RHS.\n" );
+
+ VecCopy( fVec, fTempVec );
+ VecScale( fTempVec, -1.0 );
+ MatMultAdd( G_Mat, qVec, fTempVec, fTempVec );
+ VecScale( fTempVec, -1.0 );
+ KSPSolve( velSolver, fTempVec, uVec );
+
+ /* Handling for NON-SYMMETRIC: relegated to sin bin (see comment above) LM & DAM */
+ if ( D_Mat ) {
+ MatMult( D_Mat, uVec, rVec );
+ }
+ else {
+ MatMultTranspose( G_Mat, uVec, rVec );
+ }
+ VecNorm( rVec, NORM_2, &rnorm0 );
+ VecNorm( uVec, NORM_2, &uVecNorm );
+ divU = rnorm0 / uVecNorm;
+
+ Journal_PrintfL( self->info, 2, "Initial l2Norm( Div u ) / l2Norm( u ) = %f \n", divU);
+
+ Journal_Firewall( isGoodNumber( divU ), errorStream,
+ "Error in func '%s' for %s '%s' - l2Norm( Div u ) has illegal value '%g'.\n",
+ __func__, self->type, self->name, divU );
+
+
+ Journal_DPrintfL( self->debug, 2, "Adding compressibility and prescribed divergence terms.\n" );
+
+ if ( M_Mat ) {
+ MatMultAdd( M_Mat, qVec, rVec, rVec );
+ }
+ VecAXPY( rVec, -1.0, hVec );
+
+ /* Check for existence of constant null space */
+#if 0
+ nullsp_present = _check_if_constant_nullsp_present( self, K_Mat,G_Mat,M_Mat, fTempVec,vStarVec,qTempVec,sVec, velSolver );
+#endif
+
+ /* STEP 4: Preconditioned conjugate gradient iteration loop */
+
+ Journal_DPrintfL( self->debug, 1, "Beginning main Uzawa conjugate gradient loop:\n" );
+
+ iteration_I = 0;
+
+ /* outer_it, residual, time */
+ uzawa_summary = self->monitor;
+ time = 0.0;
+ t0 = MPI_Wtime();
+// Journal_PrintfL( self->info, 1, " |r0| = %.8e \n", rnorm0 );
+
+ do{
+ Journal_DPrintfL( self->debug, 2, "Beginning solve '%u'.\n", iteration_I );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ /* STEP 4.1: Preconditioner
+ Solve:
+ Q_\hat{K} z_1 = r_1
+ Q_\hat{K} is an approximation to \hat{K} which is simple / trivial / quick to invert
+ LM & DAM
+ */
+
+ if ( pcSolver ) {
+ KSPSolve( pcSolver, rVec, qTempVec );
+ }
+ else {
+ VecCopy( rVec, qTempVec );
+ }
+
+ /* Remove the constant null space, but only if NOT compressible */
+#if 0
+ if( nullsp_present == True ) {
+ _remove_constant_nullsp( qTempVec );
+ }
+#endif
+
+ /* STEP 4.2: Calculate s_I, the pressure search direction
+ z_{I-1} . r_{I-1}
+ \beta = (z_{I-1} . r_{I-1}) / (z_{I-2} . r_{I-2})
+ \beta = 0 for the first iteration
+ s_I = z_(I-1) + \beta * s_(I-1)
+ LM & DAM
+ */
+
+ VecDot( qTempVec, rVec, &zdotr_current );
+
+ VecNorm( qTempVec, NORM_2, &qTempVecNorm );
+ VecNorm( rVec, NORM_2, &rVecNorm );
+ Journal_DPrintfL( self->debug, 2, "l2Norm (qTempVec) %g; (rVec) %g \n",
+ qTempVecNorm * qReciprocalGlobalProblemScale,
+ rVecNorm * qReciprocalGlobalProblemScale );
+
+ if ( iteration_I == 0 ) {
+ VecCopy( qTempVec, sVec );
+ }
+ else {
+ beta = zdotr_current/zdotr_previous;
+ VecAYPX( sVec, beta, qTempVec );
+ }
+
+ /* STEP 4.3: Velocity search direction corresponding to s_I is found by solving
+ K u* = G s_I
+ LM & DAM
+ */
+
+ MatMult( G_Mat, sVec, fTempVec );
+
+ Journal_DPrintfL( self->debug, 2, "Uzawa inner iteration step\n");
+
+ //START OF INNER ITERATIONS!!!!
+ /*get initial wall time for inner loop*/
+ self->inneritsinitialtime = MPI_Wtime();
+ KSPSolve( velSolver, fTempVec, vStarVec );
+ /*get end wall time for inner loop*/
+ self->inneritsendtime = MPI_Wtime();
+
+ /* add time to total time inner its: */
+ self->totalinneritstime = self->totalinneritstime + (-self->inneritsinitialtime + self->inneritsendtime);
+ /* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */
+ self->inneritsinitialtime = 0;
+ self->inneritsendtime = 0;
+
+ KSPGetIterationNumber( velSolver, (PetscInt*)(&innerLoopIterations) );
+ /* add the inner loop iterations to the total inner iterations */
+ self->totalnuminnerits = self->totalnuminnerits + innerLoopIterations;
+
+ Journal_DPrintfL( self->debug, 2, "Completed Uzawa inner iteration in '%u' iterations \n", innerLoopIterations );
+
+ /* STEP 4.4: Calculate the step size ( \alpha = z_{I-1} . r_{I-1} / (s_I . \hat{K} s_I) )
+ \hat{K} s_I = G^T u* - M s_I (u* from step 4.3)
+ LM & DAM
+ */
+
+ if ( D_Mat ) {
+ MatMult( D_Mat, vStarVec, qTempVec );
+ }
+ else {
+ MatMultTranspose( G_Mat, vStarVec, qTempVec );
+ }
+
+ /* Handling for NON-SYMMETRIC: relegated to sin bin (see comment above)
+
+ if ( D_Mat ) {
+ MatrixMultiply( D_Mat, vStarVec, qTempVec );
+ }
+ else {
+ MatrixTransposeMultiply( G_Mat, vStarVec, qTempVec );
+ }
+ LM & DAM
+ */
+
+ if ( M_Mat ) {
+ Journal_DPrintfL( self->debug, 2, "Correcting for Compressibility\n" );
+ VecScale( qTempVec, -1.0 );
+ MatMultAdd( M_Mat, sVec, qTempVec, qTempVec );
+ VecScale( qTempVec, -1.0 );
+ }
+
+ VecDot( sVec, qTempVec, &sdotGTrans_v );
+
+ alpha = zdotr_current/sdotGTrans_v;
+
+ /* STEP 4.5: Update pressure, velocity and value of residual
+ by \alpha times corresponding search direction
+ LM & DAM
+ */
+
+ Journal_DPrintfL( self->debug, 2, "zdotr_current = %g \n", zdotr_current);
+ Journal_DPrintfL( self->debug, 2, "sdotGTrans_v = %g \n", sdotGTrans_v);
+ Journal_DPrintfL( self->debug, 2, "alpha = %g \n", alpha);
+
+ Journal_Firewall(
+ isGoodNumber( zdotr_current ) && isGoodNumber( sdotGTrans_v ) && isGoodNumber( alpha ),
+ errorStream,
+ "Error in func '%s' for %s '%s' - zdotr_current, sdotGTrans_v or alpha has an illegal value: '%g','%g' or '%g'\n",
+ __func__, self->type, self->name, zdotr_current, sdotGTrans_v, alpha );
+
+ VecAXPY( qVec, alpha, sVec );
+ VecAXPY( uVec, -alpha, vStarVec );
+ VecAXPY( rVec, -alpha, qTempVec );
+
+ /* STEP 4.6: store the value of z_{I-1} . r_{I-1} for the next iteration
+ LM & DAM
+ */
+
+ zdotr_previous = zdotr_current;
+
+ VecNorm( rVec, NORM_2, &rVecNorm );
+ absResidual = rVecNorm * qReciprocalGlobalProblemScale;
+ relResidual = absResidual / uzawaRhsScale;
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+
+ if( iteration_I % outputInterval == 0 ) {
+ Journal_PrintfL( self->info, 2, "\tLoop = %u, absResidual = %.8e, relResidual = %.8e\n",
+ iteration_I, absResidual, relResidual );
+ }
+
+ Journal_Firewall( isGoodNumber( absResidual ), errorStream,
+ "Error in func '%s' for %s '%s' - absResidual has an illegal value: '%g'\n",
+ __func__, self->type, self->name, absResidual );
+
+ Journal_Firewall( iteration_I < maxIterations,
+ errorStream, "In func %s: Reached maximum number of iterations %u without converging; absResidual = %.5g, relResidual = %.5g \n",
+ __func__, iteration_I, absResidual, relResidual );
+
+/* TODO: test for small change in 10 iterations and if so restart? */
+
+ time = MPI_Wtime()-t0;
+ if (uzawa_summary) {
+ Journal_PrintfL( self->info, 1, " %1.4d uzawa residual norm %12.13e, cpu time %5.5e\n", iteration_I+1,*chosenResidual,time );
+ }
+
+ iteration_I++;
+ //END OF OUTER ITERATION LOOP!!!
+ /*get wall time for end of outer loop*/
+ self->outeritsendtime = MPI_Wtime();
+ /* add time to total time inner its: */
+ self->totalouteritstime = self->totalouteritstime + (-self->outeritsinitialtime + self->outeritsendtime);
+ /* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */
+ self->outeritsinitialtime = 0;
+ self->outeritsendtime = 0;
+ /* add the outer loop iterations to the total outer iterations */
+ self->totalnumouterits++;
+ } while ( (*chosenResidual > self->tolerance) || (iteration_I<minIterations) );
+// } while ( *chosenResidual > self->tolerance );
+
+ Journal_DPrintfL( self->debug, 1, "Pressure solution converged. Exiting uzawa \n ");
+
+ /* STEP 5: Check all the relevant residuals and report back */
+
+ if (Stream_IsEnable( self->info ) ) {
+
+ /* This information should be in an info stream */
+ Journal_PrintfL( self->info, 1, "Summary:\n");
+ Journal_PrintfL( self->info, 1, " Uzawa its. = %04d , Uzawa residual = %12.13e\n", iteration_I, relResidual );
+ MatMultTranspose( G_Mat, uVec, rVec );
+ VecNorm( rVec, NORM_2, &rVecNorm );
+ VecNorm( uVec, NORM_2, &uVecNorm );
+ divU = rVecNorm / uVecNorm;
+ Journal_PrintfL( self->info, 1, " |G^T u|/|u| = %.8e\n", divU);
+
+ /* Residual for the momentum equation
+ Compute r = || F - Ku - Gp || / || F ||
+ */
+
+ MatMult( G_Mat, qVec, vStarVec );
+ MatMultAdd( K_Mat, uVec, vStarVec, fTempVec );
+ VecAYPX( fTempVec, -1.0, fVec );
+
+ VecNorm( fTempVec, NORM_2, &fTempVecNorm );
+ VecNorm( fVec, NORM_2, &fVecNorm );
+ momentumEquationResidual = fTempVecNorm / fVecNorm;
+ Journal_PrintfL( self->info, 1, " |f - K u - G p|/|f| = %.8e\n", momentumEquationResidual );
+ Journal_Firewall( isGoodNumber( momentumEquationResidual ), errorStream,
+ "Bad residual for the momentum equation (|| F - Ku - Gp || / || F || = %g):\n"
+ "\tCheck to see if forcing term is zero or nan - \n\t|| F - Ku - Gp || = %g \n\t|| F || = %g.\n",
+ momentumEquationResidual,
+ fTempVecNorm, fVecNorm );
+
+ /* "Preconditioned" residual for the momentum equation
+ r_{w} = || Q_{K}(r) || / || Q_{K}(F)
+ fTempVec contains the residual but is overwritten once used
+ vStarVec is used to hold the diagonal preconditioner Q_{K}
+ */
+
+ MatGetDiagonal( K_Mat, vStarVec );
+ VecReciprocal( vStarVec );
+ VecPointwiseMult( vStarVec, fTempVec, fTempVec );
+ VecNorm( fTempVec, NORM_2, &weightedResidual );
+ VecPointwiseMult( vStarVec, fVec, fTempVec );
+ VecNorm( fTempVec, NORM_2, &weightedVelocityScale );
+
+ Journal_PrintfL( self->info, 1, " |f - K u - G p|_w/|f|_w = %.8e\n", weightedResidual / weightedVelocityScale );
+
+ /* Report back on the solution - velocity and pressure
+ Note - correction for dof in Vrms ??
+ */
+
+ VecNorm( uVec, NORM_INFINITY, &uVecNormInf );
+ VecNorm( uVec, NORM_2, &uVecNorm );
+ VecGetSize( uVec, &uVecSize );
+ VecNorm( qVec, NORM_INFINITY, &qVecNormInf );
+ VecNorm( qVec, NORM_2, &qVecNorm );
+ VecGetSize( qVec, &qVecSize );
+ Journal_PrintfL( self->info, 1, " |u|_{\\infty} = %.8e , u_rms = %.8e\n",
+ uVecNormInf, uVecNorm / sqrt( (double)uVecSize ) );
+ Journal_PrintfL( self->info, 1, " |p|_{\\infty} = %.8e , p_rms = %.8e\n",
+ qVecNormInf, qVecNorm / sqrt( (double)qVecSize ) );
+
+ { PetscInt lmin,lmax;
+ PetscReal min,max;
+ VecMax( uVec, &lmax, &max );
+ VecMin( uVec, &lmin, &min );
+ Journal_PrintfL( self->info, 1, " min/max(u) = %.8e [%d] / %.8e [%d]\n",min,lmin,max,lmax);
+ VecMax( qVec, &lmax, &max );
+ VecMin( qVec, &lmin, &min );
+ Journal_PrintfL( self->info, 1, " min/max(p) = %.8e [%d] / %.8e [%d]\n",min,lmin,max,lmax);
+ }
+ VecSum( qVec, &p_sum );
+ Journal_PrintfL( self->info, 1, " \\sum_i p_i = %.8e \n", p_sum );
+
+ } /* journal stream enabled */
+
+ #if DEBUG
+ if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+ Journal_DPrintf( self->debug, "Velocity solution:\n" );
+ _SLE_VectorView( uVec, self->debug );
+ Journal_DPrintf( self->debug, "Pressure solution:\n" );
+ _SLE_VectorView( qVec, self->debug );
+ }
+ #endif
+ Stream_UnIndentBranch( StgFEM_Debug );
+
+ Stream_SetPrintingRank( self->info, init_info_stream_rank );
+ /* Now gather up data for printing out to FrequentOutput file: */
+
+
+ /*!!! if non-linear need to divide by number of nonlinear iterations and we do this in SystemLinearEquations */
+ if((sle->isNonLinear != True)){
+ self->avgnuminnerits = self->totalnuminnerits/self->totalnumouterits;
+ self->avgnumouterits = self->totalnumouterits;
+ self->avgtimeouterits = (self->totalouteritstime - self->totalinneritstime)/self->totalnumouterits;
+ self->avgtimeinnerits = self->totalinneritstime/self->totalnuminnerits;
+ }
+}
+
+void _Stokes_SLE_UzawaSolver_GetSolution( void *stokesSLE, void *solver, Vec *x )
+{
+ Stokes_SLE *sle = (Stokes_SLE*)stokesSLE;
+ Vec p = sle->pSolnVec->vector;
+
+ (*x) = p;
+}
+
+
+#undef __FUNCT__
+#define __FUNCT__ "_Stokes_SLE_UzawaSolver_GetRhs"
+void _Stokes_SLE_UzawaSolver_GetRhs( void *stokesSLE, void *solver, Vec rhs )
+{
+ Stokes_SLE_UzawaSolver *self = (Stokes_SLE_UzawaSolver*)solver;
+ Stokes_SLE *sle = (Stokes_SLE*)stokesSLE;
+ /* stg linear algebra */
+ KSP A11_solver = self->velSolver;
+ Mat A12 = sle->gStiffMat->matrix;
+ Vec b1 = sle->fForceVec->vector;
+ Vec b2 = sle->hForceVec->vector;
+ Vec u_star = self->vStarVec;
+
+ /* petsc variables */
+ KSP ksp_A11;
+
+ /* check operations will be valid */
+ if (sle->dStiffMat!=NULL) { SETERRABORT( sle->comm, PETSC_ERR_SUP, "A21 must be NULL" ); }
+ if (A11_solver==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "vel_solver is NULL" ); }
+ if (A12==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "A12 is NULL" ); }
+ if (b1==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "b1 is NULL" ); }
+ if (b2==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "b2 is NULL" ); }
+ if (u_star==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "u* is NULL" ); }
+
+ /* Extract petsc objects */
+ ksp_A11 = A11_solver;
+
+ /* compute rhs = A12^T A11^{-1} b1 - b2 */
+ KSPSolve( ksp_A11, b1, u_star ); /* u* = A11^{-1} b1 */
+ MatMultTranspose( A12, u_star, rhs ); /* b2 = A12^T u* */
+ VecAXPY( rhs, -1.0, b2 ); /* rhs <- rhs - b2 */
+}
+
+
+/* Computes r = f_hat - S p */
+#undef __FUNCT__
+#define __FUNCT__ "_Stokes_SLE_UzawaSolver_FormResidual"
+void _Stokes_SLE_UzawaSolver_FormResidual( void *stokesSLE, void *solver, Vec r )
+{
+ Stokes_SLE_UzawaSolver *self = (Stokes_SLE_UzawaSolver*)solver;
+ Stokes_SLE *sle = (Stokes_SLE*)stokesSLE;
+ /* stg linear algebra objects */
+ Mat A12 = sle->gStiffMat->matrix;
+ Mat A22 = NULL;
+ Vec x2 = sle->pSolnVec->vector;
+ Vec f_star = self->fTempVec;
+ Vec u_star = self->vStarVec;
+ Vec q_star = self->pTempVec;
+ KSP A11_solver = self->velSolver;
+
+ /* petsc objects */
+ KSP ksp_A11;
+ PetscInt r_N, x2_N;
+
+ /* check operations will be valid */
+ if (A11_solver==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "vel_solver is NULL" ); }
+ if (sle->dStiffMat!=NULL) { SETERRABORT( sle->comm, PETSC_ERR_SUP, "A21 must be NULL" ); }
+ if (A12==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "A12 is NULL" ); }
+ if (x2==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "x2 is NULL" ); }
+ if (u_star==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "u* is NULL" ); }
+ if (f_star==NULL){ SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "f* is NULL" ); }
+ if (q_star==NULL) { SETERRABORT( sle->comm, PETSC_ERR_ARG_NULL, "q* is NULL" ); }
+
+ A22 = PETSC_NULL;
+ if (sle->cStiffMat!=NULL) {
+ A22 = sle->cStiffMat->matrix;
+ }
+
+
+ /* Extract petsc objects */
+ ksp_A11 = A11_solver;
+
+ /* Check sizes match */
+ VecGetSize( r, &r_N );
+ VecGetSize( x2, &x2_N );
+ if (r_N!=x2_N) {
+ SETERRABORT( sle->comm, PETSC_ERR_ARG_SIZ, "Solution vector for pressure is not compatible with residual vector" );
+ }
+
+ /* r = f_hat - (G^T K^{-1} G - M) p */
+ _Stokes_SLE_UzawaSolver_GetRhs( stokesSLE, solver, r ); /* r <- f_hat */
+
+ /* correct for non zero A22 */
+ if (A22!=PETSC_NULL) {
+ MatMultAdd( A22, x2, r, r ); /* r <- r + A22 p */
+ }
+
+ /* make correction r <- r - G^T K^{-1} G */
+ MatMult( A12, x2, f_star ); /* f* <- A12 x2 */
+ KSPSolve( ksp_A11, f_star, u_star ); /* u* <- A11^{-1} f* */
+ MatMultTranspose( A12, u_star, q_star ); /* q* <- A12 u* */
+
+ VecAXPY( r, -1.0, q_star ); /* r <- r - q* */
+}
+
+Vec _Stokes_SLE_UzawaSolver_GetResidual( void* solver, Index fv_I ) {
+ return NULL;
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/UpdateDt.c
--- a/SLE/ProvidedSystems/StokesFlow/src/UpdateDt.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: UpdateDt.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "types.h"
-#include "Stokes_SLE.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-double Stokes_SLE_UpdateDt( Stokes_SLE* self, FiniteElementContext* context ) {
- double velMax = 0;
- double minSeparation = 0;
- double minSeparationEachDim[3] = { 0, 0, 0 };
- FeVariable* velFeVar = NULL;
- double localDt;
- double globalDt;
- Dictionary* dictionary = context->dictionary;
- double factor;
-
- globalDt=Dictionary_GetDouble_WithDefault(dictionary,"dt",0.0);
-
- if(globalDt==0.0)
- {
- velFeVar = self->uSolnVec->feVariable;
- velMax = FieldVariable_GetMaxGlobalFieldMagnitude( velFeVar );
-
- Journal_DPrintf( self->debug, "In func %s for SLE '%s' - Maximum global magnitude for field '%s' = %g.\n",
- __func__, self->name, velFeVar->name, velMax );
-
- FeVariable_GetMinimumSeparation( velFeVar, &minSeparation, minSeparationEachDim );
-
- factor=Dictionary_GetDouble_WithDefault(dictionary,"dtFactor",1.0);
- localDt = factor*0.5 * minSeparation / velMax;
-
- MPI_Allreduce( &localDt, &globalDt, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD );
- }
- return globalDt;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/UpdateDt.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/StokesFlow/src/UpdateDt.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,83 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: UpdateDt.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "types.h"
+#include "Stokes_SLE.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+double Stokes_SLE_UpdateDt( Stokes_SLE* self, FiniteElementContext* context ) {
+ double velMax = 0;
+ double minSeparation = 0;
+ double minSeparationEachDim[3] = { 0, 0, 0 };
+ FeVariable* velFeVar = NULL;
+ double localDt;
+ double globalDt;
+ Dictionary* dictionary = context->dictionary;
+ double factor;
+
+ globalDt=Dictionary_GetDouble_WithDefault(dictionary,"dt",0.0);
+
+ if(globalDt==0.0)
+ {
+ velFeVar = self->uSolnVec->feVariable;
+ velMax = FieldVariable_GetMaxGlobalFieldMagnitude( velFeVar );
+
+ Journal_DPrintf( self->debug, "In func %s for SLE '%s' - Maximum global magnitude for field '%s' = %g.\n",
+ __func__, self->name, velFeVar->name, velMax );
+
+ FeVariable_GetMinimumSeparation( velFeVar, &minSeparation, minSeparationEachDim );
+
+ factor=Dictionary_GetDouble_WithDefault(dictionary,"dtFactor",1.0);
+ localDt = factor*0.5 * minSeparation / velMax;
+
+ MPI_Allreduce( &localDt, &globalDt, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD );
+ }
+ return globalDt;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/UzawaPreconditionerTerm.c
--- a/SLE/ProvidedSystems/StokesFlow/src/UzawaPreconditionerTerm.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: UzawaPreconditionerTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/SLE/SystemSetup/SystemSetup.h>
-
-#include "types.h"
-#include "UzawaPreconditionerTerm.h"
-#include "Stokes_SLE.h"
-
-#include <assert.h>
-#include <string.h>
-
-/* Textual name of this class */
-const Type UzawaPreconditionerTerm_Type = "UzawaPreconditionerTerm";
-
-UzawaPreconditionerTerm* UzawaPreconditionerTerm_New(
- Name name,
- FiniteElementContext* context,
- StiffnessMatrix* stiffnessMatrix,
- Swarm* integrationSwarm )
-{
- UzawaPreconditionerTerm* self = (UzawaPreconditionerTerm*) _UzawaPreconditionerTerm_DefaultNew( name );
-
- self->isConstructed = True;
- _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
- _UzawaPreconditionerTerm_Init( self );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-UzawaPreconditionerTerm* _UzawaPreconditionerTerm_New( UZAWAPRECONDITIONERTERM_DEFARGS )
-{
- UzawaPreconditionerTerm* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(UzawaPreconditionerTerm) );
- self = (UzawaPreconditionerTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
-
- /* Virtual info */
-
- return self;
-}
-
-void _UzawaPreconditionerTerm_Init( void* matrixTerm ) {
-}
-
-void _UzawaPreconditionerTerm_Delete( void* matrixTerm ) {
- UzawaPreconditionerTerm* self = (UzawaPreconditionerTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Delete( self );
-}
-
-void _UzawaPreconditionerTerm_Print( void* matrixTerm, Stream* stream ) {
- UzawaPreconditionerTerm* self = (UzawaPreconditionerTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Print( self, stream );
-
- /* General info */
-}
-
-void* _UzawaPreconditionerTerm_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(UzawaPreconditionerTerm);
- Type type = UzawaPreconditionerTerm_Type;
- Stg_Class_DeleteFunction* _delete = _UzawaPreconditionerTerm_Delete;
- Stg_Class_PrintFunction* _print = _UzawaPreconditionerTerm_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _UzawaPreconditionerTerm_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _UzawaPreconditionerTerm_AssignFromXML;
- Stg_Component_BuildFunction* _build = _UzawaPreconditionerTerm_Build;
- Stg_Component_InitialiseFunction* _initialise = _UzawaPreconditionerTerm_Initialise;
- Stg_Component_ExecuteFunction* _execute = _UzawaPreconditionerTerm_Execute;
- Stg_Component_DestroyFunction* _destroy = _UzawaPreconditionerTerm_Destroy;
- StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _UzawaPreconditionerTerm_AssembleElement;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*)_UzawaPreconditionerTerm_New( UZAWAPRECONDITIONERTERM_PASSARGS );
-}
-
-void _UzawaPreconditionerTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
- UzawaPreconditionerTerm* self = (UzawaPreconditionerTerm*)matrixTerm;
-
- /* Construct Parent */
- _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
-
- _UzawaPreconditionerTerm_Init( self );
-}
-
-void _UzawaPreconditionerTerm_Build( void* matrixTerm, void* data ) {
- UzawaPreconditionerTerm* self = (UzawaPreconditionerTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Build( self, data );
-}
-
-void _UzawaPreconditionerTerm_Initialise( void* matrixTerm, void* data ) {
- UzawaPreconditionerTerm* self = (UzawaPreconditionerTerm*)matrixTerm;
-
- _StiffnessMatrixTerm_Initialise( self, data );
-}
-
-void _UzawaPreconditionerTerm_Execute( void* matrixTerm, void* data ) {
- _StiffnessMatrixTerm_Execute( matrixTerm, data );
-}
-
-void _UzawaPreconditionerTerm_Destroy( void* matrixTerm, void* data ) {
- _StiffnessMatrixTerm_Destroy( matrixTerm, data );
-}
-
-
-void _UzawaPreconditionerTerm_AssembleElement(
- void* matrixTerm,
- StiffnessMatrix* stiffnessMatrix,
- Element_LocalIndex lElement_I,
- SystemLinearEquations* _sle,
- FiniteElementContext* context,
- double** elPreconditioner )
-{
- Stokes_SLE* sle = Stg_DCheckType( _sle, Stokes_SLE );
- StiffnessMatrix* gMatrix = sle->gStiffMat;
- FeVariable* gFeVariable_col = gMatrix->columnVariable;
- ElementType* gElementType_col = FeMesh_GetElementType( gFeVariable_col->feMesh, lElement_I );
- Node_ElementLocalIndex gColCount = gElementType_col->nodeCount;
- double** gElementMatrix;
-
- StiffnessMatrix* kMatrix = sle->kStiffMat;
- FeVariable* kFeVariable_row = kMatrix->rowVariable;
- ElementType* kElementType_row = FeMesh_GetElementType( kFeVariable_row->feMesh, lElement_I );
- Node_ElementLocalIndex kRowCount = kElementType_row->nodeCount;
-
- Index velocityDofCount;
- Index pressureDofCount;
- double** kElementMatrix;
-
- double** kInverseG;
- Index row_I;
- Index col_I;
- Index vel_I;
-
- pressureDofCount = gColCount;
- velocityDofCount = kRowCount * kMatrix->dim;
-
- /* Allocate Memory */
- gElementMatrix = Memory_Alloc_2DArray( double, velocityDofCount, pressureDofCount, (Name)"g element matrix" );
- memset( gElementMatrix[0], 0, sizeof(double) * velocityDofCount * pressureDofCount );
- kElementMatrix = Memory_Alloc_2DArray( double, velocityDofCount, velocityDofCount, (Name)"k element matrix" );
- memset( kElementMatrix[0], 0, sizeof(double) * velocityDofCount * velocityDofCount );
- kInverseG = Memory_Alloc_2DArray( double, velocityDofCount, pressureDofCount, (Name)"[ diag(K) ]^-1 G" );
-
- /* Assemble Element G */
- StiffnessMatrix_AssembleElement( gMatrix, lElement_I, _sle, context, gElementMatrix );
-
- /* Assemble Element K */
- StiffnessMatrix_AssembleElement( kMatrix, lElement_I, _sle, context, kElementMatrix );
-
- /* Assemble [ diag(K) ]^-1 G */
- for ( row_I = 0 ; row_I < velocityDofCount ; row_I++ ) {
- for ( col_I = 0 ; col_I < pressureDofCount ; col_I++ ) {
- kInverseG[ row_I ][ col_I ] = gElementMatrix[ row_I ][ col_I ] / kElementMatrix[ row_I ][ row_I ];
- }
- }
-
- /* Assemble Gt [ diag(K) ]^-1 G */
- for ( row_I = 0 ; row_I < pressureDofCount ; row_I++ ) {
- for ( col_I = 0 ; col_I < pressureDofCount ; col_I++ ) {
-
- for ( vel_I = 0 ; vel_I < velocityDofCount ; vel_I++ )
- elPreconditioner[ row_I ][ col_I ] += gElementMatrix[ vel_I ][ col_I ] * kInverseG[ vel_I ][ row_I ];
- }
- }
- Memory_Free( kInverseG );
- Memory_Free( gElementMatrix );
- Memory_Free( kElementMatrix );
-
-
- /* Correct for Compressibility */
- if ( sle->cStiffMat ) {
- double** mElementMatrix;
- StiffnessMatrix* cMatrix = sle->cStiffMat;
-
- mElementMatrix = Memory_Alloc_2DArray( double, pressureDofCount, pressureDofCount, (Name)"m element matrix" );
- memset( mElementMatrix[0], 0, sizeof(double) * pressureDofCount * pressureDofCount );
-
- StiffnessMatrix_AssembleElement( cMatrix, lElement_I, _sle, context, mElementMatrix );
-
- for ( row_I = 0 ; row_I < pressureDofCount ; row_I++ ) {
- for ( col_I = 0 ; col_I < pressureDofCount ; col_I++ ) {
- elPreconditioner[ row_I ][ col_I ] -= mElementMatrix[ row_I ][ col_I ];
- }
- }
-
- Memory_Free( mElementMatrix );
- }
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/StokesFlow/src/UzawaPreconditionerTerm.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/StokesFlow/src/UzawaPreconditionerTerm.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,241 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: UzawaPreconditionerTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include <StgFEM/SLE/SystemSetup/SystemSetup.h>
+
+#include "types.h"
+#include "UzawaPreconditionerTerm.h"
+#include "Stokes_SLE.h"
+
+#include <assert.h>
+#include <string.h>
+
+/* Textual name of this class */
+const Type UzawaPreconditionerTerm_Type = "UzawaPreconditionerTerm";
+
+UzawaPreconditionerTerm* UzawaPreconditionerTerm_New(
+ Name name,
+ FiniteElementContext* context,
+ StiffnessMatrix* stiffnessMatrix,
+ Swarm* integrationSwarm )
+{
+ UzawaPreconditionerTerm* self = (UzawaPreconditionerTerm*) _UzawaPreconditionerTerm_DefaultNew( name );
+
+ self->isConstructed = True;
+ _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, NULL );
+ _UzawaPreconditionerTerm_Init( self );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+UzawaPreconditionerTerm* _UzawaPreconditionerTerm_New( UZAWAPRECONDITIONERTERM_DEFARGS )
+{
+ UzawaPreconditionerTerm* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(UzawaPreconditionerTerm) );
+ self = (UzawaPreconditionerTerm*) _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _UzawaPreconditionerTerm_Init( void* matrixTerm ) {
+}
+
+void _UzawaPreconditionerTerm_Delete( void* matrixTerm ) {
+ UzawaPreconditionerTerm* self = (UzawaPreconditionerTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Delete( self );
+}
+
+void _UzawaPreconditionerTerm_Print( void* matrixTerm, Stream* stream ) {
+ UzawaPreconditionerTerm* self = (UzawaPreconditionerTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Print( self, stream );
+
+ /* General info */
+}
+
+void* _UzawaPreconditionerTerm_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(UzawaPreconditionerTerm);
+ Type type = UzawaPreconditionerTerm_Type;
+ Stg_Class_DeleteFunction* _delete = _UzawaPreconditionerTerm_Delete;
+ Stg_Class_PrintFunction* _print = _UzawaPreconditionerTerm_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _UzawaPreconditionerTerm_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _UzawaPreconditionerTerm_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _UzawaPreconditionerTerm_Build;
+ Stg_Component_InitialiseFunction* _initialise = _UzawaPreconditionerTerm_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _UzawaPreconditionerTerm_Execute;
+ Stg_Component_DestroyFunction* _destroy = _UzawaPreconditionerTerm_Destroy;
+ StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _UzawaPreconditionerTerm_AssembleElement;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*)_UzawaPreconditionerTerm_New( UZAWAPRECONDITIONERTERM_PASSARGS );
+}
+
+void _UzawaPreconditionerTerm_AssignFromXML( void* matrixTerm, Stg_ComponentFactory* cf, void* data ) {
+ UzawaPreconditionerTerm* self = (UzawaPreconditionerTerm*)matrixTerm;
+
+ /* Construct Parent */
+ _StiffnessMatrixTerm_AssignFromXML( self, cf, data );
+
+ _UzawaPreconditionerTerm_Init( self );
+}
+
+void _UzawaPreconditionerTerm_Build( void* matrixTerm, void* data ) {
+ UzawaPreconditionerTerm* self = (UzawaPreconditionerTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Build( self, data );
+}
+
+void _UzawaPreconditionerTerm_Initialise( void* matrixTerm, void* data ) {
+ UzawaPreconditionerTerm* self = (UzawaPreconditionerTerm*)matrixTerm;
+
+ _StiffnessMatrixTerm_Initialise( self, data );
+}
+
+void _UzawaPreconditionerTerm_Execute( void* matrixTerm, void* data ) {
+ _StiffnessMatrixTerm_Execute( matrixTerm, data );
+}
+
+void _UzawaPreconditionerTerm_Destroy( void* matrixTerm, void* data ) {
+ _StiffnessMatrixTerm_Destroy( matrixTerm, data );
+}
+
+
+void _UzawaPreconditionerTerm_AssembleElement(
+ void* matrixTerm,
+ StiffnessMatrix* stiffnessMatrix,
+ Element_LocalIndex lElement_I,
+ SystemLinearEquations* _sle,
+ FiniteElementContext* context,
+ double** elPreconditioner )
+{
+ Stokes_SLE* sle = Stg_DCheckType( _sle, Stokes_SLE );
+ StiffnessMatrix* gMatrix = sle->gStiffMat;
+ FeVariable* gFeVariable_col = gMatrix->columnVariable;
+ ElementType* gElementType_col = FeMesh_GetElementType( gFeVariable_col->feMesh, lElement_I );
+ Node_ElementLocalIndex gColCount = gElementType_col->nodeCount;
+ double** gElementMatrix;
+
+ StiffnessMatrix* kMatrix = sle->kStiffMat;
+ FeVariable* kFeVariable_row = kMatrix->rowVariable;
+ ElementType* kElementType_row = FeMesh_GetElementType( kFeVariable_row->feMesh, lElement_I );
+ Node_ElementLocalIndex kRowCount = kElementType_row->nodeCount;
+
+ Index velocityDofCount;
+ Index pressureDofCount;
+ double** kElementMatrix;
+
+ double** kInverseG;
+ Index row_I;
+ Index col_I;
+ Index vel_I;
+
+ pressureDofCount = gColCount;
+ velocityDofCount = kRowCount * kMatrix->dim;
+
+ /* Allocate Memory */
+ gElementMatrix = Memory_Alloc_2DArray( double, velocityDofCount, pressureDofCount, (Name)"g element matrix" );
+ memset( gElementMatrix[0], 0, sizeof(double) * velocityDofCount * pressureDofCount );
+ kElementMatrix = Memory_Alloc_2DArray( double, velocityDofCount, velocityDofCount, (Name)"k element matrix" );
+ memset( kElementMatrix[0], 0, sizeof(double) * velocityDofCount * velocityDofCount );
+ kInverseG = Memory_Alloc_2DArray( double, velocityDofCount, pressureDofCount, (Name)"[ diag(K) ]^-1 G" );
+
+ /* Assemble Element G */
+ StiffnessMatrix_AssembleElement( gMatrix, lElement_I, _sle, context, gElementMatrix );
+
+ /* Assemble Element K */
+ StiffnessMatrix_AssembleElement( kMatrix, lElement_I, _sle, context, kElementMatrix );
+
+ /* Assemble [ diag(K) ]^-1 G */
+ for ( row_I = 0 ; row_I < velocityDofCount ; row_I++ ) {
+ for ( col_I = 0 ; col_I < pressureDofCount ; col_I++ ) {
+ kInverseG[ row_I ][ col_I ] = gElementMatrix[ row_I ][ col_I ] / kElementMatrix[ row_I ][ row_I ];
+ }
+ }
+
+ /* Assemble Gt [ diag(K) ]^-1 G */
+ for ( row_I = 0 ; row_I < pressureDofCount ; row_I++ ) {
+ for ( col_I = 0 ; col_I < pressureDofCount ; col_I++ ) {
+
+ for ( vel_I = 0 ; vel_I < velocityDofCount ; vel_I++ )
+ elPreconditioner[ row_I ][ col_I ] += gElementMatrix[ vel_I ][ col_I ] * kInverseG[ vel_I ][ row_I ];
+ }
+ }
+ Memory_Free( kInverseG );
+ Memory_Free( gElementMatrix );
+ Memory_Free( kElementMatrix );
+
+
+ /* Correct for Compressibility */
+ if ( sle->cStiffMat ) {
+ double** mElementMatrix;
+ StiffnessMatrix* cMatrix = sle->cStiffMat;
+
+ mElementMatrix = Memory_Alloc_2DArray( double, pressureDofCount, pressureDofCount, (Name)"m element matrix" );
+ memset( mElementMatrix[0], 0, sizeof(double) * pressureDofCount * pressureDofCount );
+
+ StiffnessMatrix_AssembleElement( cMatrix, lElement_I, _sle, context, mElementMatrix );
+
+ for ( row_I = 0 ; row_I < pressureDofCount ; row_I++ ) {
+ for ( col_I = 0 ; col_I < pressureDofCount ; col_I++ ) {
+ elPreconditioner[ row_I ][ col_I ] -= mElementMatrix[ row_I ][ col_I ];
+ }
+ }
+
+ Memory_Free( mElementMatrix );
+ }
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/src/Finalise.c
--- a/SLE/ProvidedSystems/src/Finalise.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "StgFEM/SLE/ProvidedSystems/Energy/Energy.h"
-#include "StgFEM/SLE/ProvidedSystems/StokesFlow/StokesFlow.h"
-#include "StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/AdvectionDiffusion.h"
-#include "Finalise.h"
-
-#include <stdio.h>
-
-Bool StgFEM_SLE_ProvidedSystems_Finalise( void ) {
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- StgFEM_SLE_ProvidedSystems_Energy_Finalise();
- StgFEM_SLE_ProvidedSystems_StokesFlow_Finalise();
- StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Finalise();
-
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/src/Finalise.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/src/Finalise.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,64 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "StgFEM/SLE/ProvidedSystems/Energy/Energy.h"
+#include "StgFEM/SLE/ProvidedSystems/StokesFlow/StokesFlow.h"
+#include "StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/AdvectionDiffusion.h"
+#include "Finalise.h"
+
+#include <stdio.h>
+
+Bool StgFEM_SLE_ProvidedSystems_Finalise( void ) {
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ StgFEM_SLE_ProvidedSystems_Energy_Finalise();
+ StgFEM_SLE_ProvidedSystems_StokesFlow_Finalise();
+ StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Finalise();
+
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/src/Init.c
--- a/SLE/ProvidedSystems/src/Init.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "StgFEM/SLE/ProvidedSystems/Energy/Energy.h"
-#include "StgFEM/SLE/ProvidedSystems/StokesFlow/StokesFlow.h"
-#include "StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/AdvectionDiffusion.h"
-#include "Init.h"
-
-#include <stdio.h>
-
-/** Initialises the Linear Algebra package, then any init for this package
-such as streams etc */
-Bool StgFEM_SLE_ProvidedSystems_Init( int* argc, char** argv[] ) {
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- StgFEM_SLE_ProvidedSystems_Energy_Init( argc, argv );
- StgFEM_SLE_ProvidedSystems_StokesFlow_Init( argc, argv );
- StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Init( argc, argv );
-
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/ProvidedSystems/src/Init.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/ProvidedSystems/src/Init.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,66 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "StgFEM/SLE/ProvidedSystems/Energy/Energy.h"
+#include "StgFEM/SLE/ProvidedSystems/StokesFlow/StokesFlow.h"
+#include "StgFEM/SLE/ProvidedSystems/AdvectionDiffusion/AdvectionDiffusion.h"
+#include "Init.h"
+
+#include <stdio.h>
+
+/** Initialises the Linear Algebra package, then any init for this package
+such as streams etc */
+Bool StgFEM_SLE_ProvidedSystems_Init( int* argc, char** argv[] ) {
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ StgFEM_SLE_ProvidedSystems_Energy_Init( argc, argv );
+ StgFEM_SLE_ProvidedSystems_StokesFlow_Init( argc, argv );
+ StgFEM_SLE_ProvidedSystems_AdvectionDiffusion_Init( argc, argv );
+
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/Assembler.c
--- a/SLE/SystemSetup/src/Assembler.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,423 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Assembler.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "Discretisation/Discretisation.h"
-#include "SystemSetup.h"
-
-
-/* Textual name of this class */
-const Type Assembler_Type = "Assembler";
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-Assembler* Assembler_New() {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(Assembler);
- Type type = Assembler_Type;
- Stg_Class_DeleteFunction* _delete = _Assembler_Delete;
- Stg_Class_PrintFunction* _print = _Assembler_Print;
- Stg_Class_CopyFunction* _copy = NULL;
-
- return _Assembler_New( ASSEMBLER_PASSARGS );
-}
-
-Assembler* _Assembler_New( ASSEMBLER_DEFARGS ) {
- Assembler* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(Assembler) );
- self = (Assembler*)_Stg_Class_New( STG_CLASS_PASSARGS );
-
- /* Virtual info */
-
- /* Assembler info */
- _Assembler_Init( self );
-
- return self;
-}
-
-void _Assembler_Init( Assembler* self ) {
- assert( self && Stg_CheckType( self, Assembler ) );
-
- self->rowVar = NULL;
- self->colVar = NULL;
- self->swarm = NULL;
- self->rowRCB = NULL;
- self->rowUCB = NULL;
- self->colRCB = NULL;
- self->colUCB = NULL;
- self->obj = NULL;
-
- self->elInd = 0;
- self->particle = NULL;
- self->shapeFuncs = NULL;
- self->detJac = 0.0;
- self->globalDerivs = NULL;
- self->rowInd = 0;
- self->rowNodeInd = 0;
- self->rowDofInd = 0;
- self->rowEq = 0;
- self->colInd = 0;
- self->colNodeInd = 0;
- self->colDofInd = 0;
- self->colEq = 0;
-
- self->rowInc = IArray_New();
- self->colInc = IArray_New();
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _Assembler_Delete( void* assembler ) {
- Assembler* self = (Assembler*)assembler;
-
- assert( self && Stg_CheckType( self, Assembler ) );
-
- FreeArray( self->shapeFuncs );
- FreeArray( self->globalDerivs );
- NewClass_Delete( self->rowInc );
- NewClass_Delete( self->colInc );
-
- /* Delete the parent. */
- _Stg_Class_Delete( self );
-}
-
-void _Assembler_Print( void* assembler, Stream* stream ) {
- Assembler* self = (Assembler*)assembler;
- Stream* assemblerStream;
-
- assert( self && Stg_CheckType( self, Assembler ) );
-
- /* Set the Journal for printing informations */
- assemblerStream = Journal_Register( InfoStream_Type, (Name)"AssemblerStream" );
-
- /* Print parent */
- Journal_Printf( stream, "Assembler (ptr): (%p)\n", self );
- _Stg_Class_Print( self, stream );
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-void Assembler_SetVariables( void* assembler, FeVariable* rowVar, FeVariable* columnVar ) {
- Assembler* self = (Assembler*)assembler;
-
- assert( self && Stg_CheckType( self, Assembler ) );
- assert( rowVar || columnVar );
-
- self->rowVar = rowVar ? rowVar : columnVar;
- self->colVar = columnVar ? columnVar : rowVar;
- Assembler_Update( self );
-}
-
-void Assembler_SetIntegrationSwarm( void* assembler, Swarm* swarm ) {
- Assembler* self = (Assembler*)assembler;
-
- assert( self && Stg_CheckType( self, Assembler ) );
-
- self->swarm = swarm;
-}
-
-void Assembler_SetCallbacks( void* assembler,
- Assembler_CallbackType* particle,
- Assembler_CallbackType* rowRestricted,
- Assembler_CallbackType* rowUnrestricted,
- Assembler_CallbackType* colRestricted,
- Assembler_CallbackType* colUnrestricted,
- void* object )
-{
- Assembler* self = (Assembler*)assembler;
-
- assert( self && Stg_CheckType( self, Assembler ) );
-
- self->partCB = particle;
- self->rowRCB = rowRestricted;
- self->rowUCB = rowUnrestricted;
- self->colRCB = colRestricted;
- self->colUCB = colUnrestricted;
- self->obj = object;
-}
-
-void Assembler_Update( void* assembler ) {
- Assembler* self = (Assembler*)assembler;
- unsigned nDerivs, nDims;
- unsigned e_i;
-
- assert( self && Stg_CheckType( self, Assembler ) );
-
- nDerivs = 0;
- nDims = 0;
- if( self->rowVar ) {
- FeMesh* mesh = self->rowVar->feMesh;
-
- nDims = Mesh_GetDimSize( mesh );
- for( e_i = 0; e_i < FeMesh_GetElementLocalSize( mesh ); e_i++ ) {
- if( FeMesh_GetElementNodeSize( mesh, e_i ) > nDerivs )
- nDerivs = FeMesh_GetElementNodeSize( mesh, e_i );
- }
- }
- self->shapeFuncs = ReallocArray( self->shapeFuncs, double, nDerivs );
- self->globalDerivs = ReallocArray2D( self->globalDerivs, double, nDims, nDerivs );
-}
-
-void Assembler_IntegrateMatrixElement( void* assembler, unsigned element ) {
- Assembler* self = (Assembler*)assembler;
- FeMesh* mesh;
- Swarm* swarm;
- unsigned nDims;
- unsigned cellInd, nParticles;
- ElementType* elType;
- unsigned p_i;
-
- assert( self && Stg_CheckType( self, Assembler ) );
- assert( self->rowVar && self->colVar );
-
- mesh = self->rowVar->feMesh;
- nDims = Mesh_GetDimSize( mesh );
- swarm = self->swarm; assert( swarm );
- assert( swarm->cellLayout );
- assert( swarm->cellParticleCountTbl );
- cellInd = CellLayout_MapElementIdToCellId( swarm->cellLayout, element );
- nParticles = swarm->cellParticleCountTbl[cellInd];
- elType = FeMesh_GetElementType( mesh, element );
-
- for( p_i = 0; p_i < nParticles; p_i++ ) {
- self->particle = (IntegrationPoint*)Swarm_ParticleInCellAt( swarm, cellInd, p_i );
- assert( self->particle );
- ElementType_EvaluateShapeFunctionsAt( elType, self->particle->xi, self->shapeFuncs );
- ElementType_ShapeFunctionsGlobalDerivs( elType, mesh, element, self->particle->xi, nDims,
- &self->detJac, self->globalDerivs );
- if( self->partCB && !self->partCB( self->obj, self ) )
- continue;
-
- Assembler_LoopMatrixElement( self, element );
- }
-}
-
-void Assembler_LoopMatrixElement( void* assembler, unsigned element ) {
- Assembler* self = (Assembler*)assembler;
- unsigned nDims;
- FeVariable *rowVar, *colVar;
- FeMesh *rowMesh, *colMesh;
- FeEquationNumber *rowEqNum, *colEqNum;
- DofLayout *rowDofs, *colDofs;
- unsigned nRowDofs, nColDofs;
- unsigned nRowElNodes, *rowElNodes;
- unsigned nColElNodes, *colElNodes;
- int rowEq, colEq;
- unsigned rowInd, colInd;
- unsigned n_i, n_j, dof_i, dof_j;
-
- assert( self && Stg_CheckType( self, Assembler ) );
- assert( self->rowVar && self->colVar );
-
- self->elInd = element;
- rowVar = self->rowVar;
- colVar = self->colVar;
- rowEqNum = rowVar->eqNum; assert( rowEqNum );
- colEqNum = colVar->eqNum; assert( colEqNum );
- rowMesh = rowVar->feMesh;
- colMesh = colVar->feMesh;
- rowDofs = rowVar->dofLayout; assert( rowDofs );
- colDofs = colVar->dofLayout; assert( colDofs );
- nDims = Mesh_GetDimSize( rowMesh ); assert( nDims );
- Mesh_GetIncidence( rowMesh, (MeshTopology_Dim)nDims, element, MT_VERTEX, self->rowInc );
- nRowElNodes = IArray_GetSize( self->rowInc );
- rowElNodes = (unsigned*)IArray_GetPtr( self->rowInc );
- Mesh_GetIncidence( colMesh, Mesh_GetDimSize( colMesh ), element, MT_VERTEX,
- self->colInc );
- nColElNodes = IArray_GetSize( self->colInc );
- colElNodes = (unsigned*)IArray_GetPtr( self->colInc );
- assert( FeMesh_GetElementLocalSize( rowMesh ) == FeMesh_GetElementLocalSize( colMesh ) );
- assert( nDims == Mesh_GetDimSize( colMesh ) );
- assert( rowEqNum->locationMatrix );
- assert( colEqNum->locationMatrix );
- assert( rowEqNum->locationMatrix[element] );
- assert( colEqNum->locationMatrix[element] );
- assert( rowDofs->dofCounts );
- assert( colDofs->dofCounts );
-
- rowInd = 0;
- for( n_i = 0; n_i < nRowElNodes; n_i++ ) {
- assert( rowEqNum->locationMatrix[element][n_i] );
- nRowDofs = rowDofs->dofCounts[rowElNodes[n_i]];
- for( dof_i = 0; dof_i < nRowDofs; dof_i++ ) {
- rowEq = rowEqNum->locationMatrix[element][n_i][dof_i];
-
- self->rowInd = rowInd++;
- self->rowElNodeInd = n_i;
- self->rowNodeInd = rowElNodes[n_i];
- self->rowDofInd = dof_i;
- self->rowEq = rowEq;
- if( rowVar->bcs && FeVariable_IsBC( rowVar, rowElNodes[n_i], dof_i ) ) {
- if( !self->rowRCB || !self->rowRCB( self->obj, self ) )
- continue;
- }
- else if( self->rowUCB && !self->rowUCB( self->obj, self ) )
- continue;
-
- colInd = 0;
- for( n_j = 0; n_j < nColElNodes; n_j++ ) {
- assert( colEqNum->locationMatrix[element][n_j] );
- nColDofs = colDofs->dofCounts[colElNodes[n_j]];
- for( dof_j = 0; dof_j < nColDofs; dof_j++ ) {
- colEq = colEqNum->locationMatrix[element][n_j][dof_j];
-
- self->colInd = colInd++;
- self->colElNodeInd = n_j;
- self->colNodeInd = colElNodes[n_j];
- self->colDofInd = dof_j;
- self->colEq = colEq;
- if( colVar->bcs && FeVariable_IsBC( colVar, colElNodes[n_j], dof_j ) ) {
- if( self->colRCB )
- self->colRCB( self->obj, self );
- }
- else if( self->colUCB )
- self->colUCB( self->obj, self );
- }
- }
- }
- }
-}
-
-void Assembler_LoopMatrixDiagonal( void* assembler ) {
- Assembler* self = (Assembler*)assembler;
- unsigned nDims;
- FeVariable *rowVar;
- FeMesh *rowMesh;
- FeEquationNumber *rowEqNum;
- DofLayout *rowDofs;
- unsigned nRowDofs;
- unsigned nRowNodes;
- int rowEq;
- unsigned n_i, dof_i;
-
- assert( self && Stg_CheckType( self, Assembler ) );
- assert( self->rowVar && self->colVar );
- assert( self->rowVar == self->colVar );
-
- rowVar = self->rowVar;
- rowEqNum = rowVar->eqNum; assert( rowEqNum );
- rowMesh = rowVar->feMesh;
- rowDofs = rowVar->dofLayout; assert( rowDofs );
- nDims = Mesh_GetDimSize( rowMesh ); assert( nDims );
- nRowNodes = FeMesh_GetNodeLocalSize( rowMesh );
- assert( rowEqNum->destinationArray );
- assert( rowDofs->dofCounts );
-
- for( n_i = 0; n_i < nRowNodes; n_i++ ) {
- assert( rowEqNum->destinationArray[n_i] );
- nRowDofs = rowDofs->dofCounts[n_i];
- for( dof_i = 0; dof_i < nRowDofs; dof_i++ ) {
- rowEq = rowEqNum->destinationArray[n_i][dof_i];
-
- self->rowNodeInd = n_i;
- self->rowDofInd = dof_i;
- self->rowEq = rowEq;
- self->colNodeInd = n_i;
- self->colDofInd = dof_i;
- self->colEq = rowEq;
- if( rowVar->bcs && FeVariable_IsBC( rowVar, n_i, dof_i ) ) {
- if( self->rowRCB )
- self->rowRCB( self->obj, self );
- }
- else if( self->rowUCB )
- self->rowUCB( self->obj, self );
- }
- }
-}
-
-#if 0
-void Assembler_LoopVectorElement( void* assembler, unsigned element ) {
- Assembler* self = (Assembler*)assembler;
- unsigned nDims;
- FeVariable *rowVar;
- FeMesh *rowMesh;
- FeEquationNumber *rowEqNum;
- DofLayout *rowDofs;
- unsigned nRowDofs;
- unsigned nRowElNodes, *rowElNodes;
- int rowEq;
- unsigned n_i, dof_i;
-
- assert( self && Stg_CheckType( self, Assembler ) );
- assert( self->rowVar && self->colVar );
- assert( self->colCB );
-
- self->elInd = element;
- rowVar = self->rowVar;
- rowEqNum = rowVar->eqNum; assert( rowEqNum );
- rowMesh = rowVar->feMesh;
- rowDofs = rowVar->dofLayout; assert( rowDofs );
- nDims = Mesh_GetDimSize( rowMesh ); assert( nDims );
- Mesh_GetIncidence( rowMesh, nDims, element, MT_VERTEX, self->rowInc );
- nRowElNodes = IArray_GetSize( self->rowInc );
- rowElNodes = IArray_GetPtr( self->rowInc );
- assert( rowEqNum->locationMatrix );
- assert( rowEqNum->locationMatrix[element] );
- assert( rowDofs->dofCounts );
-
- for( n_i = 0; n_i < nRowElNodes; n_i++ ) {
- assert( rowEqNum->locationMatrix[element][n_i] );
- nRowDofs = rowDofs->dofCounts[rowElNodes[n_i]];
- for( dof_i = 0; dof_i < nRowDofs; dof_i++ ) {
- rowEq = rowEqNum->locationMatrix[element][n_i][dof_i];
-
- self->rowNodeInd = n_i;
- self->rowDofInd = dof_i;
- self->rowEq = rowEq;
- self->colCB( self );
- }
- }
-}
-#endif
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/Assembler.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/Assembler.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,423 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Assembler.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "Discretisation/Discretisation.h"
+#include "SystemSetup.h"
+
+
+/* Textual name of this class */
+const Type Assembler_Type = "Assembler";
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+Assembler* Assembler_New() {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(Assembler);
+ Type type = Assembler_Type;
+ Stg_Class_DeleteFunction* _delete = _Assembler_Delete;
+ Stg_Class_PrintFunction* _print = _Assembler_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+
+ return _Assembler_New( ASSEMBLER_PASSARGS );
+}
+
+Assembler* _Assembler_New( ASSEMBLER_DEFARGS ) {
+ Assembler* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(Assembler) );
+ self = (Assembler*)_Stg_Class_New( STG_CLASS_PASSARGS );
+
+ /* Virtual info */
+
+ /* Assembler info */
+ _Assembler_Init( self );
+
+ return self;
+}
+
+void _Assembler_Init( Assembler* self ) {
+ assert( self && Stg_CheckType( self, Assembler ) );
+
+ self->rowVar = NULL;
+ self->colVar = NULL;
+ self->swarm = NULL;
+ self->rowRCB = NULL;
+ self->rowUCB = NULL;
+ self->colRCB = NULL;
+ self->colUCB = NULL;
+ self->obj = NULL;
+
+ self->elInd = 0;
+ self->particle = NULL;
+ self->shapeFuncs = NULL;
+ self->detJac = 0.0;
+ self->globalDerivs = NULL;
+ self->rowInd = 0;
+ self->rowNodeInd = 0;
+ self->rowDofInd = 0;
+ self->rowEq = 0;
+ self->colInd = 0;
+ self->colNodeInd = 0;
+ self->colDofInd = 0;
+ self->colEq = 0;
+
+ self->rowInc = IArray_New();
+ self->colInc = IArray_New();
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _Assembler_Delete( void* assembler ) {
+ Assembler* self = (Assembler*)assembler;
+
+ assert( self && Stg_CheckType( self, Assembler ) );
+
+ FreeArray( self->shapeFuncs );
+ FreeArray( self->globalDerivs );
+ NewClass_Delete( self->rowInc );
+ NewClass_Delete( self->colInc );
+
+ /* Delete the parent. */
+ _Stg_Class_Delete( self );
+}
+
+void _Assembler_Print( void* assembler, Stream* stream ) {
+ Assembler* self = (Assembler*)assembler;
+ Stream* assemblerStream;
+
+ assert( self && Stg_CheckType( self, Assembler ) );
+
+ /* Set the Journal for printing informations */
+ assemblerStream = Journal_Register( InfoStream_Type, (Name)"AssemblerStream" );
+
+ /* Print parent */
+ Journal_Printf( stream, "Assembler (ptr): (%p)\n", self );
+ _Stg_Class_Print( self, stream );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+void Assembler_SetVariables( void* assembler, FeVariable* rowVar, FeVariable* columnVar ) {
+ Assembler* self = (Assembler*)assembler;
+
+ assert( self && Stg_CheckType( self, Assembler ) );
+ assert( rowVar || columnVar );
+
+ self->rowVar = rowVar ? rowVar : columnVar;
+ self->colVar = columnVar ? columnVar : rowVar;
+ Assembler_Update( self );
+}
+
+void Assembler_SetIntegrationSwarm( void* assembler, Swarm* swarm ) {
+ Assembler* self = (Assembler*)assembler;
+
+ assert( self && Stg_CheckType( self, Assembler ) );
+
+ self->swarm = swarm;
+}
+
+void Assembler_SetCallbacks( void* assembler,
+ Assembler_CallbackType* particle,
+ Assembler_CallbackType* rowRestricted,
+ Assembler_CallbackType* rowUnrestricted,
+ Assembler_CallbackType* colRestricted,
+ Assembler_CallbackType* colUnrestricted,
+ void* object )
+{
+ Assembler* self = (Assembler*)assembler;
+
+ assert( self && Stg_CheckType( self, Assembler ) );
+
+ self->partCB = particle;
+ self->rowRCB = rowRestricted;
+ self->rowUCB = rowUnrestricted;
+ self->colRCB = colRestricted;
+ self->colUCB = colUnrestricted;
+ self->obj = object;
+}
+
+void Assembler_Update( void* assembler ) {
+ Assembler* self = (Assembler*)assembler;
+ unsigned nDerivs, nDims;
+ unsigned e_i;
+
+ assert( self && Stg_CheckType( self, Assembler ) );
+
+ nDerivs = 0;
+ nDims = 0;
+ if( self->rowVar ) {
+ FeMesh* mesh = self->rowVar->feMesh;
+
+ nDims = Mesh_GetDimSize( mesh );
+ for( e_i = 0; e_i < FeMesh_GetElementLocalSize( mesh ); e_i++ ) {
+ if( FeMesh_GetElementNodeSize( mesh, e_i ) > nDerivs )
+ nDerivs = FeMesh_GetElementNodeSize( mesh, e_i );
+ }
+ }
+ self->shapeFuncs = ReallocArray( self->shapeFuncs, double, nDerivs );
+ self->globalDerivs = ReallocArray2D( self->globalDerivs, double, nDims, nDerivs );
+}
+
+void Assembler_IntegrateMatrixElement( void* assembler, unsigned element ) {
+ Assembler* self = (Assembler*)assembler;
+ FeMesh* mesh;
+ Swarm* swarm;
+ unsigned nDims;
+ unsigned cellInd, nParticles;
+ ElementType* elType;
+ unsigned p_i;
+
+ assert( self && Stg_CheckType( self, Assembler ) );
+ assert( self->rowVar && self->colVar );
+
+ mesh = self->rowVar->feMesh;
+ nDims = Mesh_GetDimSize( mesh );
+ swarm = self->swarm; assert( swarm );
+ assert( swarm->cellLayout );
+ assert( swarm->cellParticleCountTbl );
+ cellInd = CellLayout_MapElementIdToCellId( swarm->cellLayout, element );
+ nParticles = swarm->cellParticleCountTbl[cellInd];
+ elType = FeMesh_GetElementType( mesh, element );
+
+ for( p_i = 0; p_i < nParticles; p_i++ ) {
+ self->particle = (IntegrationPoint*)Swarm_ParticleInCellAt( swarm, cellInd, p_i );
+ assert( self->particle );
+ ElementType_EvaluateShapeFunctionsAt( elType, self->particle->xi, self->shapeFuncs );
+ ElementType_ShapeFunctionsGlobalDerivs( elType, mesh, element, self->particle->xi, nDims,
+ &self->detJac, self->globalDerivs );
+ if( self->partCB && !self->partCB( self->obj, self ) )
+ continue;
+
+ Assembler_LoopMatrixElement( self, element );
+ }
+}
+
+void Assembler_LoopMatrixElement( void* assembler, unsigned element ) {
+ Assembler* self = (Assembler*)assembler;
+ unsigned nDims;
+ FeVariable *rowVar, *colVar;
+ FeMesh *rowMesh, *colMesh;
+ FeEquationNumber *rowEqNum, *colEqNum;
+ DofLayout *rowDofs, *colDofs;
+ unsigned nRowDofs, nColDofs;
+ unsigned nRowElNodes, *rowElNodes;
+ unsigned nColElNodes, *colElNodes;
+ int rowEq, colEq;
+ unsigned rowInd, colInd;
+ unsigned n_i, n_j, dof_i, dof_j;
+
+ assert( self && Stg_CheckType( self, Assembler ) );
+ assert( self->rowVar && self->colVar );
+
+ self->elInd = element;
+ rowVar = self->rowVar;
+ colVar = self->colVar;
+ rowEqNum = rowVar->eqNum; assert( rowEqNum );
+ colEqNum = colVar->eqNum; assert( colEqNum );
+ rowMesh = rowVar->feMesh;
+ colMesh = colVar->feMesh;
+ rowDofs = rowVar->dofLayout; assert( rowDofs );
+ colDofs = colVar->dofLayout; assert( colDofs );
+ nDims = Mesh_GetDimSize( rowMesh ); assert( nDims );
+ Mesh_GetIncidence( rowMesh, (MeshTopology_Dim)nDims, element, MT_VERTEX, self->rowInc );
+ nRowElNodes = IArray_GetSize( self->rowInc );
+ rowElNodes = (unsigned*)IArray_GetPtr( self->rowInc );
+ Mesh_GetIncidence( colMesh, Mesh_GetDimSize( colMesh ), element, MT_VERTEX,
+ self->colInc );
+ nColElNodes = IArray_GetSize( self->colInc );
+ colElNodes = (unsigned*)IArray_GetPtr( self->colInc );
+ assert( FeMesh_GetElementLocalSize( rowMesh ) == FeMesh_GetElementLocalSize( colMesh ) );
+ assert( nDims == Mesh_GetDimSize( colMesh ) );
+ assert( rowEqNum->locationMatrix );
+ assert( colEqNum->locationMatrix );
+ assert( rowEqNum->locationMatrix[element] );
+ assert( colEqNum->locationMatrix[element] );
+ assert( rowDofs->dofCounts );
+ assert( colDofs->dofCounts );
+
+ rowInd = 0;
+ for( n_i = 0; n_i < nRowElNodes; n_i++ ) {
+ assert( rowEqNum->locationMatrix[element][n_i] );
+ nRowDofs = rowDofs->dofCounts[rowElNodes[n_i]];
+ for( dof_i = 0; dof_i < nRowDofs; dof_i++ ) {
+ rowEq = rowEqNum->locationMatrix[element][n_i][dof_i];
+
+ self->rowInd = rowInd++;
+ self->rowElNodeInd = n_i;
+ self->rowNodeInd = rowElNodes[n_i];
+ self->rowDofInd = dof_i;
+ self->rowEq = rowEq;
+ if( rowVar->bcs && FeVariable_IsBC( rowVar, rowElNodes[n_i], dof_i ) ) {
+ if( !self->rowRCB || !self->rowRCB( self->obj, self ) )
+ continue;
+ }
+ else if( self->rowUCB && !self->rowUCB( self->obj, self ) )
+ continue;
+
+ colInd = 0;
+ for( n_j = 0; n_j < nColElNodes; n_j++ ) {
+ assert( colEqNum->locationMatrix[element][n_j] );
+ nColDofs = colDofs->dofCounts[colElNodes[n_j]];
+ for( dof_j = 0; dof_j < nColDofs; dof_j++ ) {
+ colEq = colEqNum->locationMatrix[element][n_j][dof_j];
+
+ self->colInd = colInd++;
+ self->colElNodeInd = n_j;
+ self->colNodeInd = colElNodes[n_j];
+ self->colDofInd = dof_j;
+ self->colEq = colEq;
+ if( colVar->bcs && FeVariable_IsBC( colVar, colElNodes[n_j], dof_j ) ) {
+ if( self->colRCB )
+ self->colRCB( self->obj, self );
+ }
+ else if( self->colUCB )
+ self->colUCB( self->obj, self );
+ }
+ }
+ }
+ }
+}
+
+void Assembler_LoopMatrixDiagonal( void* assembler ) {
+ Assembler* self = (Assembler*)assembler;
+ unsigned nDims;
+ FeVariable *rowVar;
+ FeMesh *rowMesh;
+ FeEquationNumber *rowEqNum;
+ DofLayout *rowDofs;
+ unsigned nRowDofs;
+ unsigned nRowNodes;
+ int rowEq;
+ unsigned n_i, dof_i;
+
+ assert( self && Stg_CheckType( self, Assembler ) );
+ assert( self->rowVar && self->colVar );
+ assert( self->rowVar == self->colVar );
+
+ rowVar = self->rowVar;
+ rowEqNum = rowVar->eqNum; assert( rowEqNum );
+ rowMesh = rowVar->feMesh;
+ rowDofs = rowVar->dofLayout; assert( rowDofs );
+ nDims = Mesh_GetDimSize( rowMesh ); assert( nDims );
+ nRowNodes = FeMesh_GetNodeLocalSize( rowMesh );
+ assert( rowEqNum->destinationArray );
+ assert( rowDofs->dofCounts );
+
+ for( n_i = 0; n_i < nRowNodes; n_i++ ) {
+ assert( rowEqNum->destinationArray[n_i] );
+ nRowDofs = rowDofs->dofCounts[n_i];
+ for( dof_i = 0; dof_i < nRowDofs; dof_i++ ) {
+ rowEq = rowEqNum->destinationArray[n_i][dof_i];
+
+ self->rowNodeInd = n_i;
+ self->rowDofInd = dof_i;
+ self->rowEq = rowEq;
+ self->colNodeInd = n_i;
+ self->colDofInd = dof_i;
+ self->colEq = rowEq;
+ if( rowVar->bcs && FeVariable_IsBC( rowVar, n_i, dof_i ) ) {
+ if( self->rowRCB )
+ self->rowRCB( self->obj, self );
+ }
+ else if( self->rowUCB )
+ self->rowUCB( self->obj, self );
+ }
+ }
+}
+
+#if 0
+void Assembler_LoopVectorElement( void* assembler, unsigned element ) {
+ Assembler* self = (Assembler*)assembler;
+ unsigned nDims;
+ FeVariable *rowVar;
+ FeMesh *rowMesh;
+ FeEquationNumber *rowEqNum;
+ DofLayout *rowDofs;
+ unsigned nRowDofs;
+ unsigned nRowElNodes, *rowElNodes;
+ int rowEq;
+ unsigned n_i, dof_i;
+
+ assert( self && Stg_CheckType( self, Assembler ) );
+ assert( self->rowVar && self->colVar );
+ assert( self->colCB );
+
+ self->elInd = element;
+ rowVar = self->rowVar;
+ rowEqNum = rowVar->eqNum; assert( rowEqNum );
+ rowMesh = rowVar->feMesh;
+ rowDofs = rowVar->dofLayout; assert( rowDofs );
+ nDims = Mesh_GetDimSize( rowMesh ); assert( nDims );
+ Mesh_GetIncidence( rowMesh, nDims, element, MT_VERTEX, self->rowInc );
+ nRowElNodes = IArray_GetSize( self->rowInc );
+ rowElNodes = IArray_GetPtr( self->rowInc );
+ assert( rowEqNum->locationMatrix );
+ assert( rowEqNum->locationMatrix[element] );
+ assert( rowDofs->dofCounts );
+
+ for( n_i = 0; n_i < nRowElNodes; n_i++ ) {
+ assert( rowEqNum->locationMatrix[element][n_i] );
+ nRowDofs = rowDofs->dofCounts[rowElNodes[n_i]];
+ for( dof_i = 0; dof_i < nRowDofs; dof_i++ ) {
+ rowEq = rowEqNum->locationMatrix[element][n_i][dof_i];
+
+ self->rowNodeInd = n_i;
+ self->rowDofInd = dof_i;
+ self->rowEq = rowEq;
+ self->colCB( self );
+ }
+ }
+}
+#endif
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/EntryPoint.c
--- a/SLE/SystemSetup/src/EntryPoint.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,199 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: EntryPoint.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "EntryPoint.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-#include <stdarg.h>
-
-/* Textual name of this class */
-const Type FeEntryPoint_Type = "FeEntryPoint";
-
-
-FeEntryPoint* FeEntryPoint_New( Name name, unsigned int castType ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(FeEntryPoint);
- Type type = FeEntryPoint_Type;
- Stg_Class_DeleteFunction* _delete = _EntryPoint_Delete;
- Stg_Class_PrintFunction* _print = _EntryPoint_Print;
- Stg_Class_CopyFunction* _copy = _EntryPoint_Copy;
- EntryPoint_GetRunFunction* _getRun = _FeEntryPoint_GetRun;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _FeEntryPoint_New( FEENTRYPOINT_PASSARGS );
-}
-
-void FeEntryPoint_Init( void* feEntryPoint, Name name, unsigned int castType ) {
- FeEntryPoint* self = (FeEntryPoint*)feEntryPoint;
-
- /* General info */
- self->type = FeEntryPoint_Type;
- self->_sizeOfSelf = sizeof(FeEntryPoint);
- self->_deleteSelf = False;
-
- /* Virtual info */
- self->_delete = _EntryPoint_Delete;
- self->_print = _EntryPoint_Print;
- self->_copy = _EntryPoint_Copy;
- self->_getRun = _FeEntryPoint_GetRun;
- _Stg_Class_Init( (Stg_Class*)self );
- _Stg_Object_Init( (Stg_Object*)self, name, GLOBAL );
- _EntryPoint_Init( (EntryPoint*)self, castType );
-
- /* FeEntryPoint info */
- _FeEntryPoint_Init( self );
-}
-
-FeEntryPoint* _FeEntryPoint_New( FEENTRYPOINT_DEFARGS )
-{
- FeEntryPoint* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(FeEntryPoint) );
- self = (FeEntryPoint*)_EntryPoint_New( ENTRYPOINT_PASSARGS );
-
- /* General info */
-
- /* Virtual info */
-
- /* FeEntryPoint info */
- _FeEntryPoint_Init( self );
-
- return self;
-}
-
-void _FeEntryPoint_Init( FeEntryPoint* self ) {
- /* General and Virtual info should already be set */
-
- /* FeEntryPoint info */
-}
-
-
-Func_Ptr _FeEntryPoint_GetRun( void* feEntryPoint ) {
- FeEntryPoint* self = (FeEntryPoint*)feEntryPoint;
-
- /* Most frequently called EPs are put first in the switch statement */
- switch( self->castType ) {
- case FeEntryPoint_AssembleStiffnessMatrix_CastType:
- return (Func_Ptr)_FeEntryPoint_Run_AssembleStiffnessMatrix;
-
- case FeEntryPoint_AssembleForceVector_CastType:
- return (Func_Ptr)_FeEntryPoint_Run_AssembleForceVector;
-
- default:
- return (Func_Ptr)_EntryPoint_GetRun( self );
- }
-}
-
-
-void _FeEntryPoint_Run_AssembleStiffnessMatrix(
- void* feEntryPoint,
- void* stiffnessMatrix,
- Bool bcRemoveQuery,
- void* _sle,
- void* _context )
-{
- FeEntryPoint* self = (FeEntryPoint*)feEntryPoint;
- Hook_Index hookIndex;
- double wallTime;
-
- #ifdef USE_PROFILE
- Stg_CallGraph_Push( stgCallGraph, _FeEntryPoint_Run_AssembleStiffnessMatrix, self->name );
- #endif
-
- for( hookIndex = 0; hookIndex < self->hooks->count; hookIndex++ ) {
- wallTime = MPI_Wtime();
-
- ((FeEntryPoint_AssembleStiffnessMatrix_Function*)((Hook*)self->hooks->data[hookIndex])->funcPtr) (
- stiffnessMatrix,
- bcRemoveQuery,
- _sle,
- _context );
-
- stg_profile_EntryPoint( self->name, self->hooks->data[hookIndex]->name, MPI_Wtime() - wallTime );
- }
-
- #ifdef USE_PROFILE
- Stg_CallGraph_Pop( stgCallGraph );
- #endif
-}
-
-void _FeEntryPoint_Run_AssembleForceVector(
- void* feEntryPoint,
- void* forceVector )
-{
- FeEntryPoint* self = (FeEntryPoint*)feEntryPoint;
- Hook_Index hookIndex;
- double wallTime;
-
- #ifdef USE_PROFILE
- Stg_CallGraph_Push( stgCallGraph, _FeEntryPoint_Run_AssembleForceVector, self->name );
- #endif
-
- for( hookIndex = 0; hookIndex < self->hooks->count; hookIndex++ ) {
- wallTime = MPI_Wtime();
-
- ((FeEntryPoint_AssembleForceVector_Function*)((Hook*)self->hooks->data[hookIndex])->funcPtr) (
- forceVector );
-
- stg_profile_EntryPoint( self->name, self->hooks->data[hookIndex]->name, MPI_Wtime() - wallTime );
- }
-
- #ifdef USE_PROFILE
- Stg_CallGraph_Pop( stgCallGraph );
- #endif
-}
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/EntryPoint.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/EntryPoint.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,199 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: EntryPoint.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "EntryPoint.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <stdarg.h>
+
+/* Textual name of this class */
+const Type FeEntryPoint_Type = "FeEntryPoint";
+
+
+FeEntryPoint* FeEntryPoint_New( Name name, unsigned int castType ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(FeEntryPoint);
+ Type type = FeEntryPoint_Type;
+ Stg_Class_DeleteFunction* _delete = _EntryPoint_Delete;
+ Stg_Class_PrintFunction* _print = _EntryPoint_Print;
+ Stg_Class_CopyFunction* _copy = _EntryPoint_Copy;
+ EntryPoint_GetRunFunction* _getRun = _FeEntryPoint_GetRun;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _FeEntryPoint_New( FEENTRYPOINT_PASSARGS );
+}
+
+void FeEntryPoint_Init( void* feEntryPoint, Name name, unsigned int castType ) {
+ FeEntryPoint* self = (FeEntryPoint*)feEntryPoint;
+
+ /* General info */
+ self->type = FeEntryPoint_Type;
+ self->_sizeOfSelf = sizeof(FeEntryPoint);
+ self->_deleteSelf = False;
+
+ /* Virtual info */
+ self->_delete = _EntryPoint_Delete;
+ self->_print = _EntryPoint_Print;
+ self->_copy = _EntryPoint_Copy;
+ self->_getRun = _FeEntryPoint_GetRun;
+ _Stg_Class_Init( (Stg_Class*)self );
+ _Stg_Object_Init( (Stg_Object*)self, name, GLOBAL );
+ _EntryPoint_Init( (EntryPoint*)self, castType );
+
+ /* FeEntryPoint info */
+ _FeEntryPoint_Init( self );
+}
+
+FeEntryPoint* _FeEntryPoint_New( FEENTRYPOINT_DEFARGS )
+{
+ FeEntryPoint* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(FeEntryPoint) );
+ self = (FeEntryPoint*)_EntryPoint_New( ENTRYPOINT_PASSARGS );
+
+ /* General info */
+
+ /* Virtual info */
+
+ /* FeEntryPoint info */
+ _FeEntryPoint_Init( self );
+
+ return self;
+}
+
+void _FeEntryPoint_Init( FeEntryPoint* self ) {
+ /* General and Virtual info should already be set */
+
+ /* FeEntryPoint info */
+}
+
+
+Func_Ptr _FeEntryPoint_GetRun( void* feEntryPoint ) {
+ FeEntryPoint* self = (FeEntryPoint*)feEntryPoint;
+
+ /* Most frequently called EPs are put first in the switch statement */
+ switch( self->castType ) {
+ case FeEntryPoint_AssembleStiffnessMatrix_CastType:
+ return (Func_Ptr)_FeEntryPoint_Run_AssembleStiffnessMatrix;
+
+ case FeEntryPoint_AssembleForceVector_CastType:
+ return (Func_Ptr)_FeEntryPoint_Run_AssembleForceVector;
+
+ default:
+ return (Func_Ptr)_EntryPoint_GetRun( self );
+ }
+}
+
+
+void _FeEntryPoint_Run_AssembleStiffnessMatrix(
+ void* feEntryPoint,
+ void* stiffnessMatrix,
+ Bool bcRemoveQuery,
+ void* _sle,
+ void* _context )
+{
+ FeEntryPoint* self = (FeEntryPoint*)feEntryPoint;
+ Hook_Index hookIndex;
+ double wallTime;
+
+ #ifdef USE_PROFILE
+ Stg_CallGraph_Push( stgCallGraph, _FeEntryPoint_Run_AssembleStiffnessMatrix, self->name );
+ #endif
+
+ for( hookIndex = 0; hookIndex < self->hooks->count; hookIndex++ ) {
+ wallTime = MPI_Wtime();
+
+ ((FeEntryPoint_AssembleStiffnessMatrix_Function*)((Hook*)self->hooks->data[hookIndex])->funcPtr) (
+ stiffnessMatrix,
+ bcRemoveQuery,
+ _sle,
+ _context );
+
+ stg_profile_EntryPoint( self->name, self->hooks->data[hookIndex]->name, MPI_Wtime() - wallTime );
+ }
+
+ #ifdef USE_PROFILE
+ Stg_CallGraph_Pop( stgCallGraph );
+ #endif
+}
+
+void _FeEntryPoint_Run_AssembleForceVector(
+ void* feEntryPoint,
+ void* forceVector )
+{
+ FeEntryPoint* self = (FeEntryPoint*)feEntryPoint;
+ Hook_Index hookIndex;
+ double wallTime;
+
+ #ifdef USE_PROFILE
+ Stg_CallGraph_Push( stgCallGraph, _FeEntryPoint_Run_AssembleForceVector, self->name );
+ #endif
+
+ for( hookIndex = 0; hookIndex < self->hooks->count; hookIndex++ ) {
+ wallTime = MPI_Wtime();
+
+ ((FeEntryPoint_AssembleForceVector_Function*)((Hook*)self->hooks->data[hookIndex])->funcPtr) (
+ forceVector );
+
+ stg_profile_EntryPoint( self->name, self->hooks->data[hookIndex]->name, MPI_Wtime() - wallTime );
+ }
+
+ #ifdef USE_PROFILE
+ Stg_CallGraph_Pop( stgCallGraph );
+ #endif
+}
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/Finalise.c
--- a/SLE/SystemSetup/src/Finalise.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "Finalise.h"
-
-#include <stdio.h>
-
-Bool StgFEM_SLE_SystemSetup_Finalise( void ) {
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- Stream_IndentBranch( StgFEM_Debug );
- Stream_UnIndentBranch( StgFEM_Debug );
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/Finalise.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/Finalise.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,61 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "Finalise.h"
+
+#include <stdio.h>
+
+Bool StgFEM_SLE_SystemSetup_Finalise( void ) {
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ Stream_IndentBranch( StgFEM_Debug );
+ Stream_UnIndentBranch( StgFEM_Debug );
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/FiniteElementContext.c
--- a/SLE/SystemSetup/src/FiniteElementContext.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,838 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Context.c 1207 2008-08-17 15:16:25Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "FiniteElementContext.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-#include "SystemLinearEquations.h"
-#include "SolutionVector.h"
-
-#ifdef WRITE_HDF5
-#include <hdf5.h>
-#endif
-
-#define FINISHED_WRITING_TAG 9
-
-/* Textual name of this class */
-const Type FiniteElementContext_Type = "FiniteElementContext";
-const Name defaultFiniteElementContextETypeRegisterName = "finiteElementContext";
-const Name FiniteElementContext_EP_CalcDt = "FiniteElementContext_EP_CalcDt";
-
-/* Constructors ------------------------------------------------------------------------------------------------------------------*/
-
-FiniteElementContext* FiniteElementContext_New(
- Name name,
- double start,
- double stop,
- MPI_Comm communicator,
- Dictionary* dictionary )
-{
- FiniteElementContext* self = (FiniteElementContext*)FiniteElementContext_DefaultNew( name );
-
- self->isConstructed = True;
- _AbstractContext_Init( (AbstractContext*) self );
- _DomainContext_Init( (DomainContext*) self );
- _FiniteElementContext_Init( self );
-
- return self;
-}
-
-void* FiniteElementContext_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(FiniteElementContext);
- Type type = FiniteElementContext_Type;
- Stg_Class_DeleteFunction* _delete = _FiniteElementContext_Delete;
- Stg_Class_PrintFunction* _print = _FiniteElementContext_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = FiniteElementContext_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _FiniteElementContext_AssignFromXML;
- Stg_Component_BuildFunction* _build = _AbstractContext_Build;
- Stg_Component_InitialiseFunction* _initialise = _AbstractContext_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AbstractContext_Execute;
- Stg_Component_DestroyFunction* _destroy = (Stg_Component_DestroyFunction*)_FiniteElementContext_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- AbstractContext_SetDt* _setDt = _FiniteElementContext_SetDt;
- double startTime = 0;
- double stopTime = 0;
- MPI_Comm communicator = MPI_COMM_WORLD;
- Dictionary* dictionary = NULL;
-
- return _FiniteElementContext_New( FINITEELEMENTCONTEXT_PASSARGS );
-}
-
-FiniteElementContext* _FiniteElementContext_New( FINITEELEMENTCONTEXT_DEFARGS ) {
- FiniteElementContext* self;
-
- /* Allocate memory */
- self = (FiniteElementContext*)_DomainContext_New( DOMAINCONTEXT_PASSARGS );
-
- /* General info */
-
- /* Virtual info */
-
- return self;
-}
-
-void _FiniteElementContext_Init( FiniteElementContext* self ) {
- /* Set up stream preferences */
- Journal_Enable_NamedStream( InfoStream_Type, "StgFEM_VerboseConfig", False );
-
- /* register this current stream (the context) as a child of the FE stream */
- /* TODO: Want to be able to recombine this with the Abs context's debug stream at some stage */
- self->debug = Stream_RegisterChild( StgFEM_Debug, FiniteElementContext_Type );
-
- /* set up s.l.e list */
- self->slEquations = Stg_ObjectList_New();
-
- /* Create Entry Point for Calculating timestep */
- self->calcDtEP = EntryPoint_New( FiniteElementContext_EP_CalcDt, EntryPoint_Minimum_VoidPtr_CastType );
- EntryPoint_Register_Add( self->entryPoint_Register, self->calcDtEP );
-
- /* Add hooks to existing entry points... use name "default" so that plugin, etc can exert same behaviour on other contexts*/
- EntryPoint_Prepend(
- Context_GetEntryPoint( self, AbstractContext_EP_Build ),
- "_FiniteElementContext_Build",
- (void*)_FiniteElementContext_Build,
- FiniteElementContext_Type );
- EntryPoint_Prepend(
- Context_GetEntryPoint( self, AbstractContext_EP_Initialise ),
- "_FiniteElementContext_Initialise",
- (void*)_FiniteElementContext_Initialise,
- FiniteElementContext_Type );
- EntryPoint_Append(
- Context_GetEntryPoint( self, AbstractContext_EP_Solve ),
- "_FiniteElementContext_Solve",
- (void*)_FiniteElementContext_Solve,
- FiniteElementContext_Type );
- EntryPoint_Append(
- Context_GetEntryPoint( self, AbstractContext_EP_Solve ),
- "_FiniteElementContext_PostSolve",
- (void*)_FiniteElementContext_PostSolve,
- FiniteElementContext_Type );
- EntryPoint_Append(
- Context_GetEntryPoint( self, AbstractContext_EP_Dt ),
- "_FiniteElementContext_GetDt",
- (void*)_FiniteElementContext_GetDt,
- FiniteElementContext_Type );
-
- EntryPoint_Append(
- Context_GetEntryPoint( self, AbstractContext_EP_Save ),
- "_FiniteElementContext_SaveFeVariables",
- (void*)_FiniteElementContext_SaveFeVariables,
- FiniteElementContext_Type );
-
- EntryPoint_Append(
- Context_GetEntryPoint( self, AbstractContext_EP_DataSave ),
- "_FiniteElementContext_SaveFeVariables",
- (void*)_FiniteElementContext_SaveFeVariables,
- FiniteElementContext_Type );
- /* The FEM context needs to save gauss swarms so they can be re-loaded for restart later.
- This will automatically save material point swarms too if PICellerator is used.
- */
- EntryPoint_Append(
- Context_GetEntryPoint( self, AbstractContext_EP_Save ),
- "_FiniteElementContext_SaveSwarms",
- (void*)_FiniteElementContext_SaveSwarms,
- FiniteElementContext_Type );
-
- EntryPoint_Append(
- Context_GetEntryPoint( self, AbstractContext_EP_Save ),
- "_FiniteElementContext_SaveMesh",
- (void*)_FiniteElementContext_SaveMesh,
- FiniteElementContext_Type );
-
- EntryPoint_Append(
- Context_GetEntryPoint( self, AbstractContext_EP_DataSave ),
- "_FiniteElementContext_SaveMesh",
- (void*)_FiniteElementContext_SaveMesh,
- FiniteElementContext_Type );
-}
-
-
-/* Virtual Functions -------------------------------------------------------------------------------------------------------------*/
-
-void _FiniteElementContext_Delete( void* context ) {
- FiniteElementContext* self = (FiniteElementContext*)context;
-
- Journal_DPrintf( self->debug, "In: %s()\n", __func__ );
-
- Stream_IndentBranch( StgFEM_Debug );
- Journal_DPrintfL( self->debug, 2, "Deleting the element type register (and hence all element types).\n" );
- Journal_DPrintfL( self->debug, 2, "Deleting all SLEs and the SLE list.\n" );
- /* Disabling the next 2 lines as the slEquations and its object lists are
- deleted later on from the LiveComponentRegister (via LiveComponentRegister_DeleteAll)
- Stg_ObjectList_DeleteAllObjects( self->slEquations );
- Stg_Class_Delete( self->slEquations ); */
- Stream_UnIndentBranch( StgFEM_Debug );
-
- /* Stg_Class_Delete parent */
- _DomainContext_Delete( self );
-}
-
-void _FiniteElementContext_Destroy( void* context ) {
- FiniteElementContext* self = (FiniteElementContext*)context;
-
- Stg_Class_Delete( self->slEquations );
- _DomainContext_Destroy( self );
-}
-
-void _FiniteElementContext_Print( void* context, Stream* stream ) {
- FiniteElementContext* self = (FiniteElementContext*)context;
-
- /* General info */
- Journal_Printf( (void*) stream, "FiniteElementContext (ptr): %p\n", self );
-
- /* Print parent */
- _DomainContext_Print( self, stream );
-
- Journal_Printf( (void*) stream, "\tslEquations (ptr): %p\n", self->slEquations );
- Stg_Class_Print( self->slEquations, stream );
-}
-
-
-void _FiniteElementContext_SetDt( void* context, double dt ) {
- FiniteElementContext* self = (FiniteElementContext*)context;
-
- self->dt = dt;
-}
-
-
-/* Public Functions --------------------------------------------------------------------------------------------------------------*/
-
-void FiniteElementContext_AddSLE_Func( void* context, void* sle ) {
- FiniteElementContext* self = (FiniteElementContext*)context;
-
- FiniteElementContext_AddSLE_Macro( self, sle );
-}
-
-
-SystemLinearEquations* FiniteElementContext_GetSLE_Func( void* context, Name sleName ) {
- FiniteElementContext* self = (FiniteElementContext*)context;
-
- return FiniteElementContext_GetSLE_Macro( self, sleName );
-}
-
-
-/* EntryPoint Hooks --------------------------------------------------------------------------------------------------------------*/
-
-void _FiniteElementContext_AssignFromXML( void* context, Stg_ComponentFactory* cf, void* data ){
- FiniteElementContext *self = (FiniteElementContext*) context;
- Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
-
- _DomainContext_AssignFromXML( context, cf, data );
-
- self->dictionary = cf->rootDict;
-
- self->dt = 0.0f;
- self->prevTimestepDt = 0.0;
- self->limitTimeStepIncreaseRate = Dictionary_GetBool_WithDefault( self->dictionary, (Dictionary_Entry_Key)"limitTimeStepIncreaseRate", False );
- self->maxTimeStepIncreasePercentage = Dictionary_GetDouble_WithDefault( self->dictionary, (Dictionary_Entry_Key)"maxTimeStepIncreasePercentage", 10.0 );
- Journal_Firewall( self->maxTimeStepIncreasePercentage >= 0, errorStream,
- "Error - in %s(): maxTimeStepIncreasePercentage must be >= 0\n", __func__ );
-
- self->maxTimeStepSize = Dictionary_GetDouble_WithDefault( self->dictionary, (Dictionary_Entry_Key)"maxTimeStepSize", 0.0 );
-
- _FiniteElementContext_Init( self );
-}
-
-void _FiniteElementContext_Build( void* context ) {
- FiniteElementContext* self = (FiniteElementContext*)context;
- SystemLinearEquations_Index sle_I;
-
- Stream_IndentBranch( StgFEM_Debug );
- Journal_DPrintf( self->debug, "In: %s()\n", __func__ );
-
- /* build all the systems of linear equations */
- for ( sle_I = 0; sle_I < self->slEquations->count; sle_I++ ) {
- Stg_Component_Build( self->slEquations->data[sle_I], self, False );
- }
-
- /* TODO:
- This call shouldn't really be necessary - each variable used should be built
- by the FeVariable that needs it, via its dofLayout. However, unfortunately with
- "Vector" variables that use it, the app fails without this call - since otherwise
- the "velocity" variable doesn't get build, only "vx", "vy" and "vz".
- Need to debug this properly later.
- */
- Variable_Register_BuildAll( self->variable_Register );
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _FiniteElementContext_Initialise( void* context ) {
- FiniteElementContext* self = (FiniteElementContext*)context;
- SystemLinearEquations_Index sle_I;
-
- Stream_IndentBranch( StgFEM_Debug );
- Journal_DPrintf( self->debug, "In: %s()\n", __func__ );
-
- /* initialise all the systems of linear equations */
- for ( sle_I = 0; sle_I < self->slEquations->count; sle_I++ ) {
- Stg_Component_Initialise( self->slEquations->data[sle_I], self, False );
- }
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _FiniteElementContext_Solve( void* context ) {
- FiniteElementContext* self = (FiniteElementContext*)context;
- SystemLinearEquations_Index sle_I;
-
- Journal_DPrintf( self->debug, "In: %s()\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- /* solve all the systems of linear equations */
- for ( sle_I = 0; sle_I < self->slEquations->count; sle_I++ ) {
- SystemLinearEquations* currentSLE = (SystemLinearEquations*)self->slEquations->data[sle_I];
- Journal_DPrintf( self->debug, "Solving for this timestep the %s SLE:\n", self->slEquations->data[sle_I]->name );
- /* TODO: FeVariable should have the option of rebuilding ID and LM, based on sim.
- loop if geometry or BCs change...need to improve interface. */
- /* We set the "force" flag to True here - want the SLE to be re-solved every timestep */
- Stg_Component_Execute( currentSLE, self, True );
- }
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-void _FiniteElementContext_PostSolve( void* context ) {
- FiniteElementContext* self = (FiniteElementContext*)context;
-
- Journal_DPrintf( self->debug, "In: %s()\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- FiniteElementContext_CalcNewDt( self ) ;
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-double _FiniteElementContext_GetDt( void* context ) {
- FiniteElementContext* self = (FiniteElementContext*)context;
-
- return self->dt;
-}
-
-double FiniteElementContext_CalcNewDt( void* context ) {
- FiniteElementContext* self = (FiniteElementContext*)context;
-
- self->prevTimestepDt = self->dt;
-
- if ( self->calcDtEP->hooks->count == 0 ) {
- self->dt = 0.0;
- }
- else {
- self->dt = _EntryPoint_Run_Class_Minimum_VoidPtr( self->calcDtEP, self );
- }
-
- if ( ( self->timeStep > 1 ) && ( self->limitTimeStepIncreaseRate == True ) ) {
- double maxAllowedDt = self->prevTimestepDt * ( 1 + self->maxTimeStepIncreasePercentage / 100 );
-
- if ( self->dt > maxAllowedDt ) {
- int prevContextPrintingRank = Stream_GetPrintingRank( self->info );
- /* We assume the dt calculation will be the same across all procs since its a global
- operation, so only print this once */
- Stream_SetPrintingRank( self->info, 0 );
- Journal_Printf(
- self->info,
- "In %s(): dt calculated was %g (time), but prev timestep's dt\n"
- "was %g (time) and max allowed increase percentage is %.2f\n, thus limiting current\n"
- "dt to %g (time).\n",
- __func__,
- self->dt,
- self->prevTimestepDt,
- self->maxTimeStepIncreasePercentage,
- maxAllowedDt );
- self->dt = maxAllowedDt;
- Stream_SetPrintingRank( self->info, prevContextPrintingRank );
- }
- }
-
- if( self->maxTimeStepSize > 0.0 ) {
- if( self->dt > self->maxTimeStepSize )
- self->dt = self->maxTimeStepSize;
- }
-
- return self->dt;
-}
-
-
-void _FiniteElementContext_SaveFeVariables( void* context ) {
- FiniteElementContext* self = (FiniteElementContext*) context;
- Index var_I = 0;
- FieldVariable* fieldVar = NULL;
- FeVariable* feVar = NULL;
-
- /* Save the variables that have had their "isCheckpointedAndReloaded" flag enabled -
- * default is true, but the user may restrict the list by specifying the "FieldVariablesToCheckpoint"
- * flag in their constructor - see _FeVariable_AssignFromXML().
- */
- for ( var_I = 0; var_I < self->fieldVariable_Register->objects->count; var_I++ ) {
- fieldVar = FieldVariable_Register_GetByIndex( self->fieldVariable_Register, var_I );
-
- if ( Stg_Class_IsInstance( fieldVar, FeVariable_Type ) ) {
- feVar = (FeVariable*)fieldVar;
- if ( (feVar->isCheckpointedAndReloaded && (self->timeStep % self->checkpointEvery == 0)) ||
- (feVar->isCheckpointedAndReloaded && (self->checkpointAtTimeInc && (self->currentTime >= self->nextCheckpointTime))) ||
- (feVar->isSavedData && (self->timeStep % self->saveDataEvery == 0)) ){
- char* feVarSaveFileName = NULL;
- char* feVarSaveFileNamePart = NULL;
-
- feVarSaveFileNamePart = Context_GetCheckPointWritePrefixString( (void*)self );
-
-#ifdef WRITE_HDF5
- Stg_asprintf( &feVarSaveFileName, "%s%s.%.5u.h5" , feVarSaveFileNamePart, feVar->name, self->timeStep );
-#else
- Stg_asprintf( &feVarSaveFileName, "%s%s.%.5u.dat", feVarSaveFileNamePart, feVar->name, self->timeStep );
-#endif
- FeVariable_SaveToFile( feVar, feVarSaveFileName,
- Dictionary_GetBool_WithDefault( self->dictionary, (Dictionary_Entry_Key)"saveCoordsWithFields", False ) );
-
- Memory_Free( feVarSaveFileName );
- Memory_Free( feVarSaveFileNamePart );
- }
- }
- }
-}
-
-
-void _FiniteElementContext_SaveSwarms( void* context ) {
-
- Swarm_Register_SaveAllRegisteredSwarms(
- Swarm_Register_GetSwarm_Register( ), context );
-
-}
-
-
-void _FiniteElementContext_SaveMesh( void* context ) {
- FiniteElementContext* self;
- Stream* info = Journal_Register( Info_Type, (Name)"Context" );
- unsigned componentCount = LiveComponentRegister_GetCount(stgLiveComponentRegister );
- unsigned compI;
- Stg_Component* stgComp;
- FeMesh* mesh;
-
- Journal_Printf( info, "In %s(): about to save the mesh to disk:\n", __func__ );
-
- self = (FiniteElementContext*) context;
-
- /** search for entire live component register for feMesh types **/
- for( compI = 0 ; compI < componentCount ; compI++){
- stgComp = LiveComponentRegister_At( stgLiveComponentRegister, compI );
- /* check that component is of type FeMesh */
- if ( Stg_Class_IsInstance( stgComp, FeMesh_Type ) ) {
- mesh = (FeMesh*)stgComp;
- if( mesh->isCheckpointedAndReloaded == True && mesh->requiresCheckpointing == True ){
-#ifdef WRITE_HDF5
- _FiniteElementContext_DumpMeshHDF5( context, mesh );
-#else
- _FiniteElementContext_DumpMeshAscii( context, mesh );
-#endif
- }
- }
- }
- Journal_Printf( info, "%s: saving of mesh completed.\n", __func__ );
-}
-
-#ifndef WRITE_HDF5
-void _FiniteElementContext_DumpMeshAscii( void* context, FeMesh* feMesh ) {
- FiniteElementContext* self = (FiniteElementContext*) context;
- FieldVariable* fieldVar = NULL;
- FeVariable* feVar = NULL;
- Mesh* mesh;
- int rank, nRanks;
- FILE* outputFile;
- int confirmation = 0;
- MPI_Status status;
- Node_LocalIndex lNode_I = 0;
- Node_GlobalIndex gNode_I = 0;
- double* coord;
- unsigned nDims;
- char* filename = NULL;
- char* meshSaveFileNamePart = NULL;
-
- meshSaveFileNamePart = Context_GetCheckPointWritePrefixString( (void*)self );
-
- Stg_asprintf( &filename, "%sMesh.%s.%.5u.dat", meshSaveFileNamePart, feMesh->name, self->timeStep );
-
- MPI_Comm_rank( self->communicator, &rank);
- MPI_Comm_size( self->communicator, &nRanks );
-
- mesh = (Mesh*)feMesh;
-
- nDims = Mesh_GetDimSize( mesh );
-
- /* wait for go-ahead from process ranked lower than me, to avoid competition writing to file */
- if ( rank != 0 ) {
- MPI_Recv( &confirmation, 1, MPI_INT, rank - 1, FINISHED_WRITING_TAG, self->communicator, &status );
- }
-
- if ( rank == 0 ) {
- outputFile = fopen( filename, "w" );
- assert( outputFile );
-
- /* Write min and max coords to file */
- if( nDims == 2 ) {
- fprintf( outputFile, "Min: %.15g %.15g 0\n", mesh->minGlobalCrd[0], mesh->minGlobalCrd[1] );
- fprintf( outputFile, "Max: %.15g %.15g 0\n", mesh->maxGlobalCrd[0], mesh->maxGlobalCrd[1] );
- }
- else {
- fprintf( outputFile, "Min: %.15g %.15g %.15g\n", mesh->minGlobalCrd[0], mesh->minGlobalCrd[1], mesh->minGlobalCrd[2] );
- fprintf( outputFile, "Max: %.15g %.15g %.15g\n", mesh->maxGlobalCrd[0], mesh->maxGlobalCrd[1], mesh->maxGlobalCrd[2] );
- }
- }
- else {
- outputFile = fopen( filename, "a" );
- assert( outputFile );
- }
-
- for ( lNode_I = 0; lNode_I < FeMesh_GetNodeLocalSize( mesh ); lNode_I++ ) {
- gNode_I = FeMesh_NodeDomainToGlobal( mesh, lNode_I );
- fprintf( outputFile, "%u ", gNode_I );
- coord = Mesh_GetVertex( mesh, lNode_I );
-
- if(self->dim==2)
- fprintf( outputFile, "%.15g %.15g 0\n", coord[0], coord[1] );
- else
- fprintf( outputFile, "%.15g %.15g %.15g\n", coord[0], coord[1], coord[2] );
- }
-
- fclose( outputFile );
-
- /* send go-ahead from process ranked lower than me, to avoid competition writing to file */
- if ( rank != nRanks - 1 ) {
- MPI_Ssend( &confirmation, 1, MPI_INT, rank + 1, FINISHED_WRITING_TAG, self->communicator );
- }
- Memory_Free( meshSaveFileNamePart );
- Memory_Free( filename );
-
-}
-#endif
-
-#ifdef WRITE_HDF5
-void _FiniteElementContext_DumpMeshHDF5( void* context, FeMesh* mesh ) {
- FiniteElementContext* self = (FiniteElementContext*) context;
- int rank, nRanks;
- unsigned nDims;
- hid_t file, fileSpace, fileData, fileSpace2, fileData2;
- hid_t memSpace;
- hsize_t start[2], count[2], size[2];
- unsigned totalVerts;
- Node_LocalIndex lNode_I = 0;
- Node_GlobalIndex gNode_I = 0;
- double* coord;
- int buf_int[5];
- MPI_Status status;
- int confirmation = 0;
- Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
- Element_LocalIndex lElement_I;
- Element_GlobalIndex gElement_I;
- Index maxNodes;
- IArray* iarray = IArray_New( );
- char* filename = NULL;
- char* meshSaveFileNamePart = NULL;
-
- /* don't dump irregular meshes, as havn't accounted for their connectivity yet...
- * TODO: this is a hack, as we don't know about the IrregularQuadGenerator yet in StgFEM. Need to account
- * for unstructured meshes at some point in the future... dave 01.10.09 */
- if( !strcmp( mesh->generator->type, "IrregularQuadGenerator" ) )
- return;
-
- meshSaveFileNamePart = Context_GetCheckPointWritePrefixString( context );
-
- MPI_Comm_rank( self->communicator, &rank);
- MPI_Comm_size( self->communicator, &nRanks );
-
- filename = NULL;
- Stg_asprintf( &filename, "%sMesh.%s.%.5u.h5", meshSaveFileNamePart, mesh->name, self->timeStep );
-
- nDims = Mesh_GetDimSize( mesh );
-
- /* wait for go-ahead from process ranked lower than me, to avoid competition writing to file */
- if ( rank != 0 ) {
- MPI_Recv( &confirmation, 1, MPI_INT, rank - 1, FINISHED_WRITING_TAG, self->communicator, &status );
- }
-
- if ( rank == 0 ) {
- hid_t attribData_id, attrib_id, group_id;
- hsize_t a_dims;
- int attribData;
- Grid** grid;
- unsigned* sizes;
-
- /* Open the HDF5 output file. */
- file = H5Fcreate( filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT );
- assert( file );
-
- /** create file attribute */
- /** first store the checkpointing version */
- a_dims = 1;
- attribData = MeshCHECKPOINT_V2;
- attribData_id = H5Screate_simple(1, &a_dims, NULL);
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- group_id = H5Gopen(file, "/");
- attrib_id = H5Acreate(group_id, "checkpoint file version", H5T_STD_I32BE, attribData_id, H5P_DEFAULT);
- #else
- group_id = H5Gopen2(file, "/", H5P_DEFAULT);
- attrib_id = H5Acreate2(group_id, "checkpoint file version", H5T_STD_I32BE, attribData_id, H5P_DEFAULT, H5P_DEFAULT);
- #endif
- H5Awrite(attrib_id, H5T_NATIVE_INT, &attribData);
- H5Aclose(attrib_id);
- H5Gclose(group_id);
- H5Sclose(attribData_id);
-
- /** store the mesh dimensionality */
- a_dims = 1;
- attribData = self->dim;
- attribData_id = H5Screate_simple(1, &a_dims, NULL);
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- group_id = H5Gopen(file, "/");
- attrib_id = H5Acreate(group_id, "dimensions", H5T_STD_I32BE, attribData_id, H5P_DEFAULT);
- #else
- group_id = H5Gopen2(file, "/", H5P_DEFAULT);
- attrib_id = H5Acreate2(group_id, "dimensions", H5T_STD_I32BE, attribData_id, H5P_DEFAULT, H5P_DEFAULT);
- #endif
- H5Awrite(attrib_id, H5T_NATIVE_INT, &attribData);
- H5Aclose(attrib_id);
- H5Gclose(group_id);
- H5Sclose(attribData_id);
-
- /** store the mesh resolution */
- a_dims = self->dim;
- grid = (Grid**) Mesh_GetExtension( mesh, Grid*, "elementGrid" );
- sizes = Grid_GetSizes( *grid ); /** global no. of elements in each dim */
-
- attribData_id = H5Screate_simple(1, &a_dims, NULL);
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- group_id = H5Gopen(file, "/");
- attrib_id = H5Acreate(group_id, "mesh resolution", H5T_STD_I32BE, attribData_id, H5P_DEFAULT);
- #else
- group_id = H5Gopen2(file, "/", H5P_DEFAULT);
- attrib_id = H5Acreate2(group_id, "mesh resolution", H5T_STD_I32BE, attribData_id, H5P_DEFAULT, H5P_DEFAULT);
- #endif
- H5Awrite(attrib_id, H5T_NATIVE_INT, sizes);
- H5Aclose(attrib_id);
- H5Gclose(group_id);
- H5Sclose(attribData_id);
-
- /* Dump the min and max coords, and number of processes. */
- count[0] = (hsize_t)nDims;
- fileSpace = H5Screate_simple( 1, count, NULL );
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- fileData = H5Dcreate( file, "/min", H5T_NATIVE_DOUBLE, fileSpace, H5P_DEFAULT );
- #else
- fileData = H5Dcreate2( file, "/min", H5T_NATIVE_DOUBLE, fileSpace,
- H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
- #endif
-
- H5Dwrite( fileData, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, mesh->minGlobalCrd );
- H5Dclose( fileData );
- H5Sclose( fileSpace );
-
- fileSpace = H5Screate_simple( 1, count, NULL );
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- fileData = H5Dcreate( file, "/max", H5T_NATIVE_DOUBLE, fileSpace, H5P_DEFAULT );
- #else
- fileData = H5Dcreate2( file, "/max", H5T_NATIVE_DOUBLE, fileSpace,
- H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
- #endif
-
- H5Dwrite( fileData, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, mesh->maxGlobalCrd );
- H5Dclose( fileData );
- H5Sclose( fileSpace );
-
- /* Write vertex coords to file */
- /* Create our output space and data objects. */
- totalVerts = Mesh_GetGlobalSize( mesh, (MeshTopology_Dim)0 );
- size[0] = (hsize_t)totalVerts;
- size[1] = (hsize_t)nDims;
-
- fileSpace = H5Screate_simple( 2, size, NULL );
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- fileData = H5Dcreate( file, "/vertices", H5T_NATIVE_DOUBLE, fileSpace, H5P_DEFAULT );
- #else
- fileData = H5Dcreate2( file, "/vertices", H5T_NATIVE_DOUBLE, fileSpace,
- H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
- #endif
-
- /* setup element connectivity dataspaces */
- if (mesh->nElTypes == 1)
- maxNodes = FeMesh_GetElementNodeSize( mesh, 0);
- else {
- /* determine the maximum number of nodes each element has */
- maxNodes = 0;
- for ( gElement_I = 0 ; gElement_I < FeMesh_GetElementGlobalSize(mesh); gElement_I++ ) {
- unsigned numNodes;
- numNodes = FeMesh_GetElementNodeSize( mesh, gElement_I);
- if( maxNodes < numNodes ) maxNodes = numNodes;
- }
- }
-
- size[0] = (hsize_t)FeMesh_GetElementGlobalSize(mesh);
- size[1] = (hsize_t)maxNodes;
- /* Create our output space and data objects. */
- fileSpace2 = H5Screate_simple( 2, size, NULL );
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- fileData2 = H5Dcreate( file, "/connectivity", H5T_NATIVE_INT, fileSpace2, H5P_DEFAULT );
- #else
- fileData2 = H5Dcreate2( file, "/connectivity", H5T_NATIVE_INT, fileSpace2,
- H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
- #endif
-
- } else {
- /* Open the HDF5 output file. */
- file = H5Fopen( filename, H5F_ACC_RDWR, H5P_DEFAULT );
- Journal_Firewall(
- file >= 0,
- errorStr,
- "Error in %s for %s '%s' - Cannot open file %s.\n",
- __func__,
- self->type,
- self->name,
- filename );
-
- /* get the node filespace */
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- fileData = H5Dopen( file, "/vertices" );
- #else
- fileData = H5Dopen2( file, "/vertices", H5P_DEFAULT );
- #endif
- /* get the filespace handle */
- fileSpace = H5Dget_space(fileData);
-
- /* get the connectivity */
- #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
- fileData2 = H5Dopen( file, "/connectivity" );
- #else
- fileData2 = H5Dopen2( file, "/connectivity", H5P_DEFAULT );
- #endif
- /* get the filespace handle */
- fileSpace2 = H5Dget_space(fileData2);
- }
-
- count[0] = 1;
- count[1] = nDims;
- memSpace = H5Screate_simple( 2, count, NULL );
- H5Sselect_all( memSpace );
-
- for ( lNode_I = 0; lNode_I < FeMesh_GetNodeLocalSize( mesh ); lNode_I++ ) {
- gNode_I = FeMesh_NodeDomainToGlobal( mesh, lNode_I );
-
- coord = Mesh_GetVertex( mesh, lNode_I );
-
- /* select the region of dataspace to write to */
- start[1] = 0;
- start[0] = gNode_I;
- H5Sselect_hyperslab( fileSpace, H5S_SELECT_SET, start, NULL, count, NULL );
-
- H5Dwrite( fileData, H5T_NATIVE_DOUBLE, memSpace, fileSpace, H5P_DEFAULT, coord );
- }
-
- /* Close off all our handles. */
- H5Sclose( memSpace );
- H5Dclose( fileData );
- H5Sclose( fileSpace );
-
- H5Sget_simple_extent_dims( fileSpace2, size, NULL );
- count[0] = 1;
- count[1] = size[1];
- memSpace = H5Screate_simple( 2, count, NULL );
- H5Sselect_all( memSpace );
-
- for ( lElement_I = 0 ; lElement_I < FeMesh_GetElementLocalSize(mesh); lElement_I++ ) {
- int* nodeList, nodesPerEl;
- int node_I;
-
- gElement_I = FeMesh_ElementDomainToGlobal( mesh,lElement_I );
-
- /* get element nodes */
- FeMesh_GetElementNodes( mesh, lElement_I, iarray );
- nodesPerEl = IArray_GetSize( iarray );
- nodeList = IArray_GetPtr( iarray );
-
- for( node_I = 0 ; node_I < nodesPerEl ; node_I++ )
- buf_int[node_I] = Mesh_DomainToGlobal( mesh, MT_VERTEX, nodeList[node_I] );
- /* some reordering is required to account for standard node ordering */
- buf_int[3] = Mesh_DomainToGlobal( mesh, MT_VERTEX, nodeList[2] );
- buf_int[2] = Mesh_DomainToGlobal( mesh, MT_VERTEX, nodeList[3] );
- if( nDims == 3 ) {
- buf_int[7] = Mesh_DomainToGlobal( mesh, MT_VERTEX, nodeList[6] );
- buf_int[6] = Mesh_DomainToGlobal( mesh, MT_VERTEX, nodeList[7] );
- }
- /* select the region of dataspace to write to */
- start[1] = 0;
- start[0] = gElement_I;
- H5Sselect_hyperslab( fileSpace2, H5S_SELECT_SET, start, NULL, count, NULL );
-
- H5Dwrite( fileData2, H5T_NATIVE_INT, memSpace, fileSpace2, H5P_DEFAULT, buf_int );
- }
-
- /* Close off all our handles. */
- H5Sclose( memSpace );
- H5Dclose( fileData2 );
- H5Sclose( fileSpace2 );
- H5Fclose( file );
-
- /* send go-ahead from process ranked lower than me, to avoid competition writing to file */
- if ( rank != nRanks - 1 ) {
- MPI_Ssend( &confirmation, 1, MPI_INT, rank + 1, FINISHED_WRITING_TAG, self->communicator );
- }
-
- Memory_Free( filename );
-
- Memory_Free( meshSaveFileNamePart );
- NewClass_Delete( iarray );
-}
-#endif
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/FiniteElementContext.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/FiniteElementContext.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,838 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Context.c 1207 2008-08-17 15:16:25Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "FiniteElementContext.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "SystemLinearEquations.h"
+#include "SolutionVector.h"
+
+#ifdef WRITE_HDF5
+#include <hdf5.h>
+#endif
+
+#define FINISHED_WRITING_TAG 9
+
+/* Textual name of this class */
+const Type FiniteElementContext_Type = "FiniteElementContext";
+const Name defaultFiniteElementContextETypeRegisterName = "finiteElementContext";
+const Name FiniteElementContext_EP_CalcDt = "FiniteElementContext_EP_CalcDt";
+
+/* Constructors ------------------------------------------------------------------------------------------------------------------*/
+
+FiniteElementContext* FiniteElementContext_New(
+ Name name,
+ double start,
+ double stop,
+ MPI_Comm communicator,
+ Dictionary* dictionary )
+{
+ FiniteElementContext* self = (FiniteElementContext*)FiniteElementContext_DefaultNew( name );
+
+ self->isConstructed = True;
+ _AbstractContext_Init( (AbstractContext*) self );
+ _DomainContext_Init( (DomainContext*) self );
+ _FiniteElementContext_Init( self );
+
+ return self;
+}
+
+void* FiniteElementContext_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(FiniteElementContext);
+ Type type = FiniteElementContext_Type;
+ Stg_Class_DeleteFunction* _delete = _FiniteElementContext_Delete;
+ Stg_Class_PrintFunction* _print = _FiniteElementContext_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = FiniteElementContext_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _FiniteElementContext_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _AbstractContext_Build;
+ Stg_Component_InitialiseFunction* _initialise = _AbstractContext_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AbstractContext_Execute;
+ Stg_Component_DestroyFunction* _destroy = (Stg_Component_DestroyFunction*)_FiniteElementContext_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ AbstractContext_SetDt* _setDt = _FiniteElementContext_SetDt;
+ double startTime = 0;
+ double stopTime = 0;
+ MPI_Comm communicator = MPI_COMM_WORLD;
+ Dictionary* dictionary = NULL;
+
+ return _FiniteElementContext_New( FINITEELEMENTCONTEXT_PASSARGS );
+}
+
+FiniteElementContext* _FiniteElementContext_New( FINITEELEMENTCONTEXT_DEFARGS ) {
+ FiniteElementContext* self;
+
+ /* Allocate memory */
+ self = (FiniteElementContext*)_DomainContext_New( DOMAINCONTEXT_PASSARGS );
+
+ /* General info */
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _FiniteElementContext_Init( FiniteElementContext* self ) {
+ /* Set up stream preferences */
+ Journal_Enable_NamedStream( InfoStream_Type, "StgFEM_VerboseConfig", False );
+
+ /* register this current stream (the context) as a child of the FE stream */
+ /* TODO: Want to be able to recombine this with the Abs context's debug stream at some stage */
+ self->debug = Stream_RegisterChild( StgFEM_Debug, FiniteElementContext_Type );
+
+ /* set up s.l.e list */
+ self->slEquations = Stg_ObjectList_New();
+
+ /* Create Entry Point for Calculating timestep */
+ self->calcDtEP = EntryPoint_New( FiniteElementContext_EP_CalcDt, EntryPoint_Minimum_VoidPtr_CastType );
+ EntryPoint_Register_Add( self->entryPoint_Register, self->calcDtEP );
+
+ /* Add hooks to existing entry points... use name "default" so that plugin, etc can exert same behaviour on other contexts*/
+ EntryPoint_Prepend(
+ Context_GetEntryPoint( self, AbstractContext_EP_Build ),
+ "_FiniteElementContext_Build",
+ (void*)_FiniteElementContext_Build,
+ FiniteElementContext_Type );
+ EntryPoint_Prepend(
+ Context_GetEntryPoint( self, AbstractContext_EP_Initialise ),
+ "_FiniteElementContext_Initialise",
+ (void*)_FiniteElementContext_Initialise,
+ FiniteElementContext_Type );
+ EntryPoint_Append(
+ Context_GetEntryPoint( self, AbstractContext_EP_Solve ),
+ "_FiniteElementContext_Solve",
+ (void*)_FiniteElementContext_Solve,
+ FiniteElementContext_Type );
+ EntryPoint_Append(
+ Context_GetEntryPoint( self, AbstractContext_EP_Solve ),
+ "_FiniteElementContext_PostSolve",
+ (void*)_FiniteElementContext_PostSolve,
+ FiniteElementContext_Type );
+ EntryPoint_Append(
+ Context_GetEntryPoint( self, AbstractContext_EP_Dt ),
+ "_FiniteElementContext_GetDt",
+ (void*)_FiniteElementContext_GetDt,
+ FiniteElementContext_Type );
+
+ EntryPoint_Append(
+ Context_GetEntryPoint( self, AbstractContext_EP_Save ),
+ "_FiniteElementContext_SaveFeVariables",
+ (void*)_FiniteElementContext_SaveFeVariables,
+ FiniteElementContext_Type );
+
+ EntryPoint_Append(
+ Context_GetEntryPoint( self, AbstractContext_EP_DataSave ),
+ "_FiniteElementContext_SaveFeVariables",
+ (void*)_FiniteElementContext_SaveFeVariables,
+ FiniteElementContext_Type );
+ /* The FEM context needs to save gauss swarms so they can be re-loaded for restart later.
+ This will automatically save material point swarms too if PICellerator is used.
+ */
+ EntryPoint_Append(
+ Context_GetEntryPoint( self, AbstractContext_EP_Save ),
+ "_FiniteElementContext_SaveSwarms",
+ (void*)_FiniteElementContext_SaveSwarms,
+ FiniteElementContext_Type );
+
+ EntryPoint_Append(
+ Context_GetEntryPoint( self, AbstractContext_EP_Save ),
+ "_FiniteElementContext_SaveMesh",
+ (void*)_FiniteElementContext_SaveMesh,
+ FiniteElementContext_Type );
+
+ EntryPoint_Append(
+ Context_GetEntryPoint( self, AbstractContext_EP_DataSave ),
+ "_FiniteElementContext_SaveMesh",
+ (void*)_FiniteElementContext_SaveMesh,
+ FiniteElementContext_Type );
+}
+
+
+/* Virtual Functions -------------------------------------------------------------------------------------------------------------*/
+
+void _FiniteElementContext_Delete( void* context ) {
+ FiniteElementContext* self = (FiniteElementContext*)context;
+
+ Journal_DPrintf( self->debug, "In: %s()\n", __func__ );
+
+ Stream_IndentBranch( StgFEM_Debug );
+ Journal_DPrintfL( self->debug, 2, "Deleting the element type register (and hence all element types).\n" );
+ Journal_DPrintfL( self->debug, 2, "Deleting all SLEs and the SLE list.\n" );
+ /* Disabling the next 2 lines as the slEquations and its object lists are
+ deleted later on from the LiveComponentRegister (via LiveComponentRegister_DeleteAll)
+ Stg_ObjectList_DeleteAllObjects( self->slEquations );
+ Stg_Class_Delete( self->slEquations ); */
+ Stream_UnIndentBranch( StgFEM_Debug );
+
+ /* Stg_Class_Delete parent */
+ _DomainContext_Delete( self );
+}
+
+void _FiniteElementContext_Destroy( void* context ) {
+ FiniteElementContext* self = (FiniteElementContext*)context;
+
+ Stg_Class_Delete( self->slEquations );
+ _DomainContext_Destroy( self );
+}
+
+void _FiniteElementContext_Print( void* context, Stream* stream ) {
+ FiniteElementContext* self = (FiniteElementContext*)context;
+
+ /* General info */
+ Journal_Printf( (void*) stream, "FiniteElementContext (ptr): %p\n", self );
+
+ /* Print parent */
+ _DomainContext_Print( self, stream );
+
+ Journal_Printf( (void*) stream, "\tslEquations (ptr): %p\n", self->slEquations );
+ Stg_Class_Print( self->slEquations, stream );
+}
+
+
+void _FiniteElementContext_SetDt( void* context, double dt ) {
+ FiniteElementContext* self = (FiniteElementContext*)context;
+
+ self->dt = dt;
+}
+
+
+/* Public Functions --------------------------------------------------------------------------------------------------------------*/
+
+void FiniteElementContext_AddSLE_Func( void* context, void* sle ) {
+ FiniteElementContext* self = (FiniteElementContext*)context;
+
+ FiniteElementContext_AddSLE_Macro( self, sle );
+}
+
+
+SystemLinearEquations* FiniteElementContext_GetSLE_Func( void* context, Name sleName ) {
+ FiniteElementContext* self = (FiniteElementContext*)context;
+
+ return FiniteElementContext_GetSLE_Macro( self, sleName );
+}
+
+
+/* EntryPoint Hooks --------------------------------------------------------------------------------------------------------------*/
+
+void _FiniteElementContext_AssignFromXML( void* context, Stg_ComponentFactory* cf, void* data ){
+ FiniteElementContext *self = (FiniteElementContext*) context;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
+
+ _DomainContext_AssignFromXML( context, cf, data );
+
+ self->dictionary = cf->rootDict;
+
+ self->dt = 0.0f;
+ self->prevTimestepDt = 0.0;
+ self->limitTimeStepIncreaseRate = Dictionary_GetBool_WithDefault( self->dictionary, (Dictionary_Entry_Key)"limitTimeStepIncreaseRate", False );
+ self->maxTimeStepIncreasePercentage = Dictionary_GetDouble_WithDefault( self->dictionary, (Dictionary_Entry_Key)"maxTimeStepIncreasePercentage", 10.0 );
+ Journal_Firewall( self->maxTimeStepIncreasePercentage >= 0, errorStream,
+ "Error - in %s(): maxTimeStepIncreasePercentage must be >= 0\n", __func__ );
+
+ self->maxTimeStepSize = Dictionary_GetDouble_WithDefault( self->dictionary, (Dictionary_Entry_Key)"maxTimeStepSize", 0.0 );
+
+ _FiniteElementContext_Init( self );
+}
+
+void _FiniteElementContext_Build( void* context ) {
+ FiniteElementContext* self = (FiniteElementContext*)context;
+ SystemLinearEquations_Index sle_I;
+
+ Stream_IndentBranch( StgFEM_Debug );
+ Journal_DPrintf( self->debug, "In: %s()\n", __func__ );
+
+ /* build all the systems of linear equations */
+ for ( sle_I = 0; sle_I < self->slEquations->count; sle_I++ ) {
+ Stg_Component_Build( self->slEquations->data[sle_I], self, False );
+ }
+
+ /* TODO:
+ This call shouldn't really be necessary - each variable used should be built
+ by the FeVariable that needs it, via its dofLayout. However, unfortunately with
+ "Vector" variables that use it, the app fails without this call - since otherwise
+ the "velocity" variable doesn't get build, only "vx", "vy" and "vz".
+ Need to debug this properly later.
+ */
+ Variable_Register_BuildAll( self->variable_Register );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _FiniteElementContext_Initialise( void* context ) {
+ FiniteElementContext* self = (FiniteElementContext*)context;
+ SystemLinearEquations_Index sle_I;
+
+ Stream_IndentBranch( StgFEM_Debug );
+ Journal_DPrintf( self->debug, "In: %s()\n", __func__ );
+
+ /* initialise all the systems of linear equations */
+ for ( sle_I = 0; sle_I < self->slEquations->count; sle_I++ ) {
+ Stg_Component_Initialise( self->slEquations->data[sle_I], self, False );
+ }
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _FiniteElementContext_Solve( void* context ) {
+ FiniteElementContext* self = (FiniteElementContext*)context;
+ SystemLinearEquations_Index sle_I;
+
+ Journal_DPrintf( self->debug, "In: %s()\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ /* solve all the systems of linear equations */
+ for ( sle_I = 0; sle_I < self->slEquations->count; sle_I++ ) {
+ SystemLinearEquations* currentSLE = (SystemLinearEquations*)self->slEquations->data[sle_I];
+ Journal_DPrintf( self->debug, "Solving for this timestep the %s SLE:\n", self->slEquations->data[sle_I]->name );
+ /* TODO: FeVariable should have the option of rebuilding ID and LM, based on sim.
+ loop if geometry or BCs change...need to improve interface. */
+ /* We set the "force" flag to True here - want the SLE to be re-solved every timestep */
+ Stg_Component_Execute( currentSLE, self, True );
+ }
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+void _FiniteElementContext_PostSolve( void* context ) {
+ FiniteElementContext* self = (FiniteElementContext*)context;
+
+ Journal_DPrintf( self->debug, "In: %s()\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ FiniteElementContext_CalcNewDt( self ) ;
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+double _FiniteElementContext_GetDt( void* context ) {
+ FiniteElementContext* self = (FiniteElementContext*)context;
+
+ return self->dt;
+}
+
+double FiniteElementContext_CalcNewDt( void* context ) {
+ FiniteElementContext* self = (FiniteElementContext*)context;
+
+ self->prevTimestepDt = self->dt;
+
+ if ( self->calcDtEP->hooks->count == 0 ) {
+ self->dt = 0.0;
+ }
+ else {
+ self->dt = _EntryPoint_Run_Class_Minimum_VoidPtr( self->calcDtEP, self );
+ }
+
+ if ( ( self->timeStep > 1 ) && ( self->limitTimeStepIncreaseRate == True ) ) {
+ double maxAllowedDt = self->prevTimestepDt * ( 1 + self->maxTimeStepIncreasePercentage / 100 );
+
+ if ( self->dt > maxAllowedDt ) {
+ int prevContextPrintingRank = Stream_GetPrintingRank( self->info );
+ /* We assume the dt calculation will be the same across all procs since its a global
+ operation, so only print this once */
+ Stream_SetPrintingRank( self->info, 0 );
+ Journal_Printf(
+ self->info,
+ "In %s(): dt calculated was %g (time), but prev timestep's dt\n"
+ "was %g (time) and max allowed increase percentage is %.2f\n, thus limiting current\n"
+ "dt to %g (time).\n",
+ __func__,
+ self->dt,
+ self->prevTimestepDt,
+ self->maxTimeStepIncreasePercentage,
+ maxAllowedDt );
+ self->dt = maxAllowedDt;
+ Stream_SetPrintingRank( self->info, prevContextPrintingRank );
+ }
+ }
+
+ if( self->maxTimeStepSize > 0.0 ) {
+ if( self->dt > self->maxTimeStepSize )
+ self->dt = self->maxTimeStepSize;
+ }
+
+ return self->dt;
+}
+
+
+void _FiniteElementContext_SaveFeVariables( void* context ) {
+ FiniteElementContext* self = (FiniteElementContext*) context;
+ Index var_I = 0;
+ FieldVariable* fieldVar = NULL;
+ FeVariable* feVar = NULL;
+
+ /* Save the variables that have had their "isCheckpointedAndReloaded" flag enabled -
+ * default is true, but the user may restrict the list by specifying the "FieldVariablesToCheckpoint"
+ * flag in their constructor - see _FeVariable_AssignFromXML().
+ */
+ for ( var_I = 0; var_I < self->fieldVariable_Register->objects->count; var_I++ ) {
+ fieldVar = FieldVariable_Register_GetByIndex( self->fieldVariable_Register, var_I );
+
+ if ( Stg_Class_IsInstance( fieldVar, FeVariable_Type ) ) {
+ feVar = (FeVariable*)fieldVar;
+ if ( (feVar->isCheckpointedAndReloaded && (self->timeStep % self->checkpointEvery == 0)) ||
+ (feVar->isCheckpointedAndReloaded && (self->checkpointAtTimeInc && (self->currentTime >= self->nextCheckpointTime))) ||
+ (feVar->isSavedData && (self->timeStep % self->saveDataEvery == 0)) ){
+ char* feVarSaveFileName = NULL;
+ char* feVarSaveFileNamePart = NULL;
+
+ feVarSaveFileNamePart = Context_GetCheckPointWritePrefixString( (void*)self );
+
+#ifdef WRITE_HDF5
+ Stg_asprintf( &feVarSaveFileName, "%s%s.%.5u.h5" , feVarSaveFileNamePart, feVar->name, self->timeStep );
+#else
+ Stg_asprintf( &feVarSaveFileName, "%s%s.%.5u.dat", feVarSaveFileNamePart, feVar->name, self->timeStep );
+#endif
+ FeVariable_SaveToFile( feVar, feVarSaveFileName,
+ Dictionary_GetBool_WithDefault( self->dictionary, (Dictionary_Entry_Key)"saveCoordsWithFields", False ) );
+
+ Memory_Free( feVarSaveFileName );
+ Memory_Free( feVarSaveFileNamePart );
+ }
+ }
+ }
+}
+
+
+void _FiniteElementContext_SaveSwarms( void* context ) {
+
+ Swarm_Register_SaveAllRegisteredSwarms(
+ Swarm_Register_GetSwarm_Register( ), context );
+
+}
+
+
+void _FiniteElementContext_SaveMesh( void* context ) {
+ FiniteElementContext* self;
+ Stream* info = Journal_Register( Info_Type, (Name)"Context" );
+ unsigned componentCount = LiveComponentRegister_GetCount(stgLiveComponentRegister );
+ unsigned compI;
+ Stg_Component* stgComp;
+ FeMesh* mesh;
+
+ Journal_Printf( info, "In %s(): about to save the mesh to disk:\n", __func__ );
+
+ self = (FiniteElementContext*) context;
+
+ /** search for entire live component register for feMesh types **/
+ for( compI = 0 ; compI < componentCount ; compI++){
+ stgComp = LiveComponentRegister_At( stgLiveComponentRegister, compI );
+ /* check that component is of type FeMesh */
+ if ( Stg_Class_IsInstance( stgComp, FeMesh_Type ) ) {
+ mesh = (FeMesh*)stgComp;
+ if( mesh->isCheckpointedAndReloaded == True && mesh->requiresCheckpointing == True ){
+#ifdef WRITE_HDF5
+ _FiniteElementContext_DumpMeshHDF5( context, mesh );
+#else
+ _FiniteElementContext_DumpMeshAscii( context, mesh );
+#endif
+ }
+ }
+ }
+ Journal_Printf( info, "%s: saving of mesh completed.\n", __func__ );
+}
+
+#ifndef WRITE_HDF5
+void _FiniteElementContext_DumpMeshAscii( void* context, FeMesh* feMesh ) {
+ FiniteElementContext* self = (FiniteElementContext*) context;
+ FieldVariable* fieldVar = NULL;
+ FeVariable* feVar = NULL;
+ Mesh* mesh;
+ int rank, nRanks;
+ FILE* outputFile;
+ int confirmation = 0;
+ MPI_Status status;
+ Node_LocalIndex lNode_I = 0;
+ Node_GlobalIndex gNode_I = 0;
+ double* coord;
+ unsigned nDims;
+ char* filename = NULL;
+ char* meshSaveFileNamePart = NULL;
+
+ meshSaveFileNamePart = Context_GetCheckPointWritePrefixString( (void*)self );
+
+ Stg_asprintf( &filename, "%sMesh.%s.%.5u.dat", meshSaveFileNamePart, feMesh->name, self->timeStep );
+
+ MPI_Comm_rank( self->communicator, &rank);
+ MPI_Comm_size( self->communicator, &nRanks );
+
+ mesh = (Mesh*)feMesh;
+
+ nDims = Mesh_GetDimSize( mesh );
+
+ /* wait for go-ahead from process ranked lower than me, to avoid competition writing to file */
+ if ( rank != 0 ) {
+ MPI_Recv( &confirmation, 1, MPI_INT, rank - 1, FINISHED_WRITING_TAG, self->communicator, &status );
+ }
+
+ if ( rank == 0 ) {
+ outputFile = fopen( filename, "w" );
+ assert( outputFile );
+
+ /* Write min and max coords to file */
+ if( nDims == 2 ) {
+ fprintf( outputFile, "Min: %.15g %.15g 0\n", mesh->minGlobalCrd[0], mesh->minGlobalCrd[1] );
+ fprintf( outputFile, "Max: %.15g %.15g 0\n", mesh->maxGlobalCrd[0], mesh->maxGlobalCrd[1] );
+ }
+ else {
+ fprintf( outputFile, "Min: %.15g %.15g %.15g\n", mesh->minGlobalCrd[0], mesh->minGlobalCrd[1], mesh->minGlobalCrd[2] );
+ fprintf( outputFile, "Max: %.15g %.15g %.15g\n", mesh->maxGlobalCrd[0], mesh->maxGlobalCrd[1], mesh->maxGlobalCrd[2] );
+ }
+ }
+ else {
+ outputFile = fopen( filename, "a" );
+ assert( outputFile );
+ }
+
+ for ( lNode_I = 0; lNode_I < FeMesh_GetNodeLocalSize( mesh ); lNode_I++ ) {
+ gNode_I = FeMesh_NodeDomainToGlobal( mesh, lNode_I );
+ fprintf( outputFile, "%u ", gNode_I );
+ coord = Mesh_GetVertex( mesh, lNode_I );
+
+ if(self->dim==2)
+ fprintf( outputFile, "%.15g %.15g 0\n", coord[0], coord[1] );
+ else
+ fprintf( outputFile, "%.15g %.15g %.15g\n", coord[0], coord[1], coord[2] );
+ }
+
+ fclose( outputFile );
+
+ /* send go-ahead from process ranked lower than me, to avoid competition writing to file */
+ if ( rank != nRanks - 1 ) {
+ MPI_Ssend( &confirmation, 1, MPI_INT, rank + 1, FINISHED_WRITING_TAG, self->communicator );
+ }
+ Memory_Free( meshSaveFileNamePart );
+ Memory_Free( filename );
+
+}
+#endif
+
+#ifdef WRITE_HDF5
+void _FiniteElementContext_DumpMeshHDF5( void* context, FeMesh* mesh ) {
+ FiniteElementContext* self = (FiniteElementContext*) context;
+ int rank, nRanks;
+ unsigned nDims;
+ hid_t file, fileSpace, fileData, fileSpace2, fileData2;
+ hid_t memSpace;
+ hsize_t start[2], count[2], size[2];
+ unsigned totalVerts;
+ Node_LocalIndex lNode_I = 0;
+ Node_GlobalIndex gNode_I = 0;
+ double* coord;
+ int buf_int[5];
+ MPI_Status status;
+ int confirmation = 0;
+ Stream* errorStr = Journal_Register( Error_Type, (Name)self->type );
+ Element_LocalIndex lElement_I;
+ Element_GlobalIndex gElement_I;
+ Index maxNodes;
+ IArray* iarray = IArray_New( );
+ char* filename = NULL;
+ char* meshSaveFileNamePart = NULL;
+
+ /* don't dump irregular meshes, as havn't accounted for their connectivity yet...
+ * TODO: this is a hack, as we don't know about the IrregularQuadGenerator yet in StgFEM. Need to account
+ * for unstructured meshes at some point in the future... dave 01.10.09 */
+ if( !strcmp( mesh->generator->type, "IrregularQuadGenerator" ) )
+ return;
+
+ meshSaveFileNamePart = Context_GetCheckPointWritePrefixString( context );
+
+ MPI_Comm_rank( self->communicator, &rank);
+ MPI_Comm_size( self->communicator, &nRanks );
+
+ filename = NULL;
+ Stg_asprintf( &filename, "%sMesh.%s.%.5u.h5", meshSaveFileNamePart, mesh->name, self->timeStep );
+
+ nDims = Mesh_GetDimSize( mesh );
+
+ /* wait for go-ahead from process ranked lower than me, to avoid competition writing to file */
+ if ( rank != 0 ) {
+ MPI_Recv( &confirmation, 1, MPI_INT, rank - 1, FINISHED_WRITING_TAG, self->communicator, &status );
+ }
+
+ if ( rank == 0 ) {
+ hid_t attribData_id, attrib_id, group_id;
+ hsize_t a_dims;
+ int attribData;
+ Grid** grid;
+ unsigned* sizes;
+
+ /* Open the HDF5 output file. */
+ file = H5Fcreate( filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT );
+ assert( file );
+
+ /** create file attribute */
+ /** first store the checkpointing version */
+ a_dims = 1;
+ attribData = MeshCHECKPOINT_V2;
+ attribData_id = H5Screate_simple(1, &a_dims, NULL);
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ group_id = H5Gopen(file, "/");
+ attrib_id = H5Acreate(group_id, "checkpoint file version", H5T_STD_I32BE, attribData_id, H5P_DEFAULT);
+ #else
+ group_id = H5Gopen2(file, "/", H5P_DEFAULT);
+ attrib_id = H5Acreate2(group_id, "checkpoint file version", H5T_STD_I32BE, attribData_id, H5P_DEFAULT, H5P_DEFAULT);
+ #endif
+ H5Awrite(attrib_id, H5T_NATIVE_INT, &attribData);
+ H5Aclose(attrib_id);
+ H5Gclose(group_id);
+ H5Sclose(attribData_id);
+
+ /** store the mesh dimensionality */
+ a_dims = 1;
+ attribData = self->dim;
+ attribData_id = H5Screate_simple(1, &a_dims, NULL);
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ group_id = H5Gopen(file, "/");
+ attrib_id = H5Acreate(group_id, "dimensions", H5T_STD_I32BE, attribData_id, H5P_DEFAULT);
+ #else
+ group_id = H5Gopen2(file, "/", H5P_DEFAULT);
+ attrib_id = H5Acreate2(group_id, "dimensions", H5T_STD_I32BE, attribData_id, H5P_DEFAULT, H5P_DEFAULT);
+ #endif
+ H5Awrite(attrib_id, H5T_NATIVE_INT, &attribData);
+ H5Aclose(attrib_id);
+ H5Gclose(group_id);
+ H5Sclose(attribData_id);
+
+ /** store the mesh resolution */
+ a_dims = self->dim;
+ grid = (Grid**) Mesh_GetExtension( mesh, Grid*, "elementGrid" );
+ sizes = Grid_GetSizes( *grid ); /** global no. of elements in each dim */
+
+ attribData_id = H5Screate_simple(1, &a_dims, NULL);
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ group_id = H5Gopen(file, "/");
+ attrib_id = H5Acreate(group_id, "mesh resolution", H5T_STD_I32BE, attribData_id, H5P_DEFAULT);
+ #else
+ group_id = H5Gopen2(file, "/", H5P_DEFAULT);
+ attrib_id = H5Acreate2(group_id, "mesh resolution", H5T_STD_I32BE, attribData_id, H5P_DEFAULT, H5P_DEFAULT);
+ #endif
+ H5Awrite(attrib_id, H5T_NATIVE_INT, sizes);
+ H5Aclose(attrib_id);
+ H5Gclose(group_id);
+ H5Sclose(attribData_id);
+
+ /* Dump the min and max coords, and number of processes. */
+ count[0] = (hsize_t)nDims;
+ fileSpace = H5Screate_simple( 1, count, NULL );
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ fileData = H5Dcreate( file, "/min", H5T_NATIVE_DOUBLE, fileSpace, H5P_DEFAULT );
+ #else
+ fileData = H5Dcreate2( file, "/min", H5T_NATIVE_DOUBLE, fileSpace,
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
+ #endif
+
+ H5Dwrite( fileData, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, mesh->minGlobalCrd );
+ H5Dclose( fileData );
+ H5Sclose( fileSpace );
+
+ fileSpace = H5Screate_simple( 1, count, NULL );
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ fileData = H5Dcreate( file, "/max", H5T_NATIVE_DOUBLE, fileSpace, H5P_DEFAULT );
+ #else
+ fileData = H5Dcreate2( file, "/max", H5T_NATIVE_DOUBLE, fileSpace,
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
+ #endif
+
+ H5Dwrite( fileData, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, mesh->maxGlobalCrd );
+ H5Dclose( fileData );
+ H5Sclose( fileSpace );
+
+ /* Write vertex coords to file */
+ /* Create our output space and data objects. */
+ totalVerts = Mesh_GetGlobalSize( mesh, (MeshTopology_Dim)0 );
+ size[0] = (hsize_t)totalVerts;
+ size[1] = (hsize_t)nDims;
+
+ fileSpace = H5Screate_simple( 2, size, NULL );
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ fileData = H5Dcreate( file, "/vertices", H5T_NATIVE_DOUBLE, fileSpace, H5P_DEFAULT );
+ #else
+ fileData = H5Dcreate2( file, "/vertices", H5T_NATIVE_DOUBLE, fileSpace,
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
+ #endif
+
+ /* setup element connectivity dataspaces */
+ if (mesh->nElTypes == 1)
+ maxNodes = FeMesh_GetElementNodeSize( mesh, 0);
+ else {
+ /* determine the maximum number of nodes each element has */
+ maxNodes = 0;
+ for ( gElement_I = 0 ; gElement_I < FeMesh_GetElementGlobalSize(mesh); gElement_I++ ) {
+ unsigned numNodes;
+ numNodes = FeMesh_GetElementNodeSize( mesh, gElement_I);
+ if( maxNodes < numNodes ) maxNodes = numNodes;
+ }
+ }
+
+ size[0] = (hsize_t)FeMesh_GetElementGlobalSize(mesh);
+ size[1] = (hsize_t)maxNodes;
+ /* Create our output space and data objects. */
+ fileSpace2 = H5Screate_simple( 2, size, NULL );
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ fileData2 = H5Dcreate( file, "/connectivity", H5T_NATIVE_INT, fileSpace2, H5P_DEFAULT );
+ #else
+ fileData2 = H5Dcreate2( file, "/connectivity", H5T_NATIVE_INT, fileSpace2,
+ H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
+ #endif
+
+ } else {
+ /* Open the HDF5 output file. */
+ file = H5Fopen( filename, H5F_ACC_RDWR, H5P_DEFAULT );
+ Journal_Firewall(
+ file >= 0,
+ errorStr,
+ "Error in %s for %s '%s' - Cannot open file %s.\n",
+ __func__,
+ self->type,
+ self->name,
+ filename );
+
+ /* get the node filespace */
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ fileData = H5Dopen( file, "/vertices" );
+ #else
+ fileData = H5Dopen2( file, "/vertices", H5P_DEFAULT );
+ #endif
+ /* get the filespace handle */
+ fileSpace = H5Dget_space(fileData);
+
+ /* get the connectivity */
+ #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR < 8
+ fileData2 = H5Dopen( file, "/connectivity" );
+ #else
+ fileData2 = H5Dopen2( file, "/connectivity", H5P_DEFAULT );
+ #endif
+ /* get the filespace handle */
+ fileSpace2 = H5Dget_space(fileData2);
+ }
+
+ count[0] = 1;
+ count[1] = nDims;
+ memSpace = H5Screate_simple( 2, count, NULL );
+ H5Sselect_all( memSpace );
+
+ for ( lNode_I = 0; lNode_I < FeMesh_GetNodeLocalSize( mesh ); lNode_I++ ) {
+ gNode_I = FeMesh_NodeDomainToGlobal( mesh, lNode_I );
+
+ coord = Mesh_GetVertex( mesh, lNode_I );
+
+ /* select the region of dataspace to write to */
+ start[1] = 0;
+ start[0] = gNode_I;
+ H5Sselect_hyperslab( fileSpace, H5S_SELECT_SET, start, NULL, count, NULL );
+
+ H5Dwrite( fileData, H5T_NATIVE_DOUBLE, memSpace, fileSpace, H5P_DEFAULT, coord );
+ }
+
+ /* Close off all our handles. */
+ H5Sclose( memSpace );
+ H5Dclose( fileData );
+ H5Sclose( fileSpace );
+
+ H5Sget_simple_extent_dims( fileSpace2, size, NULL );
+ count[0] = 1;
+ count[1] = size[1];
+ memSpace = H5Screate_simple( 2, count, NULL );
+ H5Sselect_all( memSpace );
+
+ for ( lElement_I = 0 ; lElement_I < FeMesh_GetElementLocalSize(mesh); lElement_I++ ) {
+ int* nodeList, nodesPerEl;
+ int node_I;
+
+ gElement_I = FeMesh_ElementDomainToGlobal( mesh,lElement_I );
+
+ /* get element nodes */
+ FeMesh_GetElementNodes( mesh, lElement_I, iarray );
+ nodesPerEl = IArray_GetSize( iarray );
+ nodeList = IArray_GetPtr( iarray );
+
+ for( node_I = 0 ; node_I < nodesPerEl ; node_I++ )
+ buf_int[node_I] = Mesh_DomainToGlobal( mesh, MT_VERTEX, nodeList[node_I] );
+ /* some reordering is required to account for standard node ordering */
+ buf_int[3] = Mesh_DomainToGlobal( mesh, MT_VERTEX, nodeList[2] );
+ buf_int[2] = Mesh_DomainToGlobal( mesh, MT_VERTEX, nodeList[3] );
+ if( nDims == 3 ) {
+ buf_int[7] = Mesh_DomainToGlobal( mesh, MT_VERTEX, nodeList[6] );
+ buf_int[6] = Mesh_DomainToGlobal( mesh, MT_VERTEX, nodeList[7] );
+ }
+ /* select the region of dataspace to write to */
+ start[1] = 0;
+ start[0] = gElement_I;
+ H5Sselect_hyperslab( fileSpace2, H5S_SELECT_SET, start, NULL, count, NULL );
+
+ H5Dwrite( fileData2, H5T_NATIVE_INT, memSpace, fileSpace2, H5P_DEFAULT, buf_int );
+ }
+
+ /* Close off all our handles. */
+ H5Sclose( memSpace );
+ H5Dclose( fileData2 );
+ H5Sclose( fileSpace2 );
+ H5Fclose( file );
+
+ /* send go-ahead from process ranked lower than me, to avoid competition writing to file */
+ if ( rank != nRanks - 1 ) {
+ MPI_Ssend( &confirmation, 1, MPI_INT, rank + 1, FINISHED_WRITING_TAG, self->communicator );
+ }
+
+ Memory_Free( filename );
+
+ Memory_Free( meshSaveFileNamePart );
+ NewClass_Delete( iarray );
+}
+#endif
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/ForceTerm.c
--- a/SLE/SystemSetup/src/ForceTerm.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: ForceTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "FiniteElementContext.h"
-#include "ForceTerm.h"
-#include "SolutionVector.h"
-#include "ForceVector.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-#include "EntryPoint.h"
-
-/* Textual name of this class */
-const Type ForceTerm_Type = "ForceTerm";
-
-ForceTerm* ForceTerm_New(
- Name name,
- FiniteElementContext* context,
- ForceVector* forceVector,
- Swarm* integrationSwarm,
- Stg_Component* extraInfo )
-{
- ForceTerm* self = (ForceTerm*) _ForceTerm_DefaultNew( name );
-
- self->isConstructed = True;
- _ForceTerm_Init( self, context, forceVector, integrationSwarm, extraInfo );
-
- return self;
-}
-
-void* _ForceTerm_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(ForceTerm);
- Type type = ForceTerm_Type;
- Stg_Class_DeleteFunction* _delete = _ForceTerm_Delete;
- Stg_Class_PrintFunction* _print = _ForceTerm_Print;
- Stg_Class_CopyFunction* _copy = _ForceTerm_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _ForceTerm_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _ForceTerm_AssignFromXML;
- Stg_Component_BuildFunction* _build = _ForceTerm_Build;
- Stg_Component_InitialiseFunction* _initialise = _ForceTerm_Initialise;
- Stg_Component_ExecuteFunction* _execute = _ForceTerm_Execute;
- Stg_Component_DestroyFunction* _destroy = _ForceTerm_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- ForceTerm_AssembleElementFunction* _assembleElement = _ForceTerm_AssembleElement;
-
- return _ForceTerm_New( FORCETERM_PASSARGS );
-}
-
-ForceTerm* _ForceTerm_New( FORCETERM_DEFARGS ) {
- ForceTerm* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(ForceTerm) );
- self = (ForceTerm*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- self->_assembleElement = _assembleElement;
-
- return self;
-}
-
-
-void _ForceTerm_Init(
- void* forceTerm,
- FiniteElementContext* context,
- ForceVector* forceVector,
- Swarm* integrationSwarm,
- Stg_Component* extraInfo )
-{
- ForceTerm* self = (ForceTerm*) forceTerm;
- self->context = context;
- self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type );
- self->extraInfo = extraInfo;
- self->integrationSwarm = integrationSwarm;
- self->forceVector = forceVector;
-
- ForceVector_AddForceTerm( forceVector, self );
-}
-
-
-void _ForceTerm_Delete( void* forceTerm ) {
- ForceTerm* self = (ForceTerm*)forceTerm;
-
- Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
-
- /* Stg_Class_Delete parent*/
- _Stg_Component_Delete( self );
-}
-
-
-void _ForceTerm_Print( void* forceTerm, Stream* stream ) {
- ForceTerm* self = (ForceTerm*)forceTerm;
-
- /* General info */
- Journal_Printf( stream, "ForceTerm (ptr): %p\n", self );
-
- /* Print parent */
- _Stg_Component_Print( self, stream );
-
- /* ForceTerm info */
- Journal_Printf( stream, "\tintegrationSwarm (ptr): %p\n", self->integrationSwarm );
- Journal_Printf( stream, "\textraInfo (ptr): %p\n", self->extraInfo );
-}
-
-
-void* _ForceTerm_Copy( const void* forceTerm, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- ForceTerm* self = (ForceTerm*)forceTerm;
- ForceTerm* newForceTerm;
- PtrMap* map = ptrMap;
- Bool ownMap = False;
-
- if( !map ) {
- map = PtrMap_New( 10 );
- ownMap = True;
- }
-
- newForceTerm = (ForceTerm*)_Stg_Component_Copy( self, dest, deep, nameExt, map );
-
- newForceTerm->extraInfo = self->extraInfo;
- if( deep ) {
- newForceTerm->integrationSwarm = (Swarm*)Stg_Class_Copy( self->integrationSwarm, NULL, deep, nameExt, map );
- }
- else {
- newForceTerm->integrationSwarm = self->integrationSwarm;
- }
-
- if( ownMap ) {
- Stg_Class_Delete( map );
- }
-
- return (void*)newForceTerm;
-}
-
-void _ForceTerm_AssignFromXML( void* forceTerm, Stg_ComponentFactory* cf, void* data ) {
- FiniteElementContext* context;
- ForceTerm* self = (ForceTerm*)forceTerm;
- Swarm* swarm = NULL;
- Stg_Component* extraInfo;
- ForceVector* forceVector;
-
- context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", FiniteElementContext, False, data );
-
- if( !context )
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
-
- forceVector = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ForceVector", ForceVector, True, data ) ;
- swarm = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Swarm", Swarm, True, data ) ;
- extraInfo = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ExtraInfo", Stg_Component, False, data ) ;
-
- _ForceTerm_Init( self, context, forceVector, swarm, extraInfo );
-}
-
-void _ForceTerm_Build( void* forceTerm, void* data ) {
- ForceTerm* self = (ForceTerm*)forceTerm;
-
- Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
-
- /* ensure integrationSwarm is built */
- Stg_Component_Build( self->integrationSwarm, data, False );
- Stg_Component_Build( self->forceVector, data, False );
-
- if ( self->extraInfo )
- Stg_Component_Build( self->extraInfo, data, False );
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _ForceTerm_Initialise( void* forceTerm, void* data ) {
- ForceTerm* self = (ForceTerm*)forceTerm;
-
- Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
-
- Stg_Component_Initialise( self->integrationSwarm, data, False );
- Stg_Component_Initialise( self->forceVector, data, False );
- if ( self->extraInfo )
- Stg_Component_Initialise( self->extraInfo, data, False );
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-void _ForceTerm_Execute( void* forceTerm, void* data ) {
-}
-
-void _ForceTerm_Destroy( void* forceTerm, void* data ) {
- ForceTerm* self = (ForceTerm*)forceTerm;
-
- if ( self->extraInfo )
- Stg_Component_Destroy( self->extraInfo, data, False );
-
- Stg_Component_Destroy( self->integrationSwarm, data, False );
- Stg_Component_Destroy( self->forceVector, data, False );
-}
-
-void ForceTerm_AssembleElement(
- void* forceTerm,
- ForceVector* forceVector,
- Element_LocalIndex lElement_I,
- double* elForceVecToAdd )
-{
- ForceTerm* self = (ForceTerm*)forceTerm;
-
- self->_assembleElement( self, forceVector, lElement_I, elForceVecToAdd );
-}
-
-void _ForceTerm_AssembleElement(
- void* forceTerm,
- ForceVector* forceVector,
- Element_LocalIndex lElement_I,
- double* elForceVecToAdd )
-{
- ForceTerm* self = (ForceTerm*)forceTerm;
- Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
-
- Journal_Printf( errorStream, "Error in func %s for %s '%s' - "
- "This function is the default function which should never be called - "
- "Please set this virtual function with appropriate application dependent function.\n",
- __func__, self->type, self->name );
- abort();
-}
-
-void ForceTerm_SetAssembleElementFunction( void* forceTerm, ForceTerm_AssembleElementFunction* assembleElementFunction ) {
- ForceTerm* self = (ForceTerm*)forceTerm;
-
- self->_assembleElement = assembleElementFunction;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/ForceTerm.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/ForceTerm.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,278 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: ForceTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "FiniteElementContext.h"
+#include "ForceTerm.h"
+#include "SolutionVector.h"
+#include "ForceVector.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "EntryPoint.h"
+
+/* Textual name of this class */
+const Type ForceTerm_Type = "ForceTerm";
+
+ForceTerm* ForceTerm_New(
+ Name name,
+ FiniteElementContext* context,
+ ForceVector* forceVector,
+ Swarm* integrationSwarm,
+ Stg_Component* extraInfo )
+{
+ ForceTerm* self = (ForceTerm*) _ForceTerm_DefaultNew( name );
+
+ self->isConstructed = True;
+ _ForceTerm_Init( self, context, forceVector, integrationSwarm, extraInfo );
+
+ return self;
+}
+
+void* _ForceTerm_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(ForceTerm);
+ Type type = ForceTerm_Type;
+ Stg_Class_DeleteFunction* _delete = _ForceTerm_Delete;
+ Stg_Class_PrintFunction* _print = _ForceTerm_Print;
+ Stg_Class_CopyFunction* _copy = _ForceTerm_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _ForceTerm_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _ForceTerm_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _ForceTerm_Build;
+ Stg_Component_InitialiseFunction* _initialise = _ForceTerm_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _ForceTerm_Execute;
+ Stg_Component_DestroyFunction* _destroy = _ForceTerm_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ ForceTerm_AssembleElementFunction* _assembleElement = _ForceTerm_AssembleElement;
+
+ return _ForceTerm_New( FORCETERM_PASSARGS );
+}
+
+ForceTerm* _ForceTerm_New( FORCETERM_DEFARGS ) {
+ ForceTerm* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(ForceTerm) );
+ self = (ForceTerm*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ self->_assembleElement = _assembleElement;
+
+ return self;
+}
+
+
+void _ForceTerm_Init(
+ void* forceTerm,
+ FiniteElementContext* context,
+ ForceVector* forceVector,
+ Swarm* integrationSwarm,
+ Stg_Component* extraInfo )
+{
+ ForceTerm* self = (ForceTerm*) forceTerm;
+ self->context = context;
+ self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type );
+ self->extraInfo = extraInfo;
+ self->integrationSwarm = integrationSwarm;
+ self->forceVector = forceVector;
+
+ ForceVector_AddForceTerm( forceVector, self );
+}
+
+
+void _ForceTerm_Delete( void* forceTerm ) {
+ ForceTerm* self = (ForceTerm*)forceTerm;
+
+ Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
+
+ /* Stg_Class_Delete parent*/
+ _Stg_Component_Delete( self );
+}
+
+
+void _ForceTerm_Print( void* forceTerm, Stream* stream ) {
+ ForceTerm* self = (ForceTerm*)forceTerm;
+
+ /* General info */
+ Journal_Printf( stream, "ForceTerm (ptr): %p\n", self );
+
+ /* Print parent */
+ _Stg_Component_Print( self, stream );
+
+ /* ForceTerm info */
+ Journal_Printf( stream, "\tintegrationSwarm (ptr): %p\n", self->integrationSwarm );
+ Journal_Printf( stream, "\textraInfo (ptr): %p\n", self->extraInfo );
+}
+
+
+void* _ForceTerm_Copy( const void* forceTerm, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ ForceTerm* self = (ForceTerm*)forceTerm;
+ ForceTerm* newForceTerm;
+ PtrMap* map = ptrMap;
+ Bool ownMap = False;
+
+ if( !map ) {
+ map = PtrMap_New( 10 );
+ ownMap = True;
+ }
+
+ newForceTerm = (ForceTerm*)_Stg_Component_Copy( self, dest, deep, nameExt, map );
+
+ newForceTerm->extraInfo = self->extraInfo;
+ if( deep ) {
+ newForceTerm->integrationSwarm = (Swarm*)Stg_Class_Copy( self->integrationSwarm, NULL, deep, nameExt, map );
+ }
+ else {
+ newForceTerm->integrationSwarm = self->integrationSwarm;
+ }
+
+ if( ownMap ) {
+ Stg_Class_Delete( map );
+ }
+
+ return (void*)newForceTerm;
+}
+
+void _ForceTerm_AssignFromXML( void* forceTerm, Stg_ComponentFactory* cf, void* data ) {
+ FiniteElementContext* context;
+ ForceTerm* self = (ForceTerm*)forceTerm;
+ Swarm* swarm = NULL;
+ Stg_Component* extraInfo;
+ ForceVector* forceVector;
+
+ context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", FiniteElementContext, False, data );
+
+ if( !context )
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
+
+ forceVector = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ForceVector", ForceVector, True, data ) ;
+ swarm = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Swarm", Swarm, True, data ) ;
+ extraInfo = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ExtraInfo", Stg_Component, False, data ) ;
+
+ _ForceTerm_Init( self, context, forceVector, swarm, extraInfo );
+}
+
+void _ForceTerm_Build( void* forceTerm, void* data ) {
+ ForceTerm* self = (ForceTerm*)forceTerm;
+
+ Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ /* ensure integrationSwarm is built */
+ Stg_Component_Build( self->integrationSwarm, data, False );
+ Stg_Component_Build( self->forceVector, data, False );
+
+ if ( self->extraInfo )
+ Stg_Component_Build( self->extraInfo, data, False );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _ForceTerm_Initialise( void* forceTerm, void* data ) {
+ ForceTerm* self = (ForceTerm*)forceTerm;
+
+ Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ Stg_Component_Initialise( self->integrationSwarm, data, False );
+ Stg_Component_Initialise( self->forceVector, data, False );
+ if ( self->extraInfo )
+ Stg_Component_Initialise( self->extraInfo, data, False );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+void _ForceTerm_Execute( void* forceTerm, void* data ) {
+}
+
+void _ForceTerm_Destroy( void* forceTerm, void* data ) {
+ ForceTerm* self = (ForceTerm*)forceTerm;
+
+ if ( self->extraInfo )
+ Stg_Component_Destroy( self->extraInfo, data, False );
+
+ Stg_Component_Destroy( self->integrationSwarm, data, False );
+ Stg_Component_Destroy( self->forceVector, data, False );
+}
+
+void ForceTerm_AssembleElement(
+ void* forceTerm,
+ ForceVector* forceVector,
+ Element_LocalIndex lElement_I,
+ double* elForceVecToAdd )
+{
+ ForceTerm* self = (ForceTerm*)forceTerm;
+
+ self->_assembleElement( self, forceVector, lElement_I, elForceVecToAdd );
+}
+
+void _ForceTerm_AssembleElement(
+ void* forceTerm,
+ ForceVector* forceVector,
+ Element_LocalIndex lElement_I,
+ double* elForceVecToAdd )
+{
+ ForceTerm* self = (ForceTerm*)forceTerm;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
+
+ Journal_Printf( errorStream, "Error in func %s for %s '%s' - "
+ "This function is the default function which should never be called - "
+ "Please set this virtual function with appropriate application dependent function.\n",
+ __func__, self->type, self->name );
+ abort();
+}
+
+void ForceTerm_SetAssembleElementFunction( void* forceTerm, ForceTerm_AssembleElementFunction* assembleElementFunction ) {
+ ForceTerm* self = (ForceTerm*)forceTerm;
+
+ self->_assembleElement = assembleElementFunction;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/ForceVector.c
--- a/SLE/SystemSetup/src/ForceVector.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,558 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: ForceVector.c 1210 2008-08-25 01:17:12Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "FiniteElementContext.h"
-#include "SolutionVector.h"
-#include "ForceVector.h"
-#include "ForceTerm.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-#include "EntryPoint.h"
-#include "Assembler.h"
-
-
-Bool ForceVector_BCAsm_RowR( void* forceVec, Assembler* assm );
-
-
-/* Textual name of this class */
-const Type ForceVector_Type = "ForceVector";
-
-/** Name of this class' entry points */
-static const char ForceVector_assembleForceVectorStr[] = "assembleForceVector";
-
-ForceVector* ForceVector_New(
- Name name,
- FiniteElementContext* context,
- FeVariable* feVariable,
- Dimension_Index dim,
- void* entryPoint_Register,
- MPI_Comm comm )
-{
- ForceVector* self = (ForceVector*)_ForceVector_DefaultNew( name );
-
- self->isConstructed = True;
- _SolutionVector_Init( (SolutionVector*)self, context, comm, feVariable );
- _ForceVector_Init( self, dim, (EntryPoint_Register*)entryPoint_Register );
-
- return self;
-}
-
-void* _ForceVector_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(ForceVector);
- Type type = ForceVector_Type;
- Stg_Class_DeleteFunction* _delete = _ForceVector_Delete;
- Stg_Class_PrintFunction* _print = _ForceVector_Print;
- Stg_Class_CopyFunction* _copy = _ForceVector_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _ForceVector_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _ForceVector_AssignFromXML;
- Stg_Component_BuildFunction* _build = _ForceVector_Build;
- Stg_Component_InitialiseFunction* _initialise = _ForceVector_Initialise;
- Stg_Component_ExecuteFunction* _execute = _ForceVector_Execute;
- Stg_Component_DestroyFunction* _destroy = _ForceVector_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
-
- return _ForceVector_New( FORCEVECTOR_PASSARGS );
-}
-
-ForceVector* _ForceVector_New( FORCEVECTOR_DEFARGS ) {
- ForceVector* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(ForceVector) );
- self = (ForceVector*)_SolutionVector_New( SOLUTIONVECTOR_PASSARGS );
-
- return self;
-}
-
-
-void _ForceVector_Init( void* forceVector, Dimension_Index dim, EntryPoint_Register* entryPoint_Register ) {
- ForceVector* self = (ForceVector*) forceVector;
-
- /* ForceVector info */
- self->dim = dim;
- self->entryPoint_Register = entryPoint_Register;
-
- /* Create Stream */
- self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type );
-
- /* Create Entry Point for assembleForceVector */
- Stg_asprintf( (char**)(&self->_assembleForceVectorEPName), "%s-%s", self->name, ForceVector_assembleForceVectorStr );
- self->assembleForceVector = FeEntryPoint_New( self->_assembleForceVectorEPName, FeEntryPoint_AssembleForceVector_CastType );
- EntryPoint_Register_Add( self->entryPoint_Register, self->assembleForceVector );
-
- /* Add default hook to assembleForceVector entry point */
- EP_ReplaceAll( self->assembleForceVector, ForceVector_GlobalAssembly_General );
-
- self->forceTermList = Stg_ObjectList_New();
-
- self->bcAsm = Assembler_New();
- self->inc = IArray_New();
-
- self->nModifyCBs = 0;
- self->modifyCBs = NULL;
-}
-
-void _ForceVector_Delete( void* forceVector ) {
- ForceVector* self = (ForceVector*)forceVector;
-
- Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
-
- /* Stg_Class_Delete parent*/
- _SolutionVector_Delete( self );
-}
-
-void _ForceVector_Print( void* forceVector, Stream* stream ) {
- ForceVector* self = (ForceVector*)forceVector;
-
- /* General info */
- Journal_Printf( stream, "ForceVector (ptr): %p\n", self );
-
- /* Print parent */
- _SolutionVector_Print( self, stream );
-
- /* Virtual info */
-
- /* ForceVector info */
- Journal_Printf( stream, "\tassembleForceVector e.p. (ptr): %p\n", self->assembleForceVector );
- EntryPoint_PrintConcise( self->assembleForceVector, stream );
-
- Journal_Printf( stream, "\tVector (ptr): %p\n", self->vector );
- Journal_Printf( stream, "\tComm: %u\n", self->comm );
- Journal_Printf( stream, "\tLocalSize: %u\n", self->localSize );
-}
-
-
-void* _ForceVector_Copy( const void* forceVector, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- ForceVector* self = (ForceVector*)forceVector;
- ForceVector* newForceVector;
- PtrMap* map = ptrMap;
- Bool ownMap = False;
-
- if( !map ) {
- map = PtrMap_New( 10 );
- ownMap = True;
- }
-
- newForceVector = (ForceVector*)_SolutionVector_Copy( self, dest, deep, nameExt, map );
-
- /* TODO: copy vector? */
- newForceVector->entryPoint_Register = self->entryPoint_Register;
- newForceVector->localSize = self->localSize;
-
- if( deep ) {
- newForceVector->assembleForceVector = (FeEntryPoint*)Stg_Class_Copy( self->assembleForceVector, NULL, deep, nameExt, map );
- if( self->_assembleForceVectorEPName ) {
- if( nameExt ) {
- unsigned nameLen = strlen( self->_assembleForceVectorEPName );
-
- newForceVector->_assembleForceVectorEPName = (char*)Memory_Alloc_Bytes_Unnamed( nameLen + strlen( nameExt ) + 1, "FV->vecEPName" );
- memcpy( (char*)(newForceVector->_assembleForceVectorEPName), self->_assembleForceVectorEPName, nameLen );
- strcpy( (char*)(newForceVector->_assembleForceVectorEPName) + nameLen, nameExt );
- }
- else {
- newForceVector->_assembleForceVectorEPName = StG_Strdup( self->_assembleForceVectorEPName );
- }
- }
- else {
- newForceVector->_assembleForceVectorEPName = NULL;
- }
-
- }
- else {
- newForceVector->debug = self->debug;
- newForceVector->_assembleForceVectorEPName = self->_assembleForceVectorEPName;
- newForceVector->assembleForceVector = self->assembleForceVector;
- }
-
- if( ownMap ) {
- Stg_Class_Delete( map );
- }
-
- return (void*)newForceVector;
-}
-
-
-void _ForceVector_AssignFromXML( void* forceVector, Stg_ComponentFactory* cf, void* data ) {
- ForceVector* self = (ForceVector*)forceVector;
- Dimension_Index dim = 0;
- void* entryPointRegister = NULL;
-
- _SolutionVector_AssignFromXML( self, cf, data );
-
- dim = Stg_ComponentFactory_GetRootDictUnsignedInt( cf, (Dictionary_Entry_Key)"dim", 0 );
-
- entryPointRegister = (void*)self->context->entryPoint_Register;
- assert( entryPointRegister );
-
- _ForceVector_Init( self, dim, (EntryPoint_Register*)entryPointRegister );
-}
-
-void _ForceVector_Build( void* forceVector, void* data ) {
- ForceVector* self = (ForceVector*)forceVector;
-
- Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
- /* ensure feVariable is built */
- if( self->feVariable ) {
- Stg_Component_Build( self->feVariable, data, False );
- }
-
- /* update the size depending on our now built feVariable */
- self->localSize = self->feVariable->eqNum->localEqNumsOwnedCount;
- /* assert( self->localSize ); */
-
- /* Allocate the vector */
- Journal_DPrintfL( self->debug, 2, "Allocating the L.A. Force Vector with %d local entries.\n", self->localSize );
- VecCreate( self->comm, &self->vector );
- VecSetSizes( self->vector, (PetscInt)self->localSize, PETSC_DECIDE );
- VecSetFromOptions( self->vector );
-#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
- VecSetOption( self->vector, VEC_IGNORE_NEGATIVE_INDICES );
-#elif( PETSC_VERSION_MAJOR >= 3 )
- VecSetOption( self->vector, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
-#endif
-
- Stream_UnIndentBranch( StgFEM_Debug );
-
- Assembler_SetVariables( self->bcAsm, self->feVariable, NULL );
- Assembler_SetCallbacks( self->bcAsm,
- NULL,
- ForceVector_BCAsm_RowR, NULL,
- NULL, NULL,
- self );
-}
-
-
-void _ForceVector_Initialise( void* forceVector, void* data ) {
- ForceVector* self = (ForceVector*)forceVector;
-
- Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
- /* ensure feVariable is initialised */
- if( self->feVariable )
- Stg_Component_Initialise( self->feVariable, data, False );
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-void _ForceVector_Execute( void* forceVector, void* data ) {
-}
-
-void _ForceVector_Destroy( void* forceVector, void* data ) {
- ForceVector* self = (ForceVector*)forceVector;
-
- Memory_Free( self->_assembleForceVectorEPName );
-
- /* Don't delete entry point: E.P register will delete it automatically */
- Stg_Class_Delete( self->forceTermList );
-
- NewClass_Delete( self->inc );
-
- _SolutionVector_Destroy( self, data );
-}
-
-void ForceVector_Assemble( void* forceVector ) {
- ForceVector* self = (ForceVector*)forceVector;
- int ii;
-
- Journal_DPrintf( self->debug, "In %s - for vector \"%s\" - calling the \"%s\" E.P.\n", __func__, self->name,
- self->assembleForceVector->name );
-
- /* Call the Entry point directly from the base class */
- /* Note that it may be empty: this is deliberate. */
- if ( 0 == self->assembleForceVector->hooks->count ) {
- Journal_DPrintf( self->debug, "(E.P. has no hooks loaded -> no assembly required.)\n" );
- }
-
- ((FeEntryPoint_AssembleForceVector_CallFunction*)EntryPoint_GetRun( self->assembleForceVector ))(
- self->assembleForceVector,
- self );
-
- /* Run all the modify callbacks. */
- for( ii = 0; ii < self->nModifyCBs; ii++ ) {
- void* callback = self->modifyCBs[ii].callback;
- void* object = self->modifyCBs[ii].object;
- ((void(*)(void*))callback)( object );
- }
-}
-
-
-void ForceVector_PrintElementForceVector(
- ForceVector* self,
- Element_LocalIndex element_lI,
- Dof_EquationNumber** elementLM,
- double* elForceVecToAdd )
-{
- DofLayout* dofLayout = self->feVariable->dofLayout;
- FeMesh* feMesh = self->feVariable->feMesh;
- unsigned nInc, *inc;
- Dof_Index dofsPerNode;
- Node_LocalIndex nodesThisEl;
- Node_LocalIndex node_I;
- Dof_Index dof_I;
- Index vec_I;
- IArray* incArray;
-
- incArray = IArray_New();
- FeMesh_GetElementNodes( feMesh, element_lI, incArray );
- nInc = IArray_GetSize( incArray );
- inc = (unsigned*)IArray_GetPtr( incArray );
- dofsPerNode = dofLayout->dofCounts[inc[0]];
- nodesThisEl = nInc;
-
- for ( node_I=0; node_I < nodesThisEl; node_I++ ) {
- for ( dof_I = 0; dof_I < dofsPerNode; dof_I++ ) {
- vec_I = node_I * dofsPerNode + dof_I;
-
- Journal_DPrintf( self->debug, "Entry[%d][%d] (LM (%4d)) = %.3f\n",
- node_I, dof_I,
- elementLM[node_I][dof_I],
- elForceVecToAdd[vec_I] );
- }
- }
-
- NewClass_Delete( incArray );
-}
-
-/* from the depreciated Vector class */
-void _ForceVector_VectorView( Vec v, Stream* stream ) {
- unsigned entry_i;
- PetscInt size;
- PetscScalar* array;
-
- VecGetSize( v, &size );
- VecGetArray( v, &array );
-
- Journal_Printf( stream, "%p = [", v );
- for( entry_i = 0; entry_i < size; entry_i++ )
- Journal_Printf( stream, "\t%u: \t %.12g\n", entry_i, array[entry_i] );
- Journal_Printf( stream, "];\n" );
-
- VecRestoreArray( v, &array );
-}
-
-void ForceVector_GlobalAssembly_General( void* forceVector ) {
- ForceVector* self = (ForceVector*) forceVector;
- FeVariable* feVar = self->feVariable;
- Element_LocalIndex element_lI;
- Element_LocalIndex elementLocalCount;
- Node_ElementLocalIndex nodeCountCurrElement = 0;
- Element_Nodes nodeIdsInCurrElement = 0;
- Dof_Index totalDofsThisElement = 0;
- Dof_Index totalDofsPrevElement = 0;
- Dof_Index dofCountLastNode = 0;
- Dof_EquationNumber** elementLM = NULL;
- double* elForceVecToAdd = NULL;
- /* For output printing */
- double outputPercentage=10; /* Controls how often to give a status update of assembly progress */
- int outputInterval;
-
- Journal_DPrintf( self->debug, "In %s - for vector \"%s\"\n", __func__, self->name );
-
- Stream_IndentBranch( StgFEM_Debug );
-
- if ( Stg_ObjectList_Count( self->forceTermList ) > 0 ) {
- elementLocalCount = FeMesh_GetElementLocalSize( feVar->feMesh );
-
- /* Initialise Vector */
- outputInterval = (int)( (outputPercentage/100.0)*(double)(elementLocalCount) );
- if( outputInterval == 0 ) { outputInterval = elementLocalCount; }
-
- for( element_lI = 0; element_lI < elementLocalCount; element_lI++ ) {
- unsigned nInc, *inc;
-
- FeMesh_GetElementNodes( feVar->feMesh, element_lI, self->inc );
- nInc = IArray_GetSize( self->inc );
- inc = (unsigned*)IArray_GetPtr( self->inc );
- nodeCountCurrElement = nInc;
- /* Get the local node ids */
- nodeIdsInCurrElement = inc;
-
- /* Set value of elementLM: will automatically just index into global LM table if built */
- elementLM = FeEquationNumber_BuildOneElementLocationMatrix( feVar->eqNum, element_lI );
-
- /* work out number of dofs at the node, using LM */
- /* Since: Number of entries in LM table for this element = (by defn.) Number of dofs this element */
- dofCountLastNode = feVar->dofLayout->dofCounts[nodeIdsInCurrElement[nodeCountCurrElement-1]];
- totalDofsThisElement = &elementLM[nodeCountCurrElement-1][dofCountLastNode-1] - &elementLM[0][0] + 1;
-
- if ( totalDofsThisElement > totalDofsPrevElement ) {
- if (elForceVecToAdd) Memory_Free( elForceVecToAdd );
- Journal_DPrintfL( self->debug, 2, "Reallocating elForceVecToAdd to size %d\n", totalDofsThisElement );
- elForceVecToAdd = Memory_Alloc_Array( double, totalDofsThisElement, "elForceVecToAdd" );
- }
-
- /* Initialise Values to Zero */
- memset( elForceVecToAdd, 0, totalDofsThisElement * sizeof(double) );
-
- /* Assemble this element's element force vector: going through each force term in list */
- ForceVector_AssembleElement( self, element_lI, elForceVecToAdd );
-
-/*
- #if DEBUG
- if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
- Journal_DPrintf( self->debug, "Handling Element %d:\n", element_lI );
- FeEquationNumber_PrintElementLocationMatrix( feVar->eqNum, elementLM,
- element_lI, self->debug );
-
- Journal_DPrintf( self->debug, "El force Vec about to be added:\n" );
- ForceVector_PrintElementForceVector( self, element_lI, elementLM, elForceVecToAdd );
- }
- #endif
-*/
-
- /* When keeping BCs in we come across a bit of a problem in parallel. We're not
- allowed to add entries to the force vector here and then clobber it later with
- an insert in order to set the BC. So, what we'll do is just add zero here, that
- way later we can add the BC and it will be the same as inserting it.
- --- Luke, 20 May 2008 */
- if( !self->feVariable->eqNum->removeBCs ) {
- DofLayout* dofs;
- int nDofs, curInd;
- int ii, jj;
-
- dofs = self->feVariable->dofLayout; /* shortcut to the dof layout */
- curInd = 0; /* need a counter to track where we are in the element force vector */
- for( ii = 0; ii < nodeCountCurrElement; ii++ ) {
- nDofs = dofs->dofCounts[inc[ii]]; /* number of dofs on this node */
- for( jj = 0; jj < nDofs; jj++ ) {
- if( !FeVariable_IsBC( self->feVariable, inc[ii], jj ) ) {
- curInd++;
- continue; /* only need to clear it if it's a bc */
- }
- elForceVecToAdd[curInd] = 0.0;
- curInd++;
- }
- }
- }
-
- /* Ok, assemble into global matrix */
- //Vector_AddEntries( self->vector, totalDofsThisElement, (Index*)(elementLM[0]), elForceVecToAdd );
- VecSetValues( self->vector, totalDofsThisElement, (PetscInt*)elementLM[0], elForceVecToAdd, ADD_VALUES );
-
-#if DEBUG
- if( element_lI % outputInterval == 0 ) {
- Journal_DPrintfL( self->debug, 2, "done %d percent of global force vector assembly (general) \n",
- (int)(100.0*((double)element_lI/(double)elementLocalCount)) );
- }
-#endif
-
- /* Cleanup: If we haven't built the big LM for all elements, free the temporary one */
- if ( False == feVar->eqNum->locationMatrixBuilt ) {
- Memory_Free( elementLM );
- }
- totalDofsPrevElement = totalDofsThisElement;
- }
-
- Memory_Free( elForceVecToAdd );
- }
- else {
- Journal_DPrintf( self->debug, "No ForceTerms registered - returning.\n" );
- }
-
- /* If we're keeping BCs, insert them into the force vector. */
- if( !feVar->eqNum->removeBCs )
- Assembler_LoopVector( self->bcAsm );
-
- //Vector_AssemblyBegin( self->vector );
- //Vector_AssemblyEnd( self->vector );
- VecAssemblyBegin( self->vector );
- VecAssemblyEnd( self->vector );
-
-#if DEBUG
- if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
- Journal_DPrintf( self->debug, "Completely built vector %s is:\n", self->name );
- _ForceVector_VectorView( self->vector, self->debug );
- }
-#endif
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-void ForceVector_AssembleElement( void* forceVector, Element_LocalIndex element_lI, double* elForceVecToAdd ) {
- ForceVector* self = (ForceVector*) forceVector;
- Index forceTermCount = Stg_ObjectList_Count( self->forceTermList );
- Index forceTerm_I;
- ForceTerm* forceTerm;
-
- for ( forceTerm_I = 0 ; forceTerm_I < forceTermCount ; forceTerm_I++ ) {
- forceTerm = (ForceTerm*) Stg_ObjectList_At( self->forceTermList, forceTerm_I );
-
- ForceTerm_AssembleElement( forceTerm, self, element_lI, elForceVecToAdd );
- }
-}
-
-void ForceVector_AddForceTerm( void* forceVector, ForceTerm* forceTerm ) {
- ForceVector* self = (ForceVector*) forceVector;
-
- Stg_ObjectList_Append( self->forceTermList, Stg_CheckType( forceTerm, ForceTerm ) );
-}
-
-Bool ForceVector_BCAsm_RowR( void* forceVec, Assembler* assm ) {
- double bc;
-
- bc = DofLayout_GetValueDouble( assm->rowVar->dofLayout,
- assm->rowNodeInd,
- assm->rowDofInd );
- //Vector_AddEntries( ((ForceVector*)forceVec)->vector, 1, &assm->rowEq, &bc );
- VecSetValues( ((ForceVector*)forceVec)->vector, 1, (PetscInt*)(&assm->rowEq), &bc, ADD_VALUES );
- return True;
-}
-
-void ForceVector_AddModifyCallback( ForceVector* self, void* callback, void* object ) {
- self->nModifyCBs++;
- self->modifyCBs = ReallocArray( self->modifyCBs, Callback, self->nModifyCBs );
- self->modifyCBs[self->nModifyCBs - 1].callback = callback;
- self->modifyCBs[self->nModifyCBs - 1].object = object;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/ForceVector.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/ForceVector.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,558 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: ForceVector.c 1210 2008-08-25 01:17:12Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "FiniteElementContext.h"
+#include "SolutionVector.h"
+#include "ForceVector.h"
+#include "ForceTerm.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "EntryPoint.h"
+#include "Assembler.h"
+
+
+Bool ForceVector_BCAsm_RowR( void* forceVec, Assembler* assm );
+
+
+/* Textual name of this class */
+const Type ForceVector_Type = "ForceVector";
+
+/** Name of this class' entry points */
+static const char ForceVector_assembleForceVectorStr[] = "assembleForceVector";
+
+ForceVector* ForceVector_New(
+ Name name,
+ FiniteElementContext* context,
+ FeVariable* feVariable,
+ Dimension_Index dim,
+ void* entryPoint_Register,
+ MPI_Comm comm )
+{
+ ForceVector* self = (ForceVector*)_ForceVector_DefaultNew( name );
+
+ self->isConstructed = True;
+ _SolutionVector_Init( (SolutionVector*)self, context, comm, feVariable );
+ _ForceVector_Init( self, dim, (EntryPoint_Register*)entryPoint_Register );
+
+ return self;
+}
+
+void* _ForceVector_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(ForceVector);
+ Type type = ForceVector_Type;
+ Stg_Class_DeleteFunction* _delete = _ForceVector_Delete;
+ Stg_Class_PrintFunction* _print = _ForceVector_Print;
+ Stg_Class_CopyFunction* _copy = _ForceVector_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _ForceVector_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _ForceVector_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _ForceVector_Build;
+ Stg_Component_InitialiseFunction* _initialise = _ForceVector_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _ForceVector_Execute;
+ Stg_Component_DestroyFunction* _destroy = _ForceVector_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+
+ return _ForceVector_New( FORCEVECTOR_PASSARGS );
+}
+
+ForceVector* _ForceVector_New( FORCEVECTOR_DEFARGS ) {
+ ForceVector* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(ForceVector) );
+ self = (ForceVector*)_SolutionVector_New( SOLUTIONVECTOR_PASSARGS );
+
+ return self;
+}
+
+
+void _ForceVector_Init( void* forceVector, Dimension_Index dim, EntryPoint_Register* entryPoint_Register ) {
+ ForceVector* self = (ForceVector*) forceVector;
+
+ /* ForceVector info */
+ self->dim = dim;
+ self->entryPoint_Register = entryPoint_Register;
+
+ /* Create Stream */
+ self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type );
+
+ /* Create Entry Point for assembleForceVector */
+ Stg_asprintf( (char**)(&self->_assembleForceVectorEPName), "%s-%s", self->name, ForceVector_assembleForceVectorStr );
+ self->assembleForceVector = FeEntryPoint_New( self->_assembleForceVectorEPName, FeEntryPoint_AssembleForceVector_CastType );
+ EntryPoint_Register_Add( self->entryPoint_Register, self->assembleForceVector );
+
+ /* Add default hook to assembleForceVector entry point */
+ EP_ReplaceAll( self->assembleForceVector, ForceVector_GlobalAssembly_General );
+
+ self->forceTermList = Stg_ObjectList_New();
+
+ self->bcAsm = Assembler_New();
+ self->inc = IArray_New();
+
+ self->nModifyCBs = 0;
+ self->modifyCBs = NULL;
+}
+
+void _ForceVector_Delete( void* forceVector ) {
+ ForceVector* self = (ForceVector*)forceVector;
+
+ Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
+
+ /* Stg_Class_Delete parent*/
+ _SolutionVector_Delete( self );
+}
+
+void _ForceVector_Print( void* forceVector, Stream* stream ) {
+ ForceVector* self = (ForceVector*)forceVector;
+
+ /* General info */
+ Journal_Printf( stream, "ForceVector (ptr): %p\n", self );
+
+ /* Print parent */
+ _SolutionVector_Print( self, stream );
+
+ /* Virtual info */
+
+ /* ForceVector info */
+ Journal_Printf( stream, "\tassembleForceVector e.p. (ptr): %p\n", self->assembleForceVector );
+ EntryPoint_PrintConcise( self->assembleForceVector, stream );
+
+ Journal_Printf( stream, "\tVector (ptr): %p\n", self->vector );
+ Journal_Printf( stream, "\tComm: %u\n", self->comm );
+ Journal_Printf( stream, "\tLocalSize: %u\n", self->localSize );
+}
+
+
+void* _ForceVector_Copy( const void* forceVector, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ ForceVector* self = (ForceVector*)forceVector;
+ ForceVector* newForceVector;
+ PtrMap* map = ptrMap;
+ Bool ownMap = False;
+
+ if( !map ) {
+ map = PtrMap_New( 10 );
+ ownMap = True;
+ }
+
+ newForceVector = (ForceVector*)_SolutionVector_Copy( self, dest, deep, nameExt, map );
+
+ /* TODO: copy vector? */
+ newForceVector->entryPoint_Register = self->entryPoint_Register;
+ newForceVector->localSize = self->localSize;
+
+ if( deep ) {
+ newForceVector->assembleForceVector = (FeEntryPoint*)Stg_Class_Copy( self->assembleForceVector, NULL, deep, nameExt, map );
+ if( self->_assembleForceVectorEPName ) {
+ if( nameExt ) {
+ unsigned nameLen = strlen( self->_assembleForceVectorEPName );
+
+ newForceVector->_assembleForceVectorEPName = (char*)Memory_Alloc_Bytes_Unnamed( nameLen + strlen( nameExt ) + 1, "FV->vecEPName" );
+ memcpy( (char*)(newForceVector->_assembleForceVectorEPName), self->_assembleForceVectorEPName, nameLen );
+ strcpy( (char*)(newForceVector->_assembleForceVectorEPName) + nameLen, nameExt );
+ }
+ else {
+ newForceVector->_assembleForceVectorEPName = StG_Strdup( self->_assembleForceVectorEPName );
+ }
+ }
+ else {
+ newForceVector->_assembleForceVectorEPName = NULL;
+ }
+
+ }
+ else {
+ newForceVector->debug = self->debug;
+ newForceVector->_assembleForceVectorEPName = self->_assembleForceVectorEPName;
+ newForceVector->assembleForceVector = self->assembleForceVector;
+ }
+
+ if( ownMap ) {
+ Stg_Class_Delete( map );
+ }
+
+ return (void*)newForceVector;
+}
+
+
+void _ForceVector_AssignFromXML( void* forceVector, Stg_ComponentFactory* cf, void* data ) {
+ ForceVector* self = (ForceVector*)forceVector;
+ Dimension_Index dim = 0;
+ void* entryPointRegister = NULL;
+
+ _SolutionVector_AssignFromXML( self, cf, data );
+
+ dim = Stg_ComponentFactory_GetRootDictUnsignedInt( cf, (Dictionary_Entry_Key)"dim", 0 );
+
+ entryPointRegister = (void*)self->context->entryPoint_Register;
+ assert( entryPointRegister );
+
+ _ForceVector_Init( self, dim, (EntryPoint_Register*)entryPointRegister );
+}
+
+void _ForceVector_Build( void* forceVector, void* data ) {
+ ForceVector* self = (ForceVector*)forceVector;
+
+ Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+ /* ensure feVariable is built */
+ if( self->feVariable ) {
+ Stg_Component_Build( self->feVariable, data, False );
+ }
+
+ /* update the size depending on our now built feVariable */
+ self->localSize = self->feVariable->eqNum->localEqNumsOwnedCount;
+ /* assert( self->localSize ); */
+
+ /* Allocate the vector */
+ Journal_DPrintfL( self->debug, 2, "Allocating the L.A. Force Vector with %d local entries.\n", self->localSize );
+ VecCreate( self->comm, &self->vector );
+ VecSetSizes( self->vector, (PetscInt)self->localSize, PETSC_DECIDE );
+ VecSetFromOptions( self->vector );
+#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
+ VecSetOption( self->vector, VEC_IGNORE_NEGATIVE_INDICES );
+#elif( PETSC_VERSION_MAJOR >= 3 )
+ VecSetOption( self->vector, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
+#endif
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+
+ Assembler_SetVariables( self->bcAsm, self->feVariable, NULL );
+ Assembler_SetCallbacks( self->bcAsm,
+ NULL,
+ ForceVector_BCAsm_RowR, NULL,
+ NULL, NULL,
+ self );
+}
+
+
+void _ForceVector_Initialise( void* forceVector, void* data ) {
+ ForceVector* self = (ForceVector*)forceVector;
+
+ Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+ /* ensure feVariable is initialised */
+ if( self->feVariable )
+ Stg_Component_Initialise( self->feVariable, data, False );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+void _ForceVector_Execute( void* forceVector, void* data ) {
+}
+
+void _ForceVector_Destroy( void* forceVector, void* data ) {
+ ForceVector* self = (ForceVector*)forceVector;
+
+ Memory_Free( self->_assembleForceVectorEPName );
+
+ /* Don't delete entry point: E.P register will delete it automatically */
+ Stg_Class_Delete( self->forceTermList );
+
+ NewClass_Delete( self->inc );
+
+ _SolutionVector_Destroy( self, data );
+}
+
+void ForceVector_Assemble( void* forceVector ) {
+ ForceVector* self = (ForceVector*)forceVector;
+ int ii;
+
+ Journal_DPrintf( self->debug, "In %s - for vector \"%s\" - calling the \"%s\" E.P.\n", __func__, self->name,
+ self->assembleForceVector->name );
+
+ /* Call the Entry point directly from the base class */
+ /* Note that it may be empty: this is deliberate. */
+ if ( 0 == self->assembleForceVector->hooks->count ) {
+ Journal_DPrintf( self->debug, "(E.P. has no hooks loaded -> no assembly required.)\n" );
+ }
+
+ ((FeEntryPoint_AssembleForceVector_CallFunction*)EntryPoint_GetRun( self->assembleForceVector ))(
+ self->assembleForceVector,
+ self );
+
+ /* Run all the modify callbacks. */
+ for( ii = 0; ii < self->nModifyCBs; ii++ ) {
+ void* callback = self->modifyCBs[ii].callback;
+ void* object = self->modifyCBs[ii].object;
+ ((void(*)(void*))callback)( object );
+ }
+}
+
+
+void ForceVector_PrintElementForceVector(
+ ForceVector* self,
+ Element_LocalIndex element_lI,
+ Dof_EquationNumber** elementLM,
+ double* elForceVecToAdd )
+{
+ DofLayout* dofLayout = self->feVariable->dofLayout;
+ FeMesh* feMesh = self->feVariable->feMesh;
+ unsigned nInc, *inc;
+ Dof_Index dofsPerNode;
+ Node_LocalIndex nodesThisEl;
+ Node_LocalIndex node_I;
+ Dof_Index dof_I;
+ Index vec_I;
+ IArray* incArray;
+
+ incArray = IArray_New();
+ FeMesh_GetElementNodes( feMesh, element_lI, incArray );
+ nInc = IArray_GetSize( incArray );
+ inc = (unsigned*)IArray_GetPtr( incArray );
+ dofsPerNode = dofLayout->dofCounts[inc[0]];
+ nodesThisEl = nInc;
+
+ for ( node_I=0; node_I < nodesThisEl; node_I++ ) {
+ for ( dof_I = 0; dof_I < dofsPerNode; dof_I++ ) {
+ vec_I = node_I * dofsPerNode + dof_I;
+
+ Journal_DPrintf( self->debug, "Entry[%d][%d] (LM (%4d)) = %.3f\n",
+ node_I, dof_I,
+ elementLM[node_I][dof_I],
+ elForceVecToAdd[vec_I] );
+ }
+ }
+
+ NewClass_Delete( incArray );
+}
+
+/* from the depreciated Vector class */
+void _ForceVector_VectorView( Vec v, Stream* stream ) {
+ unsigned entry_i;
+ PetscInt size;
+ PetscScalar* array;
+
+ VecGetSize( v, &size );
+ VecGetArray( v, &array );
+
+ Journal_Printf( stream, "%p = [", v );
+ for( entry_i = 0; entry_i < size; entry_i++ )
+ Journal_Printf( stream, "\t%u: \t %.12g\n", entry_i, array[entry_i] );
+ Journal_Printf( stream, "];\n" );
+
+ VecRestoreArray( v, &array );
+}
+
+void ForceVector_GlobalAssembly_General( void* forceVector ) {
+ ForceVector* self = (ForceVector*) forceVector;
+ FeVariable* feVar = self->feVariable;
+ Element_LocalIndex element_lI;
+ Element_LocalIndex elementLocalCount;
+ Node_ElementLocalIndex nodeCountCurrElement = 0;
+ Element_Nodes nodeIdsInCurrElement = 0;
+ Dof_Index totalDofsThisElement = 0;
+ Dof_Index totalDofsPrevElement = 0;
+ Dof_Index dofCountLastNode = 0;
+ Dof_EquationNumber** elementLM = NULL;
+ double* elForceVecToAdd = NULL;
+ /* For output printing */
+ double outputPercentage=10; /* Controls how often to give a status update of assembly progress */
+ int outputInterval;
+
+ Journal_DPrintf( self->debug, "In %s - for vector \"%s\"\n", __func__, self->name );
+
+ Stream_IndentBranch( StgFEM_Debug );
+
+ if ( Stg_ObjectList_Count( self->forceTermList ) > 0 ) {
+ elementLocalCount = FeMesh_GetElementLocalSize( feVar->feMesh );
+
+ /* Initialise Vector */
+ outputInterval = (int)( (outputPercentage/100.0)*(double)(elementLocalCount) );
+ if( outputInterval == 0 ) { outputInterval = elementLocalCount; }
+
+ for( element_lI = 0; element_lI < elementLocalCount; element_lI++ ) {
+ unsigned nInc, *inc;
+
+ FeMesh_GetElementNodes( feVar->feMesh, element_lI, self->inc );
+ nInc = IArray_GetSize( self->inc );
+ inc = (unsigned*)IArray_GetPtr( self->inc );
+ nodeCountCurrElement = nInc;
+ /* Get the local node ids */
+ nodeIdsInCurrElement = inc;
+
+ /* Set value of elementLM: will automatically just index into global LM table if built */
+ elementLM = FeEquationNumber_BuildOneElementLocationMatrix( feVar->eqNum, element_lI );
+
+ /* work out number of dofs at the node, using LM */
+ /* Since: Number of entries in LM table for this element = (by defn.) Number of dofs this element */
+ dofCountLastNode = feVar->dofLayout->dofCounts[nodeIdsInCurrElement[nodeCountCurrElement-1]];
+ totalDofsThisElement = &elementLM[nodeCountCurrElement-1][dofCountLastNode-1] - &elementLM[0][0] + 1;
+
+ if ( totalDofsThisElement > totalDofsPrevElement ) {
+ if (elForceVecToAdd) Memory_Free( elForceVecToAdd );
+ Journal_DPrintfL( self->debug, 2, "Reallocating elForceVecToAdd to size %d\n", totalDofsThisElement );
+ elForceVecToAdd = Memory_Alloc_Array( double, totalDofsThisElement, "elForceVecToAdd" );
+ }
+
+ /* Initialise Values to Zero */
+ memset( elForceVecToAdd, 0, totalDofsThisElement * sizeof(double) );
+
+ /* Assemble this element's element force vector: going through each force term in list */
+ ForceVector_AssembleElement( self, element_lI, elForceVecToAdd );
+
+/*
+ #if DEBUG
+ if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+ Journal_DPrintf( self->debug, "Handling Element %d:\n", element_lI );
+ FeEquationNumber_PrintElementLocationMatrix( feVar->eqNum, elementLM,
+ element_lI, self->debug );
+
+ Journal_DPrintf( self->debug, "El force Vec about to be added:\n" );
+ ForceVector_PrintElementForceVector( self, element_lI, elementLM, elForceVecToAdd );
+ }
+ #endif
+*/
+
+ /* When keeping BCs in we come across a bit of a problem in parallel. We're not
+ allowed to add entries to the force vector here and then clobber it later with
+ an insert in order to set the BC. So, what we'll do is just add zero here, that
+ way later we can add the BC and it will be the same as inserting it.
+ --- Luke, 20 May 2008 */
+ if( !self->feVariable->eqNum->removeBCs ) {
+ DofLayout* dofs;
+ int nDofs, curInd;
+ int ii, jj;
+
+ dofs = self->feVariable->dofLayout; /* shortcut to the dof layout */
+ curInd = 0; /* need a counter to track where we are in the element force vector */
+ for( ii = 0; ii < nodeCountCurrElement; ii++ ) {
+ nDofs = dofs->dofCounts[inc[ii]]; /* number of dofs on this node */
+ for( jj = 0; jj < nDofs; jj++ ) {
+ if( !FeVariable_IsBC( self->feVariable, inc[ii], jj ) ) {
+ curInd++;
+ continue; /* only need to clear it if it's a bc */
+ }
+ elForceVecToAdd[curInd] = 0.0;
+ curInd++;
+ }
+ }
+ }
+
+ /* Ok, assemble into global matrix */
+ //Vector_AddEntries( self->vector, totalDofsThisElement, (Index*)(elementLM[0]), elForceVecToAdd );
+ VecSetValues( self->vector, totalDofsThisElement, (PetscInt*)elementLM[0], elForceVecToAdd, ADD_VALUES );
+
+#if DEBUG
+ if( element_lI % outputInterval == 0 ) {
+ Journal_DPrintfL( self->debug, 2, "done %d percent of global force vector assembly (general) \n",
+ (int)(100.0*((double)element_lI/(double)elementLocalCount)) );
+ }
+#endif
+
+ /* Cleanup: If we haven't built the big LM for all elements, free the temporary one */
+ if ( False == feVar->eqNum->locationMatrixBuilt ) {
+ Memory_Free( elementLM );
+ }
+ totalDofsPrevElement = totalDofsThisElement;
+ }
+
+ Memory_Free( elForceVecToAdd );
+ }
+ else {
+ Journal_DPrintf( self->debug, "No ForceTerms registered - returning.\n" );
+ }
+
+ /* If we're keeping BCs, insert them into the force vector. */
+ if( !feVar->eqNum->removeBCs )
+ Assembler_LoopVector( self->bcAsm );
+
+ //Vector_AssemblyBegin( self->vector );
+ //Vector_AssemblyEnd( self->vector );
+ VecAssemblyBegin( self->vector );
+ VecAssemblyEnd( self->vector );
+
+#if DEBUG
+ if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+ Journal_DPrintf( self->debug, "Completely built vector %s is:\n", self->name );
+ _ForceVector_VectorView( self->vector, self->debug );
+ }
+#endif
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+void ForceVector_AssembleElement( void* forceVector, Element_LocalIndex element_lI, double* elForceVecToAdd ) {
+ ForceVector* self = (ForceVector*) forceVector;
+ Index forceTermCount = Stg_ObjectList_Count( self->forceTermList );
+ Index forceTerm_I;
+ ForceTerm* forceTerm;
+
+ for ( forceTerm_I = 0 ; forceTerm_I < forceTermCount ; forceTerm_I++ ) {
+ forceTerm = (ForceTerm*) Stg_ObjectList_At( self->forceTermList, forceTerm_I );
+
+ ForceTerm_AssembleElement( forceTerm, self, element_lI, elForceVecToAdd );
+ }
+}
+
+void ForceVector_AddForceTerm( void* forceVector, ForceTerm* forceTerm ) {
+ ForceVector* self = (ForceVector*) forceVector;
+
+ Stg_ObjectList_Append( self->forceTermList, Stg_CheckType( forceTerm, ForceTerm ) );
+}
+
+Bool ForceVector_BCAsm_RowR( void* forceVec, Assembler* assm ) {
+ double bc;
+
+ bc = DofLayout_GetValueDouble( assm->rowVar->dofLayout,
+ assm->rowNodeInd,
+ assm->rowDofInd );
+ //Vector_AddEntries( ((ForceVector*)forceVec)->vector, 1, &assm->rowEq, &bc );
+ VecSetValues( ((ForceVector*)forceVec)->vector, 1, (PetscInt*)(&assm->rowEq), &bc, ADD_VALUES );
+ return True;
+}
+
+void ForceVector_AddModifyCallback( ForceVector* self, void* callback, void* object ) {
+ self->nModifyCBs++;
+ self->modifyCBs = ReallocArray( self->modifyCBs, Callback, self->nModifyCBs );
+ self->modifyCBs[self->nModifyCBs - 1].callback = callback;
+ self->modifyCBs[self->nModifyCBs - 1].object = object;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/Init.c
--- a/SLE/SystemSetup/src/Init.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "SystemSetup.h"
-
-
-Stream* StgFEM_SLE_Debug = NULL;
-Stream* StgFEM_SLE_SystemSetup_Debug = NULL;
-
-/** Initialises the Linear Algebra package, then any init for this package
-such as streams etc */
-Bool StgFEM_SLE_SystemSetup_Init( int* argc, char** argv[] ) {
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- /* initialise this level's streams */
- StgFEM_SLE_Debug = Stream_RegisterChild( StgFEM_Debug, "SLE" );
- StgFEM_SLE_SystemSetup_Debug = Stream_RegisterChild( StgFEM_SLE_Debug, "SystemSetup" );
-
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), FiniteElementContext_Type, (Name)"0", FiniteElementContext_DefaultNew );
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ), ForceVector_Type, "0", _ForceVector_DefaultNew );
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), SolutionVector_Type, (Name)"0", _SolutionVector_DefaultNew );
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ), StiffnessMatrix_Type, "0", StiffnessMatrix_DefaultNew );
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), StiffnessMatrixTerm_Type, (Name)"0", _StiffnessMatrixTerm_DefaultNew );
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ), SystemLinearEquations_Type, "0", _SystemLinearEquations_DefaultNew );
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), ForceTerm_Type, (Name)"0", _ForceTerm_DefaultNew );
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ),
- MultigridSolver_Type, "0",
- (Stg_Component_DefaultConstructorFunction*)MultigridSolver_New );
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), SROpGenerator_Type, (Name)"0", (Stg_Component_DefaultConstructorFunction*)SROpGenerator_New );
- Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ),
- PETScMGSolver_Type, "0",
- (Stg_Component_DefaultConstructorFunction*)PETScMGSolver_New );
-
- RegisterParent( SystemLinearEquations_Type, Stg_Component_Type );
- RegisterParent( SLE_Solver_Type, Stg_Component_Type );
- RegisterParent( StiffnessMatrix_Type, Stg_Component_Type );
- RegisterParent( StiffnessMatrixTerm_Type, Stg_Component_Type );
- RegisterParent( SolutionVector_Type, Stg_Component_Type );
- RegisterParent( ForceVector_Type, SolutionVector_Type );
- RegisterParent( ForceTerm_Type, Stg_Component_Type );
- RegisterParent( Assembler_Type, Stg_Class_Type );
- RegisterParent( FiniteElementContext_Type, DomainContext_Type );
- RegisterParent( PETScMGSolver_Type, Stg_Component_Type );
- RegisterParent( MultigridSolver_Type, Stg_Component_Type );
- RegisterParent( MGOpGenerator_Type, Stg_Component_Type );
- RegisterParent( SROpGenerator_Type, MGOpGenerator_Type);
-
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/Init.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/Init.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,95 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "SystemSetup.h"
+
+
+Stream* StgFEM_SLE_Debug = NULL;
+Stream* StgFEM_SLE_SystemSetup_Debug = NULL;
+
+/** Initialises the Linear Algebra package, then any init for this package
+such as streams etc */
+Bool StgFEM_SLE_SystemSetup_Init( int* argc, char** argv[] ) {
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ /* initialise this level's streams */
+ StgFEM_SLE_Debug = Stream_RegisterChild( StgFEM_Debug, "SLE" );
+ StgFEM_SLE_SystemSetup_Debug = Stream_RegisterChild( StgFEM_SLE_Debug, "SystemSetup" );
+
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), FiniteElementContext_Type, (Name)"0", FiniteElementContext_DefaultNew );
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ), ForceVector_Type, "0", _ForceVector_DefaultNew );
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), SolutionVector_Type, (Name)"0", _SolutionVector_DefaultNew );
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ), StiffnessMatrix_Type, "0", StiffnessMatrix_DefaultNew );
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), StiffnessMatrixTerm_Type, (Name)"0", _StiffnessMatrixTerm_DefaultNew );
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ), SystemLinearEquations_Type, "0", _SystemLinearEquations_DefaultNew );
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), ForceTerm_Type, (Name)"0", _ForceTerm_DefaultNew );
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ),
+ MultigridSolver_Type, "0",
+ (Stg_Component_DefaultConstructorFunction*)MultigridSolver_New );
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister(), SROpGenerator_Type, (Name)"0", (Stg_Component_DefaultConstructorFunction*)SROpGenerator_New );
+ Stg_ComponentRegister_Add( Stg_ComponentRegister_Get_ComponentRegister( ),
+ PETScMGSolver_Type, "0",
+ (Stg_Component_DefaultConstructorFunction*)PETScMGSolver_New );
+
+ RegisterParent( SystemLinearEquations_Type, Stg_Component_Type );
+ RegisterParent( SLE_Solver_Type, Stg_Component_Type );
+ RegisterParent( StiffnessMatrix_Type, Stg_Component_Type );
+ RegisterParent( StiffnessMatrixTerm_Type, Stg_Component_Type );
+ RegisterParent( SolutionVector_Type, Stg_Component_Type );
+ RegisterParent( ForceVector_Type, SolutionVector_Type );
+ RegisterParent( ForceTerm_Type, Stg_Component_Type );
+ RegisterParent( Assembler_Type, Stg_Class_Type );
+ RegisterParent( FiniteElementContext_Type, DomainContext_Type );
+ RegisterParent( PETScMGSolver_Type, Stg_Component_Type );
+ RegisterParent( MultigridSolver_Type, Stg_Component_Type );
+ RegisterParent( MGOpGenerator_Type, Stg_Component_Type );
+ RegisterParent( SROpGenerator_Type, MGOpGenerator_Type);
+
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/MGOpGenerator.c
--- a/SLE/SystemSetup/src/MGOpGenerator.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,183 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: MGOpGenerator.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-
-#include "SystemSetup.h"
-
-
-/* Textual name of this class */
-const Type MGOpGenerator_Type = "MGOpGenerator";
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-MGOpGenerator* _MGOpGenerator_New( MGOPGENERATOR_DEFARGS ) {
- MGOpGenerator* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(MGOpGenerator) );
- self = (MGOpGenerator*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- /* stuff previously housed in the MatrixSolver class */
- self->solver = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
- self->solver->ksp = PETSC_NULL;
- self->solver->matrix = PETSC_NULL;
- self->solver->inversion = PETSC_NULL;
- self->solver->residual = PETSC_NULL;
- self->solver->curRHS = PETSC_NULL;
- self->solver->curSolution = PETSC_NULL;
- self->solver->expiredResidual = True;
- self->solver->matrixChanged = True;
-
- /* Virtual info */
- self->setNumLevelsFunc = setNumLevelsFunc;
- self->hasExpiredFunc = hasExpiredFunc;
- self->generateFunc = generateFunc;
-
- /* MGOpGenerator info */
- _MGOpGenerator_Init( self );
-
- return self;
-}
-
-void _MGOpGenerator_Init( MGOpGenerator* self ) {
- assert( self && Stg_CheckType( self, MGOpGenerator ) );
-
- self->nLevels = 0;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _MGOpGenerator_Delete( void* mgOpGenerator ) {
- MGOpGenerator* self = (MGOpGenerator*)mgOpGenerator;
-
- assert( self && Stg_CheckType( self, MGOpGenerator ) );
-
- /* this stuff was previously taken care of in the MatrixSolver class */
- if( self->solver ) {
- /*if( self->solver->ksp != PETSC_NULL ) KSPDestroy( self->solver->ksp );*/
- if( self->solver->matrix != PETSC_NULL ) MatDestroy( self->solver->matrix );
- if( self->solver->inversion != PETSC_NULL ) MatDestroy( self->solver->inversion );
- if( self->solver->residual != PETSC_NULL ) VecDestroy( self->solver->residual );
- if( self->solver->curRHS != PETSC_NULL ) VecDestroy( self->solver->curRHS );
- if( self->solver->curSolution != PETSC_NULL ) VecDestroy( self->solver->curSolution );
- free( self->solver );
- }
-
- /* Delete the parent. */
- _Stg_Component_Delete( self );
-}
-
-void _MGOpGenerator_Print( void* mgOpGenerator, Stream* stream ) {
- MGOpGenerator* self = (MGOpGenerator*)mgOpGenerator;
-
- /* Set the Journal for printing informations */
- Stream* mgOpGeneratorStream;
- mgOpGeneratorStream = Journal_Register( InfoStream_Type, (Name)"MGOpGeneratorStream" );
-
- assert( self && Stg_CheckType( self, MGOpGenerator ) );
-
- /* Print parent */
- Journal_Printf( stream, "MGOpGenerator (ptr): (%p)\n", self );
- _Stg_Component_Print( self, stream );
-}
-
-void _MGOpGenerator_AssignFromXML( void* mgOpGenerator, Stg_ComponentFactory* cf, void* data ) {
- MGOpGenerator* self = (MGOpGenerator*)mgOpGenerator;
-
- assert( self && Stg_CheckType( self, MGOpGenerator ) );
- assert( cf );
-}
-
-void _MGOpGenerator_Build( void* mgOpGenerator, void* data ) {
-}
-
-void _MGOpGenerator_Initialise( void* mgOpGenerator, void* data ) {
-}
-
-void _MGOpGenerator_Execute( void* mgOpGenerator, void* data ) {
-}
-
-void _MGOpGenerator_Destroy( void* mgOpGenerator, void* data ) {
-}
-
-void _MGOpGenerator_SetNumLevels( void* mgOpGenerator, unsigned nLevels ) {
- MGOpGenerator* self = (MGOpGenerator*)mgOpGenerator;
-
- assert( self && Stg_CheckType( self, MGOpGenerator ) );
-
- self->nLevels = nLevels;
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-void MGOpGenerator_SetMatrixSolver( void* mgOpGenerator, void* _solver ) {
- MGOpGenerator* self = (MGOpGenerator*)mgOpGenerator;
- //MatrixSolver* solver = (MatrixSolver*)_solver;
- KSP solver = (KSP)_solver;
-
- assert( self && Stg_CheckType( self, MGOpGenerator ) );
- //assert( solver && Stg_CheckType( solver, MatrixSolver ) );
-
- //self->solver = solver;
- self->solver->ksp = solver;
-}
-
-unsigned MGOpGenerator_GetNumLevels( void* mgOpGenerator ) {
- MGOpGenerator* self = (MGOpGenerator*)mgOpGenerator;
-
- assert( self && Stg_CheckType( self, MGOpGenerator ) );
-
- return self->nLevels;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/MGOpGenerator.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/MGOpGenerator.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,183 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: MGOpGenerator.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+
+#include "SystemSetup.h"
+
+
+/* Textual name of this class */
+const Type MGOpGenerator_Type = "MGOpGenerator";
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+MGOpGenerator* _MGOpGenerator_New( MGOPGENERATOR_DEFARGS ) {
+ MGOpGenerator* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(MGOpGenerator) );
+ self = (MGOpGenerator*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ /* stuff previously housed in the MatrixSolver class */
+ self->solver = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
+ self->solver->ksp = PETSC_NULL;
+ self->solver->matrix = PETSC_NULL;
+ self->solver->inversion = PETSC_NULL;
+ self->solver->residual = PETSC_NULL;
+ self->solver->curRHS = PETSC_NULL;
+ self->solver->curSolution = PETSC_NULL;
+ self->solver->expiredResidual = True;
+ self->solver->matrixChanged = True;
+
+ /* Virtual info */
+ self->setNumLevelsFunc = setNumLevelsFunc;
+ self->hasExpiredFunc = hasExpiredFunc;
+ self->generateFunc = generateFunc;
+
+ /* MGOpGenerator info */
+ _MGOpGenerator_Init( self );
+
+ return self;
+}
+
+void _MGOpGenerator_Init( MGOpGenerator* self ) {
+ assert( self && Stg_CheckType( self, MGOpGenerator ) );
+
+ self->nLevels = 0;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _MGOpGenerator_Delete( void* mgOpGenerator ) {
+ MGOpGenerator* self = (MGOpGenerator*)mgOpGenerator;
+
+ assert( self && Stg_CheckType( self, MGOpGenerator ) );
+
+ /* this stuff was previously taken care of in the MatrixSolver class */
+ if( self->solver ) {
+ /*if( self->solver->ksp != PETSC_NULL ) KSPDestroy( self->solver->ksp );*/
+ if( self->solver->matrix != PETSC_NULL ) MatDestroy( self->solver->matrix );
+ if( self->solver->inversion != PETSC_NULL ) MatDestroy( self->solver->inversion );
+ if( self->solver->residual != PETSC_NULL ) VecDestroy( self->solver->residual );
+ if( self->solver->curRHS != PETSC_NULL ) VecDestroy( self->solver->curRHS );
+ if( self->solver->curSolution != PETSC_NULL ) VecDestroy( self->solver->curSolution );
+ free( self->solver );
+ }
+
+ /* Delete the parent. */
+ _Stg_Component_Delete( self );
+}
+
+void _MGOpGenerator_Print( void* mgOpGenerator, Stream* stream ) {
+ MGOpGenerator* self = (MGOpGenerator*)mgOpGenerator;
+
+ /* Set the Journal for printing informations */
+ Stream* mgOpGeneratorStream;
+ mgOpGeneratorStream = Journal_Register( InfoStream_Type, (Name)"MGOpGeneratorStream" );
+
+ assert( self && Stg_CheckType( self, MGOpGenerator ) );
+
+ /* Print parent */
+ Journal_Printf( stream, "MGOpGenerator (ptr): (%p)\n", self );
+ _Stg_Component_Print( self, stream );
+}
+
+void _MGOpGenerator_AssignFromXML( void* mgOpGenerator, Stg_ComponentFactory* cf, void* data ) {
+ MGOpGenerator* self = (MGOpGenerator*)mgOpGenerator;
+
+ assert( self && Stg_CheckType( self, MGOpGenerator ) );
+ assert( cf );
+}
+
+void _MGOpGenerator_Build( void* mgOpGenerator, void* data ) {
+}
+
+void _MGOpGenerator_Initialise( void* mgOpGenerator, void* data ) {
+}
+
+void _MGOpGenerator_Execute( void* mgOpGenerator, void* data ) {
+}
+
+void _MGOpGenerator_Destroy( void* mgOpGenerator, void* data ) {
+}
+
+void _MGOpGenerator_SetNumLevels( void* mgOpGenerator, unsigned nLevels ) {
+ MGOpGenerator* self = (MGOpGenerator*)mgOpGenerator;
+
+ assert( self && Stg_CheckType( self, MGOpGenerator ) );
+
+ self->nLevels = nLevels;
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+void MGOpGenerator_SetMatrixSolver( void* mgOpGenerator, void* _solver ) {
+ MGOpGenerator* self = (MGOpGenerator*)mgOpGenerator;
+ //MatrixSolver* solver = (MatrixSolver*)_solver;
+ KSP solver = (KSP)_solver;
+
+ assert( self && Stg_CheckType( self, MGOpGenerator ) );
+ //assert( solver && Stg_CheckType( solver, MatrixSolver ) );
+
+ //self->solver = solver;
+ self->solver->ksp = solver;
+}
+
+unsigned MGOpGenerator_GetNumLevels( void* mgOpGenerator ) {
+ MGOpGenerator* self = (MGOpGenerator*)mgOpGenerator;
+
+ assert( self && Stg_CheckType( self, MGOpGenerator ) );
+
+ return self->nLevels;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/MultigridSolver.c
--- a/SLE/SystemSetup/src/MultigridSolver.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1233 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: MultigridSolver.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-
-#include "SystemSetup.h"
-
-
-/* Textual name of this class */
-const Type MultigridSolver_Type = "MultigridSolver";
-
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-MultigridSolver* MultigridSolver_New( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(MultigridSolver);
- Type type = MultigridSolver_Type;
- Stg_Class_DeleteFunction* _delete = _MultigridSolver_Delete;
- Stg_Class_PrintFunction* _print = _MultigridSolver_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_MultigridSolver_New;
- Stg_Component_ConstructFunction* _construct = _MultigridSolver_AssignFromXML;
- Stg_Component_BuildFunction* _build = _MultigridSolver_Build;
- Stg_Component_InitialiseFunction* _initialise = _MultigridSolver_Initialise;
- Stg_Component_ExecuteFunction* _execute = _MultigridSolver_Execute;
- Stg_Component_DestroyFunction* _destroy = _MultigridSolver_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- MGSolver_SetCommFunc* setCommFunc = MultigridSolver_SetComm;
- MGSolver_SetMatrixFunc* setMatrixFunc = MultigridSolver_SetMatrix;
- MGSolver_SetMaxIterationsFunc* setMaxIterationsFunc = MultigridSolver_SetMaxIterations;
- MGSolver_SetRelativeToleranceFunc* setRelativeToleranceFunc = MultigridSolver_SetRelativeTolerance;
- MGSolver_SetAbsoluteToleranceFunc* setAbsoluteToleranceFunc = MultigridSolver_SetAbsoluteTolerance;
- MGSolver_SetUseInitialSolutionFunc* setUseInitialSolutionFunc = MultigridSolver_SetUseInitialSolution;
- MGSolver_SolveFunc* solveFunc = MultigridSolver_Solve;
- MGSolver_SetupFunc* setupFunc = MultigridSolver_Setup;
- MGSolver_GetSolveStatusFunc* getSolveStatusFunc = MultigridSolver_GetSolveStatus;
- MGSolver_GetIterationsFunc* getIterationsFunc = MultigridSolver_GetIterations;
- MGSolver_GetMaxIterationsFunc* getMaxIterationsFunc = MultigridSolver_GetMaxIterations;
- MGSolver_GetResidualNormFunc* getResidualNormFunc = MultigridSolver_GetResidualNorm;
-
- return _MultigridSolver_New( MULTIGRIDSOLVER_PASSARGS );
-}
-
-MultigridSolver* _MultigridSolver_New( MULTIGRIDSOLVER_DEFARGS ) {
- MultigridSolver* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(MultigridSolver) );
-
- self = (MultigridSolver*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- /* function assignments previously in the MatrixSolver_New func */
- self->setCommFunc = setCommFunc;
- self->setMatrixFunc = setMatrixFunc;
- self->setMaxIterationsFunc = setMaxIterationsFunc;
- self->setRelativeToleranceFunc = setRelativeToleranceFunc;
- self->setAbsoluteToleranceFunc = setAbsoluteToleranceFunc;
- self->setUseInitialSolutionFunc = setUseInitialSolutionFunc;
-
- self->solveFunc = solveFunc;
- self->setupFunc = setupFunc;
-
- self->getSolveStatusFunc = getSolveStatusFunc;
- self->getIterationsFunc = getIterationsFunc;
- self->getMaxIterationsFunc = getMaxIterationsFunc;
- self->getResidualNormFunc = getResidualNormFunc;
-
- /* Virtual info */
-
- /* MultigridSolver info */
- _MultigridSolver_Init( self );
-
- return self;
-}
-
-void _MultigridSolver_Init( MultigridSolver* self ) {
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- /* these initialisations previously done in the MatrixSolver_Init func */
- self->mgData = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
-
- self->mgData->comm = MPI_COMM_WORLD;
- KSPCreate( MPI_COMM_WORLD, &self->mgData->ksp );
- self->mgData->matrix = PETSC_NULL;
- self->mgData->inversion = PETSC_NULL;
- self->mgData->residual = PETSC_NULL;
- self->mgData->expiredResidual = True;
- self->mgData->matrixChanged = True;
-
- self->mgData->curRHS = PETSC_NULL;
- self->mgData->curSolution = PETSC_NULL;
- /* end of old MatrixSolver_Init initialisations */
-
- self->nLevels = 0;
- self->levels = NULL;
- self->opGen = NULL;
- self->solversChanged = True;
- self->opsChanged = True;
-
- self->curIt = 0;
- self->maxIts = 500;
- self->relTol = 1e-5;
- self->rnorm = 0.0;
- self->useInitial = False;
- //self->outerSolver = NULL;
- self->outerSolver = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
- self->outerSolver->ksp = PETSC_NULL;
- self->outerSolver->matrix = PETSC_NULL;
- self->outerSolver->inversion = PETSC_NULL;
- self->outerSolver->residual = PETSC_NULL;
- self->outerSolver->curRHS = PETSC_NULL;
- self->outerSolver->curSolution = PETSC_NULL;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _MultigridSolver_Delete( void* matrixSolver ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- MultigridSolver_Destruct( self );
-
- /* Delete the parent. */
- _Stg_Component_Delete( self );
-}
-
-void _MultigridSolver_Print( void* matrixSolver, Stream* stream ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- /* Set the Journal for printing informations */
- Stream* matrixSolverStream;
- matrixSolverStream = Journal_Register( InfoStream_Type, (Name)"MultigridSolverStream" );
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- /* Print parent */
- Journal_Printf( stream, "MultigridSolver (ptr): (%p)\n", self );
- _Stg_Component_Print( self, stream );
-}
-
-void _MultigridSolver_AssignFromXML( void* matrixSolver, Stg_ComponentFactory* cf, void* data ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- unsigned nLevels;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
- assert( cf );
-
- nLevels = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"levels", 1 );
- MultigridSolver_SetLevels( self, nLevels );
- self->opGen = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"opGenerator", MGOpGenerator, True, data );
- MGOpGenerator_SetMatrixSolver( self->opGen, self );
- MGOpGenerator_SetNumLevels( self->opGen, nLevels );
-}
-
-void _MultigridSolver_Build( void* matrixSolver, void* data ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- self->stream = Journal_Register( InfoStream_Type, (Name)"general" );
- if( self->opGen )
- Stg_Component_Build( self->opGen, data, False );
-}
-
-void _MultigridSolver_Initialise( void* matrixSolver, void* data ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- if( self->opGen )
- Stg_Component_Initialise( self->opGen, data, False );
-}
-
-void _MultigridSolver_Execute( void* matrixSolver, void* data ) {
-}
-
-void _MultigridSolver_Destroy( void* matrixSolver, void* data ) {
-}
-
-/* copied from the PETScMatrixSolver class, has been depreciated */
-void MultigridSolver_SetComm( void* matrixSolver, MPI_Comm comm ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- self->mgData->comm = comm;
-
- if( self->mgData->ksp != PETSC_NULL )
- KSPDestroy( self->mgData->ksp );
- KSPCreate( comm, &self->mgData->ksp );
-}
-
-/* copied from the PETScMatrixSolver class, has been depreciated */
-void MultigridSolver_SetMatrix( void* matrixSolver, void* _matrix ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- Mat matrix = (Mat)_matrix;
-
- self->mgData->matrix = matrix;
- KSPSetOperators( self->mgData->ksp, matrix, matrix, DIFFERENT_NONZERO_PATTERN );
-}
-
-void MultigridSolver_SetMaxIterations( void* matrixSolver, unsigned nIterations ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- self->maxIts = nIterations;
-}
-
-void MultigridSolver_SetRelativeTolerance( void* matrixSolver, double tolerance ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- self->relTol = tolerance;
- self->solversChanged = True;
-}
-
-void MultigridSolver_SetAbsoluteTolerance( void* matrixSolver, double tolerance ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- //MatrixSolver_SetAbsoluteTolerance( self->outerSolver, tolerance );
- KSPSetTolerances( self->outerSolver->ksp, PETSC_DEFAULT, tolerance, PETSC_DEFAULT, PETSC_DEFAULT );
-
- self->solversChanged = True;
-}
-
-void MultigridSolver_SetUseInitialSolution( void* matrixSolver, Bool state ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- self->useInitial = state;
-}
-
-/* these functions were associated with the PETScMatrixSolver class, before it was
- * depreciated */
-Vec _GetResidual( MGSolver_PETScData* mgData ) {
- if( mgData->expiredResidual ) {
- VecDuplicate( mgData->curSolution, &mgData->residual );
- VecSetFromOptions( mgData->residual );
-#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
- VecSetOption( mgData->residual, VEC_IGNORE_NEGATIVE_INDICES );
-#elif( PETSC_VERSION_MAJOR >= 3 )
- VecSetOption( mgData->residual, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
-#endif
- MatMult( mgData->matrix, mgData->curSolution, mgData->residual );
- VecAYPX( mgData->residual, -1.0, mgData->curRHS );
-
- mgData->expiredResidual = False;
- }
-
- return mgData->residual;
-}
-
-double _GetResidualNorm( MGSolver_PETScData* mgData ) {
- PC pc;
- const KSPType kspType;
- const PCType pcType;
- PetscScalar rnorm;
- PetscErrorCode ec;
-
- ec = KSPGetType( mgData->ksp, &kspType );
- CheckPETScError( ec );
- ec = KSPGetPC( mgData->ksp, &pc );
- CheckPETScError( ec );
- ec = PCGetType( pc, &pcType );
- CheckPETScError( ec );
-
- if( !strcmp( kspType, KSPRICHARDSON ) && !strcmp( pcType, PCSOR ) ) {
- Vec residual;
-
- //residual = MatrixSolver_GetResidual( mgData );
- //rnorm = (PetscScalar)Vector_L2Norm( residual );
- residual = _GetResidual( mgData );
- VecNorm( residual, NORM_2, &rnorm );
- }
- else {
- ec = KSPGetResidualNorm( mgData->ksp, &rnorm );
- CheckPETScError( ec );
- }
-
- return (double)rnorm;
-}
-
-#define MultigridSolver_NormType_Preconditioned 1
-
-MGSolver_Status _GetSolveStatus( MGSolver_PETScData* mgData ) {
- PC pc;
- const KSPType kspType;
- const PCType pcType;
- KSPConvergedReason reason;
- PetscErrorCode ec;
-
- ec = KSPGetType( mgData->ksp, &kspType );
- CheckPETScError( ec );
- ec = KSPGetPC( mgData->ksp, &pc );
- CheckPETScError( ec );
- ec = PCGetType( pc, &pcType );
- CheckPETScError( ec );
-
- if( !strcmp( kspType, KSPRICHARDSON ) && !strcmp( pcType, PCSOR ) ) {
- double rnorm;
- PetscInt curIt;
-
- //rnorm = PETScMatrixSolver_GetResidualNorm( self );
- //curIt = PETScMatrixSolver_GetIterations( self );
- rnorm = _GetResidualNorm( mgData );
- KSPGetIterationNumber( mgData->ksp, &curIt );
- //PETScMatrixSolver_SetNormType( self, MultigridSolver_NormType_Preconditioned );
- KSPSetNormType( mgData->ksp, (KSPNormType)MultigridSolver_NormType_Preconditioned );
- ec = KSPDefaultConverged( mgData->ksp, curIt, (PetscScalar)rnorm, &reason, PETSC_NULL );
- CheckPETScError( ec );
- }
- else {
- ec = KSPGetConvergedReason( mgData->ksp, &reason );
- CheckPETScError( ec );
- }
-
- return (MGSolver_Status)reason;
-}
-
-/* end of functions formerly defined in the PETScMatrixSolver class */
-
-void MultigridSolver_Solve( void* matrixSolver, void* _rhs, void* _solution ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- Vec rhs = (Vec)_rhs;
- Vec solution = (Vec)_solution;
- double wallTime;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
- //assert( rhs && Stg_CheckType( rhs, Vector ) );
- //assert( solution && Stg_CheckType( solution, Vector ) );
-
- Journal_Printf( self->stream, "MultigridSolver: Starting solve ...\n" );
- Stream_Indent( self->stream );
-
- if( !self->useInitial ) {
- Journal_Printf( self->stream, "Zeroing initial solution\n" );
- //Vector_Zero( solution );
- VecSet( solution, 0.0 );
- }
- else
- Journal_Printf( self->stream, "Keeping initial solution\n" );
-
- wallTime = MPI_Wtime();
- MultigridSolver_Setup( self, rhs, solution );
- stg_profile_Func( "MultigridSolver_Setup", MPI_Wtime() - wallTime);
- self->curIt = 0;
- //while( MatrixSolver_GetSolveStatus( self ) == MultigridSolver_Status_Iterating && self->curIt < self->maxIts ) {
- while( _GetSolveStatus( self->mgData ) == MGSolver_Status_Iterating && self->curIt < self->maxIts ) {
- Journal_Printf( self->stream, "Iteration %d: residual %.10lf\n",
- //self->curIt, MatrixSolver_GetResidualNorm( self->outerSolver ) );
- self->curIt, _GetResidualNorm( self->outerSolver ) );
- MultigridSolver_LevelCycle( self, self->nLevels - 1, rhs, solution );
- self->curIt++;
- }
- Journal_Printf( self->stream, "Iteration %d: residual %.10lf\n",
- //self->curIt, MatrixSolver_GetResidualNorm( self->outerSolver ) );
- self->curIt, _GetResidualNorm( self->outerSolver ) );
-
- Stream_UnIndent( self->stream );
- Journal_Printf( self->stream, "done.\n" );
-}
-
-void MultigridSolver_Setup( void* matrixSolver, void* rhs, void* solution ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- Bool rebuildOps;
- double wallTime;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- //_MatrixSolver_Setup( self, rhs, solution );
- self->mgData->curRHS = (struct _p_Vec*)rhs;
- self->mgData->curSolution = (struct _p_Vec*)solution;
- self->mgData->expiredResidual = True;
-
- /* Need to rebuild the operators? */
- if( self->opGen )
- rebuildOps = MGOpGenerator_HasExpired( self->opGen );
- else
- rebuildOps = False;
- if( !rebuildOps ) {
- unsigned l_i;
-
- for( l_i = 1; l_i < self->nLevels; l_i++ ) {
- if( !MultigridSolver_GetRestriction( self, l_i ) || !MultigridSolver_GetProlongation( self, l_i ) ) {
- rebuildOps = True;
- break;
- }
- }
- }
-
- if( rebuildOps )
- wallTime = MPI_Wtime();
- MultigridSolver_UpdateOps( self );
- stg_profile_Func( "MultigridSolver_UpdateOps", MPI_Wtime() - wallTime);
- //if( self->matrixChanged || rebuildOps || self->opsChanged || self->solversChanged ) {
- if( self->mgData->matrixChanged || rebuildOps || self->opsChanged || self->solversChanged ) {
- wallTime = MPI_Wtime();
- MultigridSolver_UpdateMatrices( self );
- stg_profile_Func( "MultigridSolver_UpdateMatrices", MPI_Wtime() - wallTime);
-
- wallTime = MPI_Wtime();
- MultigridSolver_UpdateWorkVectors( self );
- stg_profile_Func( "MultigridSolver_UpdateWorkVectors", MPI_Wtime() - wallTime);
-
-
- }
- self->solversChanged = False;
- //self->matrixChanged = False;
- self->mgData->matrixChanged = False;
- self->opsChanged = False;
-}
-
-MGSolver_Status MultigridSolver_GetSolveStatus( void* matrixSolver ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- MGSolver_Status outerStatus;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- //MatrixSolver_Solve( self->outerSolver, self->curRHS, self->curSolution );
- //outerStatus = MatrixSolver_GetSolveStatus( self->outerSolver );
- KSPSolve( self->outerSolver->ksp, self->mgData->curRHS, self->mgData->curSolution );
- outerStatus = _GetSolveStatus( self->outerSolver );
-
- if( outerStatus == MGSolver_Status_ConvergedIterations ||
- outerStatus == MGSolver_Status_DivergedIterations ||
- outerStatus == MGSolver_Status_Iterating )
- {
- return MGSolver_Status_Iterating;
- }
- else if( outerStatus == MGSolver_Status_ConvergedRelative )
- return MGSolver_Status_ConvergedRelative;
- else
- return outerStatus;
-}
-
-unsigned MultigridSolver_GetIterations( void* matrixSolver ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- return self->curIt;
-}
-
-unsigned MultigridSolver_GetMaxIterations( void* matrixSolver ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- return self->maxIts;
-}
-
-double MultigridSolver_GetResidualNorm( void* matrixSolver ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- return _GetResidualNorm( self->outerSolver );
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-void MultigridSolver_SetLevels( void* matrixSolver, unsigned nLevels ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- unsigned nProcs;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- MultigridSolver_DestructLevels( self );
-
- self->nLevels = nLevels;
- self->levels = AllocArray( MultigridSolver_Level, nLevels );
- //MPI_Comm_size( self->comm, (int*)&nProcs );
- MPI_Comm_size( self->mgData->comm, (int*)&nProcs );
-
- for( l_i = 0; l_i < nLevels; l_i++ ) {
- MultigridSolver_Level* level = self->levels + l_i;
-
- //level->downSolver = NULL;
- level->downSolver = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
- level->nDownIts = 1;
- //level->upSolver = NULL;
- level->upSolver = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
- level->nUpIts = l_i ? 1 : 0;
- level->nCycles = 1;
-
- level->A = NULL;
- level->R = NULL;
- level->P = NULL;
-
- level->workRHS = NULL;
- level->workSol = NULL;
- }
-}
-
-void MultigridSolver_SetRestriction( void* matrixSolver, unsigned levelInd, void* _R ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- MultigridSolver_Level* level;
- //Matrix* R = (Matrix*)_R;
- Mat R = (Mat)_R;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
- assert( levelInd < self->nLevels && levelInd > 0 );
- //assert( !R || Stg_CheckType( R, Matrix ) );
-
- level = self->levels + levelInd;
- if( level->R != R )
- self->opsChanged = True;
- //if( level->R )
- // Stg_Class_RemoveRef( level->R );
- level->R = R;
- //if( R )
- // Stg_Class_AddRef( R );
-}
-
-void MultigridSolver_SetProlongation( void* matrixSolver, unsigned levelInd, void* _P ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- MultigridSolver_Level* level;
- Mat P = (Mat)_P;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
- assert( levelInd < self->nLevels && levelInd > 0 );
- //assert( !P || Stg_CheckType( P, Matrix ) );
-
- level = self->levels + levelInd;
- if( level->P != P )
- self->opsChanged = True;
- //if( level->P )
- // Stg_Class_RemoveRef( level->P );
- if( level->P != PETSC_NULL )
- MatDestroy( level->P );
- level->P = P;
- //if( P )
- // Stg_Class_AddRef( P );
-}
-
-void MultigridSolver_SetLevelDownSolver( void* matrixSolver, unsigned levelInd, void* solver ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- MultigridSolver_Level* level;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
- assert( levelInd < self->nLevels );
- //assert( !solver || Stg_CheckType( solver, MatrixSolver ) );
-
- level = self->levels + levelInd;
- if( level->downSolver != solver )
- self->solversChanged = True;
- if( level->downSolver ) {
- // Stg_Class_RemoveRef( level->downSolver );
- if( level->downSolver->ksp != PETSC_NULL ) KSPDestroy( level->downSolver->ksp );
- if( level->downSolver->matrix != PETSC_NULL ) MatDestroy( level->downSolver->matrix );
- if( level->downSolver->inversion != PETSC_NULL ) MatDestroy( level->downSolver->inversion );
- if( level->downSolver->residual != PETSC_NULL ) VecDestroy( level->downSolver->residual );
- if( level->downSolver->curRHS != PETSC_NULL ) VecDestroy( level->downSolver->curRHS );
- if( level->downSolver->curSolution != PETSC_NULL ) VecDestroy( level->downSolver->curSolution );
- free( level->downSolver );
- }
- level->downSolver = (MGSolver_PETScData*)solver;
- //if( solver )
- // Stg_Class_AddRef( solver );
-}
-
-void MultigridSolver_SetLevelDownIterations( void* matrixSolver, unsigned level, unsigned nIts ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
- assert( level < self->nLevels );
-
- self->levels[level].nDownIts = nIts;
- self->solversChanged = True;
-}
-
-/* this function was applying to the down solver before - pretty sure this is a mistake */
-void MultigridSolver_SetLevelUpSolver( void* matrixSolver, unsigned levelInd, void* solver ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- MultigridSolver_Level* level;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
- assert( levelInd < self->nLevels && levelInd > 0 );
-
- level = self->levels + levelInd;
- if( level->upSolver != solver )
- self->solversChanged = True;
- if( level->upSolver ) {
- // Stg_Class_RemoveRef( level->downSolver );
- if( level->upSolver->ksp != PETSC_NULL ) KSPDestroy( level->upSolver->ksp );
- if( level->upSolver->matrix != PETSC_NULL ) MatDestroy( level->upSolver->matrix );
- if( level->upSolver->inversion != PETSC_NULL ) MatDestroy( level->upSolver->inversion );
- if( level->upSolver->residual != PETSC_NULL ) VecDestroy( level->upSolver->residual );
- if( level->upSolver->curRHS != PETSC_NULL ) VecDestroy( level->upSolver->curRHS );
- if( level->upSolver->curSolution != PETSC_NULL ) VecDestroy( level->upSolver->curSolution );
- free( level->upSolver );
- }
- level->upSolver = (MGSolver_PETScData*)solver;
- //if( solver )
- // Stg_Class_AddRef( solver );
-}
-
-void MultigridSolver_SetLevelUpIterations( void* matrixSolver, unsigned level, unsigned nIts ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
- assert( level < self->nLevels );
- assert( level > 0 );
-
- self->levels[level].nUpIts = nIts;
- self->solversChanged = True;
-}
-
-void MultigridSolver_SetLevelCycles( void* matrixSolver, unsigned level, unsigned nCycles ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
- assert( level < self->nLevels );
- assert( level > 0 );
-
- self->levels[level].nCycles = nCycles;
- self->solversChanged = True;
-}
-
-void MultigridSolver_SetAllDownSolver( void* matrixSolver, void* solver ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- for( l_i = 1; l_i < self->nLevels; l_i++ )
- MultigridSolver_SetLevelDownSolver( self, l_i, solver );
-}
-
-void MultigridSolver_SetAllDownIterations( void* matrixSolver, unsigned level, unsigned nIts ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- for( l_i = 1; l_i < self->nLevels; l_i++ )
- MultigridSolver_SetLevelDownIterations( self, l_i, nIts );
-}
-
-void MultigridSolver_SetAllUpSolver( void* matrixSolver, void* solver ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- for( l_i = 1; l_i < self->nLevels; l_i++ )
- MultigridSolver_SetLevelUpSolver( self, l_i, solver );
-}
-
-void MultigridSolver_SetAllUpIterations( void* matrixSolver, unsigned level, unsigned nIts ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- for( l_i = 1; l_i < self->nLevels; l_i++ )
- MultigridSolver_SetLevelUpIterations( self, l_i, nIts );
-}
-
-void MultigridSolver_SetAllSolver( void* matrixSolver, void* solver ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self );
-
- MultigridSolver_SetAllDownSolver( self, solver );
- MultigridSolver_SetAllUpSolver( self, solver );
-}
-
-void MultigridSolver_SetCoarseSolver( void* matrixSolver, void* solver ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self );
-
- MultigridSolver_SetLevelDownSolver( self, 0, solver );
-}
-
-unsigned MultigridSolver_GetNumLevels( void* matrixSolver ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- return self->nLevels;
-}
-
-Mat MultigridSolver_GetRestriction( void* matrixSolver, unsigned level ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
- assert( level < self->nLevels && level > 0 );
-
- return self->levels[level].R;
-}
-
-Mat MultigridSolver_GetProlongation( void* matrixSolver, unsigned level ) {
- MultigridSolver* self = (MultigridSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
- assert( level < self->nLevels && level > 0 );
-
- return self->levels[level].P;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-void MultigridSolver_RestrictMatrix( MultigridSolver* self, MultigridSolver_Level* level, Mat* dstMatrix ) {
- Mat srcMat;
- PetscInt nSrcRows, nSrcCols;
- PetscInt nRRows, nRCols;
-
-#if( PETSC_VERSION_MAJOR > 2 )
- PetscInt dummy;
-#endif
-
- PetscScalar fillRatio;
- MatInfo mInfo;
- PetscInt nRowsA, nRowsC;
- PetscScalar nzA, nzP, nzC;
-
- assert( self );
- assert( level );
- assert( dstMatrix );
-
- srcMat = level->downSolver->matrix;
- MatGetSize( srcMat, &nSrcRows, &nSrcCols );
- MatGetSize( level->R, &nRRows, &nRCols );
- if( nRCols == nSrcRows ) {
- //Matrix_PAPt( srcMat, level->R, (void**)dstMatrix );
- /* this function implementation was commented out in the PETScMatrix function - not sure if it should
- * be implemented here?? */
- MatGetInfo( srcMat, MAT_GLOBAL_SUM, &mInfo );
-#if( PETSC_VERSION_MAJOR <= 2 )
- nRowsA = mInfo.rows_global;
-#else
- MatGetSize( srcMat, &nRowsA, &dummy );
-#endif
- nzA = mInfo.nz_used;
- MatGetInfo( level->R, MAT_GLOBAL_SUM, &mInfo );
-#if( PETSC_VERSION_MAJOR <= 2 )
- nRowsC = mInfo.columns_global;
-#else
- MatGetSize( level->R, &dummy, &nRowsC );
-#endif
- nzP = mInfo.nz_used;
-
- nzC = ( nRowsC / nRowsA ) * nzA;
- fillRatio = nzC / ( nzA + nzP );
-
- /* this function doesn't exist! */
- //MatPAPt( srcMat, level->R, MAT_REUSE_MATRIX, fillRatio, dstMatrix );
- }
- else {
- //Matrix_PtAP( srcMat, level->R, (void**)dstMatrix );
- if( dstMatrix )
- MatPtAP( srcMat, level->R, MAT_REUSE_MATRIX, 1.0, dstMatrix );
- else
- MatPtAP( srcMat, level->R, MAT_INITIAL_MATRIX, 1.0, dstMatrix );
- }
-}
-
-//void MultigridSolver_LevelCycle( MultigridSolver* self, unsigned levelInd, Vector* rhs, Vector* solution ) {
-void MultigridSolver_LevelCycle( MultigridSolver* self, unsigned levelInd, Vec rhs, Vec solution ) {
- MultigridSolver_Level* level;
-
- assert( self );
- assert( levelInd < self->nLevels );
-
- Stream_Indent( self->stream );
- level = self->levels + levelInd;
-
- if( level->nDownIts ) {
- Journal_Printf( self->stream, "Down-solve on level %d... ", levelInd );
- //MatrixSolver_Solve( level->downSolver, rhs, solution );
- //Journal_Printf( self->stream, "residual: %.10lf\n", MatrixSolver_GetResidualNorm( level->downSolver ) );
- KSPSolve( level->downSolver->ksp, rhs, solution );
- Journal_Printf( self->stream, "residual: %.10lf\n", _GetResidualNorm( level->downSolver ) );
- }
-
- if( levelInd > 0 ) {
- MultigridSolver_Level* nextLevel;
- unsigned c_i;
-
- nextLevel = self->levels + (levelInd - 1);
- if( level->R == level->P )
- //Matrix_TransposeMultiply( level->R, MatrixSolver_GetResidual( level->downSolver ), nextLevel->workRHS );
- MatMultTranspose( level->R, _GetResidual( level->downSolver ), nextLevel->workRHS );
- else
- //Matrix_Multiply( level->R, MatrixSolver_GetResidual( level->downSolver ), nextLevel->workRHS );
- MatMult( level->R, _GetResidual( level->downSolver ), nextLevel->workRHS );
- for( c_i = 0; c_i < level->nCycles; c_i++ )
- MultigridSolver_LevelCycle( self, levelInd - 1, nextLevel->workRHS, nextLevel->workSol );
- //Matrix_MultiplyAdd( level->P, nextLevel->workSol, solution, solution );
- MatMultAdd( level->P, nextLevel->workSol, solution, solution );
- }
-
- if( level->nUpIts ) {
- Journal_Printf( self->stream, "Up-solve on level %d... ", levelInd );
- //MatrixSolver_Solve( level->upSolver, rhs, solution );
- //Journal_Printf( self->stream, "residual: %.10lf\n", MatrixSolver_GetResidualNorm( level->upSolver ) );
- KSPSolve( level->upSolver->ksp, rhs, solution );
- Journal_Printf( self->stream, "residual: %.10lf\n", _GetResidualNorm( level->upSolver ) );
- }
-
- Stream_UnIndent( self->stream );
-}
-
-void MultigridSolver_UpdateSolvers( MultigridSolver* self ) {
- MultigridSolver_Level* level;
- unsigned l_i;
- PetscInt nDownIts, nUpIts;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- for( l_i = self->nLevels - 1; l_i < self->nLevels; l_i-- ) {
- level = self->levels + l_i;
-
- if( l_i > 0 ) {
- KSPGetTolerances( level->downSolver->ksp, PETSC_NULL, PETSC_NULL, PETSC_NULL, &nDownIts );
- KSPGetTolerances( level->upSolver->ksp, PETSC_NULL, PETSC_NULL, PETSC_NULL, &nUpIts );
- if( /*MatrixSolver_GetMaxIterations( level->downSolver )*/nDownIts != level->nDownIts )
- //MatrixSolver_SetMaxIterations( level->downSolver, level->nDownIts );
- KSPSetTolerances( level->downSolver->ksp, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, level->nDownIts );
- if( /*MatrixSolver_GetMaxIterations( level->upSolver )*/nUpIts != level->nUpIts )
- //MatrixSolver_SetMaxIterations( level->upSolver, level->nUpIts );
- KSPSetTolerances( level->upSolver->ksp, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, level->nUpIts );
-
- if( l_i == self->nLevels - 1 )
- //MatrixSolver_SetUseInitialSolution( level->downSolver, True );
- KSPSetInitialGuessNonzero( level->downSolver->ksp, (PetscTruth)True );
- else
- //MatrixSolver_SetUseInitialSolution( level->downSolver, False );
- KSPSetInitialGuessNonzero( level->downSolver->ksp, (PetscTruth)False );
- //MatrixSolver_SetUseInitialSolution( level->upSolver, True );
- KSPSetInitialGuessNonzero( level->upSolver->ksp, (PetscTruth)True );
- }
- }
-
- //FreeObject( self->outerSolver );
- self->outerSolver = MultigridSolver_CreateOuterSolver( self, self->mgData->matrix );
- //MatrixSolver_SetRelativeTolerance( self->outerSolver, self->relTol );
- KSPSetTolerances( self->outerSolver->ksp, self->relTol, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT );
-}
-
-void MultigridSolver_UpdateMatrices( MultigridSolver* self ) {
- MultigridSolver_Level* level;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- for( l_i = self->nLevels - 1; l_i < self->nLevels; l_i-- ) {
- level = self->levels + l_i;
-
- Journal_Printf( self->stream, "Updating matrix on level %d...\n", l_i );
-
- if( l_i < self->nLevels - 1 ) {
- //Matrix* mat;
- Mat mat;
-
- if( level->downSolver )
- //mat = MatrixSolver_GetMatrix( level->downSolver );
- mat = level->downSolver->matrix;
- else
- mat = NULL;
- //if( mat ) {
- if( mat != PETSC_NULL ) {
- //KillObject( mat );
- MatDestroy( mat );
- }
- MultigridSolver_RestrictMatrix( self, self->levels + l_i + 1, &mat );
- level->A = mat;
- if( level->downSolver ) {
- //MatrixSolver_SetMatrix( level->downSolver, mat );
- level->downSolver->matrix = mat;
- KSPSetOperators( level->downSolver->ksp, mat, mat, DIFFERENT_NONZERO_PATTERN );
- }
- else {
- if( l_i > 0 )
- level->downSolver = MultigridSolver_CreateSmoother( self, mat );
- else
- level->downSolver = MultigridSolver_CreateCoarseSolver( self, mat );
- }
- if( l_i > 0 ) {
- if( level->upSolver ) {
- //MatrixSolver_SetMatrix( level->upSolver, mat );
- level->upSolver->matrix = mat;
- KSPSetOperators( level->upSolver->ksp, mat, mat, DIFFERENT_NONZERO_PATTERN );
- }
- else
- level->upSolver = MultigridSolver_CreateSmoother( self, mat );
- }
- }
- else {
- level->A = self->mgData->matrix;
- if( level->downSolver ) {
- //MatrixSolver_SetMatrix( level->downSolver, self->matrix );
- level->downSolver->matrix = self->mgData->matrix;
- KSPSetOperators( level->downSolver->ksp, self->mgData->matrix, self->mgData->matrix, DIFFERENT_NONZERO_PATTERN );
- }
- else {
- if( l_i > 0 )
- level->downSolver = MultigridSolver_CreateSmoother( self, self->mgData->matrix );
- else
- level->downSolver = MultigridSolver_CreateCoarseSolver( self, self->mgData->matrix );
- }
- if( l_i > 0 ) {
- if( level->upSolver ) {
- //MatrixSolver_SetMatrix( level->upSolver, self->matrix );
- level->upSolver->matrix = self->mgData->matrix;
- KSPSetOperators( level->upSolver->ksp, self->mgData->matrix, self->mgData->matrix, DIFFERENT_NONZERO_PATTERN );
- }
- else
- level->upSolver = MultigridSolver_CreateSmoother( self, self->mgData->matrix );
- }
- }
-
- Journal_Printf( self->stream, "done\n" );
- }
-
- MultigridSolver_UpdateSolvers( self );
- //MatrixSolver_SetMatrix( self->outerSolver, self->matrix );
- self->outerSolver->matrix = self->mgData->matrix;
- KSPSetOperators( self->outerSolver->ksp, self->mgData->matrix, self->mgData->matrix, DIFFERENT_NONZERO_PATTERN );
-}
-
-void MultigridSolver_UpdateOps( MultigridSolver* self ) {
- MultigridSolver_Level* level;
- //Matrix **pOps, **rOps;
- Mat *pOps, *rOps;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- MGOpGenerator_Generate( self->opGen, &pOps, &rOps );
- for( l_i = 1; l_i < self->nLevels; l_i++ ) {
- level = self->levels + l_i;
-
- //if( !level->P ) {
- if( level->P == PETSC_NULL ) {
- level->P = pOps[l_i];
- //Stg_Class_AddRef( level->P );
- }
- else
- MatDestroy( pOps[l_i] );
- //Stg_Class_RemoveRef( pOps[l_i] );
-
-
- //if( !level->R ) {
- if( level->R == PETSC_NULL ) {
- level->R = rOps[l_i];
- //Stg_Class_AddRef( level->R );
- }
- else
- MatDestroy( rOps[l_i] );
- //Stg_Class_RemoveRef( rOps[l_i] );
- }
-
- FreeArray( pOps );
- FreeArray( rOps );
-}
-
-void MultigridSolver_UpdateWorkVectors( MultigridSolver* self ) {
- MultigridSolver_Level* level;
- //unsigned rowSize, colSize;
- PetscInt rowSize, colSize, vecSize;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- for( l_i = 0; l_i < self->nLevels - 1; l_i++ ) {
- level = self->levels + l_i;
-
- //Matrix_GetLocalSize( MatrixSolver_GetMatrix( level->downSolver ), &rowSize, &colSize );
- MatGetLocalSize( level->downSolver->matrix, &rowSize, &colSize );
-
- VecGetLocalSize( level->workSol, &vecSize );
-
- //if( !level->workSol || Vector_GetLocalSize( level->workSol ) != rowSize ) {
- if( !level->workSol || vecSize != rowSize ) {
- //if( level->workSol )
- // Stg_Class_RemoveRef( level->workSol );
- //Vector_Duplicate( self->curSolution, (void**)&level->workSol );
- //Vector_SetLocalSize( level->workSol, rowSize );
- if( level->workSol != PETSC_NULL )
- VecDestroy( level->workSol );
- VecCreate( self->mgData->comm, &level->workSol );
- VecSetSizes( level->workSol, rowSize, PETSC_DECIDE );
- VecSetFromOptions( level->workSol );
-#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
- VecSetOption( level->workSol, VEC_IGNORE_NEGATIVE_INDICES );
-#elif( PETSC_VERSION_MAJOR >= 3 )
- VecSetOption( level->workSol, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
-#endif
- }
-
- VecGetLocalSize( level->workRHS, &vecSize );
-
- if( !level->workRHS || /*Vector_GetLocalSize( level->workRHS )*/vecSize != rowSize ) {
- //if( level->workRHS )
- // Stg_Class_RemoveRef( level->workRHS );
- //Vector_Duplicate( self->curSolution, (void**)&level->workRHS );
- //Vector_SetLocalSize( level->workRHS, rowSize );
- if( level->workRHS != PETSC_NULL )
- VecDestroy( level->workRHS );
- VecCreate( self->mgData->comm, &level->workRHS );
- VecSetSizes( level->workRHS, rowSize, PETSC_DECIDE );
- VecSetFromOptions( level->workRHS );
-#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
- VecSetOption( level->workRHS, VEC_IGNORE_NEGATIVE_INDICES );
-#elif( PETSC_VERSION_MAJOR >= 3 )
- VecSetOption( level->workRHS, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
-#endif
- }
- }
-}
-
-MGSolver_PETScData* MultigridSolver_CreateOuterSolver( MultigridSolver* self, Mat matrix ) {
- //MatrixSolver* outerSolver;
- MGSolver_PETScData* outerSolver = (MGSolver_PETScData*)malloc( sizeof(MGSolver_PETScData) );
- PC pc;
-
- /*
- outerSolver = (MatrixSolver*)PETScMatrixSolver_New( "" );
- PETScMatrixSolver_SetKSPType( outerSolver, PETScMatrixSolver_KSPType_Richardson );
- PETScMatrixSolver_SetPCType( outerSolver, PETScMatrixSolver_PCType_SOR );
- PETScMatrixSolver_SetMatrix( outerSolver, matrix );
- PETScMatrixSolver_SetMaxIterations( outerSolver, 3 );
- PETScMatrixSolver_SetUseInitialSolution( outerSolver, True );
- PETScMatrixSolver_SetNormType( outerSolver, PETScMatrixSolver_NormType_Preconditioned );
- */
- KSPCreate( MPI_COMM_WORLD, &outerSolver->ksp );
- KSPSetType( outerSolver->ksp, KSPRICHARDSON );
- KSPGetPC( outerSolver->ksp, &pc );
- PCSetType( pc, PCSOR );
- if( outerSolver->matrix != PETSC_NULL )
- MatDestroy( outerSolver->matrix );
- outerSolver->matrix = matrix;
- KSPSetOperators( outerSolver->ksp, matrix, matrix, DIFFERENT_NONZERO_PATTERN );
- KSPSetTolerances( outerSolver->ksp, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, (PetscInt)3 );
- KSPSetInitialGuessNonzero( outerSolver->ksp, (PetscTruth)True );
- KSPSetNormType( outerSolver->ksp, (KSPNormType)MultigridSolver_NormType_Preconditioned );
-
- return outerSolver;
-}
-
-MGSolver_PETScData* MultigridSolver_CreateSmoother( MultigridSolver* self, Mat matrix ) {
- //MatrixSolver* smoother;
- MGSolver_PETScData* smoother = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
- //unsigned nBlocks;
- //KSP* ksps;
- PC pc;
- //PetscErrorCode ec;
-
- /*
- smoother = (MatrixSolver*)PETScMatrixSolver_New( "" );
- PETScMatrixSolver_SetKSPType( smoother,
- PETScMatrixSolver_KSPType_Richardson );
- PETScMatrixSolver_SetPCType( smoother,
- PETScMatrixSolver_PCType_SOR );
- MatrixSolver_SetMatrix( smoother, matrix );
- */
- KSPCreate( MPI_COMM_WORLD, &smoother->ksp );
- KSPSetType( smoother->ksp, KSPRICHARDSON );
- KSPGetPC( smoother->ksp, &pc );
- PCSetType( pc, PCSOR );
- if( smoother->matrix != PETSC_NULL )
- MatDestroy( smoother->matrix );
- smoother->matrix = matrix;
- KSPSetOperators( smoother->ksp, matrix, matrix, DIFFERENT_NONZERO_PATTERN );
-
- return smoother;
-}
-
-MGSolver_PETScData* MultigridSolver_CreateCoarseSolver( MultigridSolver* self, Mat matrix ) {
- //MatrixSolver* coarseSolver;
- MGSolver_PETScData* courseSolver;
- unsigned nProcs;
- PC pc;
-
- MPI_Comm_size( self->mgData->comm, (int*)&nProcs );
-
- /*
- coarseSolver = (MatrixSolver*)PETScMatrixSolver_New( "" );
- PETScMatrixSolver_SetKSPType( coarseSolver,
- PETScMatrixSolver_KSPType_PreOnly );
- if( nProcs == 1 ) {
- PETScMatrixSolver_SetPCType( coarseSolver,
- PETScMatrixSolver_PCType_LU );
- }
- else {
- PETScMatrixSolver_SetPCType( coarseSolver,
- PETScMatrixSolver_PCType_RedundantLU );
- }
- MatrixSolver_SetMatrix( coarseSolver, matrix );
- */
- KSPCreate( MPI_COMM_WORLD, &courseSolver->ksp );
- KSPSetType( courseSolver->ksp, KSPPREONLY );
- KSPGetPC( courseSolver->ksp, &pc );
- if( nProcs == 1 )
- PCSetType( pc, PCLU );
- else {
- PCSetType( pc, PCREDUNDANT );
- PCRedundantGetPC( pc, &pc );
- PCSetType( pc, PCLU );
- }
- if( courseSolver->matrix != PETSC_NULL )
- MatDestroy( courseSolver->matrix );
- courseSolver->matrix = matrix;
- KSPSetOperators( courseSolver->ksp, matrix, matrix, DIFFERENT_NONZERO_PATTERN );
-
- return courseSolver;
-}
-
-void MultigridSolver_Destruct( MultigridSolver* self ) {
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- MultigridSolver_DestructLevels( self );
- KillObject( self->opGen );
-}
-
-void MultigridSolver_DestructLevels( MultigridSolver* self ) {
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, MultigridSolver ) );
-
- for( l_i = 0; l_i < self->nLevels; l_i++ ) {
- MultigridSolver_Level* level = self->levels + l_i;
-
- if( level->downSolver ) {
- //Stg_Class_RemoveRef( MatrixSolver_GetMatrix( level->downSolver ) );
- //Stg_Class_RemoveRef( level->downSolver );
- if( level->downSolver->ksp != PETSC_NULL ) KSPDestroy( level->downSolver->ksp );
- if( level->downSolver->matrix != PETSC_NULL ) MatDestroy( level->downSolver->matrix );
- if( level->downSolver->inversion != PETSC_NULL ) MatDestroy( level->downSolver->inversion );
- if( level->downSolver->residual != PETSC_NULL ) VecDestroy( level->downSolver->residual );
- if( level->downSolver->curRHS != PETSC_NULL ) VecDestroy( level->downSolver->curRHS );
- if( level->downSolver->curSolution != PETSC_NULL ) VecDestroy( level->downSolver->curSolution );
- free( level->downSolver );
- }
- if( level->upSolver ) {
- //Stg_Class_RemoveRef( MatrixSolver_GetMatrix( level->upSolver ) );
- //Stg_Class_RemoveRef( level->upSolver );
- if( level->upSolver->ksp != PETSC_NULL ) KSPDestroy( level->upSolver->ksp );
- if( level->upSolver->matrix != PETSC_NULL ) MatDestroy( level->upSolver->matrix );
- if( level->upSolver->inversion != PETSC_NULL ) MatDestroy( level->upSolver->inversion );
- if( level->upSolver->residual != PETSC_NULL ) VecDestroy( level->upSolver->residual );
- if( level->upSolver->curRHS != PETSC_NULL ) VecDestroy( level->upSolver->curRHS );
- if( level->upSolver->curSolution != PETSC_NULL ) VecDestroy( level->upSolver->curSolution );
- free( level->upSolver );
- }
- if( level->R != PETSC_NULL )
- //Stg_Class_RemoveRef( level->R );
- MatDestroy( level->R );
- if( level->P != PETSC_NULL )
- //Stg_Class_RemoveRef( level->P );
- MatDestroy( level->P );
- if( level->workRHS != PETSC_NULL )
- //Stg_Class_RemoveRef( level->workRHS );
- VecDestroy( level->workRHS );
- if( level->workSol != PETSC_NULL )
- //Stg_Class_RemoveRef( level->workSol );
- VecDestroy( level->workSol );
- }
-
- KillArray( self->levels );
- self->nLevels = 0;
- self->solversChanged = True;
- self->opsChanged = True;
-
- /* Temporary. */
- //KillObject( self->outerSolver );
- if( self->outerSolver->ksp ) KSPDestroy( self->outerSolver->ksp );
- if( self->outerSolver->matrix ) MatDestroy( self->outerSolver->matrix );
- if( self->outerSolver->inversion ) MatDestroy( self->outerSolver->inversion );
- if( self->outerSolver->residual ) VecDestroy( self->outerSolver->residual );
- if( self->outerSolver->curRHS ) VecDestroy( self->outerSolver->curRHS );
- if( self->outerSolver->curSolution ) VecDestroy( self->outerSolver->curSolution );
- free( self->outerSolver );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/MultigridSolver.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/MultigridSolver.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,1233 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: MultigridSolver.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+
+#include "SystemSetup.h"
+
+
+/* Textual name of this class */
+const Type MultigridSolver_Type = "MultigridSolver";
+
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+MultigridSolver* MultigridSolver_New( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(MultigridSolver);
+ Type type = MultigridSolver_Type;
+ Stg_Class_DeleteFunction* _delete = _MultigridSolver_Delete;
+ Stg_Class_PrintFunction* _print = _MultigridSolver_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_MultigridSolver_New;
+ Stg_Component_ConstructFunction* _construct = _MultigridSolver_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _MultigridSolver_Build;
+ Stg_Component_InitialiseFunction* _initialise = _MultigridSolver_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _MultigridSolver_Execute;
+ Stg_Component_DestroyFunction* _destroy = _MultigridSolver_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ MGSolver_SetCommFunc* setCommFunc = MultigridSolver_SetComm;
+ MGSolver_SetMatrixFunc* setMatrixFunc = MultigridSolver_SetMatrix;
+ MGSolver_SetMaxIterationsFunc* setMaxIterationsFunc = MultigridSolver_SetMaxIterations;
+ MGSolver_SetRelativeToleranceFunc* setRelativeToleranceFunc = MultigridSolver_SetRelativeTolerance;
+ MGSolver_SetAbsoluteToleranceFunc* setAbsoluteToleranceFunc = MultigridSolver_SetAbsoluteTolerance;
+ MGSolver_SetUseInitialSolutionFunc* setUseInitialSolutionFunc = MultigridSolver_SetUseInitialSolution;
+ MGSolver_SolveFunc* solveFunc = MultigridSolver_Solve;
+ MGSolver_SetupFunc* setupFunc = MultigridSolver_Setup;
+ MGSolver_GetSolveStatusFunc* getSolveStatusFunc = MultigridSolver_GetSolveStatus;
+ MGSolver_GetIterationsFunc* getIterationsFunc = MultigridSolver_GetIterations;
+ MGSolver_GetMaxIterationsFunc* getMaxIterationsFunc = MultigridSolver_GetMaxIterations;
+ MGSolver_GetResidualNormFunc* getResidualNormFunc = MultigridSolver_GetResidualNorm;
+
+ return _MultigridSolver_New( MULTIGRIDSOLVER_PASSARGS );
+}
+
+MultigridSolver* _MultigridSolver_New( MULTIGRIDSOLVER_DEFARGS ) {
+ MultigridSolver* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(MultigridSolver) );
+
+ self = (MultigridSolver*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ /* function assignments previously in the MatrixSolver_New func */
+ self->setCommFunc = setCommFunc;
+ self->setMatrixFunc = setMatrixFunc;
+ self->setMaxIterationsFunc = setMaxIterationsFunc;
+ self->setRelativeToleranceFunc = setRelativeToleranceFunc;
+ self->setAbsoluteToleranceFunc = setAbsoluteToleranceFunc;
+ self->setUseInitialSolutionFunc = setUseInitialSolutionFunc;
+
+ self->solveFunc = solveFunc;
+ self->setupFunc = setupFunc;
+
+ self->getSolveStatusFunc = getSolveStatusFunc;
+ self->getIterationsFunc = getIterationsFunc;
+ self->getMaxIterationsFunc = getMaxIterationsFunc;
+ self->getResidualNormFunc = getResidualNormFunc;
+
+ /* Virtual info */
+
+ /* MultigridSolver info */
+ _MultigridSolver_Init( self );
+
+ return self;
+}
+
+void _MultigridSolver_Init( MultigridSolver* self ) {
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ /* these initialisations previously done in the MatrixSolver_Init func */
+ self->mgData = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
+
+ self->mgData->comm = MPI_COMM_WORLD;
+ KSPCreate( MPI_COMM_WORLD, &self->mgData->ksp );
+ self->mgData->matrix = PETSC_NULL;
+ self->mgData->inversion = PETSC_NULL;
+ self->mgData->residual = PETSC_NULL;
+ self->mgData->expiredResidual = True;
+ self->mgData->matrixChanged = True;
+
+ self->mgData->curRHS = PETSC_NULL;
+ self->mgData->curSolution = PETSC_NULL;
+ /* end of old MatrixSolver_Init initialisations */
+
+ self->nLevels = 0;
+ self->levels = NULL;
+ self->opGen = NULL;
+ self->solversChanged = True;
+ self->opsChanged = True;
+
+ self->curIt = 0;
+ self->maxIts = 500;
+ self->relTol = 1e-5;
+ self->rnorm = 0.0;
+ self->useInitial = False;
+ //self->outerSolver = NULL;
+ self->outerSolver = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
+ self->outerSolver->ksp = PETSC_NULL;
+ self->outerSolver->matrix = PETSC_NULL;
+ self->outerSolver->inversion = PETSC_NULL;
+ self->outerSolver->residual = PETSC_NULL;
+ self->outerSolver->curRHS = PETSC_NULL;
+ self->outerSolver->curSolution = PETSC_NULL;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _MultigridSolver_Delete( void* matrixSolver ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ MultigridSolver_Destruct( self );
+
+ /* Delete the parent. */
+ _Stg_Component_Delete( self );
+}
+
+void _MultigridSolver_Print( void* matrixSolver, Stream* stream ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ /* Set the Journal for printing informations */
+ Stream* matrixSolverStream;
+ matrixSolverStream = Journal_Register( InfoStream_Type, (Name)"MultigridSolverStream" );
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ /* Print parent */
+ Journal_Printf( stream, "MultigridSolver (ptr): (%p)\n", self );
+ _Stg_Component_Print( self, stream );
+}
+
+void _MultigridSolver_AssignFromXML( void* matrixSolver, Stg_ComponentFactory* cf, void* data ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ unsigned nLevels;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+ assert( cf );
+
+ nLevels = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"levels", 1 );
+ MultigridSolver_SetLevels( self, nLevels );
+ self->opGen = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"opGenerator", MGOpGenerator, True, data );
+ MGOpGenerator_SetMatrixSolver( self->opGen, self );
+ MGOpGenerator_SetNumLevels( self->opGen, nLevels );
+}
+
+void _MultigridSolver_Build( void* matrixSolver, void* data ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ self->stream = Journal_Register( InfoStream_Type, (Name)"general" );
+ if( self->opGen )
+ Stg_Component_Build( self->opGen, data, False );
+}
+
+void _MultigridSolver_Initialise( void* matrixSolver, void* data ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ if( self->opGen )
+ Stg_Component_Initialise( self->opGen, data, False );
+}
+
+void _MultigridSolver_Execute( void* matrixSolver, void* data ) {
+}
+
+void _MultigridSolver_Destroy( void* matrixSolver, void* data ) {
+}
+
+/* copied from the PETScMatrixSolver class, has been depreciated */
+void MultigridSolver_SetComm( void* matrixSolver, MPI_Comm comm ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ self->mgData->comm = comm;
+
+ if( self->mgData->ksp != PETSC_NULL )
+ KSPDestroy( self->mgData->ksp );
+ KSPCreate( comm, &self->mgData->ksp );
+}
+
+/* copied from the PETScMatrixSolver class, has been depreciated */
+void MultigridSolver_SetMatrix( void* matrixSolver, void* _matrix ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ Mat matrix = (Mat)_matrix;
+
+ self->mgData->matrix = matrix;
+ KSPSetOperators( self->mgData->ksp, matrix, matrix, DIFFERENT_NONZERO_PATTERN );
+}
+
+void MultigridSolver_SetMaxIterations( void* matrixSolver, unsigned nIterations ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ self->maxIts = nIterations;
+}
+
+void MultigridSolver_SetRelativeTolerance( void* matrixSolver, double tolerance ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ self->relTol = tolerance;
+ self->solversChanged = True;
+}
+
+void MultigridSolver_SetAbsoluteTolerance( void* matrixSolver, double tolerance ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ //MatrixSolver_SetAbsoluteTolerance( self->outerSolver, tolerance );
+ KSPSetTolerances( self->outerSolver->ksp, PETSC_DEFAULT, tolerance, PETSC_DEFAULT, PETSC_DEFAULT );
+
+ self->solversChanged = True;
+}
+
+void MultigridSolver_SetUseInitialSolution( void* matrixSolver, Bool state ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ self->useInitial = state;
+}
+
+/* these functions were associated with the PETScMatrixSolver class, before it was
+ * depreciated */
+Vec _GetResidual( MGSolver_PETScData* mgData ) {
+ if( mgData->expiredResidual ) {
+ VecDuplicate( mgData->curSolution, &mgData->residual );
+ VecSetFromOptions( mgData->residual );
+#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
+ VecSetOption( mgData->residual, VEC_IGNORE_NEGATIVE_INDICES );
+#elif( PETSC_VERSION_MAJOR >= 3 )
+ VecSetOption( mgData->residual, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
+#endif
+ MatMult( mgData->matrix, mgData->curSolution, mgData->residual );
+ VecAYPX( mgData->residual, -1.0, mgData->curRHS );
+
+ mgData->expiredResidual = False;
+ }
+
+ return mgData->residual;
+}
+
+double _GetResidualNorm( MGSolver_PETScData* mgData ) {
+ PC pc;
+ const KSPType kspType;
+ const PCType pcType;
+ PetscScalar rnorm;
+ PetscErrorCode ec;
+
+ ec = KSPGetType( mgData->ksp, &kspType );
+ CheckPETScError( ec );
+ ec = KSPGetPC( mgData->ksp, &pc );
+ CheckPETScError( ec );
+ ec = PCGetType( pc, &pcType );
+ CheckPETScError( ec );
+
+ if( !strcmp( kspType, KSPRICHARDSON ) && !strcmp( pcType, PCSOR ) ) {
+ Vec residual;
+
+ //residual = MatrixSolver_GetResidual( mgData );
+ //rnorm = (PetscScalar)Vector_L2Norm( residual );
+ residual = _GetResidual( mgData );
+ VecNorm( residual, NORM_2, &rnorm );
+ }
+ else {
+ ec = KSPGetResidualNorm( mgData->ksp, &rnorm );
+ CheckPETScError( ec );
+ }
+
+ return (double)rnorm;
+}
+
+#define MultigridSolver_NormType_Preconditioned 1
+
+MGSolver_Status _GetSolveStatus( MGSolver_PETScData* mgData ) {
+ PC pc;
+ const KSPType kspType;
+ const PCType pcType;
+ KSPConvergedReason reason;
+ PetscErrorCode ec;
+
+ ec = KSPGetType( mgData->ksp, &kspType );
+ CheckPETScError( ec );
+ ec = KSPGetPC( mgData->ksp, &pc );
+ CheckPETScError( ec );
+ ec = PCGetType( pc, &pcType );
+ CheckPETScError( ec );
+
+ if( !strcmp( kspType, KSPRICHARDSON ) && !strcmp( pcType, PCSOR ) ) {
+ double rnorm;
+ PetscInt curIt;
+
+ //rnorm = PETScMatrixSolver_GetResidualNorm( self );
+ //curIt = PETScMatrixSolver_GetIterations( self );
+ rnorm = _GetResidualNorm( mgData );
+ KSPGetIterationNumber( mgData->ksp, &curIt );
+ //PETScMatrixSolver_SetNormType( self, MultigridSolver_NormType_Preconditioned );
+ KSPSetNormType( mgData->ksp, (KSPNormType)MultigridSolver_NormType_Preconditioned );
+ ec = KSPDefaultConverged( mgData->ksp, curIt, (PetscScalar)rnorm, &reason, PETSC_NULL );
+ CheckPETScError( ec );
+ }
+ else {
+ ec = KSPGetConvergedReason( mgData->ksp, &reason );
+ CheckPETScError( ec );
+ }
+
+ return (MGSolver_Status)reason;
+}
+
+/* end of functions formerly defined in the PETScMatrixSolver class */
+
+void MultigridSolver_Solve( void* matrixSolver, void* _rhs, void* _solution ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ Vec rhs = (Vec)_rhs;
+ Vec solution = (Vec)_solution;
+ double wallTime;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+ //assert( rhs && Stg_CheckType( rhs, Vector ) );
+ //assert( solution && Stg_CheckType( solution, Vector ) );
+
+ Journal_Printf( self->stream, "MultigridSolver: Starting solve ...\n" );
+ Stream_Indent( self->stream );
+
+ if( !self->useInitial ) {
+ Journal_Printf( self->stream, "Zeroing initial solution\n" );
+ //Vector_Zero( solution );
+ VecSet( solution, 0.0 );
+ }
+ else
+ Journal_Printf( self->stream, "Keeping initial solution\n" );
+
+ wallTime = MPI_Wtime();
+ MultigridSolver_Setup( self, rhs, solution );
+ stg_profile_Func( "MultigridSolver_Setup", MPI_Wtime() - wallTime);
+ self->curIt = 0;
+ //while( MatrixSolver_GetSolveStatus( self ) == MultigridSolver_Status_Iterating && self->curIt < self->maxIts ) {
+ while( _GetSolveStatus( self->mgData ) == MGSolver_Status_Iterating && self->curIt < self->maxIts ) {
+ Journal_Printf( self->stream, "Iteration %d: residual %.10lf\n",
+ //self->curIt, MatrixSolver_GetResidualNorm( self->outerSolver ) );
+ self->curIt, _GetResidualNorm( self->outerSolver ) );
+ MultigridSolver_LevelCycle( self, self->nLevels - 1, rhs, solution );
+ self->curIt++;
+ }
+ Journal_Printf( self->stream, "Iteration %d: residual %.10lf\n",
+ //self->curIt, MatrixSolver_GetResidualNorm( self->outerSolver ) );
+ self->curIt, _GetResidualNorm( self->outerSolver ) );
+
+ Stream_UnIndent( self->stream );
+ Journal_Printf( self->stream, "done.\n" );
+}
+
+void MultigridSolver_Setup( void* matrixSolver, void* rhs, void* solution ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ Bool rebuildOps;
+ double wallTime;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ //_MatrixSolver_Setup( self, rhs, solution );
+ self->mgData->curRHS = (struct _p_Vec*)rhs;
+ self->mgData->curSolution = (struct _p_Vec*)solution;
+ self->mgData->expiredResidual = True;
+
+ /* Need to rebuild the operators? */
+ if( self->opGen )
+ rebuildOps = MGOpGenerator_HasExpired( self->opGen );
+ else
+ rebuildOps = False;
+ if( !rebuildOps ) {
+ unsigned l_i;
+
+ for( l_i = 1; l_i < self->nLevels; l_i++ ) {
+ if( !MultigridSolver_GetRestriction( self, l_i ) || !MultigridSolver_GetProlongation( self, l_i ) ) {
+ rebuildOps = True;
+ break;
+ }
+ }
+ }
+
+ if( rebuildOps )
+ wallTime = MPI_Wtime();
+ MultigridSolver_UpdateOps( self );
+ stg_profile_Func( "MultigridSolver_UpdateOps", MPI_Wtime() - wallTime);
+ //if( self->matrixChanged || rebuildOps || self->opsChanged || self->solversChanged ) {
+ if( self->mgData->matrixChanged || rebuildOps || self->opsChanged || self->solversChanged ) {
+ wallTime = MPI_Wtime();
+ MultigridSolver_UpdateMatrices( self );
+ stg_profile_Func( "MultigridSolver_UpdateMatrices", MPI_Wtime() - wallTime);
+
+ wallTime = MPI_Wtime();
+ MultigridSolver_UpdateWorkVectors( self );
+ stg_profile_Func( "MultigridSolver_UpdateWorkVectors", MPI_Wtime() - wallTime);
+
+
+ }
+ self->solversChanged = False;
+ //self->matrixChanged = False;
+ self->mgData->matrixChanged = False;
+ self->opsChanged = False;
+}
+
+MGSolver_Status MultigridSolver_GetSolveStatus( void* matrixSolver ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ MGSolver_Status outerStatus;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ //MatrixSolver_Solve( self->outerSolver, self->curRHS, self->curSolution );
+ //outerStatus = MatrixSolver_GetSolveStatus( self->outerSolver );
+ KSPSolve( self->outerSolver->ksp, self->mgData->curRHS, self->mgData->curSolution );
+ outerStatus = _GetSolveStatus( self->outerSolver );
+
+ if( outerStatus == MGSolver_Status_ConvergedIterations ||
+ outerStatus == MGSolver_Status_DivergedIterations ||
+ outerStatus == MGSolver_Status_Iterating )
+ {
+ return MGSolver_Status_Iterating;
+ }
+ else if( outerStatus == MGSolver_Status_ConvergedRelative )
+ return MGSolver_Status_ConvergedRelative;
+ else
+ return outerStatus;
+}
+
+unsigned MultigridSolver_GetIterations( void* matrixSolver ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ return self->curIt;
+}
+
+unsigned MultigridSolver_GetMaxIterations( void* matrixSolver ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ return self->maxIts;
+}
+
+double MultigridSolver_GetResidualNorm( void* matrixSolver ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ return _GetResidualNorm( self->outerSolver );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+void MultigridSolver_SetLevels( void* matrixSolver, unsigned nLevels ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ unsigned nProcs;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ MultigridSolver_DestructLevels( self );
+
+ self->nLevels = nLevels;
+ self->levels = AllocArray( MultigridSolver_Level, nLevels );
+ //MPI_Comm_size( self->comm, (int*)&nProcs );
+ MPI_Comm_size( self->mgData->comm, (int*)&nProcs );
+
+ for( l_i = 0; l_i < nLevels; l_i++ ) {
+ MultigridSolver_Level* level = self->levels + l_i;
+
+ //level->downSolver = NULL;
+ level->downSolver = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
+ level->nDownIts = 1;
+ //level->upSolver = NULL;
+ level->upSolver = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
+ level->nUpIts = l_i ? 1 : 0;
+ level->nCycles = 1;
+
+ level->A = NULL;
+ level->R = NULL;
+ level->P = NULL;
+
+ level->workRHS = NULL;
+ level->workSol = NULL;
+ }
+}
+
+void MultigridSolver_SetRestriction( void* matrixSolver, unsigned levelInd, void* _R ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ MultigridSolver_Level* level;
+ //Matrix* R = (Matrix*)_R;
+ Mat R = (Mat)_R;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+ assert( levelInd < self->nLevels && levelInd > 0 );
+ //assert( !R || Stg_CheckType( R, Matrix ) );
+
+ level = self->levels + levelInd;
+ if( level->R != R )
+ self->opsChanged = True;
+ //if( level->R )
+ // Stg_Class_RemoveRef( level->R );
+ level->R = R;
+ //if( R )
+ // Stg_Class_AddRef( R );
+}
+
+void MultigridSolver_SetProlongation( void* matrixSolver, unsigned levelInd, void* _P ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ MultigridSolver_Level* level;
+ Mat P = (Mat)_P;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+ assert( levelInd < self->nLevels && levelInd > 0 );
+ //assert( !P || Stg_CheckType( P, Matrix ) );
+
+ level = self->levels + levelInd;
+ if( level->P != P )
+ self->opsChanged = True;
+ //if( level->P )
+ // Stg_Class_RemoveRef( level->P );
+ if( level->P != PETSC_NULL )
+ MatDestroy( level->P );
+ level->P = P;
+ //if( P )
+ // Stg_Class_AddRef( P );
+}
+
+void MultigridSolver_SetLevelDownSolver( void* matrixSolver, unsigned levelInd, void* solver ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ MultigridSolver_Level* level;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+ assert( levelInd < self->nLevels );
+ //assert( !solver || Stg_CheckType( solver, MatrixSolver ) );
+
+ level = self->levels + levelInd;
+ if( level->downSolver != solver )
+ self->solversChanged = True;
+ if( level->downSolver ) {
+ // Stg_Class_RemoveRef( level->downSolver );
+ if( level->downSolver->ksp != PETSC_NULL ) KSPDestroy( level->downSolver->ksp );
+ if( level->downSolver->matrix != PETSC_NULL ) MatDestroy( level->downSolver->matrix );
+ if( level->downSolver->inversion != PETSC_NULL ) MatDestroy( level->downSolver->inversion );
+ if( level->downSolver->residual != PETSC_NULL ) VecDestroy( level->downSolver->residual );
+ if( level->downSolver->curRHS != PETSC_NULL ) VecDestroy( level->downSolver->curRHS );
+ if( level->downSolver->curSolution != PETSC_NULL ) VecDestroy( level->downSolver->curSolution );
+ free( level->downSolver );
+ }
+ level->downSolver = (MGSolver_PETScData*)solver;
+ //if( solver )
+ // Stg_Class_AddRef( solver );
+}
+
+void MultigridSolver_SetLevelDownIterations( void* matrixSolver, unsigned level, unsigned nIts ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+ assert( level < self->nLevels );
+
+ self->levels[level].nDownIts = nIts;
+ self->solversChanged = True;
+}
+
+/* this function was applying to the down solver before - pretty sure this is a mistake */
+void MultigridSolver_SetLevelUpSolver( void* matrixSolver, unsigned levelInd, void* solver ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ MultigridSolver_Level* level;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+ assert( levelInd < self->nLevels && levelInd > 0 );
+
+ level = self->levels + levelInd;
+ if( level->upSolver != solver )
+ self->solversChanged = True;
+ if( level->upSolver ) {
+ // Stg_Class_RemoveRef( level->downSolver );
+ if( level->upSolver->ksp != PETSC_NULL ) KSPDestroy( level->upSolver->ksp );
+ if( level->upSolver->matrix != PETSC_NULL ) MatDestroy( level->upSolver->matrix );
+ if( level->upSolver->inversion != PETSC_NULL ) MatDestroy( level->upSolver->inversion );
+ if( level->upSolver->residual != PETSC_NULL ) VecDestroy( level->upSolver->residual );
+ if( level->upSolver->curRHS != PETSC_NULL ) VecDestroy( level->upSolver->curRHS );
+ if( level->upSolver->curSolution != PETSC_NULL ) VecDestroy( level->upSolver->curSolution );
+ free( level->upSolver );
+ }
+ level->upSolver = (MGSolver_PETScData*)solver;
+ //if( solver )
+ // Stg_Class_AddRef( solver );
+}
+
+void MultigridSolver_SetLevelUpIterations( void* matrixSolver, unsigned level, unsigned nIts ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+ assert( level < self->nLevels );
+ assert( level > 0 );
+
+ self->levels[level].nUpIts = nIts;
+ self->solversChanged = True;
+}
+
+void MultigridSolver_SetLevelCycles( void* matrixSolver, unsigned level, unsigned nCycles ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+ assert( level < self->nLevels );
+ assert( level > 0 );
+
+ self->levels[level].nCycles = nCycles;
+ self->solversChanged = True;
+}
+
+void MultigridSolver_SetAllDownSolver( void* matrixSolver, void* solver ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ for( l_i = 1; l_i < self->nLevels; l_i++ )
+ MultigridSolver_SetLevelDownSolver( self, l_i, solver );
+}
+
+void MultigridSolver_SetAllDownIterations( void* matrixSolver, unsigned level, unsigned nIts ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ for( l_i = 1; l_i < self->nLevels; l_i++ )
+ MultigridSolver_SetLevelDownIterations( self, l_i, nIts );
+}
+
+void MultigridSolver_SetAllUpSolver( void* matrixSolver, void* solver ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ for( l_i = 1; l_i < self->nLevels; l_i++ )
+ MultigridSolver_SetLevelUpSolver( self, l_i, solver );
+}
+
+void MultigridSolver_SetAllUpIterations( void* matrixSolver, unsigned level, unsigned nIts ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ for( l_i = 1; l_i < self->nLevels; l_i++ )
+ MultigridSolver_SetLevelUpIterations( self, l_i, nIts );
+}
+
+void MultigridSolver_SetAllSolver( void* matrixSolver, void* solver ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self );
+
+ MultigridSolver_SetAllDownSolver( self, solver );
+ MultigridSolver_SetAllUpSolver( self, solver );
+}
+
+void MultigridSolver_SetCoarseSolver( void* matrixSolver, void* solver ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self );
+
+ MultigridSolver_SetLevelDownSolver( self, 0, solver );
+}
+
+unsigned MultigridSolver_GetNumLevels( void* matrixSolver ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ return self->nLevels;
+}
+
+Mat MultigridSolver_GetRestriction( void* matrixSolver, unsigned level ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+ assert( level < self->nLevels && level > 0 );
+
+ return self->levels[level].R;
+}
+
+Mat MultigridSolver_GetProlongation( void* matrixSolver, unsigned level ) {
+ MultigridSolver* self = (MultigridSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+ assert( level < self->nLevels && level > 0 );
+
+ return self->levels[level].P;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+void MultigridSolver_RestrictMatrix( MultigridSolver* self, MultigridSolver_Level* level, Mat* dstMatrix ) {
+ Mat srcMat;
+ PetscInt nSrcRows, nSrcCols;
+ PetscInt nRRows, nRCols;
+
+#if( PETSC_VERSION_MAJOR > 2 )
+ PetscInt dummy;
+#endif
+
+ PetscScalar fillRatio;
+ MatInfo mInfo;
+ PetscInt nRowsA, nRowsC;
+ PetscScalar nzA, nzP, nzC;
+
+ assert( self );
+ assert( level );
+ assert( dstMatrix );
+
+ srcMat = level->downSolver->matrix;
+ MatGetSize( srcMat, &nSrcRows, &nSrcCols );
+ MatGetSize( level->R, &nRRows, &nRCols );
+ if( nRCols == nSrcRows ) {
+ //Matrix_PAPt( srcMat, level->R, (void**)dstMatrix );
+ /* this function implementation was commented out in the PETScMatrix function - not sure if it should
+ * be implemented here?? */
+ MatGetInfo( srcMat, MAT_GLOBAL_SUM, &mInfo );
+#if( PETSC_VERSION_MAJOR <= 2 )
+ nRowsA = mInfo.rows_global;
+#else
+ MatGetSize( srcMat, &nRowsA, &dummy );
+#endif
+ nzA = mInfo.nz_used;
+ MatGetInfo( level->R, MAT_GLOBAL_SUM, &mInfo );
+#if( PETSC_VERSION_MAJOR <= 2 )
+ nRowsC = mInfo.columns_global;
+#else
+ MatGetSize( level->R, &dummy, &nRowsC );
+#endif
+ nzP = mInfo.nz_used;
+
+ nzC = ( nRowsC / nRowsA ) * nzA;
+ fillRatio = nzC / ( nzA + nzP );
+
+ /* this function doesn't exist! */
+ //MatPAPt( srcMat, level->R, MAT_REUSE_MATRIX, fillRatio, dstMatrix );
+ }
+ else {
+ //Matrix_PtAP( srcMat, level->R, (void**)dstMatrix );
+ if( dstMatrix )
+ MatPtAP( srcMat, level->R, MAT_REUSE_MATRIX, 1.0, dstMatrix );
+ else
+ MatPtAP( srcMat, level->R, MAT_INITIAL_MATRIX, 1.0, dstMatrix );
+ }
+}
+
+//void MultigridSolver_LevelCycle( MultigridSolver* self, unsigned levelInd, Vector* rhs, Vector* solution ) {
+void MultigridSolver_LevelCycle( MultigridSolver* self, unsigned levelInd, Vec rhs, Vec solution ) {
+ MultigridSolver_Level* level;
+
+ assert( self );
+ assert( levelInd < self->nLevels );
+
+ Stream_Indent( self->stream );
+ level = self->levels + levelInd;
+
+ if( level->nDownIts ) {
+ Journal_Printf( self->stream, "Down-solve on level %d... ", levelInd );
+ //MatrixSolver_Solve( level->downSolver, rhs, solution );
+ //Journal_Printf( self->stream, "residual: %.10lf\n", MatrixSolver_GetResidualNorm( level->downSolver ) );
+ KSPSolve( level->downSolver->ksp, rhs, solution );
+ Journal_Printf( self->stream, "residual: %.10lf\n", _GetResidualNorm( level->downSolver ) );
+ }
+
+ if( levelInd > 0 ) {
+ MultigridSolver_Level* nextLevel;
+ unsigned c_i;
+
+ nextLevel = self->levels + (levelInd - 1);
+ if( level->R == level->P )
+ //Matrix_TransposeMultiply( level->R, MatrixSolver_GetResidual( level->downSolver ), nextLevel->workRHS );
+ MatMultTranspose( level->R, _GetResidual( level->downSolver ), nextLevel->workRHS );
+ else
+ //Matrix_Multiply( level->R, MatrixSolver_GetResidual( level->downSolver ), nextLevel->workRHS );
+ MatMult( level->R, _GetResidual( level->downSolver ), nextLevel->workRHS );
+ for( c_i = 0; c_i < level->nCycles; c_i++ )
+ MultigridSolver_LevelCycle( self, levelInd - 1, nextLevel->workRHS, nextLevel->workSol );
+ //Matrix_MultiplyAdd( level->P, nextLevel->workSol, solution, solution );
+ MatMultAdd( level->P, nextLevel->workSol, solution, solution );
+ }
+
+ if( level->nUpIts ) {
+ Journal_Printf( self->stream, "Up-solve on level %d... ", levelInd );
+ //MatrixSolver_Solve( level->upSolver, rhs, solution );
+ //Journal_Printf( self->stream, "residual: %.10lf\n", MatrixSolver_GetResidualNorm( level->upSolver ) );
+ KSPSolve( level->upSolver->ksp, rhs, solution );
+ Journal_Printf( self->stream, "residual: %.10lf\n", _GetResidualNorm( level->upSolver ) );
+ }
+
+ Stream_UnIndent( self->stream );
+}
+
+void MultigridSolver_UpdateSolvers( MultigridSolver* self ) {
+ MultigridSolver_Level* level;
+ unsigned l_i;
+ PetscInt nDownIts, nUpIts;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ for( l_i = self->nLevels - 1; l_i < self->nLevels; l_i-- ) {
+ level = self->levels + l_i;
+
+ if( l_i > 0 ) {
+ KSPGetTolerances( level->downSolver->ksp, PETSC_NULL, PETSC_NULL, PETSC_NULL, &nDownIts );
+ KSPGetTolerances( level->upSolver->ksp, PETSC_NULL, PETSC_NULL, PETSC_NULL, &nUpIts );
+ if( /*MatrixSolver_GetMaxIterations( level->downSolver )*/nDownIts != level->nDownIts )
+ //MatrixSolver_SetMaxIterations( level->downSolver, level->nDownIts );
+ KSPSetTolerances( level->downSolver->ksp, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, level->nDownIts );
+ if( /*MatrixSolver_GetMaxIterations( level->upSolver )*/nUpIts != level->nUpIts )
+ //MatrixSolver_SetMaxIterations( level->upSolver, level->nUpIts );
+ KSPSetTolerances( level->upSolver->ksp, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, level->nUpIts );
+
+ if( l_i == self->nLevels - 1 )
+ //MatrixSolver_SetUseInitialSolution( level->downSolver, True );
+ KSPSetInitialGuessNonzero( level->downSolver->ksp, (PetscTruth)True );
+ else
+ //MatrixSolver_SetUseInitialSolution( level->downSolver, False );
+ KSPSetInitialGuessNonzero( level->downSolver->ksp, (PetscTruth)False );
+ //MatrixSolver_SetUseInitialSolution( level->upSolver, True );
+ KSPSetInitialGuessNonzero( level->upSolver->ksp, (PetscTruth)True );
+ }
+ }
+
+ //FreeObject( self->outerSolver );
+ self->outerSolver = MultigridSolver_CreateOuterSolver( self, self->mgData->matrix );
+ //MatrixSolver_SetRelativeTolerance( self->outerSolver, self->relTol );
+ KSPSetTolerances( self->outerSolver->ksp, self->relTol, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT );
+}
+
+void MultigridSolver_UpdateMatrices( MultigridSolver* self ) {
+ MultigridSolver_Level* level;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ for( l_i = self->nLevels - 1; l_i < self->nLevels; l_i-- ) {
+ level = self->levels + l_i;
+
+ Journal_Printf( self->stream, "Updating matrix on level %d...\n", l_i );
+
+ if( l_i < self->nLevels - 1 ) {
+ //Matrix* mat;
+ Mat mat;
+
+ if( level->downSolver )
+ //mat = MatrixSolver_GetMatrix( level->downSolver );
+ mat = level->downSolver->matrix;
+ else
+ mat = NULL;
+ //if( mat ) {
+ if( mat != PETSC_NULL ) {
+ //KillObject( mat );
+ MatDestroy( mat );
+ }
+ MultigridSolver_RestrictMatrix( self, self->levels + l_i + 1, &mat );
+ level->A = mat;
+ if( level->downSolver ) {
+ //MatrixSolver_SetMatrix( level->downSolver, mat );
+ level->downSolver->matrix = mat;
+ KSPSetOperators( level->downSolver->ksp, mat, mat, DIFFERENT_NONZERO_PATTERN );
+ }
+ else {
+ if( l_i > 0 )
+ level->downSolver = MultigridSolver_CreateSmoother( self, mat );
+ else
+ level->downSolver = MultigridSolver_CreateCoarseSolver( self, mat );
+ }
+ if( l_i > 0 ) {
+ if( level->upSolver ) {
+ //MatrixSolver_SetMatrix( level->upSolver, mat );
+ level->upSolver->matrix = mat;
+ KSPSetOperators( level->upSolver->ksp, mat, mat, DIFFERENT_NONZERO_PATTERN );
+ }
+ else
+ level->upSolver = MultigridSolver_CreateSmoother( self, mat );
+ }
+ }
+ else {
+ level->A = self->mgData->matrix;
+ if( level->downSolver ) {
+ //MatrixSolver_SetMatrix( level->downSolver, self->matrix );
+ level->downSolver->matrix = self->mgData->matrix;
+ KSPSetOperators( level->downSolver->ksp, self->mgData->matrix, self->mgData->matrix, DIFFERENT_NONZERO_PATTERN );
+ }
+ else {
+ if( l_i > 0 )
+ level->downSolver = MultigridSolver_CreateSmoother( self, self->mgData->matrix );
+ else
+ level->downSolver = MultigridSolver_CreateCoarseSolver( self, self->mgData->matrix );
+ }
+ if( l_i > 0 ) {
+ if( level->upSolver ) {
+ //MatrixSolver_SetMatrix( level->upSolver, self->matrix );
+ level->upSolver->matrix = self->mgData->matrix;
+ KSPSetOperators( level->upSolver->ksp, self->mgData->matrix, self->mgData->matrix, DIFFERENT_NONZERO_PATTERN );
+ }
+ else
+ level->upSolver = MultigridSolver_CreateSmoother( self, self->mgData->matrix );
+ }
+ }
+
+ Journal_Printf( self->stream, "done\n" );
+ }
+
+ MultigridSolver_UpdateSolvers( self );
+ //MatrixSolver_SetMatrix( self->outerSolver, self->matrix );
+ self->outerSolver->matrix = self->mgData->matrix;
+ KSPSetOperators( self->outerSolver->ksp, self->mgData->matrix, self->mgData->matrix, DIFFERENT_NONZERO_PATTERN );
+}
+
+void MultigridSolver_UpdateOps( MultigridSolver* self ) {
+ MultigridSolver_Level* level;
+ //Matrix **pOps, **rOps;
+ Mat *pOps, *rOps;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ MGOpGenerator_Generate( self->opGen, &pOps, &rOps );
+ for( l_i = 1; l_i < self->nLevels; l_i++ ) {
+ level = self->levels + l_i;
+
+ //if( !level->P ) {
+ if( level->P == PETSC_NULL ) {
+ level->P = pOps[l_i];
+ //Stg_Class_AddRef( level->P );
+ }
+ else
+ MatDestroy( pOps[l_i] );
+ //Stg_Class_RemoveRef( pOps[l_i] );
+
+
+ //if( !level->R ) {
+ if( level->R == PETSC_NULL ) {
+ level->R = rOps[l_i];
+ //Stg_Class_AddRef( level->R );
+ }
+ else
+ MatDestroy( rOps[l_i] );
+ //Stg_Class_RemoveRef( rOps[l_i] );
+ }
+
+ FreeArray( pOps );
+ FreeArray( rOps );
+}
+
+void MultigridSolver_UpdateWorkVectors( MultigridSolver* self ) {
+ MultigridSolver_Level* level;
+ //unsigned rowSize, colSize;
+ PetscInt rowSize, colSize, vecSize;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ for( l_i = 0; l_i < self->nLevels - 1; l_i++ ) {
+ level = self->levels + l_i;
+
+ //Matrix_GetLocalSize( MatrixSolver_GetMatrix( level->downSolver ), &rowSize, &colSize );
+ MatGetLocalSize( level->downSolver->matrix, &rowSize, &colSize );
+
+ VecGetLocalSize( level->workSol, &vecSize );
+
+ //if( !level->workSol || Vector_GetLocalSize( level->workSol ) != rowSize ) {
+ if( !level->workSol || vecSize != rowSize ) {
+ //if( level->workSol )
+ // Stg_Class_RemoveRef( level->workSol );
+ //Vector_Duplicate( self->curSolution, (void**)&level->workSol );
+ //Vector_SetLocalSize( level->workSol, rowSize );
+ if( level->workSol != PETSC_NULL )
+ VecDestroy( level->workSol );
+ VecCreate( self->mgData->comm, &level->workSol );
+ VecSetSizes( level->workSol, rowSize, PETSC_DECIDE );
+ VecSetFromOptions( level->workSol );
+#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
+ VecSetOption( level->workSol, VEC_IGNORE_NEGATIVE_INDICES );
+#elif( PETSC_VERSION_MAJOR >= 3 )
+ VecSetOption( level->workSol, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
+#endif
+ }
+
+ VecGetLocalSize( level->workRHS, &vecSize );
+
+ if( !level->workRHS || /*Vector_GetLocalSize( level->workRHS )*/vecSize != rowSize ) {
+ //if( level->workRHS )
+ // Stg_Class_RemoveRef( level->workRHS );
+ //Vector_Duplicate( self->curSolution, (void**)&level->workRHS );
+ //Vector_SetLocalSize( level->workRHS, rowSize );
+ if( level->workRHS != PETSC_NULL )
+ VecDestroy( level->workRHS );
+ VecCreate( self->mgData->comm, &level->workRHS );
+ VecSetSizes( level->workRHS, rowSize, PETSC_DECIDE );
+ VecSetFromOptions( level->workRHS );
+#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
+ VecSetOption( level->workRHS, VEC_IGNORE_NEGATIVE_INDICES );
+#elif( PETSC_VERSION_MAJOR >= 3 )
+ VecSetOption( level->workRHS, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
+#endif
+ }
+ }
+}
+
+MGSolver_PETScData* MultigridSolver_CreateOuterSolver( MultigridSolver* self, Mat matrix ) {
+ //MatrixSolver* outerSolver;
+ MGSolver_PETScData* outerSolver = (MGSolver_PETScData*)malloc( sizeof(MGSolver_PETScData) );
+ PC pc;
+
+ /*
+ outerSolver = (MatrixSolver*)PETScMatrixSolver_New( "" );
+ PETScMatrixSolver_SetKSPType( outerSolver, PETScMatrixSolver_KSPType_Richardson );
+ PETScMatrixSolver_SetPCType( outerSolver, PETScMatrixSolver_PCType_SOR );
+ PETScMatrixSolver_SetMatrix( outerSolver, matrix );
+ PETScMatrixSolver_SetMaxIterations( outerSolver, 3 );
+ PETScMatrixSolver_SetUseInitialSolution( outerSolver, True );
+ PETScMatrixSolver_SetNormType( outerSolver, PETScMatrixSolver_NormType_Preconditioned );
+ */
+ KSPCreate( MPI_COMM_WORLD, &outerSolver->ksp );
+ KSPSetType( outerSolver->ksp, KSPRICHARDSON );
+ KSPGetPC( outerSolver->ksp, &pc );
+ PCSetType( pc, PCSOR );
+ if( outerSolver->matrix != PETSC_NULL )
+ MatDestroy( outerSolver->matrix );
+ outerSolver->matrix = matrix;
+ KSPSetOperators( outerSolver->ksp, matrix, matrix, DIFFERENT_NONZERO_PATTERN );
+ KSPSetTolerances( outerSolver->ksp, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, (PetscInt)3 );
+ KSPSetInitialGuessNonzero( outerSolver->ksp, (PetscTruth)True );
+ KSPSetNormType( outerSolver->ksp, (KSPNormType)MultigridSolver_NormType_Preconditioned );
+
+ return outerSolver;
+}
+
+MGSolver_PETScData* MultigridSolver_CreateSmoother( MultigridSolver* self, Mat matrix ) {
+ //MatrixSolver* smoother;
+ MGSolver_PETScData* smoother = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
+ //unsigned nBlocks;
+ //KSP* ksps;
+ PC pc;
+ //PetscErrorCode ec;
+
+ /*
+ smoother = (MatrixSolver*)PETScMatrixSolver_New( "" );
+ PETScMatrixSolver_SetKSPType( smoother,
+ PETScMatrixSolver_KSPType_Richardson );
+ PETScMatrixSolver_SetPCType( smoother,
+ PETScMatrixSolver_PCType_SOR );
+ MatrixSolver_SetMatrix( smoother, matrix );
+ */
+ KSPCreate( MPI_COMM_WORLD, &smoother->ksp );
+ KSPSetType( smoother->ksp, KSPRICHARDSON );
+ KSPGetPC( smoother->ksp, &pc );
+ PCSetType( pc, PCSOR );
+ if( smoother->matrix != PETSC_NULL )
+ MatDestroy( smoother->matrix );
+ smoother->matrix = matrix;
+ KSPSetOperators( smoother->ksp, matrix, matrix, DIFFERENT_NONZERO_PATTERN );
+
+ return smoother;
+}
+
+MGSolver_PETScData* MultigridSolver_CreateCoarseSolver( MultigridSolver* self, Mat matrix ) {
+ //MatrixSolver* coarseSolver;
+ MGSolver_PETScData* courseSolver;
+ unsigned nProcs;
+ PC pc;
+
+ MPI_Comm_size( self->mgData->comm, (int*)&nProcs );
+
+ /*
+ coarseSolver = (MatrixSolver*)PETScMatrixSolver_New( "" );
+ PETScMatrixSolver_SetKSPType( coarseSolver,
+ PETScMatrixSolver_KSPType_PreOnly );
+ if( nProcs == 1 ) {
+ PETScMatrixSolver_SetPCType( coarseSolver,
+ PETScMatrixSolver_PCType_LU );
+ }
+ else {
+ PETScMatrixSolver_SetPCType( coarseSolver,
+ PETScMatrixSolver_PCType_RedundantLU );
+ }
+ MatrixSolver_SetMatrix( coarseSolver, matrix );
+ */
+ KSPCreate( MPI_COMM_WORLD, &courseSolver->ksp );
+ KSPSetType( courseSolver->ksp, KSPPREONLY );
+ KSPGetPC( courseSolver->ksp, &pc );
+ if( nProcs == 1 )
+ PCSetType( pc, PCLU );
+ else {
+ PCSetType( pc, PCREDUNDANT );
+ PCRedundantGetPC( pc, &pc );
+ PCSetType( pc, PCLU );
+ }
+ if( courseSolver->matrix != PETSC_NULL )
+ MatDestroy( courseSolver->matrix );
+ courseSolver->matrix = matrix;
+ KSPSetOperators( courseSolver->ksp, matrix, matrix, DIFFERENT_NONZERO_PATTERN );
+
+ return courseSolver;
+}
+
+void MultigridSolver_Destruct( MultigridSolver* self ) {
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ MultigridSolver_DestructLevels( self );
+ KillObject( self->opGen );
+}
+
+void MultigridSolver_DestructLevels( MultigridSolver* self ) {
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, MultigridSolver ) );
+
+ for( l_i = 0; l_i < self->nLevels; l_i++ ) {
+ MultigridSolver_Level* level = self->levels + l_i;
+
+ if( level->downSolver ) {
+ //Stg_Class_RemoveRef( MatrixSolver_GetMatrix( level->downSolver ) );
+ //Stg_Class_RemoveRef( level->downSolver );
+ if( level->downSolver->ksp != PETSC_NULL ) KSPDestroy( level->downSolver->ksp );
+ if( level->downSolver->matrix != PETSC_NULL ) MatDestroy( level->downSolver->matrix );
+ if( level->downSolver->inversion != PETSC_NULL ) MatDestroy( level->downSolver->inversion );
+ if( level->downSolver->residual != PETSC_NULL ) VecDestroy( level->downSolver->residual );
+ if( level->downSolver->curRHS != PETSC_NULL ) VecDestroy( level->downSolver->curRHS );
+ if( level->downSolver->curSolution != PETSC_NULL ) VecDestroy( level->downSolver->curSolution );
+ free( level->downSolver );
+ }
+ if( level->upSolver ) {
+ //Stg_Class_RemoveRef( MatrixSolver_GetMatrix( level->upSolver ) );
+ //Stg_Class_RemoveRef( level->upSolver );
+ if( level->upSolver->ksp != PETSC_NULL ) KSPDestroy( level->upSolver->ksp );
+ if( level->upSolver->matrix != PETSC_NULL ) MatDestroy( level->upSolver->matrix );
+ if( level->upSolver->inversion != PETSC_NULL ) MatDestroy( level->upSolver->inversion );
+ if( level->upSolver->residual != PETSC_NULL ) VecDestroy( level->upSolver->residual );
+ if( level->upSolver->curRHS != PETSC_NULL ) VecDestroy( level->upSolver->curRHS );
+ if( level->upSolver->curSolution != PETSC_NULL ) VecDestroy( level->upSolver->curSolution );
+ free( level->upSolver );
+ }
+ if( level->R != PETSC_NULL )
+ //Stg_Class_RemoveRef( level->R );
+ MatDestroy( level->R );
+ if( level->P != PETSC_NULL )
+ //Stg_Class_RemoveRef( level->P );
+ MatDestroy( level->P );
+ if( level->workRHS != PETSC_NULL )
+ //Stg_Class_RemoveRef( level->workRHS );
+ VecDestroy( level->workRHS );
+ if( level->workSol != PETSC_NULL )
+ //Stg_Class_RemoveRef( level->workSol );
+ VecDestroy( level->workSol );
+ }
+
+ KillArray( self->levels );
+ self->nLevels = 0;
+ self->solversChanged = True;
+ self->opsChanged = True;
+
+ /* Temporary. */
+ //KillObject( self->outerSolver );
+ if( self->outerSolver->ksp ) KSPDestroy( self->outerSolver->ksp );
+ if( self->outerSolver->matrix ) MatDestroy( self->outerSolver->matrix );
+ if( self->outerSolver->inversion ) MatDestroy( self->outerSolver->inversion );
+ if( self->outerSolver->residual ) VecDestroy( self->outerSolver->residual );
+ if( self->outerSolver->curRHS ) VecDestroy( self->outerSolver->curRHS );
+ if( self->outerSolver->curSolution ) VecDestroy( self->outerSolver->curSolution );
+ free( self->outerSolver );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/PETScMGSolver.c
--- a/SLE/SystemSetup/src/PETScMGSolver.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,764 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: PETScMGSolver.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-
-#include "SystemSetup.h"
-
-
-/* Textual name of this class */
-const Type PETScMGSolver_Type = "PETScMGSolver";
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-PETScMGSolver* PETScMGSolver_New( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(PETScMGSolver);
- Type type = PETScMGSolver_Type;
- Stg_Class_DeleteFunction* _delete = _PETScMGSolver_Delete;
- Stg_Class_PrintFunction* _print = _PETScMGSolver_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_PETScMGSolver_New;
- Stg_Component_ConstructFunction* _construct = _PETScMGSolver_AssignFromXML;
- Stg_Component_BuildFunction* _build = _PETScMGSolver_Build;
- Stg_Component_InitialiseFunction* _initialise = _PETScMGSolver_Initialise;
- Stg_Component_ExecuteFunction* _execute = _PETScMGSolver_Execute;
- Stg_Component_DestroyFunction* _destroy = _PETScMGSolver_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- MGSolver_SetCommFunc* setCommFunc = PETScMGSolver_SetComm;
- MGSolver_SetMatrixFunc* setMatrixFunc = NULL;
- MGSolver_SetMaxIterationsFunc* setMaxIterationsFunc = NULL;
- MGSolver_SetRelativeToleranceFunc* setRelativeToleranceFunc = NULL;
- MGSolver_SetAbsoluteToleranceFunc* setAbsoluteToleranceFunc = NULL;
- MGSolver_SetUseInitialSolutionFunc* setUseInitialSolutionFunc = NULL;
- MGSolver_SolveFunc* solveFunc = NULL;
- MGSolver_SetupFunc* setupFunc = PETScMGSolver_Setup;
- MGSolver_GetSolveStatusFunc* getSolveStatusFunc = NULL;
- MGSolver_GetIterationsFunc* getIterationsFunc = NULL;
- MGSolver_GetMaxIterationsFunc* getMaxIterationsFunc = NULL;
- MGSolver_GetResidualNormFunc* getResidualNormFunc = NULL;
-
- return _PETScMGSolver_New( PETSCMGSOLVER_PASSARGS );
-}
-
-PETScMGSolver* _PETScMGSolver_New( PETSCMGSOLVER_DEFARGS ) {
- PETScMGSolver* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(PETScMGSolver) );
- //self = (PETScMGSolver*)_PETScMatrixSolver_New( STG_COMPONENT_PASSARGS );
- self = (PETScMGSolver*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- /* Virtual info */
- /* from the depreciated MatrixSolver_New func */
- self->setCommFunc = setCommFunc;
- self->setMatrixFunc = setMatrixFunc;
- self->setMaxIterationsFunc = setMaxIterationsFunc;
- self->setRelativeToleranceFunc = setRelativeToleranceFunc;
- self->setAbsoluteToleranceFunc = setAbsoluteToleranceFunc;
- self->setUseInitialSolutionFunc = setUseInitialSolutionFunc;
-
- self->solveFunc = solveFunc;
- self->setupFunc = setupFunc;
-
- self->getSolveStatusFunc = getSolveStatusFunc;
- self->getIterationsFunc = getIterationsFunc;
- self->getMaxIterationsFunc = getMaxIterationsFunc;
- self->getResidualNormFunc = getResidualNormFunc;
-
- /* PETScMGSolver info */
- _PETScMGSolver_Init( self );
-
- return self;
-}
-
-void _PETScMGSolver_Init( PETScMGSolver* self ) {
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- self->mgData = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
-
- /* from the depreciated MatrixSolver_Init func */
- self->mgData->comm = MPI_COMM_WORLD;
- KSPCreate( MPI_COMM_WORLD, &self->mgData->ksp );
- self->mgData->matrix = PETSC_NULL;
- self->mgData->inversion = PETSC_NULL;
- self->mgData->residual = PETSC_NULL;
- self->mgData->expiredResidual = True;
- self->mgData->matrixChanged = True;
- self->mgData->optionsReady = False;
-
- self->mgData->curRHS = PETSC_NULL;
- self->mgData->curSolution = PETSC_NULL;
- /* end of MatrixSolver_Init stuff */
-
- self->nLevels = 0;
- self->levels = NULL;
- self->opGen = NULL;
- self->solversChanged = True;
- self->opsChanged = True;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _PETScMGSolver_Delete( void* matrixSolver ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- PETScMGSolver_Destruct( self );
-
- /* Delete the parent. */
- //_PETScMatrixSolver_Delete( self );
- _Stg_Component_Delete( self );
-}
-
-void _PETScMGSolver_Print( void* matrixSolver, Stream* stream ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
-
- /* Set the Journal for printing informations */
- Stream* matrixSolverStream;
- matrixSolverStream = Journal_Register( InfoStream_Type, (Name)"PETScMGSolverStream" );
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- /* Print parent */
- Journal_Printf( stream, "PETScMGSolver (ptr): (%p)\n", self );
- //_PETScMatrixSolver_Print( self, stream );
- _Stg_Component_Print( self, stream );
-}
-
-void _PETScMGSolver_AssignFromXML( void* matrixSolver, Stg_ComponentFactory* cf, void* data ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
- Bool pure;
- unsigned nLevels;
- unsigned nCycles;
- unsigned nDownIts, nUpIts;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
- assert( cf );
-
- //_PETScMatrixSolver_AssignFromXML( self, cf, data );
-
- pure = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"pure", False );
- nLevels = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"levels", 1 );
- nCycles = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"cycles", 1 );
- nDownIts = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"downIterations", 1 );
- nUpIts = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"upIterations", 1 );
-
- self->pure = pure;
- PETScMGSolver_SetLevels( self, nLevels );
- PETScMGSolver_SetLevelCycles( self, nLevels - 1, nCycles );
- PETScMGSolver_SetAllDownIterations( self, nDownIts );
- PETScMGSolver_SetAllUpIterations( self, nUpIts );
-
- self->opGen = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"opGenerator", MGOpGenerator, True, data );
- MGOpGenerator_SetMatrixSolver( self->opGen, self );
- MGOpGenerator_SetNumLevels( self->opGen, nLevels );
-}
-
-void _PETScMGSolver_Build( void* matrixSolver, void* data ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- if( self->opGen )
- Stg_Component_Build( self->opGen, data, False );
-}
-
-void _PETScMGSolver_Initialise( void* matrixSolver, void* data ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- if( self->opGen )
- Stg_Component_Initialise( self->opGen, data, False );
-}
-
-void _PETScMGSolver_Execute( void* matrixSolver, void* data ) {
-}
-
-void _PETScMGSolver_Destroy( void* matrixSolver, void* data ) {
-}
-
-void PETScMGSolver_SetComm( void* matrixSolver, MPI_Comm comm ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
- PC pc;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- //PETScMatrixSolver_SetComm( self, comm );
- self->mgData->comm = comm;
- if( self->mgData->ksp )
- KSPDestroy( self->mgData->ksp );
- KSPCreate( comm, &self->mgData->ksp );
-
- if( self->pure )
- //PETScMatrixSolver_SetKSPType( self, PETScMatrixSolver_KSPType_Richardson );
- KSPSetType( self->mgData->ksp, KSPRICHARDSON );
- else
- //PETScMatrixSolver_SetKSPType( self, PETScMatrixSolver_KSPType_FGMRes );
- KSPSetType( self->mgData->ksp, KSPFGMRES );
- //PETScMatrixSolver_SetPCType( self, PETScMatrixSolver_PCType_Multigrid );
- KSPGetPC( self->mgData->ksp, &pc );
- PCSetType( pc, PCMG );
-}
-
-void PETScMGSolver_Setup( void* matrixSolver, void* rhs, void* solution ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
- Bool rebuildOps;
- double wallTime;
- PetscErrorCode ec;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- wallTime = MPI_Wtime();
-
- //_MatrixSolver_Setup( self, rhs, solution );
- self->mgData->curRHS = (struct _p_Vec*)rhs;
- self->mgData->curSolution = (struct _p_Vec*)solution;
- self->mgData->expiredResidual = True;
-
- PetscPrintf( PETSC_COMM_WORLD, "_MatrixSolver_Setup %g\n", MPI_Wtime() - wallTime);
-
-
- if( self->opGen )
- rebuildOps = MGOpGenerator_HasExpired( self->opGen );
- else
- rebuildOps = False;
- if( !rebuildOps ) {
- unsigned l_i;
-
- for( l_i = 1; l_i < self->nLevels; l_i++ ) {
- if( !self->levels[l_i].R || !self->levels[l_i].P ) {
- rebuildOps = True;
- break;
- }
- }
- }
-
- if( self->solversChanged || rebuildOps || self->opsChanged ) {
- wallTime = MPI_Wtime();
- PETScMGSolver_UpdateSolvers( self );
- stg_profile_Func( "PETScMGSolver_UpdateSolvers", MPI_Wtime() - wallTime);
- PetscPrintf( PETSC_COMM_WORLD, "PETScMGSolver_UpdateSolvers %g\n", MPI_Wtime() - wallTime);
- }
- if( rebuildOps ) {
- wallTime = MPI_Wtime();
- PETScMGSolver_UpdateOps( self );
- stg_profile_Func( "PETScMGSolver_UpdateOps", MPI_Wtime() - wallTime);
- PetscPrintf( PETSC_COMM_WORLD, "PETScMGSolver_UpdateOps %g\n", MPI_Wtime() - wallTime);
-
- }
- //if( self->matrixChanged || self->solversChanged || rebuildOps || self->opsChanged ) {
- if( self->mgData->matrixChanged || self->solversChanged || rebuildOps || self->opsChanged ) {
- wallTime = MPI_Wtime();
- PETScMGSolver_UpdateMatrices( self );
- PETScMGSolver_UpdateWorkVectors( self );
- stg_profile_Func( "PETScMGSolver_UpdateMats-WorkVecs", MPI_Wtime() - wallTime);
- PetscPrintf( PETSC_COMM_WORLD, "PETScMGSolver_UpdateMats-WorkVecs %g\n", MPI_Wtime() - wallTime);
- }
-
- self->solversChanged = False;
- //self->matrixChanged = False;
- self->mgData->matrixChanged = False;
- self->opsChanged = False;
-
- //if( !self->optionsReady ) {
- if( !self->mgData->optionsReady ) {
- KSPSetOptionsPrefix( self->mgData->ksp, "A11_" );
- ec = KSPSetFromOptions( self->mgData->ksp );
- CheckPETScError( ec );
- //self->optionsReady = True;
- self->mgData->optionsReady = True;
- }
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-void PETScMGSolver_SetLevels( void* matrixSolver, unsigned nLevels ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- PETScMGSolver_DestructLevels( self );
-
- self->nLevels = nLevels;
- self->levels = AllocArray( PETScMGSolver_Level, nLevels );
- for( l_i = 0; l_i < nLevels; l_i++ ) {
- PETScMGSolver_Level* level = self->levels + l_i;
-
- level->nDownIts = 1;
- level->nUpIts = (l_i == 0) ? 0 : 1;
- level->nCycles = 1;
- level->R = NULL;
- level->P = NULL;
- level->A = NULL;
- level->workRes = NULL;
- level->workSol = NULL;
- level->workRHS = NULL;
- }
-}
-
-//void PETScMGSolver_SetRestriction( void* matrixSolver, unsigned levelInd, void* R ) {
-void PETScMGSolver_SetRestriction( void* matrixSolver, unsigned levelInd, void* _R ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
- PETScMGSolver_Level* level;
- Mat R = (Mat)_R;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
- assert( levelInd < self->nLevels && levelInd > 0 );
- //assert( !R || Stg_CheckType( R, PETScMatrix ) );
-
- level = self->levels + levelInd;
- if( level->R != R )
- self->opsChanged = True;
- //if( R )
- // Stg_Class_AddRef( R );
- //if( level->R )
- // Stg_Class_RemoveRef( level->R );
- if( level->R != PETSC_NULL )
- MatDestroy( level->R );
- level->R = R;
-}
-
-void PETScMGSolver_SetProlongation( void* matrixSolver, unsigned levelInd, void* _P ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
- PETScMGSolver_Level* level;
- Mat P = (Mat)_P;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
- assert( levelInd < self->nLevels && levelInd > 0 );
- //assert( !P || Stg_CheckType( P, PETScMatrix ) );
-
- level = self->levels + levelInd;
- if( level->P != P )
- self->opsChanged = True;
- //if( P )
- // Stg_Class_AddRef( P );
- //if( level->P )
- // Stg_Class_RemoveRef( level->P );
- if( level->P != PETSC_NULL ) {
- MatDestroy( level->P );
- if(level->P == level->R)
- level->R = PETSC_NULL;
- }
- level->P = P;
-}
-
-void PETScMGSolver_SetLevelDownIterations( void* matrixSolver, unsigned level, unsigned nIts ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
- assert( level < self->nLevels );
-
- self->levels[level].nDownIts = nIts;
- self->solversChanged = True;
-}
-
-void PETScMGSolver_SetLevelUpIterations( void* matrixSolver, unsigned level, unsigned nIts ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
- assert( level < self->nLevels );
- assert( level > 0 );
-
- self->levels[level].nUpIts = nIts;
- self->solversChanged = True;
-}
-
-void PETScMGSolver_SetLevelCycles( void* matrixSolver, unsigned level, unsigned nCycles ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
- assert( level < self->nLevels );
- assert( level > 0 );
-
- self->levels[level].nCycles = nCycles;
- self->solversChanged = True;
-}
-
-void PETScMGSolver_SetAllDownIterations( void* matrixSolver, unsigned nIts ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- for( l_i = 1; l_i < self->nLevels; l_i++ )
- PETScMGSolver_SetLevelDownIterations( self, l_i, nIts );
-}
-
-void PETScMGSolver_SetAllUpIterations( void* matrixSolver, unsigned nIts ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- for( l_i = 1; l_i < self->nLevels; l_i++ )
- PETScMGSolver_SetLevelUpIterations( self, l_i, nIts );
-}
-
-unsigned PETScMGSolver_GetNumLevels( void* matrixSolver ) {
- PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- return self->nLevels;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-void PETScMGSolver_UpdateOps( PETScMGSolver* self ) {
- PC pc;
- Mat *pOps, *rOps;
- PetscErrorCode ec;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- ec = KSPGetPC( self->mgData->ksp, &pc );
- CheckPETScError( ec );
-
- MGOpGenerator_Generate( self->opGen, (Mat**)&pOps, (Mat**)&rOps );
-
- for( l_i = 1; l_i < self->nLevels; l_i++ ) {
- //assert( Stg_CheckType( pOps[l_i], PETScMatrix ) );
- //assert( Stg_CheckType( rOps[l_i], PETScMatrix ) );
-
- PETScMGSolver_SetProlongation( self, l_i, pOps[l_i] );
-#if( ((PETSC_VERSION_MAJOR==2) && (PETSC_VERSION_MINOR==3) && (PETSC_VERSION_SUBMINOR==3)) || (PETSC_VERSION_MAJOR==3) )
- ec = PCMGSetInterpolation( pc, l_i, pOps[l_i] );
-#else
- ec = PCMGSetInterpolate( pc, l_i, pOps[l_i] );
-#endif
- CheckPETScError( ec );
-
- PETScMGSolver_SetRestriction( self, l_i, rOps[l_i] );
- ec = PCMGSetRestriction( pc, l_i, rOps[l_i] );
- CheckPETScError( ec );
- }
-
- FreeArray( pOps );
- FreeArray( rOps );
-}
-
-void PETScMGSolver_UpdateMatrices( PETScMGSolver* self ) {
- Stream* stream;
- PETScMGSolver_Level* level;
- PC pc;
- KSP levelKSP;
- PetscErrorCode ec;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
- //assert( self->matrix && Stg_CheckType( self->matrix, PETScMatrix ) );
-
- stream = Journal_Register( InfoStream_Type, (Name)"general" ); assert( stream );
- Journal_Printf( stream, "Updating MG matrices ...\n" );
-
- ec = KSPGetPC( self->mgData->ksp, &pc );
- CheckPETScError( ec );
-
- for( l_i = self->nLevels - 1; l_i < self->nLevels; l_i-- ) {
- level = self->levels + l_i;
-
- if( l_i == self->nLevels - 1 )
- //level->A = (PETScMatrix*)self->matrix;
- level->A = self->mgData->matrix;
- else {
- if( level->A )
- MatPtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, MAT_REUSE_MATRIX, 1.0, &level->A );
- else
- MatPtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, MAT_INITIAL_MATRIX, 1.0, &level->A );
- //Matrix_PtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, (void**)&level->A );
-
-/*
- if( self->levels[l_i + 1].P )
- MatPtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, MAT_REUSE_MATRIX, 1.0, &level->A );
- else
- MatPtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, MAT_INITIAL_MATRIX, 1.0, &level->A );
-*/
- }
-
- ec = PCMGGetSmootherDown( pc, l_i, &levelKSP );
- CheckPETScError( ec );
- //ec = KSPSetOperators( levelKSP, level->A->petscMat, level->A->petscMat, DIFFERENT_NONZERO_PATTERN );
- ec = KSPSetOperators( levelKSP, level->A, level->A, DIFFERENT_NONZERO_PATTERN );
- CheckPETScError( ec );
- //ec = PCMGSetResidual( pc, l_i, PCMGDefaultResidual, level->A->petscMat );
- ec = PCMGSetResidual( pc, l_i, PCMGDefaultResidual, level->A );
- CheckPETScError( ec );
-
- if( l_i > 0 ) {
- PCMGGetSmootherUp( pc, l_i, &levelKSP );
- //ec = KSPSetOperators( levelKSP, level->A->petscMat, level->A->petscMat, DIFFERENT_NONZERO_PATTERN );
- ec = KSPSetOperators( levelKSP, level->A, level->A, DIFFERENT_NONZERO_PATTERN );
- CheckPETScError( ec );
- }
- }
-
- Journal_Printf( stream, "done\n" );
-}
-
-void PETScMGSolver_UpdateWorkVectors( PETScMGSolver* self ) {
- PETScMGSolver_Level* level;
- PC pc;
- //unsigned size;
- PetscInt size, vecSize;
- PetscErrorCode ec;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- if( self->nLevels == 1 )
- return;
-
- ec = KSPGetPC( self->mgData->ksp, &pc );
- CheckPETScError( ec );
-
- for( l_i = 0; l_i < self->nLevels; l_i++ ) {
- level = self->levels + l_i;
-
- //Matrix_GetLocalSize( level->A, &size, NULL );
- MatGetLocalSize( level->A, &size, PETSC_NULL );
-
- if( level->workRes )
- VecGetLocalSize( level->workRes, &vecSize );
-
- if( l_i > 0 && (!level->workRes || /*Vector_GetLocalSize( level->workRes )*/vecSize != size) ) {
- if( level->workRes )
- VecDestroy( level->workRes );
- // FreeObject( level->workRes );
- //Vector_Duplicate( self->curSolution, (void**)&level->workRes );
- //Vector_SetLocalSize( level->workRes, size );
- //ec = PCMGSetR( pc, l_i, level->workRes->petscVec );
- VecCreate( MPI_COMM_WORLD, &level->workRes );
- VecSetSizes( level->workRes, size, PETSC_DECIDE );
- VecSetFromOptions( level->workRes );
-#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
- VecSetOption( level->workRes, VEC_IGNORE_NEGATIVE_INDICES );
-#elif( PETSC_VERSION_MAJOR >= 3 )
- VecSetOption( level->workRes, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
-#endif
- ec = PCMGSetR( pc, l_i, level->workRes );
- CheckPETScError( ec );
- }
-
- if( l_i < self->nLevels - 1 ) {
- if( level->workSol )
- VecGetLocalSize( level->workSol, &vecSize );
- if( !level->workSol || /*Vector_GetLocalSize( level->workSol )*/vecSize != size ) {
- if( level->workSol )
- VecDestroy( level->workSol );
- // FreeObject( level->workSol );
- //Vector_Duplicate( self->curSolution, (void**)&level->workSol );
- //Vector_SetLocalSize( level->workSol, size );
- //ec = PCMGSetX( pc, l_i, level->workSol->petscVec );
- VecCreate( MPI_COMM_WORLD, &level->workSol );
- VecSetSizes( level->workSol, size, PETSC_DECIDE );
- VecSetFromOptions( level->workSol );
-#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
- VecSetOption( level->workSol, VEC_IGNORE_NEGATIVE_INDICES );
-#elif( PETSC_VERSION_MAJOR >= 3 )
- VecSetOption( level->workSol, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
-#endif
- ec = PCMGSetX( pc, l_i, level->workSol );
- CheckPETScError( ec );
- }
-
- if( level->workRHS )
- VecGetLocalSize( level->workRHS, &vecSize );
- if( !level->workRHS || /*Vector_GetLocalSize( level->workRHS )*/vecSize != size ) {
- if( level->workRHS )
- VecDestroy( level->workRHS );
- // FreeObject( level->workRHS );
- //Vector_Duplicate( self->curSolution, (void**)&level->workRHS );
- //Vector_SetLocalSize( level->workRHS, size );
- //ec = PCMGSetRhs( pc, l_i, level->workRHS->petscVec );
- VecCreate( MPI_COMM_WORLD, &level->workRHS );
- VecSetSizes( level->workRHS, size, PETSC_DECIDE );
- VecSetFromOptions( level->workRHS );
-#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
- VecSetOption( level->workRHS, VEC_IGNORE_NEGATIVE_INDICES );
-#elif( PETSC_VERSION_MAJOR >= 3 )
- VecSetOption( level->workRHS, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
-#endif
- ec = PCMGSetRhs( pc, l_i, level->workRHS );
- CheckPETScError( ec );
- }
- }
- }
-}
-
-void PETScMGSolver_UpdateSolvers( PETScMGSolver* self ) {
- PETScMGSolver_Level* level;
- PC pc;
- KSP levelKSP;
- PC levelPC;
- PetscErrorCode ec;
- unsigned l_i;
- PetscTruth smoothers_differ, flag;
- PetscMPIInt size;
- MPI_Comm comm;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- ec = KSPGetPC( self->mgData->ksp, &pc );
- CheckPETScError( ec );
-
- ec = PCMGSetLevels( pc, self->nLevels, PETSC_NULL );
- CheckPETScError( ec );
- ec = PCMGSetType( pc, PC_MG_MULTIPLICATIVE );
- CheckPETScError( ec );
-
- ec=PetscOptionsGetTruth( PETSC_NULL, "-pc_mg_different_smoothers", &smoothers_differ, &flag ); CheckPETScError(ec);
-
- ec=PetscObjectGetComm( (PetscObject)pc, &comm ); CheckPETScError(ec);
- MPI_Comm_size( comm, &size );
-
- for( l_i = 1; l_i < self->nLevels; l_i++ ) {
- level = self->levels + l_i;
-
- printf("Configuring MG level %d \n", l_i );
- ec = PCMGGetSmootherDown( pc, l_i, &levelKSP );
- CheckPETScError( ec );
- if(smoothers_differ==PETSC_TRUE) { ec=KSPAppendOptionsPrefix( levelKSP, "down_" ); CheckPETScError(ec); }
- ec = KSPSetType( levelKSP, KSPRICHARDSON ); CheckPETScError( ec );
- ec = KSPGetPC( levelKSP, &levelPC ); CheckPETScError( ec );
-
- if(size==1) {
- ec = PCSetType( levelPC, PCSOR ); CheckPETScError( ec );
- }
- /* This does not work - bug with the order the operators are created I guess */
- /* For parallel jobs you best bet is to use the command line args and let petsc work it out */
- /*
- else {
- KSP *sub_ksp;
- PetscInt k, n_local, first_local;
- PC sub_pc;
-
- PCSetType( levelPC, PCBJACOBI );
- KSPSetUp( levelKSP );
- PCBJacobiGetSubKSP( levelPC, &n_local,&first_local,&sub_ksp);
- for(k=0;k<n_local;k++ ) {
- KSPSetType( sub_ksp[k], KSPFGMRES );
- KSPGetPC( sub_ksp[k], &sub_pc );
- PCSetType( sub_pc, PCSOR );
- }
- }
- */
- ec = KSPSetTolerances( levelKSP, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, level->nDownIts ); CheckPETScError( ec );
- if( l_i == self->nLevels - 1 ) {
- ec = KSPSetInitialGuessNonzero( levelKSP, PETSC_TRUE ); CheckPETScError( ec );
- }
- else { ec = KSPSetInitialGuessNonzero( levelKSP, PETSC_FALSE ); CheckPETScError( ec ); }
-
- ec = PCMGGetSmootherUp( pc, l_i, &levelKSP ); CheckPETScError( ec );
- if(smoothers_differ==PETSC_TRUE) { ec=KSPAppendOptionsPrefix( levelKSP, "up_" ); CheckPETScError(ec); }
- ec = KSPSetType( levelKSP, KSPRICHARDSON ); CheckPETScError( ec );
- ec = KSPGetPC( levelKSP, &levelPC ); CheckPETScError( ec );
- if(size==1) {
- ec = PCSetType( levelPC, PCSOR ); CheckPETScError( ec );
- }
- ec = KSPSetTolerances( levelKSP, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, level->nUpIts ); CheckPETScError( ec );
- ec = KSPSetInitialGuessNonzero( levelKSP, PETSC_TRUE ); CheckPETScError( ec );
-
- ec = PCMGSetCyclesOnLevel( pc, l_i, level->nCycles ); CheckPETScError( ec );
- }
-}
-
-void PETScMGSolver_Destruct( PETScMGSolver* self ) {
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- PETScMGSolver_DestructLevels( self );
- /*KillObject( self->opGen );*/
-}
-
-void PETScMGSolver_DestructLevels( PETScMGSolver* self ) {
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, PETScMGSolver ) );
-
- for( l_i = 0; l_i < self->nLevels; l_i++ ) {
- PETScMGSolver_Level* level = self->levels + l_i;
-
- /*
- if( level->R )
- Stg_Class_RemoveRef( level->R );
- if( level->P )
- Stg_Class_RemoveRef( level->P );
- if( level->A )
- Stg_Class_RemoveRef( level->A );
- */
- if( level->R != PETSC_NULL && level->R != level->P )
- MatDestroy( level->R );
- if( level->P != PETSC_NULL ) MatDestroy( level->P );
-/*
- if( level->A != PETSC_NULL ) MatDestroy( level->A );
-*/
-
- //FreeObject( level->workRes );
- //FreeObject( level->workSol );
- //FreeObject( level->workRHS );
- if( level->workRes )
- VecDestroy( level->workRes );
- if( level->workSol )
- VecDestroy( level->workSol );
- if( level->workRHS )
- VecDestroy( level->workRHS );
- }
-
- KillArray( self->levels );
- self->nLevels = 0;
- self->solversChanged = True;
- self->opsChanged = True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/PETScMGSolver.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/PETScMGSolver.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,764 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: PETScMGSolver.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+
+#include "SystemSetup.h"
+
+
+/* Textual name of this class */
+const Type PETScMGSolver_Type = "PETScMGSolver";
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+PETScMGSolver* PETScMGSolver_New( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(PETScMGSolver);
+ Type type = PETScMGSolver_Type;
+ Stg_Class_DeleteFunction* _delete = _PETScMGSolver_Delete;
+ Stg_Class_PrintFunction* _print = _PETScMGSolver_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))_PETScMGSolver_New;
+ Stg_Component_ConstructFunction* _construct = _PETScMGSolver_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _PETScMGSolver_Build;
+ Stg_Component_InitialiseFunction* _initialise = _PETScMGSolver_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _PETScMGSolver_Execute;
+ Stg_Component_DestroyFunction* _destroy = _PETScMGSolver_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ MGSolver_SetCommFunc* setCommFunc = PETScMGSolver_SetComm;
+ MGSolver_SetMatrixFunc* setMatrixFunc = NULL;
+ MGSolver_SetMaxIterationsFunc* setMaxIterationsFunc = NULL;
+ MGSolver_SetRelativeToleranceFunc* setRelativeToleranceFunc = NULL;
+ MGSolver_SetAbsoluteToleranceFunc* setAbsoluteToleranceFunc = NULL;
+ MGSolver_SetUseInitialSolutionFunc* setUseInitialSolutionFunc = NULL;
+ MGSolver_SolveFunc* solveFunc = NULL;
+ MGSolver_SetupFunc* setupFunc = PETScMGSolver_Setup;
+ MGSolver_GetSolveStatusFunc* getSolveStatusFunc = NULL;
+ MGSolver_GetIterationsFunc* getIterationsFunc = NULL;
+ MGSolver_GetMaxIterationsFunc* getMaxIterationsFunc = NULL;
+ MGSolver_GetResidualNormFunc* getResidualNormFunc = NULL;
+
+ return _PETScMGSolver_New( PETSCMGSOLVER_PASSARGS );
+}
+
+PETScMGSolver* _PETScMGSolver_New( PETSCMGSOLVER_DEFARGS ) {
+ PETScMGSolver* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(PETScMGSolver) );
+ //self = (PETScMGSolver*)_PETScMatrixSolver_New( STG_COMPONENT_PASSARGS );
+ self = (PETScMGSolver*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ /* Virtual info */
+ /* from the depreciated MatrixSolver_New func */
+ self->setCommFunc = setCommFunc;
+ self->setMatrixFunc = setMatrixFunc;
+ self->setMaxIterationsFunc = setMaxIterationsFunc;
+ self->setRelativeToleranceFunc = setRelativeToleranceFunc;
+ self->setAbsoluteToleranceFunc = setAbsoluteToleranceFunc;
+ self->setUseInitialSolutionFunc = setUseInitialSolutionFunc;
+
+ self->solveFunc = solveFunc;
+ self->setupFunc = setupFunc;
+
+ self->getSolveStatusFunc = getSolveStatusFunc;
+ self->getIterationsFunc = getIterationsFunc;
+ self->getMaxIterationsFunc = getMaxIterationsFunc;
+ self->getResidualNormFunc = getResidualNormFunc;
+
+ /* PETScMGSolver info */
+ _PETScMGSolver_Init( self );
+
+ return self;
+}
+
+void _PETScMGSolver_Init( PETScMGSolver* self ) {
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ self->mgData = (MGSolver_PETScData*)malloc( sizeof( MGSolver_PETScData ) );
+
+ /* from the depreciated MatrixSolver_Init func */
+ self->mgData->comm = MPI_COMM_WORLD;
+ KSPCreate( MPI_COMM_WORLD, &self->mgData->ksp );
+ self->mgData->matrix = PETSC_NULL;
+ self->mgData->inversion = PETSC_NULL;
+ self->mgData->residual = PETSC_NULL;
+ self->mgData->expiredResidual = True;
+ self->mgData->matrixChanged = True;
+ self->mgData->optionsReady = False;
+
+ self->mgData->curRHS = PETSC_NULL;
+ self->mgData->curSolution = PETSC_NULL;
+ /* end of MatrixSolver_Init stuff */
+
+ self->nLevels = 0;
+ self->levels = NULL;
+ self->opGen = NULL;
+ self->solversChanged = True;
+ self->opsChanged = True;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _PETScMGSolver_Delete( void* matrixSolver ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ PETScMGSolver_Destruct( self );
+
+ /* Delete the parent. */
+ //_PETScMatrixSolver_Delete( self );
+ _Stg_Component_Delete( self );
+}
+
+void _PETScMGSolver_Print( void* matrixSolver, Stream* stream ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+
+ /* Set the Journal for printing informations */
+ Stream* matrixSolverStream;
+ matrixSolverStream = Journal_Register( InfoStream_Type, (Name)"PETScMGSolverStream" );
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ /* Print parent */
+ Journal_Printf( stream, "PETScMGSolver (ptr): (%p)\n", self );
+ //_PETScMatrixSolver_Print( self, stream );
+ _Stg_Component_Print( self, stream );
+}
+
+void _PETScMGSolver_AssignFromXML( void* matrixSolver, Stg_ComponentFactory* cf, void* data ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+ Bool pure;
+ unsigned nLevels;
+ unsigned nCycles;
+ unsigned nDownIts, nUpIts;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+ assert( cf );
+
+ //_PETScMatrixSolver_AssignFromXML( self, cf, data );
+
+ pure = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"pure", False );
+ nLevels = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"levels", 1 );
+ nCycles = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"cycles", 1 );
+ nDownIts = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"downIterations", 1 );
+ nUpIts = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"upIterations", 1 );
+
+ self->pure = pure;
+ PETScMGSolver_SetLevels( self, nLevels );
+ PETScMGSolver_SetLevelCycles( self, nLevels - 1, nCycles );
+ PETScMGSolver_SetAllDownIterations( self, nDownIts );
+ PETScMGSolver_SetAllUpIterations( self, nUpIts );
+
+ self->opGen = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"opGenerator", MGOpGenerator, True, data );
+ MGOpGenerator_SetMatrixSolver( self->opGen, self );
+ MGOpGenerator_SetNumLevels( self->opGen, nLevels );
+}
+
+void _PETScMGSolver_Build( void* matrixSolver, void* data ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ if( self->opGen )
+ Stg_Component_Build( self->opGen, data, False );
+}
+
+void _PETScMGSolver_Initialise( void* matrixSolver, void* data ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ if( self->opGen )
+ Stg_Component_Initialise( self->opGen, data, False );
+}
+
+void _PETScMGSolver_Execute( void* matrixSolver, void* data ) {
+}
+
+void _PETScMGSolver_Destroy( void* matrixSolver, void* data ) {
+}
+
+void PETScMGSolver_SetComm( void* matrixSolver, MPI_Comm comm ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+ PC pc;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ //PETScMatrixSolver_SetComm( self, comm );
+ self->mgData->comm = comm;
+ if( self->mgData->ksp )
+ KSPDestroy( self->mgData->ksp );
+ KSPCreate( comm, &self->mgData->ksp );
+
+ if( self->pure )
+ //PETScMatrixSolver_SetKSPType( self, PETScMatrixSolver_KSPType_Richardson );
+ KSPSetType( self->mgData->ksp, KSPRICHARDSON );
+ else
+ //PETScMatrixSolver_SetKSPType( self, PETScMatrixSolver_KSPType_FGMRes );
+ KSPSetType( self->mgData->ksp, KSPFGMRES );
+ //PETScMatrixSolver_SetPCType( self, PETScMatrixSolver_PCType_Multigrid );
+ KSPGetPC( self->mgData->ksp, &pc );
+ PCSetType( pc, PCMG );
+}
+
+void PETScMGSolver_Setup( void* matrixSolver, void* rhs, void* solution ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+ Bool rebuildOps;
+ double wallTime;
+ PetscErrorCode ec;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ wallTime = MPI_Wtime();
+
+ //_MatrixSolver_Setup( self, rhs, solution );
+ self->mgData->curRHS = (struct _p_Vec*)rhs;
+ self->mgData->curSolution = (struct _p_Vec*)solution;
+ self->mgData->expiredResidual = True;
+
+ PetscPrintf( PETSC_COMM_WORLD, "_MatrixSolver_Setup %g\n", MPI_Wtime() - wallTime);
+
+
+ if( self->opGen )
+ rebuildOps = MGOpGenerator_HasExpired( self->opGen );
+ else
+ rebuildOps = False;
+ if( !rebuildOps ) {
+ unsigned l_i;
+
+ for( l_i = 1; l_i < self->nLevels; l_i++ ) {
+ if( !self->levels[l_i].R || !self->levels[l_i].P ) {
+ rebuildOps = True;
+ break;
+ }
+ }
+ }
+
+ if( self->solversChanged || rebuildOps || self->opsChanged ) {
+ wallTime = MPI_Wtime();
+ PETScMGSolver_UpdateSolvers( self );
+ stg_profile_Func( "PETScMGSolver_UpdateSolvers", MPI_Wtime() - wallTime);
+ PetscPrintf( PETSC_COMM_WORLD, "PETScMGSolver_UpdateSolvers %g\n", MPI_Wtime() - wallTime);
+ }
+ if( rebuildOps ) {
+ wallTime = MPI_Wtime();
+ PETScMGSolver_UpdateOps( self );
+ stg_profile_Func( "PETScMGSolver_UpdateOps", MPI_Wtime() - wallTime);
+ PetscPrintf( PETSC_COMM_WORLD, "PETScMGSolver_UpdateOps %g\n", MPI_Wtime() - wallTime);
+
+ }
+ //if( self->matrixChanged || self->solversChanged || rebuildOps || self->opsChanged ) {
+ if( self->mgData->matrixChanged || self->solversChanged || rebuildOps || self->opsChanged ) {
+ wallTime = MPI_Wtime();
+ PETScMGSolver_UpdateMatrices( self );
+ PETScMGSolver_UpdateWorkVectors( self );
+ stg_profile_Func( "PETScMGSolver_UpdateMats-WorkVecs", MPI_Wtime() - wallTime);
+ PetscPrintf( PETSC_COMM_WORLD, "PETScMGSolver_UpdateMats-WorkVecs %g\n", MPI_Wtime() - wallTime);
+ }
+
+ self->solversChanged = False;
+ //self->matrixChanged = False;
+ self->mgData->matrixChanged = False;
+ self->opsChanged = False;
+
+ //if( !self->optionsReady ) {
+ if( !self->mgData->optionsReady ) {
+ KSPSetOptionsPrefix( self->mgData->ksp, "A11_" );
+ ec = KSPSetFromOptions( self->mgData->ksp );
+ CheckPETScError( ec );
+ //self->optionsReady = True;
+ self->mgData->optionsReady = True;
+ }
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+void PETScMGSolver_SetLevels( void* matrixSolver, unsigned nLevels ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ PETScMGSolver_DestructLevels( self );
+
+ self->nLevels = nLevels;
+ self->levels = AllocArray( PETScMGSolver_Level, nLevels );
+ for( l_i = 0; l_i < nLevels; l_i++ ) {
+ PETScMGSolver_Level* level = self->levels + l_i;
+
+ level->nDownIts = 1;
+ level->nUpIts = (l_i == 0) ? 0 : 1;
+ level->nCycles = 1;
+ level->R = NULL;
+ level->P = NULL;
+ level->A = NULL;
+ level->workRes = NULL;
+ level->workSol = NULL;
+ level->workRHS = NULL;
+ }
+}
+
+//void PETScMGSolver_SetRestriction( void* matrixSolver, unsigned levelInd, void* R ) {
+void PETScMGSolver_SetRestriction( void* matrixSolver, unsigned levelInd, void* _R ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+ PETScMGSolver_Level* level;
+ Mat R = (Mat)_R;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+ assert( levelInd < self->nLevels && levelInd > 0 );
+ //assert( !R || Stg_CheckType( R, PETScMatrix ) );
+
+ level = self->levels + levelInd;
+ if( level->R != R )
+ self->opsChanged = True;
+ //if( R )
+ // Stg_Class_AddRef( R );
+ //if( level->R )
+ // Stg_Class_RemoveRef( level->R );
+ if( level->R != PETSC_NULL )
+ MatDestroy( level->R );
+ level->R = R;
+}
+
+void PETScMGSolver_SetProlongation( void* matrixSolver, unsigned levelInd, void* _P ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+ PETScMGSolver_Level* level;
+ Mat P = (Mat)_P;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+ assert( levelInd < self->nLevels && levelInd > 0 );
+ //assert( !P || Stg_CheckType( P, PETScMatrix ) );
+
+ level = self->levels + levelInd;
+ if( level->P != P )
+ self->opsChanged = True;
+ //if( P )
+ // Stg_Class_AddRef( P );
+ //if( level->P )
+ // Stg_Class_RemoveRef( level->P );
+ if( level->P != PETSC_NULL ) {
+ MatDestroy( level->P );
+ if(level->P == level->R)
+ level->R = PETSC_NULL;
+ }
+ level->P = P;
+}
+
+void PETScMGSolver_SetLevelDownIterations( void* matrixSolver, unsigned level, unsigned nIts ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+ assert( level < self->nLevels );
+
+ self->levels[level].nDownIts = nIts;
+ self->solversChanged = True;
+}
+
+void PETScMGSolver_SetLevelUpIterations( void* matrixSolver, unsigned level, unsigned nIts ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+ assert( level < self->nLevels );
+ assert( level > 0 );
+
+ self->levels[level].nUpIts = nIts;
+ self->solversChanged = True;
+}
+
+void PETScMGSolver_SetLevelCycles( void* matrixSolver, unsigned level, unsigned nCycles ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+ assert( level < self->nLevels );
+ assert( level > 0 );
+
+ self->levels[level].nCycles = nCycles;
+ self->solversChanged = True;
+}
+
+void PETScMGSolver_SetAllDownIterations( void* matrixSolver, unsigned nIts ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ for( l_i = 1; l_i < self->nLevels; l_i++ )
+ PETScMGSolver_SetLevelDownIterations( self, l_i, nIts );
+}
+
+void PETScMGSolver_SetAllUpIterations( void* matrixSolver, unsigned nIts ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ for( l_i = 1; l_i < self->nLevels; l_i++ )
+ PETScMGSolver_SetLevelUpIterations( self, l_i, nIts );
+}
+
+unsigned PETScMGSolver_GetNumLevels( void* matrixSolver ) {
+ PETScMGSolver* self = (PETScMGSolver*)matrixSolver;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ return self->nLevels;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+void PETScMGSolver_UpdateOps( PETScMGSolver* self ) {
+ PC pc;
+ Mat *pOps, *rOps;
+ PetscErrorCode ec;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ ec = KSPGetPC( self->mgData->ksp, &pc );
+ CheckPETScError( ec );
+
+ MGOpGenerator_Generate( self->opGen, (Mat**)&pOps, (Mat**)&rOps );
+
+ for( l_i = 1; l_i < self->nLevels; l_i++ ) {
+ //assert( Stg_CheckType( pOps[l_i], PETScMatrix ) );
+ //assert( Stg_CheckType( rOps[l_i], PETScMatrix ) );
+
+ PETScMGSolver_SetProlongation( self, l_i, pOps[l_i] );
+#if( ((PETSC_VERSION_MAJOR==2) && (PETSC_VERSION_MINOR==3) && (PETSC_VERSION_SUBMINOR==3)) || (PETSC_VERSION_MAJOR==3) )
+ ec = PCMGSetInterpolation( pc, l_i, pOps[l_i] );
+#else
+ ec = PCMGSetInterpolate( pc, l_i, pOps[l_i] );
+#endif
+ CheckPETScError( ec );
+
+ PETScMGSolver_SetRestriction( self, l_i, rOps[l_i] );
+ ec = PCMGSetRestriction( pc, l_i, rOps[l_i] );
+ CheckPETScError( ec );
+ }
+
+ FreeArray( pOps );
+ FreeArray( rOps );
+}
+
+void PETScMGSolver_UpdateMatrices( PETScMGSolver* self ) {
+ Stream* stream;
+ PETScMGSolver_Level* level;
+ PC pc;
+ KSP levelKSP;
+ PetscErrorCode ec;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+ //assert( self->matrix && Stg_CheckType( self->matrix, PETScMatrix ) );
+
+ stream = Journal_Register( InfoStream_Type, (Name)"general" ); assert( stream );
+ Journal_Printf( stream, "Updating MG matrices ...\n" );
+
+ ec = KSPGetPC( self->mgData->ksp, &pc );
+ CheckPETScError( ec );
+
+ for( l_i = self->nLevels - 1; l_i < self->nLevels; l_i-- ) {
+ level = self->levels + l_i;
+
+ if( l_i == self->nLevels - 1 )
+ //level->A = (PETScMatrix*)self->matrix;
+ level->A = self->mgData->matrix;
+ else {
+ if( level->A )
+ MatPtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, MAT_REUSE_MATRIX, 1.0, &level->A );
+ else
+ MatPtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, MAT_INITIAL_MATRIX, 1.0, &level->A );
+ //Matrix_PtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, (void**)&level->A );
+
+/*
+ if( self->levels[l_i + 1].P )
+ MatPtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, MAT_REUSE_MATRIX, 1.0, &level->A );
+ else
+ MatPtAP( self->levels[l_i + 1].A, self->levels[l_i + 1].P, MAT_INITIAL_MATRIX, 1.0, &level->A );
+*/
+ }
+
+ ec = PCMGGetSmootherDown( pc, l_i, &levelKSP );
+ CheckPETScError( ec );
+ //ec = KSPSetOperators( levelKSP, level->A->petscMat, level->A->petscMat, DIFFERENT_NONZERO_PATTERN );
+ ec = KSPSetOperators( levelKSP, level->A, level->A, DIFFERENT_NONZERO_PATTERN );
+ CheckPETScError( ec );
+ //ec = PCMGSetResidual( pc, l_i, PCMGDefaultResidual, level->A->petscMat );
+ ec = PCMGSetResidual( pc, l_i, PCMGDefaultResidual, level->A );
+ CheckPETScError( ec );
+
+ if( l_i > 0 ) {
+ PCMGGetSmootherUp( pc, l_i, &levelKSP );
+ //ec = KSPSetOperators( levelKSP, level->A->petscMat, level->A->petscMat, DIFFERENT_NONZERO_PATTERN );
+ ec = KSPSetOperators( levelKSP, level->A, level->A, DIFFERENT_NONZERO_PATTERN );
+ CheckPETScError( ec );
+ }
+ }
+
+ Journal_Printf( stream, "done\n" );
+}
+
+void PETScMGSolver_UpdateWorkVectors( PETScMGSolver* self ) {
+ PETScMGSolver_Level* level;
+ PC pc;
+ //unsigned size;
+ PetscInt size, vecSize;
+ PetscErrorCode ec;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ if( self->nLevels == 1 )
+ return;
+
+ ec = KSPGetPC( self->mgData->ksp, &pc );
+ CheckPETScError( ec );
+
+ for( l_i = 0; l_i < self->nLevels; l_i++ ) {
+ level = self->levels + l_i;
+
+ //Matrix_GetLocalSize( level->A, &size, NULL );
+ MatGetLocalSize( level->A, &size, PETSC_NULL );
+
+ if( level->workRes )
+ VecGetLocalSize( level->workRes, &vecSize );
+
+ if( l_i > 0 && (!level->workRes || /*Vector_GetLocalSize( level->workRes )*/vecSize != size) ) {
+ if( level->workRes )
+ VecDestroy( level->workRes );
+ // FreeObject( level->workRes );
+ //Vector_Duplicate( self->curSolution, (void**)&level->workRes );
+ //Vector_SetLocalSize( level->workRes, size );
+ //ec = PCMGSetR( pc, l_i, level->workRes->petscVec );
+ VecCreate( MPI_COMM_WORLD, &level->workRes );
+ VecSetSizes( level->workRes, size, PETSC_DECIDE );
+ VecSetFromOptions( level->workRes );
+#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
+ VecSetOption( level->workRes, VEC_IGNORE_NEGATIVE_INDICES );
+#elif( PETSC_VERSION_MAJOR >= 3 )
+ VecSetOption( level->workRes, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
+#endif
+ ec = PCMGSetR( pc, l_i, level->workRes );
+ CheckPETScError( ec );
+ }
+
+ if( l_i < self->nLevels - 1 ) {
+ if( level->workSol )
+ VecGetLocalSize( level->workSol, &vecSize );
+ if( !level->workSol || /*Vector_GetLocalSize( level->workSol )*/vecSize != size ) {
+ if( level->workSol )
+ VecDestroy( level->workSol );
+ // FreeObject( level->workSol );
+ //Vector_Duplicate( self->curSolution, (void**)&level->workSol );
+ //Vector_SetLocalSize( level->workSol, size );
+ //ec = PCMGSetX( pc, l_i, level->workSol->petscVec );
+ VecCreate( MPI_COMM_WORLD, &level->workSol );
+ VecSetSizes( level->workSol, size, PETSC_DECIDE );
+ VecSetFromOptions( level->workSol );
+#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
+ VecSetOption( level->workSol, VEC_IGNORE_NEGATIVE_INDICES );
+#elif( PETSC_VERSION_MAJOR >= 3 )
+ VecSetOption( level->workSol, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
+#endif
+ ec = PCMGSetX( pc, l_i, level->workSol );
+ CheckPETScError( ec );
+ }
+
+ if( level->workRHS )
+ VecGetLocalSize( level->workRHS, &vecSize );
+ if( !level->workRHS || /*Vector_GetLocalSize( level->workRHS )*/vecSize != size ) {
+ if( level->workRHS )
+ VecDestroy( level->workRHS );
+ // FreeObject( level->workRHS );
+ //Vector_Duplicate( self->curSolution, (void**)&level->workRHS );
+ //Vector_SetLocalSize( level->workRHS, size );
+ //ec = PCMGSetRhs( pc, l_i, level->workRHS->petscVec );
+ VecCreate( MPI_COMM_WORLD, &level->workRHS );
+ VecSetSizes( level->workRHS, size, PETSC_DECIDE );
+ VecSetFromOptions( level->workRHS );
+#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
+ VecSetOption( level->workRHS, VEC_IGNORE_NEGATIVE_INDICES );
+#elif( PETSC_VERSION_MAJOR >= 3 )
+ VecSetOption( level->workRHS, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
+#endif
+ ec = PCMGSetRhs( pc, l_i, level->workRHS );
+ CheckPETScError( ec );
+ }
+ }
+ }
+}
+
+void PETScMGSolver_UpdateSolvers( PETScMGSolver* self ) {
+ PETScMGSolver_Level* level;
+ PC pc;
+ KSP levelKSP;
+ PC levelPC;
+ PetscErrorCode ec;
+ unsigned l_i;
+ PetscTruth smoothers_differ, flag;
+ PetscMPIInt size;
+ MPI_Comm comm;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ ec = KSPGetPC( self->mgData->ksp, &pc );
+ CheckPETScError( ec );
+
+ ec = PCMGSetLevels( pc, self->nLevels, PETSC_NULL );
+ CheckPETScError( ec );
+ ec = PCMGSetType( pc, PC_MG_MULTIPLICATIVE );
+ CheckPETScError( ec );
+
+ ec=PetscOptionsGetTruth( PETSC_NULL, "-pc_mg_different_smoothers", &smoothers_differ, &flag ); CheckPETScError(ec);
+
+ ec=PetscObjectGetComm( (PetscObject)pc, &comm ); CheckPETScError(ec);
+ MPI_Comm_size( comm, &size );
+
+ for( l_i = 1; l_i < self->nLevels; l_i++ ) {
+ level = self->levels + l_i;
+
+ printf("Configuring MG level %d \n", l_i );
+ ec = PCMGGetSmootherDown( pc, l_i, &levelKSP );
+ CheckPETScError( ec );
+ if(smoothers_differ==PETSC_TRUE) { ec=KSPAppendOptionsPrefix( levelKSP, "down_" ); CheckPETScError(ec); }
+ ec = KSPSetType( levelKSP, KSPRICHARDSON ); CheckPETScError( ec );
+ ec = KSPGetPC( levelKSP, &levelPC ); CheckPETScError( ec );
+
+ if(size==1) {
+ ec = PCSetType( levelPC, PCSOR ); CheckPETScError( ec );
+ }
+ /* This does not work - bug with the order the operators are created I guess */
+ /* For parallel jobs you best bet is to use the command line args and let petsc work it out */
+ /*
+ else {
+ KSP *sub_ksp;
+ PetscInt k, n_local, first_local;
+ PC sub_pc;
+
+ PCSetType( levelPC, PCBJACOBI );
+ KSPSetUp( levelKSP );
+ PCBJacobiGetSubKSP( levelPC, &n_local,&first_local,&sub_ksp);
+ for(k=0;k<n_local;k++ ) {
+ KSPSetType( sub_ksp[k], KSPFGMRES );
+ KSPGetPC( sub_ksp[k], &sub_pc );
+ PCSetType( sub_pc, PCSOR );
+ }
+ }
+ */
+ ec = KSPSetTolerances( levelKSP, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, level->nDownIts ); CheckPETScError( ec );
+ if( l_i == self->nLevels - 1 ) {
+ ec = KSPSetInitialGuessNonzero( levelKSP, PETSC_TRUE ); CheckPETScError( ec );
+ }
+ else { ec = KSPSetInitialGuessNonzero( levelKSP, PETSC_FALSE ); CheckPETScError( ec ); }
+
+ ec = PCMGGetSmootherUp( pc, l_i, &levelKSP ); CheckPETScError( ec );
+ if(smoothers_differ==PETSC_TRUE) { ec=KSPAppendOptionsPrefix( levelKSP, "up_" ); CheckPETScError(ec); }
+ ec = KSPSetType( levelKSP, KSPRICHARDSON ); CheckPETScError( ec );
+ ec = KSPGetPC( levelKSP, &levelPC ); CheckPETScError( ec );
+ if(size==1) {
+ ec = PCSetType( levelPC, PCSOR ); CheckPETScError( ec );
+ }
+ ec = KSPSetTolerances( levelKSP, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT, level->nUpIts ); CheckPETScError( ec );
+ ec = KSPSetInitialGuessNonzero( levelKSP, PETSC_TRUE ); CheckPETScError( ec );
+
+ ec = PCMGSetCyclesOnLevel( pc, l_i, level->nCycles ); CheckPETScError( ec );
+ }
+}
+
+void PETScMGSolver_Destruct( PETScMGSolver* self ) {
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ PETScMGSolver_DestructLevels( self );
+ /*KillObject( self->opGen );*/
+}
+
+void PETScMGSolver_DestructLevels( PETScMGSolver* self ) {
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, PETScMGSolver ) );
+
+ for( l_i = 0; l_i < self->nLevels; l_i++ ) {
+ PETScMGSolver_Level* level = self->levels + l_i;
+
+ /*
+ if( level->R )
+ Stg_Class_RemoveRef( level->R );
+ if( level->P )
+ Stg_Class_RemoveRef( level->P );
+ if( level->A )
+ Stg_Class_RemoveRef( level->A );
+ */
+ if( level->R != PETSC_NULL && level->R != level->P )
+ MatDestroy( level->R );
+ if( level->P != PETSC_NULL ) MatDestroy( level->P );
+/*
+ if( level->A != PETSC_NULL ) MatDestroy( level->A );
+*/
+
+ //FreeObject( level->workRes );
+ //FreeObject( level->workSol );
+ //FreeObject( level->workRHS );
+ if( level->workRes )
+ VecDestroy( level->workRes );
+ if( level->workSol )
+ VecDestroy( level->workSol );
+ if( level->workRHS )
+ VecDestroy( level->workRHS );
+ }
+
+ KillArray( self->levels );
+ self->nLevels = 0;
+ self->solversChanged = True;
+ self->opsChanged = True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/SLE_Solver.c
--- a/SLE/SystemSetup/src/SLE_Solver.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,256 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: SLE_Solver.c 1125 2008-05-12 14:22:02Z DavidMay $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "FiniteElementContext.h"
-#include "SLE_Solver.h"
-
-#include <assert.h>
-
-/** Textual name of this class */
-const Type SLE_Solver_Type = "SLE_Solver";
-
-SLE_Solver* _SLE_Solver_New( SLE_SOLVER_DEFARGS )
-{
- SLE_Solver* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(SLE_Solver) );
- /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
- /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
- and so should be set to ZERO in any children of this class. */
- nameAllocationType = NON_GLOBAL;
-
- self = (SLE_Solver*) _Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- /* General info */
-
- /* Virtual info */
- self->_solverSetup = _solverSetup;
- self->_solve = _solve;
- self->_getResidual = _getResidual;
-
- self->_formResidual = NULL;
- self->_getRhs = NULL;
- self->_getSolution = NULL;
-
- return self;
-
-}
-
-void _SLE_Solver_Init( SLE_Solver* self, Bool useStatSolve, int statReps ) {
- self->isConstructed = True;
- self->extensionManager = ExtensionManager_New_OfExistingObject( self->name, self );
-
- self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type );
- self->info = Journal_MyStream( Info_Type, self );
- self->maxIterations = 0;
-
- self->previoustimestep = 0;
- self->currenttimestep = 0;
- self->nonlinearitsinitialtime = 0;
- self->nonlinearitsendtime = 0;
- self->totalnonlinearitstime = 0;
- self->totalnumnonlinearits = 0;
- self->avgtimenonlinearits = 0;
- self->inneritsinitialtime = 0;
- self->outeritsinitialtime = 0;
- self->inneritsendtime = 0;
- self->outeritsendtime = 0;
- self->totalinneritstime = 0;
- self->totalouteritstime = 0;
- self->totalnuminnerits = 0;
- self->totalnumouterits = 0;
- self->avgnuminnerits = 0;
- self->avgnumouterits = 0;
- self->avgtimeinnerits = 0;
- self->avgtimeouterits = 0;
-
- self->useStatSolve = useStatSolve;
- self->nStatReps = statReps;
-}
-
-void SLE_Solver_InitAll( void* sleSolver, Bool useStatSolve, int statReps ) {
- _SLE_Solver_Init( (SLE_Solver*) sleSolver, useStatSolve, statReps );
-}
-
-void* _SLE_Solver_Copy( const void* sleSolver, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- SLE_Solver* self = (SLE_Solver*)sleSolver;
- SLE_Solver* newSleSolver;
- PtrMap* map = ptrMap;
- Bool ownMap = False;
-
- if( !map ) {
- map = PtrMap_New( 10 );
- ownMap = True;
- }
-
- newSleSolver = (SLE_Solver*)_Stg_Component_Copy( self, dest, deep, nameExt, map );
-
- /* virtual functions */
- newSleSolver->_solverSetup = self->_solverSetup;
- newSleSolver->_solve = self->_solve;
- newSleSolver->maxIterations = self->maxIterations;
-
- newSleSolver->inneritsinitialtime = self->inneritsinitialtime;
- newSleSolver->outeritsinitialtime = self->outeritsinitialtime;
- newSleSolver->nonlinearitsinitialtime = self->nonlinearitsinitialtime;
- newSleSolver->inneritsendtime = self->inneritsendtime;
- newSleSolver->outeritsendtime = self->outeritsendtime;
- newSleSolver->nonlinearitsendtime = self->nonlinearitsendtime;
- newSleSolver->totalinneritstime = self->totalinneritstime;
- newSleSolver->totalouteritstime = self->totalouteritstime;
- newSleSolver->totalnonlinearitstime = self->totalnonlinearitstime;
- newSleSolver->totalnuminnerits = self->totalnuminnerits;
- newSleSolver->totalnumouterits = self->totalnumouterits;
- newSleSolver->totalnumnonlinearits = self->totalnumnonlinearits;
- newSleSolver->avgnuminnerits = self->avgnuminnerits;
- newSleSolver->avgnumouterits = self->avgnumouterits;
- newSleSolver->avgtimeinnerits = self->avgtimeinnerits;
- newSleSolver->avgtimeouterits = self->avgtimeouterits;
- newSleSolver->avgtimenonlinearits = self->avgtimenonlinearits;
- newSleSolver->currenttimestep = self->currenttimestep;
- newSleSolver->previoustimestep = self->previoustimestep;
-
- if( deep ) {
- if( (newSleSolver->debug = (Stream*)PtrMap_Find( map, self->debug )) == NULL ) {
- newSleSolver->debug = (Stream*)Stg_Class_Copy( self->debug, NULL, deep, nameExt, map );
- PtrMap_Append( map, self->debug, newSleSolver->debug );
- }
- if( (newSleSolver->extensionManager = (ExtensionManager*)PtrMap_Find( map, self->extensionManager )) == NULL ) {
- newSleSolver->extensionManager = (ExtensionManager*)Stg_Class_Copy( self->extensionManager, NULL, deep, nameExt, map );
- PtrMap_Append( map, self->extensionManager, newSleSolver->extensionManager );
- }
- }
- else {
- newSleSolver->debug = self->debug;
- newSleSolver->extensionManager = (ExtensionManager*)Stg_Class_Copy( self->extensionManager, NULL, deep, nameExt, map );
- }
-
- if( ownMap ) {
- Stg_Class_Delete( map );
- }
-
- return (void*)newSleSolver;
-}
-
-
-void _SLE_Solver_Delete( void* sleSolver ) {
- SLE_Solver* self = (SLE_Solver*)sleSolver;
-
- _Stg_Component_Delete( self );
-}
-
-void _SLE_Solver_Print( void* sleSolver, Stream* stream ) {
- SLE_Solver* self = (SLE_Solver*)sleSolver;
-
- _Stg_Component_Print( self, stream );
-
- Journal_PrintPointer( stream, self->extensionManager );
-
- Journal_PrintPointer( stream, self->_solverSetup );
- Journal_PrintPointer( stream, self->_solve );
- Journal_PrintPointer( stream, self->_getResidual );
-
- Journal_PrintPointer( stream, self->debug );
- Journal_PrintValue( stream, self->maxIterations );
-}
-
-void _SLE_Solver_Build( void* sleSolver, void* data ) {
- /* Do nothing by default */
-}
-
-void _SLE_Solver_AssignFromXML( void* sleSolver, Stg_ComponentFactory* cf, void* data ) {
- SLE_Solver* self = (SLE_Solver*)sleSolver;
- Bool useStatSolve;
- int nStatReps;
-
- self->context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", FiniteElementContext, False, data );
- if( !self->context )
- self->context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
-
- useStatSolve = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"statSolve", False );
- nStatReps = Stg_ComponentFactory_GetInt( cf, self->name, (Dictionary_Entry_Key)"statReps", 0 );
-
- _SLE_Solver_Init( self, useStatSolve, nStatReps );
-}
-
-void _SLE_Solver_Initialise( void* sleSolver, void* data ) {
-}
-
-
-void _SLE_Solver_Execute( void* sleSolver, void* data ) {
- SLE_Solver* self = (SLE_Solver*)sleSolver;
-
- Journal_DPrintf( self->debug, "In %s()\n", __func__ );
-
- Stream_IndentBranch( StgFEM_Debug );
- SLE_Solver_SolverSetup( self, data );
- SLE_Solver_Solve( self, data );
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-void _SLE_Solver_Destroy( void* sleSolver, void* data ) {
- SLE_Solver* self = (SLE_Solver*)sleSolver;
-
- Stg_Class_Delete( self->extensionManager );
-}
-
-void SLE_Solver_SolverSetup( void* sleSolver, void* sle ) {
- SLE_Solver* self = (SLE_Solver*)sleSolver;
-
- self->_solverSetup( self, sle );
-}
-
-
-void SLE_Solver_Solve( void* sleSolver, void* sle ) {
- SLE_Solver* self = (SLE_Solver*)sleSolver;
-
- self->_solve( self, sle );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/SLE_Solver.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/SLE_Solver.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,256 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: SLE_Solver.c 1125 2008-05-12 14:22:02Z DavidMay $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "FiniteElementContext.h"
+#include "SLE_Solver.h"
+
+#include <assert.h>
+
+/** Textual name of this class */
+const Type SLE_Solver_Type = "SLE_Solver";
+
+SLE_Solver* _SLE_Solver_New( SLE_SOLVER_DEFARGS )
+{
+ SLE_Solver* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(SLE_Solver) );
+ /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
+ /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
+ and so should be set to ZERO in any children of this class. */
+ nameAllocationType = NON_GLOBAL;
+
+ self = (SLE_Solver*) _Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ /* General info */
+
+ /* Virtual info */
+ self->_solverSetup = _solverSetup;
+ self->_solve = _solve;
+ self->_getResidual = _getResidual;
+
+ self->_formResidual = NULL;
+ self->_getRhs = NULL;
+ self->_getSolution = NULL;
+
+ return self;
+
+}
+
+void _SLE_Solver_Init( SLE_Solver* self, Bool useStatSolve, int statReps ) {
+ self->isConstructed = True;
+ self->extensionManager = ExtensionManager_New_OfExistingObject( self->name, self );
+
+ self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type );
+ self->info = Journal_MyStream( Info_Type, self );
+ self->maxIterations = 0;
+
+ self->previoustimestep = 0;
+ self->currenttimestep = 0;
+ self->nonlinearitsinitialtime = 0;
+ self->nonlinearitsendtime = 0;
+ self->totalnonlinearitstime = 0;
+ self->totalnumnonlinearits = 0;
+ self->avgtimenonlinearits = 0;
+ self->inneritsinitialtime = 0;
+ self->outeritsinitialtime = 0;
+ self->inneritsendtime = 0;
+ self->outeritsendtime = 0;
+ self->totalinneritstime = 0;
+ self->totalouteritstime = 0;
+ self->totalnuminnerits = 0;
+ self->totalnumouterits = 0;
+ self->avgnuminnerits = 0;
+ self->avgnumouterits = 0;
+ self->avgtimeinnerits = 0;
+ self->avgtimeouterits = 0;
+
+ self->useStatSolve = useStatSolve;
+ self->nStatReps = statReps;
+}
+
+void SLE_Solver_InitAll( void* sleSolver, Bool useStatSolve, int statReps ) {
+ _SLE_Solver_Init( (SLE_Solver*) sleSolver, useStatSolve, statReps );
+}
+
+void* _SLE_Solver_Copy( const void* sleSolver, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ SLE_Solver* self = (SLE_Solver*)sleSolver;
+ SLE_Solver* newSleSolver;
+ PtrMap* map = ptrMap;
+ Bool ownMap = False;
+
+ if( !map ) {
+ map = PtrMap_New( 10 );
+ ownMap = True;
+ }
+
+ newSleSolver = (SLE_Solver*)_Stg_Component_Copy( self, dest, deep, nameExt, map );
+
+ /* virtual functions */
+ newSleSolver->_solverSetup = self->_solverSetup;
+ newSleSolver->_solve = self->_solve;
+ newSleSolver->maxIterations = self->maxIterations;
+
+ newSleSolver->inneritsinitialtime = self->inneritsinitialtime;
+ newSleSolver->outeritsinitialtime = self->outeritsinitialtime;
+ newSleSolver->nonlinearitsinitialtime = self->nonlinearitsinitialtime;
+ newSleSolver->inneritsendtime = self->inneritsendtime;
+ newSleSolver->outeritsendtime = self->outeritsendtime;
+ newSleSolver->nonlinearitsendtime = self->nonlinearitsendtime;
+ newSleSolver->totalinneritstime = self->totalinneritstime;
+ newSleSolver->totalouteritstime = self->totalouteritstime;
+ newSleSolver->totalnonlinearitstime = self->totalnonlinearitstime;
+ newSleSolver->totalnuminnerits = self->totalnuminnerits;
+ newSleSolver->totalnumouterits = self->totalnumouterits;
+ newSleSolver->totalnumnonlinearits = self->totalnumnonlinearits;
+ newSleSolver->avgnuminnerits = self->avgnuminnerits;
+ newSleSolver->avgnumouterits = self->avgnumouterits;
+ newSleSolver->avgtimeinnerits = self->avgtimeinnerits;
+ newSleSolver->avgtimeouterits = self->avgtimeouterits;
+ newSleSolver->avgtimenonlinearits = self->avgtimenonlinearits;
+ newSleSolver->currenttimestep = self->currenttimestep;
+ newSleSolver->previoustimestep = self->previoustimestep;
+
+ if( deep ) {
+ if( (newSleSolver->debug = (Stream*)PtrMap_Find( map, self->debug )) == NULL ) {
+ newSleSolver->debug = (Stream*)Stg_Class_Copy( self->debug, NULL, deep, nameExt, map );
+ PtrMap_Append( map, self->debug, newSleSolver->debug );
+ }
+ if( (newSleSolver->extensionManager = (ExtensionManager*)PtrMap_Find( map, self->extensionManager )) == NULL ) {
+ newSleSolver->extensionManager = (ExtensionManager*)Stg_Class_Copy( self->extensionManager, NULL, deep, nameExt, map );
+ PtrMap_Append( map, self->extensionManager, newSleSolver->extensionManager );
+ }
+ }
+ else {
+ newSleSolver->debug = self->debug;
+ newSleSolver->extensionManager = (ExtensionManager*)Stg_Class_Copy( self->extensionManager, NULL, deep, nameExt, map );
+ }
+
+ if( ownMap ) {
+ Stg_Class_Delete( map );
+ }
+
+ return (void*)newSleSolver;
+}
+
+
+void _SLE_Solver_Delete( void* sleSolver ) {
+ SLE_Solver* self = (SLE_Solver*)sleSolver;
+
+ _Stg_Component_Delete( self );
+}
+
+void _SLE_Solver_Print( void* sleSolver, Stream* stream ) {
+ SLE_Solver* self = (SLE_Solver*)sleSolver;
+
+ _Stg_Component_Print( self, stream );
+
+ Journal_PrintPointer( stream, self->extensionManager );
+
+ Journal_PrintPointer( stream, self->_solverSetup );
+ Journal_PrintPointer( stream, self->_solve );
+ Journal_PrintPointer( stream, self->_getResidual );
+
+ Journal_PrintPointer( stream, self->debug );
+ Journal_PrintValue( stream, self->maxIterations );
+}
+
+void _SLE_Solver_Build( void* sleSolver, void* data ) {
+ /* Do nothing by default */
+}
+
+void _SLE_Solver_AssignFromXML( void* sleSolver, Stg_ComponentFactory* cf, void* data ) {
+ SLE_Solver* self = (SLE_Solver*)sleSolver;
+ Bool useStatSolve;
+ int nStatReps;
+
+ self->context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", FiniteElementContext, False, data );
+ if( !self->context )
+ self->context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
+
+ useStatSolve = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"statSolve", False );
+ nStatReps = Stg_ComponentFactory_GetInt( cf, self->name, (Dictionary_Entry_Key)"statReps", 0 );
+
+ _SLE_Solver_Init( self, useStatSolve, nStatReps );
+}
+
+void _SLE_Solver_Initialise( void* sleSolver, void* data ) {
+}
+
+
+void _SLE_Solver_Execute( void* sleSolver, void* data ) {
+ SLE_Solver* self = (SLE_Solver*)sleSolver;
+
+ Journal_DPrintf( self->debug, "In %s()\n", __func__ );
+
+ Stream_IndentBranch( StgFEM_Debug );
+ SLE_Solver_SolverSetup( self, data );
+ SLE_Solver_Solve( self, data );
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+void _SLE_Solver_Destroy( void* sleSolver, void* data ) {
+ SLE_Solver* self = (SLE_Solver*)sleSolver;
+
+ Stg_Class_Delete( self->extensionManager );
+}
+
+void SLE_Solver_SolverSetup( void* sleSolver, void* sle ) {
+ SLE_Solver* self = (SLE_Solver*)sleSolver;
+
+ self->_solverSetup( self, sle );
+}
+
+
+void SLE_Solver_Solve( void* sleSolver, void* sle ) {
+ SLE_Solver* self = (SLE_Solver*)sleSolver;
+
+ self->_solve( self, sle );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/SROpGenerator.c
--- a/SLE/SystemSetup/src/SROpGenerator.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1331 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: SROpGenerator.c 3584 2006-05-16 11:11:07Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-
-#include "SystemSetup.h"
-
-#include "petsc.h"
-#include "petscvec.h"
-#include "petscmat.h"
-
-/* Textual name of this class */
-const Type SROpGenerator_Type = "SROpGenerator";
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Constructors
-*/
-
-SROpGenerator* SROpGenerator_New( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(SROpGenerator);
- Type type = SROpGenerator_Type;
- Stg_Class_DeleteFunction* _delete = _SROpGenerator_Delete;
- Stg_Class_PrintFunction* _print = _SROpGenerator_Print;
- Stg_Class_CopyFunction* _copy = NULL;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))SROpGenerator_New;
- Stg_Component_ConstructFunction* _construct = _SROpGenerator_AssignFromXML;
- Stg_Component_BuildFunction* _build = _SROpGenerator_Build;
- Stg_Component_InitialiseFunction* _initialise = _SROpGenerator_Initialise;
- Stg_Component_ExecuteFunction* _execute = _SROpGenerator_Execute;
- Stg_Component_DestroyFunction* _destroy = _SROpGenerator_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
- MGOpGenerator_SetNumLevelsFunc* setNumLevelsFunc = _MGOpGenerator_SetNumLevels;
- MGOpGenerator_HasExpiredFunc* hasExpiredFunc = SROpGenerator_HasExpired;
- MGOpGenerator_GenerateFunc* generateFunc = SROpGenerator_Generate;
-
- return _SROpGenerator_New( SROPGENERATOR_PASSARGS );
-}
-
-SROpGenerator* _SROpGenerator_New( SROPGENERATOR_DEFARGS ) {
- SROpGenerator* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(SROpGenerator) );
- self = (SROpGenerator*)_MGOpGenerator_New( MGOPGENERATOR_PASSARGS );
-
- /* Virtual info */
-
- /* SROpGenerator info */
- _SROpGenerator_Init( self );
-
- return self;
-}
-
-void _SROpGenerator_Init( SROpGenerator* self ) {
- assert( self && Stg_CheckType( self, SROpGenerator ) );
-
- self->fineVar = NULL;
- self->fineEqNum = NULL;
- self->meshes = NULL;
- self->topMaps = NULL;
- self->eqNums = NULL;
- self->nLocalEqNums = NULL;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Virtual functions
-*/
-
-void _SROpGenerator_Delete( void* srOpGenerator ) {
- SROpGenerator* self = (SROpGenerator*)srOpGenerator;
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
-
- /* Delete the parent. */
- _MGOpGenerator_Delete( self );
-}
-
-void _SROpGenerator_Print( void* srOpGenerator, Stream* stream ) {
- SROpGenerator* self = (SROpGenerator*)srOpGenerator;
-
- /* Set the Journal for printing informations */
- Stream* srOpGeneratorStream;
- srOpGeneratorStream = Journal_Register( InfoStream_Type, (Name)"SROpGeneratorStream" );
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
-
- /* Print parent */
- Journal_Printf( stream, "SROpGenerator (ptr): (%p)\n", self );
- _MGOpGenerator_Print( self, stream );
-}
-
-void _SROpGenerator_AssignFromXML( void* srOpGenerator, Stg_ComponentFactory* cf, void* data ) {
- SROpGenerator* self = (SROpGenerator*)srOpGenerator;
- FeVariable* var;
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
-
- var = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"fineVariable", FeVariable, True, data );
- SROpGenerator_SetFineVariable( self, var );
-}
-
-void _SROpGenerator_Build( void* srOpGenerator, void* data ) {
-}
-
-void _SROpGenerator_Initialise( void* srOpGenerator, void* data ) {
-}
-
-void _SROpGenerator_Execute( void* srOpGenerator, void* data ) {
-}
-
-void _SROpGenerator_Destroy( void* srOpGenerator, void* data ) {
-}
-
-Bool SROpGenerator_HasExpired( void* srOpGenerator ) {
- SROpGenerator* self = (SROpGenerator*)srOpGenerator;
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
-
- return False;
-}
-
-//void SROpGenerator_Generate( void* srOpGenerator, Matrix*** pOps, Matrix*** rOps ) {
-void SROpGenerator_Generate( void* srOpGenerator, Mat** pOps, Mat** rOps ) {
- SROpGenerator* self = (SROpGenerator*)srOpGenerator;
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
- assert( pOps && rOps );
-
- //*pOps = AllocArray( Matrix*, self->nLevels );
- //*rOps = AllocArray( Matrix*, self->nLevels );
- //memset( *pOps, 0, self->nLevels * sizeof(Matrix*) );
- //memset( *rOps, 0, self->nLevels * sizeof(Matrix*) );
- *pOps = AllocArray( Mat, self->nLevels );
- *rOps = AllocArray( Mat, self->nLevels );
- memset( *pOps, 0, self->nLevels * sizeof(Mat) );
- memset( *rOps, 0, self->nLevels * sizeof(Mat) );
-
-/*
- self->fineEqNum = self->fineVar->eqNum;
- SROpGenerator_GenMeshes( self );
- SROpGenerator_GenOps( self, *pOps, *rOps );
- SROpGenerator_DestructMeshes( self );
-*/
- SROpGenerator_Simple( self, *pOps, *rOps );
-}
-
-
-/*--------------------------------------------------------------------------------------------------------------------------
-** Public Functions
-*/
-
-void SROpGenerator_SetFineVariable( void* srOpGenerator, void* _variable ) {
- SROpGenerator* self = (SROpGenerator*)srOpGenerator;
- FeVariable* variable = (FeVariable*)_variable;
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
- assert( !variable || Stg_CheckType( variable, FeVariable ) );
-
- SROpGenerator_DestructMeshes( self );
- self->fineVar = variable;
- self->fineEqNum = NULL;
-}
-
-
-/*----------------------------------------------------------------------------------------------------------------------------------
-** Private Functions
-*/
-
-void SROpGenerator_GenMeshes( SROpGenerator* self ) {
- unsigned nLevels;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
-
- nLevels = self->nLevels;
- self->meshes = AllocArray( Mesh*, nLevels );
- memset( self->meshes, 0, nLevels * sizeof(Mesh*) );
- self->topMaps = AllocArray( unsigned*, nLevels );
- memset( self->topMaps, 0, nLevels * sizeof(unsigned*) );
- self->eqNums = AllocArray( unsigned**, nLevels );
- memset( self->eqNums, 0, nLevels * sizeof(unsigned**) );
- self->nLocalEqNums = AllocArray( unsigned, nLevels );
- memset( self->nLocalEqNums, 0, nLevels * sizeof(unsigned) );
- self->eqNumBases = AllocArray( unsigned, nLevels );
- memset( self->eqNumBases, 0, nLevels * sizeof(unsigned) );
-
- self->meshes[nLevels - 1] = (Mesh*)self->fineEqNum->feMesh;
- self->eqNumBases[nLevels - 1] = self->fineEqNum->firstOwnedEqNum;
- for( l_i = nLevels - 2; l_i < nLevels; l_i-- ) {
- SROpGenerator_GenLevelMesh( self, l_i );
- SROpGenerator_GenLevelTopMap( self, l_i );
- SROpGenerator_GenLevelEqNums( self, l_i );
- }
-}
-
-void SROpGenerator_GenLevelMesh( SROpGenerator* self, unsigned level ) {
- Stream* errorStream = Journal_Register( ErrorStream_Type, (Name)"SROpGenerator::GenLevelMesh" );
- Mesh *fMesh, *cMesh;
- CartesianGenerator *fGen, *cGen;
- unsigned nDims;
- unsigned* cSize;
- double crdMin[3], crdMax[3];
- unsigned d_i;
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
- assert( self->meshes );
- assert( level < self->nLevels );
-
- fMesh = self->meshes[level + 1];
- nDims = Mesh_GetDimSize( fMesh );
- fGen = (CartesianGenerator*)fMesh->generator;
- Journal_Firewall( fGen && !strcmp( fGen->type, CartesianGenerator_Type ),
- errorStream,
- "\n" \
- "****************************************************************\n" \
- "* Error: Simple regular multigrid operator generation requires *\n" \
- "* a fine mesh that has been generated with a *\n" \
- "* cartesian generator. *\n" \
- "****************************************************************\n" \
- "\n" );
-
- cGen = CartesianGenerator_New( "", NULL );
- CartesianGenerator_SetDimSize( cGen, nDims );
- cSize = AllocArray( unsigned, nDims );
- for( d_i = 0; d_i < nDims; d_i++ )
- cSize[d_i] = fGen->elGrid->sizes[d_i] / 2;
- CartesianGenerator_SetTopologyParams( cGen, cSize, fGen->maxDecompDims, fGen->minDecomp, fGen->maxDecomp );
- Mesh_GetGlobalCoordRange( fMesh, crdMin, crdMax );
- CartesianGenerator_SetGeometryParams( cGen, crdMin, crdMax );
- CartesianGenerator_SetShadowDepth( cGen, 0 );
- FreeArray( cSize );
-
- cMesh = (Mesh*)FeMesh_New( "", NULL );
- Mesh_SetGenerator( cMesh, cGen );
- FeMesh_SetElementFamily( cMesh, ((FeMesh*)fMesh)->feElFamily );
- Stg_Component_Build( cMesh, NULL, False );
- Stg_Component_Initialise( cMesh, NULL, False );
- self->meshes[level] = cMesh;
-}
-
-void SROpGenerator_GenLevelTopMap( SROpGenerator* self, unsigned level ) {
- Stream* errorStream = Journal_Register( ErrorStream_Type, (Name)"SROpGenerator::GenLevelTopMap" );
- Mesh *fMesh, *cMesh;
- unsigned nDomainNodes;
- unsigned nLevels;
- unsigned nDims;
- unsigned nearest;
- double *cVert, *fVert;
- unsigned d_i, n_i;
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
- assert( self->meshes );
- assert( level < self->nLevels );
-
- fMesh = self->meshes[level + 1];
- cMesh = self->meshes[level];
- nDims = Mesh_GetDimSize( fMesh );
- nLevels = self->nLevels;
- nDomainNodes = Mesh_GetDomainSize( cMesh, MT_VERTEX );
- self->topMaps[level] = ReallocArray( self->topMaps[level], unsigned, nDomainNodes );
- for( n_i = 0; n_i < nDomainNodes; n_i++ ) {
- cVert = Mesh_GetVertex( cMesh, n_i );
- nearest = Mesh_NearestVertex( fMesh, cVert );
- fVert = Mesh_GetVertex( fMesh, nearest );
- for( d_i = 0; d_i < nDims; d_i++ ) {
- if( !Num_Approx( cVert[d_i], fVert[d_i] ) )
- break;
- }
-
- Journal_Firewall( d_i == nDims,
- errorStream,
- "\n" \
- "*****************************************************************\n" \
- "* Error: The finest grid could not be sub-sampled to all coarse *\n" \
- "* levels. This is due to the size of the finest grid. *\n" \
- "*****************************************************************\n" \
- "\n" );
-
- if( level < nLevels - 2 )
- self->topMaps[level][n_i] = self->topMaps[level + 1][nearest];
- else
- self->topMaps[level][n_i] = nearest;
- }
-}
-
-void SROpGenerator_GenLevelEqNums( SROpGenerator* self, unsigned level ) {
- Mesh* cMesh;
- unsigned* nNodalDofs;
- unsigned nDomainNodes, nLocalNodes;
- DofLayout* dofLayout;
- unsigned** dstArray;
- unsigned curEqNum;
- unsigned maxDofs;
- unsigned topNode;
- unsigned base, subTotal;
- MPI_Comm comm;
- unsigned nProcs, rank;
- MPI_Status status;
- unsigned* tuples;
- Sync* sync;
- unsigned n_i, dof_i;
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
- assert( self->meshes && self->topMaps && self->eqNums );
- assert( level < self->nLevels );
-
- cMesh = self->meshes[level];
- nDomainNodes = Mesh_GetDomainSize( cMesh, MT_VERTEX );
- nLocalNodes = Mesh_GetLocalSize( cMesh, MT_VERTEX );
- dofLayout = self->fineEqNum->dofLayout;
- comm = Comm_GetMPIComm( Mesh_GetCommTopology( cMesh, MT_VERTEX ) );
- MPI_Comm_size( comm, (int*)&nProcs );
- MPI_Comm_rank( comm, (int*)&rank );
-
- /* Allocate for destination array. */
- nNodalDofs = AllocArray( unsigned, nDomainNodes );
- for( n_i = 0; n_i < nDomainNodes; n_i++ )
- nNodalDofs[n_i] = dofLayout->dofCounts[self->topMaps[level][n_i]];
- dstArray = AllocComplex2D( unsigned, nDomainNodes, nNodalDofs );
-
- /* Build initial destination array and store max dofs. */
- curEqNum = 0;
- maxDofs = 0;
- for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
- if( nNodalDofs[n_i] > maxDofs )
- maxDofs = nNodalDofs[n_i];
-
- topNode = self->topMaps[level][n_i];
- for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
- if( self->fineEqNum->destinationArray[topNode][dof_i] != (unsigned)-1 )
- dstArray[n_i][dof_i] = curEqNum++;
- else
- dstArray[n_i][dof_i] = (unsigned)-1;
- }
- }
-
- /* Order the equation numbers based on processor rank; cascade counts forward. */
- base = 0;
- subTotal = curEqNum;
- if( rank > 0 ) {
- insist( MPI_Recv( &base, 1, MPI_UNSIGNED, rank - 1, 6669, comm, &status ), == MPI_SUCCESS );
- subTotal = base + curEqNum;
- }
- if( rank < nProcs - 1 )
- insist( MPI_Send( &subTotal, 1, MPI_UNSIGNED, rank + 1, 6669, comm ), == MPI_SUCCESS );
-
- /* Modify existing destination array and dump to a tuple array. */
- tuples = AllocArray( unsigned, nDomainNodes * maxDofs );
- for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
- for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
- if( dstArray[n_i][dof_i] != (unsigned)-1 )
- dstArray[n_i][dof_i] += base;
- tuples[n_i * maxDofs + dof_i] = dstArray[n_i][dof_i];
- }
- }
-
- /* Update all other procs. */
- sync = Mesh_GetSync( cMesh, MT_VERTEX );
- Sync_SyncArray( sync, tuples, maxDofs * sizeof(unsigned),
- tuples + nLocalNodes * maxDofs, maxDofs * sizeof(unsigned),
- maxDofs * sizeof(unsigned) );
-
- /* Update destination array's domain indices. */
- for( n_i = nLocalNodes; n_i < nDomainNodes; n_i++ ) {
- topNode = self->topMaps[level][n_i];
- for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
- if( self->fineEqNum->destinationArray[topNode][dof_i] != (unsigned)-1 )
- dstArray[n_i][dof_i] = tuples[n_i * maxDofs + dof_i];
- else
- dstArray[n_i][dof_i] = -1;
- }
- }
-
- /* Destroy arrays. */
- FreeArray( nNodalDofs );
- FreeArray( tuples );
-
- self->eqNums[level] = dstArray;
- self->nLocalEqNums[level] = curEqNum;
- self->eqNumBases[level] = base;
-}
-
-//void SROpGenerator_GenOps( SROpGenerator* self, Matrix** pOps, Matrix** rOps ) {
-void SROpGenerator_GenOps( SROpGenerator* self, Mat* pOps, Mat* rOps ) {
- unsigned nLevels;
- //Matrix *fineMat, *P;
- Mat fineMat, P;
- unsigned nRows, nCols;
- unsigned l_i;
- /* unsigned nProcs; */
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
- assert( pOps && rOps );
-
- //fineMat = MatrixSolver_GetMatrix( self->solver );
- fineMat = self->solver->matrix;
- nLevels = self->nLevels;
-
- for( l_i = nLevels - 1; l_i > 0; l_i-- ) {
- nRows = self->eqNums[l_i] ? self->nLocalEqNums[l_i] :
- self->fineEqNum->localEqNumsOwnedCount;
- nCols = self->nLocalEqNums[l_i - 1];
-
- //Matrix_Duplicate( fineMat, (void**)&P );
- //Matrix_SetComm( P, fineMat->comm );
- //Matrix_SetLocalSize( P, nRows, nCols );
- MatCreate( self->solver->comm, &P );
- MatSetSizes( P, nRows, nCols, PETSC_DETERMINE, PETSC_DETERMINE );
- MatSetFromOptions( P );
- //if( !strcmp( P->type, PETScMatrix_Type ) ) {
- // unsigned *nDiagNonZeros, *nOffDiagNonZeros;
- //
- // SROpGenerator_CalcOpNonZeros( self, l_i, &nDiagNonZeros, &nOffDiagNonZeros );
- //PETScMatrix_SetNonZeroStructure( (PETScMatrix*)P, 0, nDiagNonZeros, nOffDiagNonZeros );
- // MPI_Comm_size( self->solver->comm, &nProcs );
- // if( nProcs > 1 )
- // MatMPIAIJSetPreallocation( P, PETSC_NULL, nDiagNonZeros, PETSC_NULL, nOffDiagNonZeros );
- // else
- // MatSeqAIJSetPreallocation( P, PETSC_NULL, nDiagNonZeros );
- // FreeArray( nDiagNonZeros );
- // FreeArray( nOffDiagNonZeros );
- //}
-
- SROpGenerator_GenLevelOp( self, l_i, P );
- pOps[l_i] = P;
- //Stg_Class_AddRef( P );
- rOps[l_i] = P;
- //Stg_Class_AddRef( P );
- }
-}
-
-//void SROpGenerator_GenLevelOp( SROpGenerator* self, unsigned level, Matrix* P ) {
-void SROpGenerator_GenLevelOp( SROpGenerator* self, unsigned level, Mat P ) {
- Mesh *fMesh, *cMesh;
- unsigned nDims;
- unsigned nLocalFineNodes;
- DofLayout* dofLayout;
- unsigned ind;
- unsigned nInc, *inc;
- unsigned maxInc;
- unsigned fTopNode, cTopNode;
- unsigned fEqNum, cEqNum;
- double *localCoord, *basis;
- IArray *incArray;
- unsigned n_i, dof_i, inc_i, e_i;
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
- assert( self->meshes );
- assert( level < self->nLevels );
- assert( P );
-
- fMesh = self->meshes[level];
- cMesh = self->meshes[level - 1];
- nDims = Mesh_GetDimSize( fMesh );
- nLocalFineNodes = Mesh_GetLocalSize( fMesh, MT_VERTEX );
- dofLayout = self->fineEqNum->dofLayout;
- localCoord = AllocArray( double, nDims );
-
- maxInc = 0;
- for( e_i = 0; e_i < Mesh_GetDomainSize( cMesh, (MeshTopology_Dim)nDims ); e_i++ ) {
- nInc = Mesh_GetIncidenceSize( cMesh, (MeshTopology_Dim)nDims, e_i, MT_VERTEX );
- if( nInc > maxInc )
- maxInc = nInc;
- }
- basis = AllocArray( double, maxInc );
-
- incArray = IArray_New();
- for( n_i = 0; n_i < nLocalFineNodes; n_i++ ) {
- if( self->topMaps[level] )
- fTopNode = self->topMaps[level][n_i];
- else
- fTopNode = n_i;
-
- for( dof_i = 0; dof_i < dofLayout->dofCounts[fTopNode]; dof_i++ ) {
- if( self->eqNums[level] )
- fEqNum = self->eqNums[level][n_i][dof_i];
- else
- fEqNum = self->fineEqNum->destinationArray[fTopNode][dof_i];
-
- if( fEqNum == (unsigned)-1 )
- continue;
-
- insist( Mesh_SearchElements( cMesh, Mesh_GetVertex( fMesh, n_i ), &ind ), == True );
- FeMesh_CoordGlobalToLocal( cMesh, ind, Mesh_GetVertex( fMesh, n_i ), localCoord );
- FeMesh_EvalBasis( cMesh, ind, localCoord, basis );
- Mesh_GetIncidence( cMesh, (MeshTopology_Dim)nDims, ind, MT_VERTEX, incArray );
- nInc = IArray_GetSize( incArray );
- inc = (unsigned*)IArray_GetPtr( incArray );
- for( inc_i = 0; inc_i < nInc; inc_i++ ) {
- cTopNode = self->topMaps[level - 1][inc[inc_i]];
- cEqNum = self->eqNums[level - 1][inc[inc_i]][dof_i];
- if( cEqNum != (unsigned)-1 && !Num_Approx( basis[inc_i], 0.0 ) )
- //Matrix_InsertEntries( P, 1, &fEqNum, 1, &cEqNum, basis + inc_i );
- MatSetValues( P, 1, (PetscInt*)(&fEqNum), 1, (PetscInt*)(&cEqNum), basis + inc_i, INSERT_VALUES );
- }
- }
- }
- NewClass_Delete( incArray );
-
- FreeArray( localCoord );
- FreeArray( basis );
-
- //Matrix_AssemblyBegin( P );
- //Matrix_AssemblyEnd( P );
- MatAssemblyBegin( P, MAT_FINAL_ASSEMBLY );
- MatAssemblyEnd( P, MAT_FINAL_ASSEMBLY );
-}
-
-void SROpGenerator_CalcOpNonZeros( SROpGenerator* self, unsigned level,
- unsigned** nDiagNonZeros, unsigned** nOffDiagNonZeros )
-{
- Mesh *fMesh, *cMesh;
- unsigned nLocalFineNodes;
- DofLayout* dofLayout;
- unsigned dim, ind;
- unsigned nInc, *inc;
- unsigned fTopNode, cTopNode;
- unsigned fEqNum, cEqNum;
- unsigned nLocalEqNums;
- IArray* incArray;
- unsigned n_i, dof_i, dof_j, inc_i;
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
- assert( self->meshes );
- assert( level < self->nLevels );
-
- fMesh = self->meshes[level];
- cMesh = self->meshes[level - 1];
- nLocalFineNodes = Mesh_GetLocalSize( fMesh, MT_VERTEX );
- dofLayout = self->fineEqNum->dofLayout;
- if( self->eqNums[level] )
- nLocalEqNums = self->nLocalEqNums[level];
- else
- nLocalEqNums = self->fineEqNum->localEqNumsOwnedCount;
-
- *nDiagNonZeros = AllocArray( unsigned, nLocalEqNums );
- memset( *nDiagNonZeros, 0, nLocalEqNums * sizeof(unsigned) );
- *nOffDiagNonZeros = AllocArray( unsigned, nLocalEqNums );
- memset( *nOffDiagNonZeros, 0, nLocalEqNums * sizeof(unsigned) );
-
- incArray = IArray_New();
-
- for( n_i = 0; n_i < nLocalFineNodes; n_i++ ) {
- if( self->topMaps[level] )
- fTopNode = self->topMaps[level][n_i];
- else
- fTopNode = n_i;
-
- for( dof_i = 0; dof_i < dofLayout->dofCounts[fTopNode]; dof_i++ ) {
- if( self->eqNums[level] )
- fEqNum = self->eqNums[level][n_i][dof_i];
- else
- fEqNum = self->fineEqNum->destinationArray[fTopNode][dof_i];
-
- if( fEqNum == (unsigned)-1 )
- continue;
-
- insist( Mesh_SearchElements( cMesh, Mesh_GetVertex( fMesh, n_i ), &ind ), == True );
- dim = Mesh_GetDimSize( fMesh );
- if( dim == MT_VERTEX ) {
- cTopNode = self->topMaps[level - 1][ind];
- for( dof_j = 0; dof_j < dofLayout->dofCounts[cTopNode]; dof_j++ ) {
- cEqNum = self->eqNums[level - 1][ind][dof_j];
- if( cEqNum == (unsigned)-1 )
- continue;
-
- if( cEqNum - self->eqNumBases[level - 1] < nLocalEqNums )
- (*nDiagNonZeros)[fEqNum - self->eqNumBases[level]]++;
- else
- (*nOffDiagNonZeros)[fEqNum - self->eqNumBases[level]]++;
- }
- }
- else {
- Mesh_GetIncidence( cMesh, (MeshTopology_Dim)dim, ind, MT_VERTEX, incArray );
- nInc = IArray_GetSize( incArray );
- inc = (unsigned*)IArray_GetPtr( incArray );
- for( inc_i = 0; inc_i < nInc; inc_i++ ) {
- cTopNode = self->topMaps[level - 1][inc[inc_i]];
- for( dof_j = 0; dof_j < dofLayout->dofCounts[cTopNode]; dof_j++ ) {
- cEqNum = self->eqNums[level - 1][inc[inc_i]][dof_j];
- if( cEqNum == (unsigned)-1 )
- continue;
-
- if( cEqNum - self->eqNumBases[level - 1] < nLocalEqNums )
- (*nDiagNonZeros)[fEqNum - self->eqNumBases[level]]++;
- else
- (*nOffDiagNonZeros)[fEqNum - self->eqNumBases[level]]++;
- }
- }
- }
- }
- }
-
- NewClass_Delete( incArray );
-}
-
-void SROpGenerator_DestructMeshes( SROpGenerator* self ) {
- unsigned nLevels;
- unsigned l_i;
-
- assert( self && Stg_CheckType( self, SROpGenerator ) );
-
- if( self->meshes ) {
- nLevels = self->nLevels;
- for( l_i = 0; l_i < nLevels - 1; l_i++ ) {
- FreeObject( self->meshes[l_i] );
- FreeArray( self->topMaps[l_i] );
- FreeArray( self->eqNums[l_i] );
- }
- KillArray( self->meshes );
- KillArray( self->topMaps );
- KillArray( self->eqNums );
- KillArray( self->nLocalEqNums );
- KillArray( self->eqNumBases );
- }
-}
-
-
-//void SROpGenerator_Simple( SROpGenerator *self, Matrix **pOps, Matrix **rOps ) {
-void SROpGenerator_Simple( SROpGenerator *self, Mat* pOps, Mat* rOps ) {
- double t0;
- if( self->nLevels > 1 ) {
- //Matrix *P;
- Mat P;
- int ii;
-
- t0 = MPI_Wtime();
- P = SROpGenerator_SimpleFinestLevel( self );
- PetscPrintf( PETSC_COMM_WORLD, "SROpGenerator_SimpleFinestLevel: time = %5.5e \n", MPI_Wtime()-t0 );
- pOps[self->nLevels - 1] = rOps[self->nLevels - 1] = P;
- for( ii = self->nLevels - 2; ii > 0; ii-- ) {
- t0 = MPI_Wtime();
- P = SROpGenerator_SimpleCoarserLevel( self, ii );
- PetscPrintf( PETSC_COMM_WORLD, " [%d] SROpGenerator_SimpleCoarserLevel: time = %5.5e \n",ii, MPI_Wtime()-t0 );
- pOps[ii] = rOps[ii] = P;
- }
- }
-}
-
-
-PetscErrorCode _VecGetOwnershipRanges( Vec X, PetscInt **_ranges )
-{
- PetscInt start,end;
- PetscMPIInt nproc,rank;
- MPI_Comm comm;
- Vec all, out;
- VecScatter scat;
- PetscInt *ranges,i;
- PetscScalar *v;
- double t0;
-
- t0 = MPI_Wtime();
-
- PetscObjectGetComm( (PetscObject)X, &comm );
- MPI_Comm_size( comm, &nproc );
- MPI_Comm_rank( comm, &rank );
- VecGetOwnershipRange( X, &start, &end );
-
- VecCreate( comm, &all );
- VecSetSizes( all, PETSC_DECIDE, nproc+1 );
- VecSetFromOptions( all );
-
- VecSetValue( all, rank, (PetscScalar)start, INSERT_VALUES );
- VecSetValue( all, rank+1, (PetscScalar)end, INSERT_VALUES );
- VecAssemblyBegin( all );
- VecAssemblyEnd( all );
-
- VecScatterCreateToAll( all, &scat, &out );
-
-#if(PETSC_VERSION_SUBMINOR==2)
- VecScatterBegin(all,out,INSERT_VALUES,SCATTER_FORWARD,scat);
- VecScatterEnd(all,out,INSERT_VALUES,SCATTER_FORWARD,scat);
-#elif(PETSC_VERSION_SUBMINOR==3)
- VecScatterBegin(scat, all,out,INSERT_VALUES,SCATTER_FORWARD);
- VecScatterEnd(scat, all,out,INSERT_VALUES,SCATTER_FORWARD);
-#endif
-
- PetscMalloc( sizeof(PetscInt)*(nproc+1), &ranges );
- VecGetArray( out, &v );
- for( i=0; i<nproc+1; i++ ) {
- ranges[i] = (PetscInt)v[i];
- }
- VecRestoreArray( out, &v );
-
- *_ranges = ranges;
-
- VecScatterDestroy( scat );
- VecDestroy( out );
- VecDestroy( all );
-
-
- PetscFunctionReturn(0);
-}
-
-
-/*
-Efficiency alert!!
- This comments relates to both SROpGenerator_SimpleFinestLevel() and
- SROpGenerator_SimpleCoarserLevel().
-
- For O(n) setup times, we MUST provide some information concerning the
- preallocation of the nonzero structure for the restriction operators.
-
- As a first hack we check the spatial dimension and choose a value accordingly.
- In doing so we have assumed that the fine grid is obtained by bisecting
- the coarse grid. Coarse grid nodes are hiearchical. We have also assumed
- that the elements are quads (2d) and hexs (3d).
-
- The hack above made little effort to miminise memory usage and as such we allocate
- the same amount of memory for the on and off diagonal parts of the restriction
- operator. This kinda kills use in parallel.
-
- An more accurate estimate has thus been implemented.
-*/
-//Matrix *SROpGenerator_SimpleFinestLevel( SROpGenerator *self ) {
-Mat SROpGenerator_SimpleFinestLevel( SROpGenerator *self ) {
- FeMesh *mesh;
- int nDims, nDofsPerNode;
- int sideSizes[2][3];
- int inds[2][3], offsInds[3], nOffs[3];
- int nGlobalNodes[2];
- int nGlobalEqs[2];
- Grid *vertGrid, *elGrid, *grid[2], *offsGrid;
- int nodes[8];
- int nodeInd;
- double dfrac;
- int nEntries, indices[8];
- double values[8];
- Mat P;
- //PETScMatrix *mat;
- Mat mat;
- int ii, jj, kk;
- PetscInt o_nz, d_nz;
- PetscInt *o_nnz, *d_nnz;
- PetscInt sr,er, sc,ec, row_idx;
- Vec vec_o_nnz, vec_d_nnz;
- PetscScalar *v;
- PetscTruth is_seq;
- PetscInt p, proc_owner, *rranges,*cranges;
- MPI_Comm comm;
- PetscMPIInt nproc,rank;
-
- /* Calculate level side lengths. */
- mesh = self->fineVar->feMesh;
- nDims = Mesh_GetDimSize( mesh );
-
- /* crude estimate of number of nonzeros in the on-off diagonal portitions of the matrix */
- o_nz = d_nz = 0;
- if( nDims == 2 ) {
- o_nz = d_nz = 4;
- }
- if( nDims==3 ) {
- o_nz = d_nz = 8;
- }
-
- nDofsPerNode = self->fineVar->dofLayout->dofCounts[0]; /* ASSUME */
- elGrid = *Mesh_GetExtension( mesh, Grid**, "elementGrid" );
- vertGrid = *Mesh_GetExtension( mesh, Grid**, "vertexGrid" );
- nGlobalNodes[0] = nGlobalNodes[1] = 1;
- for( ii = 0; ii < nDims; ii++ ) {
- sideSizes[1][ii] = elGrid->sizes[ii];
- sideSizes[0][ii] = elGrid->sizes[ii] / 2;
- if( sideSizes[0][ii] * 2 != elGrid->sizes[ii] ) {
- printf( "(MG) Error: Too many levels specified for geometric multigrid.\n" );
- printf( " Please modify mesh size or reduce number of levels.\n" );
- exit( 1 );
- }
- sideSizes[1][ii]++; sideSizes[0][ii]++;
- nGlobalNodes[1] *= sideSizes[1][ii];
- nGlobalNodes[0] *= sideSizes[0][ii];
- }
-
- /* Have PETSc create the operator matrix and then extract local sizes
- and offsets into the global vector. */
- nGlobalEqs[1] = nGlobalNodes[1] * nDofsPerNode;
- nGlobalEqs[0] = nGlobalNodes[0] * nDofsPerNode;
-/*
- MatCreateMPIAIJ( MPI_COMM_WORLD,
- self->fineVar->eqNum->localEqNumsOwnedCount, PETSC_DECIDE,
- PETSC_DECIDE, nGlobalEqs[0],
- o_nz, PETSC_NULL, d_nz, PETSC_NULL, &P );
-
-*/
- MatCreate( MPI_COMM_WORLD, &P );
- MatSetSizes( P, self->fineVar->eqNum->localEqNumsOwnedCount, PETSC_DECIDE, PETSC_DECIDE, nGlobalEqs[0] );
- MatSetType( P, MATAIJ );
-// MatGetOwnershipRange( P, &sr, &er );
-
- PetscObjectGetComm( (PetscObject)P, &comm );
- MPI_Comm_size( comm, &nproc );
- MPI_Comm_rank( comm, &rank );
-
-// printf( " sr,er = %d -> %d \n", sr, er );
- { Vec L,R;
- PetscInt M,N, m,n;
-
- MatGetSize( P, &M,&N );
- MatGetLocalSize( P, &m,&n );
-// PetscPrintf( PETSC_COMM_WORLD, "size = %D x %D \n", M, N );
- MatGetVecs( P, &R, &L );
- VecGetOwnershipRange( L, &sr,&er );
- VecGetOwnershipRange( R, &sc,&ec );
-// printf( " [%d] mxn = %d x %d ; sr,er = %d -> %d ; sc,ec = %d -> %d \n", rank, m,n, sr,er, sc,ec );
-
- _VecGetOwnershipRanges( L, &rranges );
- _VecGetOwnershipRanges( R, &cranges );
-
- VecDestroy( L );
- VecDestroy( R );
- }
-
- PetscMalloc( sizeof(PetscInt)*(er-sr), &o_nnz );
- PetscMalloc( sizeof(PetscInt)*(er-sr), &d_nnz );
-
- /* Need a grid representing the coarse level. */
- grid[0] = Grid_New();
- offsGrid = Grid_New();
- Grid_SetNumDims( grid[0], nDims );
- Grid_SetNumDims( offsGrid, nDims );
- Grid_SetSizes( grid[0], (unsigned*)(sideSizes[0]) );
-
- /* Determine preallocation information */
- MatGetVecs( P, PETSC_NULL, &vec_d_nnz );
- VecDuplicate( vec_d_nnz, &vec_o_nnz );
-
- /* Loop over fine nodes. */
- for( ii = 0; ii < Mesh_GetLocalSize( mesh, (MeshTopology_Dim)0 ); ii++ ) {
- nodeInd = Mesh_DomainToGlobal( mesh, (MeshTopology_Dim)0, ii );
- Grid_Lift( vertGrid, nodeInd, (unsigned*)(inds[1]) );
-
- /* An odd grid index means we need to interpolate from surrounding
- coarse nodes in the current dimension. */
- for( jj = 0; jj < nDims; jj++ ) {
- /* Store the offsets we need to consider. */
- nOffs[jj] = (inds[1][jj] & 1) ? 2 : 1;
- }
-
- /* 'Multiply' the offsets to build the set of nodes we need to
- interpolate from. */
- Grid_SetSizes( offsGrid, (unsigned*)nOffs );
- for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
- Grid_Lift( offsGrid, jj, (unsigned*)offsInds );
- for( kk = 0; kk < nDims; kk++ )
- inds[0][kk] = (inds[1][kk] >> 1) + offsInds[kk];
-
- /* Store the coarse global node number. */
- nodes[jj] = Grid_Project( grid[0], (unsigned*)(inds[0]) );
- }
-
- /* Insert this row into the operator matrix. */
- nEntries = offsGrid->nPoints;
- for( kk = 0; kk < nDofsPerNode; kk++ ) {
- /* Skip the entire thing if it's a BC. */
- if( self->fineVar->eqNum->destinationArray[ii][kk] == -1 )
- continue;
-
- row_idx = (PetscInt)(self->fineVar->eqNum->destinationArray[ii][kk]);
-
-
- /* find owning proc */
- proc_owner = -1;
- for( p=0; p<nproc; p++ ) {
- if( (row_idx>=rranges[p]) && (row_idx<rranges[p+1]) ) {
- proc_owner = p;
- break;
- }
- }
-
-
- for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
- indices[jj] = nodes[jj] * nDofsPerNode + kk;
- // printf( "[%d]: (owner=%d): row=%d : c_index=%d \n", rank, proc_owner, row_idx, indices[jj] );
- if( (row_idx>=rranges[proc_owner]) && (row_idx<rranges[proc_owner+1]) ) {
- if( (indices[jj]>=cranges[proc_owner]) && (indices[jj]<cranges[proc_owner+1]) ) {
- VecSetValue( vec_d_nnz, row_idx, 1.0, ADD_VALUES );
- }
- else {
- VecSetValue( vec_o_nnz, row_idx, 1.0, ADD_VALUES );
- }
- }
- }
-
-
-/*
- for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
- indices[jj] = nodes[jj] * nDofsPerNode + kk;
- printf( "[%d]: row=%d : c_index=%d \n", rank, row_idx, indices[jj] );
- if( (row_idx>=sr) && (row_idx<er) ) {
- if( (indices[jj]>=sc) && (indices[jj]<ec) ) {
- VecSetValue( vec_d_nnz, row_idx, 1.0, ADD_VALUES );
- }
- }
- else {
- VecSetValue( vec_o_nnz, row_idx, 1.0, ADD_VALUES );
- }
- }
-*/
-
-
- }
- }
- VecAssemblyBegin( vec_d_nnz );
- VecAssemblyEnd( vec_d_nnz );
-
- VecAssemblyBegin( vec_o_nnz );
- VecAssemblyEnd( vec_o_nnz );
-
- VecGetArray( vec_d_nnz, &v );
- for( kk=0; kk<(er-sr); kk++ ) {
- d_nnz[kk] = (PetscInt)v[kk];
- }
- VecRestoreArray( vec_d_nnz, &v );
-
- VecGetArray( vec_o_nnz, &v );
- for( kk=0; kk<(er-sr); kk++ ) {
- o_nnz[kk] = (PetscInt)v[kk];
- }
- VecRestoreArray( vec_o_nnz, &v );
-
- PetscTypeCompare( (PetscObject)vec_o_nnz, VECSEQ, &is_seq );
- if(nproc==1) {
- MatSeqAIJSetPreallocation( P, PETSC_NULL, d_nnz );
- }
- else {
-// for( kk=0; kk<(er-sr); kk++ ) {
-// printf( "[%d]: row=%d : d_nnz=%d : o_nnz=%d \n", rank, kk+sr, d_nnz[kk], o_nnz[kk] );
-// }
- MatMPIAIJSetPreallocation( P, PETSC_NULL, d_nnz, PETSC_NULL, o_nnz );
-
-// MatMPIAIJSetPreallocation( P, d_nz,PETSC_NULL, o_nz,PETSC_NULL );
- }
-
- /* Loop over fine nodes. */
- for( ii = 0; ii < Mesh_GetLocalSize( mesh, (MeshTopology_Dim)0 ); ii++ ) {
-// if( ii%5000 == 0 ) {
-// PetscPrintf( PETSC_COMM_WORLD, "Done %d of %d \n", ii, Mesh_GetLocalSize( mesh, 0 ) );
-// }
- nodeInd = Mesh_DomainToGlobal( mesh, (MeshTopology_Dim)0, ii );
- Grid_Lift( vertGrid, nodeInd, (unsigned*)(inds[1]) );
-
- /* An odd grid index means we need to interpolate from surrounding
- coarse nodes in the current dimension. */
- for( jj = 0; jj < nDims; jj++ ) {
- /* Store the offsets we need to consider. */
- nOffs[jj] = (inds[1][jj] & 1) ? 2 : 1;
- }
-
- /* 'Multiply' the offsets to build the set of nodes we need to
- interpolate from. */
- Grid_SetSizes( offsGrid, (unsigned*)nOffs );
- for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
- Grid_Lift( offsGrid, jj, (unsigned*)offsInds );
- for( kk = 0; kk < nDims; kk++ )
- inds[0][kk] = (inds[1][kk] >> 1) + offsInds[kk];
-
- /* Store the coarse global node number. */
- nodes[jj] = Grid_Project( grid[0], (unsigned*)(inds[0]) );
- }
-
- /* Insert this row into the operator matrix. */
- dfrac = 1.0 / (double)offsGrid->nPoints;
- nEntries = offsGrid->nPoints;
- for( kk = 0; kk < nDofsPerNode; kk++ ) {
- /* Skip the entire thing if it's a BC. */
- if( self->fineVar->eqNum->destinationArray[ii][kk] == -1 )
- continue;
-
- for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
- indices[jj] = nodes[jj] * nDofsPerNode + kk;
- values[jj] = dfrac;
- }
- MatSetValues( P, 1, self->fineVar->eqNum->destinationArray[ii] + kk,
- nEntries, indices, values, INSERT_VALUES );
- }
- }
-// PetscPrintf( PETSC_COMM_WORLD, "Done all MatSetValues \n");
-
- /* Assemble the matrix. */
- MatAssemblyBegin( P, MAT_FINAL_ASSEMBLY );
- MatAssemblyEnd( P, MAT_FINAL_ASSEMBLY );
-
-/*
- {
- PetscInt M,N, m,n;
- for( p=0; p<nproc; p++ ) {
- PetscPrintf( PETSC_COMM_WORLD, "[%d]: r_range (%d->%d) ; c_range (%d->%d)\n", p, rranges[p], rranges[p+1], cranges[p], cranges[p+1] );
- }
-
- MatGetSize( P, &M,&N );
- MatGetLocalSize( P, &m,&n );
- PetscPrintf( PETSC_COMM_WORLD, "P_size = %D x %D \n", M, N );
- MatGetOwnershipRange( P, &sr,&er );
- printf( " [%d] mxn = %d x %d ; sr,er = %d -> %d (local rows=%d) \n", rank, m,n, sr,er, er-sr );
- }
- PetscViewerSetFormat( PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_DENSE );
- MatView( P, PETSC_VIEWER_STDOUT_WORLD );
-*/
-
- /* Piss off those grids. */
- Stg_Class_Delete( grid[0] );
-
- Stg_Class_Delete(offsGrid);
-
- VecDestroy( vec_o_nnz );
- VecDestroy( vec_d_nnz );
- PetscFree( o_nnz );
- PetscFree( d_nnz );
- PetscFree( rranges );
- PetscFree( cranges );
-
-
- /* Create a new matrix. */
- //mat = PETScMatrix_New( "" );
- //mat->petscMat = P;
- mat = P;
- return mat;
-}
-
-//Matrix *SROpGenerator_SimpleCoarserLevel( SROpGenerator *self, int level ) {
-Mat SROpGenerator_SimpleCoarserLevel( SROpGenerator *self, int level ) {
- FeMesh *mesh;
- int nDims, nDofsPerNode, rowDof;
- int sideSizes[2][3];
- int inds[2][3], offsInds[3], nOffs[3];
- int nGlobalNodes[2];
- int nGlobalEqs[2];
- int eqRangeBegin, eqRangeEnd;
- Grid *vertGrid, *elGrid, *grid[2], *offsGrid;
- int nodes[8];
- int ifrac, nodeInd;
- double dfrac;
- int nEntries, indices[8];
- double values[8];
- Mat P;
- //PETScMatrix *mat;
- Mat mat;
- int ii, jj, kk;
- PetscInt o_nz, d_nz;
- PetscInt *o_nnz, *d_nnz;
- PetscInt sr,er, sc,ec, row_idx;
- Vec vec_o_nnz, vec_d_nnz;
- PetscScalar *v;
- PetscInt p, proc_owner, *row_ranges, *col_ranges;
- MPI_Comm comm;
- PetscMPIInt nproc;
-
- /* Calculate depth fraction. */
- ifrac = 1;
- for( ii = 0; ii < self->nLevels - level - 1; ii++ )
- ifrac *= 2;
-
- /* Calculate level side lengths. */
- mesh = self->fineVar->feMesh;
- nDims = Mesh_GetDimSize( mesh );
-
- /* crude estimate of number of nonzeros in the on-off diagonal portitions of the matrix */
- o_nz = d_nz = 0;
- if( nDims==2 ) {
- o_nz = d_nz = 4;
- }
- if( nDims==3 ) {
- o_nz = d_nz = 8;
- }
-
- nDofsPerNode = self->fineVar->dofLayout->dofCounts[0]; /* ASSUME */
- elGrid = *Mesh_GetExtension( mesh, Grid**, "elementGrid" );
- vertGrid = *Mesh_GetExtension( mesh, Grid**, "vertexGrid" );
- nGlobalNodes[0] = nGlobalNodes[1] = 1;
- for( ii = 0; ii < nDims; ii++ ) {
- sideSizes[1][ii] = elGrid->sizes[ii] / ifrac;
- sideSizes[0][ii] = elGrid->sizes[ii] / (ifrac * 2);
- if( sideSizes[1][ii] * ifrac != elGrid->sizes[ii] ||
- sideSizes[0][ii] * (ifrac * 2) != elGrid->sizes[ii] )
- {
- printf( "(MG) Error: Too many levels specified for geometric multigrid.\n" );
- printf( " Please modify mesh size or reduce number of levels.\n" );
- exit( 1 );
- }
- sideSizes[1][ii]++; sideSizes[0][ii]++;
- nGlobalNodes[1] *= sideSizes[1][ii];
- nGlobalNodes[0] *= sideSizes[0][ii];
- }
-
- /* Have PETSc create the operator matrix and then extract local sizes
- and offsets into the global vector. */
- nGlobalEqs[1] = nGlobalNodes[1] * nDofsPerNode;
- nGlobalEqs[0] = nGlobalNodes[0] * nDofsPerNode;
-
-/*
- MatCreateMPIAIJ( MPI_COMM_WORLD,
- PETSC_DECIDE, PETSC_DECIDE, nGlobalEqs[1], nGlobalEqs[0],
- o_nz, PETSC_NULL, d_nz, PETSC_NULL, &P );
- MatGetOwnershipRange( P, &eqRangeBegin, &eqRangeEnd );
-*/
- MatCreate( MPI_COMM_WORLD, &P );
- MatSetSizes( P, PETSC_DECIDE, PETSC_DECIDE, nGlobalEqs[1], nGlobalEqs[0] );
- MatSetType( P, MATAIJ );
- MatGetOwnershipRange( P, &eqRangeBegin, &eqRangeEnd );
-
- {
- Vec L,R;
- PetscInt M,N;
- MatGetSize( P, &M,&N );
-// PetscPrintf( PETSC_COMM_WORLD, "size = %D x %D \n", M, N );
- MatGetVecs( P, &R, &L );
- VecGetOwnershipRange( L, &sr,&er );
- VecGetOwnershipRange( R, &sc,&ec );
-// printf( " 2) sr,er = %d -> %d \n", sr, er );
-// printf( " 2) sc,ec = %d -> %d \n", sc, ec );
-
- _VecGetOwnershipRanges( L, &row_ranges );
- _VecGetOwnershipRanges( R, &col_ranges );
-
- VecDestroy( L );
- VecDestroy( R );
- }
-
-
- PetscMalloc( sizeof(PetscInt)*(er-sr), &o_nnz );
- PetscMalloc( sizeof(PetscInt)*(er-sr), &d_nnz );
-
-
-
- /* Need a grid representing the coarse level. */
- grid[1] = Grid_New();
- grid[0] = Grid_New();
- offsGrid = Grid_New();
- Grid_SetNumDims( grid[1], nDims );
- Grid_SetNumDims( grid[0], nDims );
- Grid_SetNumDims( offsGrid, nDims );
- Grid_SetSizes( grid[1], (unsigned*)(sideSizes[1]) );
- Grid_SetSizes( grid[0], (unsigned*)(sideSizes[0]) );
-
- /* Determine preallocation */
- MatGetVecs( P, PETSC_NULL, &vec_d_nnz );
- VecDuplicate( vec_d_nnz, &vec_o_nnz );
- PetscObjectGetComm( (PetscObject)P, &comm );
- MPI_Comm_size( comm, &nproc );
-
-
-
- /* Loop over the finer of the two levels. */
- for( ii = eqRangeBegin; ii < eqRangeEnd; ii++ ) {
- /* Convert the global equation number to the global node index. */
- nodeInd = ii / nDofsPerNode;
- rowDof = ii - nodeInd * nDofsPerNode;
- Grid_Lift( grid[1], nodeInd, (unsigned*)(inds[1]) );
-
- /* An odd grid index means we need to interpolate from surrounding
- coarse nodes in the current dimension. */
- for( jj = 0; jj < nDims; jj++ ) {
- /* Store the offsets we need to consider. */
- nOffs[jj] = (inds[1][jj] & 1) ? 2 : 1;
- }
-
- /* 'Multiply' the offsets to build the set of nodes we need to
- interpolate from. */
- Grid_SetSizes( offsGrid, (unsigned*)(nOffs) );
- for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
- Grid_Lift( offsGrid, jj, (unsigned*)(offsInds) );
- for( kk = 0; kk < nDims; kk++ )
- inds[0][kk] = (inds[1][kk] >> 1) + offsInds[kk];
-
- /* Store the coarse global node number. */
- nodes[jj] = Grid_Project( grid[0], (unsigned*)(inds[0]) );
- }
-
- /* Insert this row into the operator matrix. */
- row_idx = (PetscInt)ii;
- /* find owning proc */
- proc_owner = -1;
- for( p=0; p<nproc; p++ ) {
- if( (row_idx>=row_ranges[p]) && (row_idx<row_ranges[p+1]) ) {
- proc_owner = p;
- break;
- }
- }
-/*
- if( (row_idx>=sr) && (row_idx<er) ) {
- for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
- indices[jj] = nodes[jj] * nDofsPerNode + rowDof;
- if( (indices[jj]>=sc) && (indices[jj]<ec) ) {
- VecSetValue( vec_d_nnz, row_idx, 1.0, ADD_VALUES );
- }
- }
- }
- else {
- VecSetValue( vec_o_nnz, row_idx, 1.0, ADD_VALUES );
- }
-*/
-
- for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
- indices[jj] = nodes[jj] * nDofsPerNode + rowDof;
-// printf("ridx=%d,cidx=%d : owner:%d rrange [%d-%d] : crange [%d-%d] \n", row_idx, indices[jj], proc_owner, row_ranges[proc_owner],row_ranges[proc_owner+1], col_ranges[proc_owner], col_ranges[proc_owner+1] );
- if( (row_idx>=row_ranges[proc_owner]) && (row_idx<row_ranges[proc_owner+1]) ) {
- if( (indices[jj]>=col_ranges[proc_owner]) && (indices[jj]<col_ranges[proc_owner+1]) ) {
- VecSetValue( vec_d_nnz, row_idx, 1.0, ADD_VALUES );
- }
- else {
- VecSetValue( vec_o_nnz, row_idx, 1.0, ADD_VALUES );
- }
- }
- }
-
- }
-
- VecAssemblyBegin( vec_d_nnz );
- VecAssemblyEnd( vec_d_nnz );
-
- VecAssemblyBegin( vec_o_nnz );
- VecAssemblyEnd( vec_o_nnz );
-
- VecGetArray( vec_d_nnz, &v );
- for( kk=0; kk<(er-sr); kk++ ) {
- d_nnz[kk] = (PetscInt)v[kk];
- }
- VecRestoreArray( vec_d_nnz, &v );
-
- VecGetArray( vec_o_nnz, &v );
- for( kk=0; kk<(er-sr); kk++ ) {
- o_nnz[kk] = (PetscInt)v[kk];
- }
- VecRestoreArray( vec_o_nnz, &v );
-
-
- if(nproc==1) {
- MatSeqAIJSetPreallocation( P, PETSC_NULL, d_nnz );
- }
- else {
- MatMPIAIJSetPreallocation( P, PETSC_NULL, d_nnz, PETSC_NULL, o_nnz );
- }
-
-
- /* Loop over the finer of the two levels. */
- for( ii = eqRangeBegin; ii < eqRangeEnd; ii++ ) {
- /* Convert the global equation number to the global node index. */
- nodeInd = ii / nDofsPerNode;
- rowDof = ii - nodeInd * nDofsPerNode;
- Grid_Lift( grid[1], nodeInd, (unsigned*)(inds[1]) );
-
- /* An odd grid index means we need to interpolate from surrounding
- coarse nodes in the current dimension. */
- for( jj = 0; jj < nDims; jj++ ) {
- /* Store the offsets we need to consider. */
- nOffs[jj] = (inds[1][jj] & 1) ? 2 : 1;
- }
-
- /* 'Multiply' the offsets to build the set of nodes we need to
- interpolate from. */
- Grid_SetSizes( offsGrid, (unsigned*)(nOffs) );
- for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
- Grid_Lift( offsGrid, jj, (unsigned*)(offsInds) );
- for( kk = 0; kk < nDims; kk++ )
- inds[0][kk] = (inds[1][kk] >> 1) + offsInds[kk];
-
- /* Store the coarse global node number. */
- nodes[jj] = Grid_Project( grid[0], (unsigned*)(inds[0]) );
- }
-
- /* Insert this row into the operator matrix. */
- dfrac = 1.0 / (double)offsGrid->nPoints;
- nEntries = offsGrid->nPoints;
- for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
- indices[jj] = nodes[jj] * nDofsPerNode + rowDof;
- values[jj] = dfrac;
- }
- MatSetValues( P, 1, &ii, nEntries, indices, values, INSERT_VALUES );
- }
-
- /* Assemble the matrix. */
- MatAssemblyBegin( P, MAT_FINAL_ASSEMBLY );
- MatAssemblyEnd( P, MAT_FINAL_ASSEMBLY );
-
- /* Piss off those grids. */
- Stg_Class_Delete( grid[0] );
- Stg_Class_Delete( grid[1] );
- Stg_Class_Delete( offsGrid );
-
- VecDestroy( vec_o_nnz );
- VecDestroy( vec_d_nnz );
- PetscFree( o_nnz );
- PetscFree( d_nnz );
- PetscFree( row_ranges );
- PetscFree( col_ranges );
-
-
- /* Create a new matrix. */
- //mat = PETScMatrix_New( "" );
- //mat->petscMat = P;
- mat = P;
- return mat;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/SROpGenerator.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/SROpGenerator.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,1331 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: SROpGenerator.c 3584 2006-05-16 11:11:07Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+
+#include "SystemSetup.h"
+
+#include "petsc.h"
+#include "petscvec.h"
+#include "petscmat.h"
+
+/* Textual name of this class */
+const Type SROpGenerator_Type = "SROpGenerator";
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Constructors
+*/
+
+SROpGenerator* SROpGenerator_New( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(SROpGenerator);
+ Type type = SROpGenerator_Type;
+ Stg_Class_DeleteFunction* _delete = _SROpGenerator_Delete;
+ Stg_Class_PrintFunction* _print = _SROpGenerator_Print;
+ Stg_Class_CopyFunction* _copy = NULL;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = (void* (*)(Name))SROpGenerator_New;
+ Stg_Component_ConstructFunction* _construct = _SROpGenerator_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _SROpGenerator_Build;
+ Stg_Component_InitialiseFunction* _initialise = _SROpGenerator_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _SROpGenerator_Execute;
+ Stg_Component_DestroyFunction* _destroy = _SROpGenerator_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+ MGOpGenerator_SetNumLevelsFunc* setNumLevelsFunc = _MGOpGenerator_SetNumLevels;
+ MGOpGenerator_HasExpiredFunc* hasExpiredFunc = SROpGenerator_HasExpired;
+ MGOpGenerator_GenerateFunc* generateFunc = SROpGenerator_Generate;
+
+ return _SROpGenerator_New( SROPGENERATOR_PASSARGS );
+}
+
+SROpGenerator* _SROpGenerator_New( SROPGENERATOR_DEFARGS ) {
+ SROpGenerator* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(SROpGenerator) );
+ self = (SROpGenerator*)_MGOpGenerator_New( MGOPGENERATOR_PASSARGS );
+
+ /* Virtual info */
+
+ /* SROpGenerator info */
+ _SROpGenerator_Init( self );
+
+ return self;
+}
+
+void _SROpGenerator_Init( SROpGenerator* self ) {
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+
+ self->fineVar = NULL;
+ self->fineEqNum = NULL;
+ self->meshes = NULL;
+ self->topMaps = NULL;
+ self->eqNums = NULL;
+ self->nLocalEqNums = NULL;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Virtual functions
+*/
+
+void _SROpGenerator_Delete( void* srOpGenerator ) {
+ SROpGenerator* self = (SROpGenerator*)srOpGenerator;
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+
+ /* Delete the parent. */
+ _MGOpGenerator_Delete( self );
+}
+
+void _SROpGenerator_Print( void* srOpGenerator, Stream* stream ) {
+ SROpGenerator* self = (SROpGenerator*)srOpGenerator;
+
+ /* Set the Journal for printing informations */
+ Stream* srOpGeneratorStream;
+ srOpGeneratorStream = Journal_Register( InfoStream_Type, (Name)"SROpGeneratorStream" );
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+
+ /* Print parent */
+ Journal_Printf( stream, "SROpGenerator (ptr): (%p)\n", self );
+ _MGOpGenerator_Print( self, stream );
+}
+
+void _SROpGenerator_AssignFromXML( void* srOpGenerator, Stg_ComponentFactory* cf, void* data ) {
+ SROpGenerator* self = (SROpGenerator*)srOpGenerator;
+ FeVariable* var;
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+
+ var = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"fineVariable", FeVariable, True, data );
+ SROpGenerator_SetFineVariable( self, var );
+}
+
+void _SROpGenerator_Build( void* srOpGenerator, void* data ) {
+}
+
+void _SROpGenerator_Initialise( void* srOpGenerator, void* data ) {
+}
+
+void _SROpGenerator_Execute( void* srOpGenerator, void* data ) {
+}
+
+void _SROpGenerator_Destroy( void* srOpGenerator, void* data ) {
+}
+
+Bool SROpGenerator_HasExpired( void* srOpGenerator ) {
+ SROpGenerator* self = (SROpGenerator*)srOpGenerator;
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+
+ return False;
+}
+
+//void SROpGenerator_Generate( void* srOpGenerator, Matrix*** pOps, Matrix*** rOps ) {
+void SROpGenerator_Generate( void* srOpGenerator, Mat** pOps, Mat** rOps ) {
+ SROpGenerator* self = (SROpGenerator*)srOpGenerator;
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+ assert( pOps && rOps );
+
+ //*pOps = AllocArray( Matrix*, self->nLevels );
+ //*rOps = AllocArray( Matrix*, self->nLevels );
+ //memset( *pOps, 0, self->nLevels * sizeof(Matrix*) );
+ //memset( *rOps, 0, self->nLevels * sizeof(Matrix*) );
+ *pOps = AllocArray( Mat, self->nLevels );
+ *rOps = AllocArray( Mat, self->nLevels );
+ memset( *pOps, 0, self->nLevels * sizeof(Mat) );
+ memset( *rOps, 0, self->nLevels * sizeof(Mat) );
+
+/*
+ self->fineEqNum = self->fineVar->eqNum;
+ SROpGenerator_GenMeshes( self );
+ SROpGenerator_GenOps( self, *pOps, *rOps );
+ SROpGenerator_DestructMeshes( self );
+*/
+ SROpGenerator_Simple( self, *pOps, *rOps );
+}
+
+
+/*--------------------------------------------------------------------------------------------------------------------------
+** Public Functions
+*/
+
+void SROpGenerator_SetFineVariable( void* srOpGenerator, void* _variable ) {
+ SROpGenerator* self = (SROpGenerator*)srOpGenerator;
+ FeVariable* variable = (FeVariable*)_variable;
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+ assert( !variable || Stg_CheckType( variable, FeVariable ) );
+
+ SROpGenerator_DestructMeshes( self );
+ self->fineVar = variable;
+ self->fineEqNum = NULL;
+}
+
+
+/*----------------------------------------------------------------------------------------------------------------------------------
+** Private Functions
+*/
+
+void SROpGenerator_GenMeshes( SROpGenerator* self ) {
+ unsigned nLevels;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+
+ nLevels = self->nLevels;
+ self->meshes = AllocArray( Mesh*, nLevels );
+ memset( self->meshes, 0, nLevels * sizeof(Mesh*) );
+ self->topMaps = AllocArray( unsigned*, nLevels );
+ memset( self->topMaps, 0, nLevels * sizeof(unsigned*) );
+ self->eqNums = AllocArray( unsigned**, nLevels );
+ memset( self->eqNums, 0, nLevels * sizeof(unsigned**) );
+ self->nLocalEqNums = AllocArray( unsigned, nLevels );
+ memset( self->nLocalEqNums, 0, nLevels * sizeof(unsigned) );
+ self->eqNumBases = AllocArray( unsigned, nLevels );
+ memset( self->eqNumBases, 0, nLevels * sizeof(unsigned) );
+
+ self->meshes[nLevels - 1] = (Mesh*)self->fineEqNum->feMesh;
+ self->eqNumBases[nLevels - 1] = self->fineEqNum->firstOwnedEqNum;
+ for( l_i = nLevels - 2; l_i < nLevels; l_i-- ) {
+ SROpGenerator_GenLevelMesh( self, l_i );
+ SROpGenerator_GenLevelTopMap( self, l_i );
+ SROpGenerator_GenLevelEqNums( self, l_i );
+ }
+}
+
+void SROpGenerator_GenLevelMesh( SROpGenerator* self, unsigned level ) {
+ Stream* errorStream = Journal_Register( ErrorStream_Type, (Name)"SROpGenerator::GenLevelMesh" );
+ Mesh *fMesh, *cMesh;
+ CartesianGenerator *fGen, *cGen;
+ unsigned nDims;
+ unsigned* cSize;
+ double crdMin[3], crdMax[3];
+ unsigned d_i;
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+ assert( self->meshes );
+ assert( level < self->nLevels );
+
+ fMesh = self->meshes[level + 1];
+ nDims = Mesh_GetDimSize( fMesh );
+ fGen = (CartesianGenerator*)fMesh->generator;
+ Journal_Firewall( fGen && !strcmp( fGen->type, CartesianGenerator_Type ),
+ errorStream,
+ "\n" \
+ "****************************************************************\n" \
+ "* Error: Simple regular multigrid operator generation requires *\n" \
+ "* a fine mesh that has been generated with a *\n" \
+ "* cartesian generator. *\n" \
+ "****************************************************************\n" \
+ "\n" );
+
+ cGen = CartesianGenerator_New( "", NULL );
+ CartesianGenerator_SetDimSize( cGen, nDims );
+ cSize = AllocArray( unsigned, nDims );
+ for( d_i = 0; d_i < nDims; d_i++ )
+ cSize[d_i] = fGen->elGrid->sizes[d_i] / 2;
+ CartesianGenerator_SetTopologyParams( cGen, cSize, fGen->maxDecompDims, fGen->minDecomp, fGen->maxDecomp );
+ Mesh_GetGlobalCoordRange( fMesh, crdMin, crdMax );
+ CartesianGenerator_SetGeometryParams( cGen, crdMin, crdMax );
+ CartesianGenerator_SetShadowDepth( cGen, 0 );
+ FreeArray( cSize );
+
+ cMesh = (Mesh*)FeMesh_New( "", NULL );
+ Mesh_SetGenerator( cMesh, cGen );
+ FeMesh_SetElementFamily( cMesh, ((FeMesh*)fMesh)->feElFamily );
+ Stg_Component_Build( cMesh, NULL, False );
+ Stg_Component_Initialise( cMesh, NULL, False );
+ self->meshes[level] = cMesh;
+}
+
+void SROpGenerator_GenLevelTopMap( SROpGenerator* self, unsigned level ) {
+ Stream* errorStream = Journal_Register( ErrorStream_Type, (Name)"SROpGenerator::GenLevelTopMap" );
+ Mesh *fMesh, *cMesh;
+ unsigned nDomainNodes;
+ unsigned nLevels;
+ unsigned nDims;
+ unsigned nearest;
+ double *cVert, *fVert;
+ unsigned d_i, n_i;
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+ assert( self->meshes );
+ assert( level < self->nLevels );
+
+ fMesh = self->meshes[level + 1];
+ cMesh = self->meshes[level];
+ nDims = Mesh_GetDimSize( fMesh );
+ nLevels = self->nLevels;
+ nDomainNodes = Mesh_GetDomainSize( cMesh, MT_VERTEX );
+ self->topMaps[level] = ReallocArray( self->topMaps[level], unsigned, nDomainNodes );
+ for( n_i = 0; n_i < nDomainNodes; n_i++ ) {
+ cVert = Mesh_GetVertex( cMesh, n_i );
+ nearest = Mesh_NearestVertex( fMesh, cVert );
+ fVert = Mesh_GetVertex( fMesh, nearest );
+ for( d_i = 0; d_i < nDims; d_i++ ) {
+ if( !Num_Approx( cVert[d_i], fVert[d_i] ) )
+ break;
+ }
+
+ Journal_Firewall( d_i == nDims,
+ errorStream,
+ "\n" \
+ "*****************************************************************\n" \
+ "* Error: The finest grid could not be sub-sampled to all coarse *\n" \
+ "* levels. This is due to the size of the finest grid. *\n" \
+ "*****************************************************************\n" \
+ "\n" );
+
+ if( level < nLevels - 2 )
+ self->topMaps[level][n_i] = self->topMaps[level + 1][nearest];
+ else
+ self->topMaps[level][n_i] = nearest;
+ }
+}
+
+void SROpGenerator_GenLevelEqNums( SROpGenerator* self, unsigned level ) {
+ Mesh* cMesh;
+ unsigned* nNodalDofs;
+ unsigned nDomainNodes, nLocalNodes;
+ DofLayout* dofLayout;
+ unsigned** dstArray;
+ unsigned curEqNum;
+ unsigned maxDofs;
+ unsigned topNode;
+ unsigned base, subTotal;
+ MPI_Comm comm;
+ unsigned nProcs, rank;
+ MPI_Status status;
+ unsigned* tuples;
+ Sync* sync;
+ unsigned n_i, dof_i;
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+ assert( self->meshes && self->topMaps && self->eqNums );
+ assert( level < self->nLevels );
+
+ cMesh = self->meshes[level];
+ nDomainNodes = Mesh_GetDomainSize( cMesh, MT_VERTEX );
+ nLocalNodes = Mesh_GetLocalSize( cMesh, MT_VERTEX );
+ dofLayout = self->fineEqNum->dofLayout;
+ comm = Comm_GetMPIComm( Mesh_GetCommTopology( cMesh, MT_VERTEX ) );
+ MPI_Comm_size( comm, (int*)&nProcs );
+ MPI_Comm_rank( comm, (int*)&rank );
+
+ /* Allocate for destination array. */
+ nNodalDofs = AllocArray( unsigned, nDomainNodes );
+ for( n_i = 0; n_i < nDomainNodes; n_i++ )
+ nNodalDofs[n_i] = dofLayout->dofCounts[self->topMaps[level][n_i]];
+ dstArray = AllocComplex2D( unsigned, nDomainNodes, nNodalDofs );
+
+ /* Build initial destination array and store max dofs. */
+ curEqNum = 0;
+ maxDofs = 0;
+ for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
+ if( nNodalDofs[n_i] > maxDofs )
+ maxDofs = nNodalDofs[n_i];
+
+ topNode = self->topMaps[level][n_i];
+ for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
+ if( self->fineEqNum->destinationArray[topNode][dof_i] != (unsigned)-1 )
+ dstArray[n_i][dof_i] = curEqNum++;
+ else
+ dstArray[n_i][dof_i] = (unsigned)-1;
+ }
+ }
+
+ /* Order the equation numbers based on processor rank; cascade counts forward. */
+ base = 0;
+ subTotal = curEqNum;
+ if( rank > 0 ) {
+ insist( MPI_Recv( &base, 1, MPI_UNSIGNED, rank - 1, 6669, comm, &status ), == MPI_SUCCESS );
+ subTotal = base + curEqNum;
+ }
+ if( rank < nProcs - 1 )
+ insist( MPI_Send( &subTotal, 1, MPI_UNSIGNED, rank + 1, 6669, comm ), == MPI_SUCCESS );
+
+ /* Modify existing destination array and dump to a tuple array. */
+ tuples = AllocArray( unsigned, nDomainNodes * maxDofs );
+ for( n_i = 0; n_i < nLocalNodes; n_i++ ) {
+ for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
+ if( dstArray[n_i][dof_i] != (unsigned)-1 )
+ dstArray[n_i][dof_i] += base;
+ tuples[n_i * maxDofs + dof_i] = dstArray[n_i][dof_i];
+ }
+ }
+
+ /* Update all other procs. */
+ sync = Mesh_GetSync( cMesh, MT_VERTEX );
+ Sync_SyncArray( sync, tuples, maxDofs * sizeof(unsigned),
+ tuples + nLocalNodes * maxDofs, maxDofs * sizeof(unsigned),
+ maxDofs * sizeof(unsigned) );
+
+ /* Update destination array's domain indices. */
+ for( n_i = nLocalNodes; n_i < nDomainNodes; n_i++ ) {
+ topNode = self->topMaps[level][n_i];
+ for( dof_i = 0; dof_i < nNodalDofs[n_i]; dof_i++ ) {
+ if( self->fineEqNum->destinationArray[topNode][dof_i] != (unsigned)-1 )
+ dstArray[n_i][dof_i] = tuples[n_i * maxDofs + dof_i];
+ else
+ dstArray[n_i][dof_i] = -1;
+ }
+ }
+
+ /* Destroy arrays. */
+ FreeArray( nNodalDofs );
+ FreeArray( tuples );
+
+ self->eqNums[level] = dstArray;
+ self->nLocalEqNums[level] = curEqNum;
+ self->eqNumBases[level] = base;
+}
+
+//void SROpGenerator_GenOps( SROpGenerator* self, Matrix** pOps, Matrix** rOps ) {
+void SROpGenerator_GenOps( SROpGenerator* self, Mat* pOps, Mat* rOps ) {
+ unsigned nLevels;
+ //Matrix *fineMat, *P;
+ Mat fineMat, P;
+ unsigned nRows, nCols;
+ unsigned l_i;
+ /* unsigned nProcs; */
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+ assert( pOps && rOps );
+
+ //fineMat = MatrixSolver_GetMatrix( self->solver );
+ fineMat = self->solver->matrix;
+ nLevels = self->nLevels;
+
+ for( l_i = nLevels - 1; l_i > 0; l_i-- ) {
+ nRows = self->eqNums[l_i] ? self->nLocalEqNums[l_i] :
+ self->fineEqNum->localEqNumsOwnedCount;
+ nCols = self->nLocalEqNums[l_i - 1];
+
+ //Matrix_Duplicate( fineMat, (void**)&P );
+ //Matrix_SetComm( P, fineMat->comm );
+ //Matrix_SetLocalSize( P, nRows, nCols );
+ MatCreate( self->solver->comm, &P );
+ MatSetSizes( P, nRows, nCols, PETSC_DETERMINE, PETSC_DETERMINE );
+ MatSetFromOptions( P );
+ //if( !strcmp( P->type, PETScMatrix_Type ) ) {
+ // unsigned *nDiagNonZeros, *nOffDiagNonZeros;
+ //
+ // SROpGenerator_CalcOpNonZeros( self, l_i, &nDiagNonZeros, &nOffDiagNonZeros );
+ //PETScMatrix_SetNonZeroStructure( (PETScMatrix*)P, 0, nDiagNonZeros, nOffDiagNonZeros );
+ // MPI_Comm_size( self->solver->comm, &nProcs );
+ // if( nProcs > 1 )
+ // MatMPIAIJSetPreallocation( P, PETSC_NULL, nDiagNonZeros, PETSC_NULL, nOffDiagNonZeros );
+ // else
+ // MatSeqAIJSetPreallocation( P, PETSC_NULL, nDiagNonZeros );
+ // FreeArray( nDiagNonZeros );
+ // FreeArray( nOffDiagNonZeros );
+ //}
+
+ SROpGenerator_GenLevelOp( self, l_i, P );
+ pOps[l_i] = P;
+ //Stg_Class_AddRef( P );
+ rOps[l_i] = P;
+ //Stg_Class_AddRef( P );
+ }
+}
+
+//void SROpGenerator_GenLevelOp( SROpGenerator* self, unsigned level, Matrix* P ) {
+void SROpGenerator_GenLevelOp( SROpGenerator* self, unsigned level, Mat P ) {
+ Mesh *fMesh, *cMesh;
+ unsigned nDims;
+ unsigned nLocalFineNodes;
+ DofLayout* dofLayout;
+ unsigned ind;
+ unsigned nInc, *inc;
+ unsigned maxInc;
+ unsigned fTopNode, cTopNode;
+ unsigned fEqNum, cEqNum;
+ double *localCoord, *basis;
+ IArray *incArray;
+ unsigned n_i, dof_i, inc_i, e_i;
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+ assert( self->meshes );
+ assert( level < self->nLevels );
+ assert( P );
+
+ fMesh = self->meshes[level];
+ cMesh = self->meshes[level - 1];
+ nDims = Mesh_GetDimSize( fMesh );
+ nLocalFineNodes = Mesh_GetLocalSize( fMesh, MT_VERTEX );
+ dofLayout = self->fineEqNum->dofLayout;
+ localCoord = AllocArray( double, nDims );
+
+ maxInc = 0;
+ for( e_i = 0; e_i < Mesh_GetDomainSize( cMesh, (MeshTopology_Dim)nDims ); e_i++ ) {
+ nInc = Mesh_GetIncidenceSize( cMesh, (MeshTopology_Dim)nDims, e_i, MT_VERTEX );
+ if( nInc > maxInc )
+ maxInc = nInc;
+ }
+ basis = AllocArray( double, maxInc );
+
+ incArray = IArray_New();
+ for( n_i = 0; n_i < nLocalFineNodes; n_i++ ) {
+ if( self->topMaps[level] )
+ fTopNode = self->topMaps[level][n_i];
+ else
+ fTopNode = n_i;
+
+ for( dof_i = 0; dof_i < dofLayout->dofCounts[fTopNode]; dof_i++ ) {
+ if( self->eqNums[level] )
+ fEqNum = self->eqNums[level][n_i][dof_i];
+ else
+ fEqNum = self->fineEqNum->destinationArray[fTopNode][dof_i];
+
+ if( fEqNum == (unsigned)-1 )
+ continue;
+
+ insist( Mesh_SearchElements( cMesh, Mesh_GetVertex( fMesh, n_i ), &ind ), == True );
+ FeMesh_CoordGlobalToLocal( cMesh, ind, Mesh_GetVertex( fMesh, n_i ), localCoord );
+ FeMesh_EvalBasis( cMesh, ind, localCoord, basis );
+ Mesh_GetIncidence( cMesh, (MeshTopology_Dim)nDims, ind, MT_VERTEX, incArray );
+ nInc = IArray_GetSize( incArray );
+ inc = (unsigned*)IArray_GetPtr( incArray );
+ for( inc_i = 0; inc_i < nInc; inc_i++ ) {
+ cTopNode = self->topMaps[level - 1][inc[inc_i]];
+ cEqNum = self->eqNums[level - 1][inc[inc_i]][dof_i];
+ if( cEqNum != (unsigned)-1 && !Num_Approx( basis[inc_i], 0.0 ) )
+ //Matrix_InsertEntries( P, 1, &fEqNum, 1, &cEqNum, basis + inc_i );
+ MatSetValues( P, 1, (PetscInt*)(&fEqNum), 1, (PetscInt*)(&cEqNum), basis + inc_i, INSERT_VALUES );
+ }
+ }
+ }
+ NewClass_Delete( incArray );
+
+ FreeArray( localCoord );
+ FreeArray( basis );
+
+ //Matrix_AssemblyBegin( P );
+ //Matrix_AssemblyEnd( P );
+ MatAssemblyBegin( P, MAT_FINAL_ASSEMBLY );
+ MatAssemblyEnd( P, MAT_FINAL_ASSEMBLY );
+}
+
+void SROpGenerator_CalcOpNonZeros( SROpGenerator* self, unsigned level,
+ unsigned** nDiagNonZeros, unsigned** nOffDiagNonZeros )
+{
+ Mesh *fMesh, *cMesh;
+ unsigned nLocalFineNodes;
+ DofLayout* dofLayout;
+ unsigned dim, ind;
+ unsigned nInc, *inc;
+ unsigned fTopNode, cTopNode;
+ unsigned fEqNum, cEqNum;
+ unsigned nLocalEqNums;
+ IArray* incArray;
+ unsigned n_i, dof_i, dof_j, inc_i;
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+ assert( self->meshes );
+ assert( level < self->nLevels );
+
+ fMesh = self->meshes[level];
+ cMesh = self->meshes[level - 1];
+ nLocalFineNodes = Mesh_GetLocalSize( fMesh, MT_VERTEX );
+ dofLayout = self->fineEqNum->dofLayout;
+ if( self->eqNums[level] )
+ nLocalEqNums = self->nLocalEqNums[level];
+ else
+ nLocalEqNums = self->fineEqNum->localEqNumsOwnedCount;
+
+ *nDiagNonZeros = AllocArray( unsigned, nLocalEqNums );
+ memset( *nDiagNonZeros, 0, nLocalEqNums * sizeof(unsigned) );
+ *nOffDiagNonZeros = AllocArray( unsigned, nLocalEqNums );
+ memset( *nOffDiagNonZeros, 0, nLocalEqNums * sizeof(unsigned) );
+
+ incArray = IArray_New();
+
+ for( n_i = 0; n_i < nLocalFineNodes; n_i++ ) {
+ if( self->topMaps[level] )
+ fTopNode = self->topMaps[level][n_i];
+ else
+ fTopNode = n_i;
+
+ for( dof_i = 0; dof_i < dofLayout->dofCounts[fTopNode]; dof_i++ ) {
+ if( self->eqNums[level] )
+ fEqNum = self->eqNums[level][n_i][dof_i];
+ else
+ fEqNum = self->fineEqNum->destinationArray[fTopNode][dof_i];
+
+ if( fEqNum == (unsigned)-1 )
+ continue;
+
+ insist( Mesh_SearchElements( cMesh, Mesh_GetVertex( fMesh, n_i ), &ind ), == True );
+ dim = Mesh_GetDimSize( fMesh );
+ if( dim == MT_VERTEX ) {
+ cTopNode = self->topMaps[level - 1][ind];
+ for( dof_j = 0; dof_j < dofLayout->dofCounts[cTopNode]; dof_j++ ) {
+ cEqNum = self->eqNums[level - 1][ind][dof_j];
+ if( cEqNum == (unsigned)-1 )
+ continue;
+
+ if( cEqNum - self->eqNumBases[level - 1] < nLocalEqNums )
+ (*nDiagNonZeros)[fEqNum - self->eqNumBases[level]]++;
+ else
+ (*nOffDiagNonZeros)[fEqNum - self->eqNumBases[level]]++;
+ }
+ }
+ else {
+ Mesh_GetIncidence( cMesh, (MeshTopology_Dim)dim, ind, MT_VERTEX, incArray );
+ nInc = IArray_GetSize( incArray );
+ inc = (unsigned*)IArray_GetPtr( incArray );
+ for( inc_i = 0; inc_i < nInc; inc_i++ ) {
+ cTopNode = self->topMaps[level - 1][inc[inc_i]];
+ for( dof_j = 0; dof_j < dofLayout->dofCounts[cTopNode]; dof_j++ ) {
+ cEqNum = self->eqNums[level - 1][inc[inc_i]][dof_j];
+ if( cEqNum == (unsigned)-1 )
+ continue;
+
+ if( cEqNum - self->eqNumBases[level - 1] < nLocalEqNums )
+ (*nDiagNonZeros)[fEqNum - self->eqNumBases[level]]++;
+ else
+ (*nOffDiagNonZeros)[fEqNum - self->eqNumBases[level]]++;
+ }
+ }
+ }
+ }
+ }
+
+ NewClass_Delete( incArray );
+}
+
+void SROpGenerator_DestructMeshes( SROpGenerator* self ) {
+ unsigned nLevels;
+ unsigned l_i;
+
+ assert( self && Stg_CheckType( self, SROpGenerator ) );
+
+ if( self->meshes ) {
+ nLevels = self->nLevels;
+ for( l_i = 0; l_i < nLevels - 1; l_i++ ) {
+ FreeObject( self->meshes[l_i] );
+ FreeArray( self->topMaps[l_i] );
+ FreeArray( self->eqNums[l_i] );
+ }
+ KillArray( self->meshes );
+ KillArray( self->topMaps );
+ KillArray( self->eqNums );
+ KillArray( self->nLocalEqNums );
+ KillArray( self->eqNumBases );
+ }
+}
+
+
+//void SROpGenerator_Simple( SROpGenerator *self, Matrix **pOps, Matrix **rOps ) {
+void SROpGenerator_Simple( SROpGenerator *self, Mat* pOps, Mat* rOps ) {
+ double t0;
+ if( self->nLevels > 1 ) {
+ //Matrix *P;
+ Mat P;
+ int ii;
+
+ t0 = MPI_Wtime();
+ P = SROpGenerator_SimpleFinestLevel( self );
+ PetscPrintf( PETSC_COMM_WORLD, "SROpGenerator_SimpleFinestLevel: time = %5.5e \n", MPI_Wtime()-t0 );
+ pOps[self->nLevels - 1] = rOps[self->nLevels - 1] = P;
+ for( ii = self->nLevels - 2; ii > 0; ii-- ) {
+ t0 = MPI_Wtime();
+ P = SROpGenerator_SimpleCoarserLevel( self, ii );
+ PetscPrintf( PETSC_COMM_WORLD, " [%d] SROpGenerator_SimpleCoarserLevel: time = %5.5e \n",ii, MPI_Wtime()-t0 );
+ pOps[ii] = rOps[ii] = P;
+ }
+ }
+}
+
+
+PetscErrorCode _VecGetOwnershipRanges( Vec X, PetscInt **_ranges )
+{
+ PetscInt start,end;
+ PetscMPIInt nproc,rank;
+ MPI_Comm comm;
+ Vec all, out;
+ VecScatter scat;
+ PetscInt *ranges,i;
+ PetscScalar *v;
+ double t0;
+
+ t0 = MPI_Wtime();
+
+ PetscObjectGetComm( (PetscObject)X, &comm );
+ MPI_Comm_size( comm, &nproc );
+ MPI_Comm_rank( comm, &rank );
+ VecGetOwnershipRange( X, &start, &end );
+
+ VecCreate( comm, &all );
+ VecSetSizes( all, PETSC_DECIDE, nproc+1 );
+ VecSetFromOptions( all );
+
+ VecSetValue( all, rank, (PetscScalar)start, INSERT_VALUES );
+ VecSetValue( all, rank+1, (PetscScalar)end, INSERT_VALUES );
+ VecAssemblyBegin( all );
+ VecAssemblyEnd( all );
+
+ VecScatterCreateToAll( all, &scat, &out );
+
+#if(PETSC_VERSION_SUBMINOR==2)
+ VecScatterBegin(all,out,INSERT_VALUES,SCATTER_FORWARD,scat);
+ VecScatterEnd(all,out,INSERT_VALUES,SCATTER_FORWARD,scat);
+#elif(PETSC_VERSION_SUBMINOR==3)
+ VecScatterBegin(scat, all,out,INSERT_VALUES,SCATTER_FORWARD);
+ VecScatterEnd(scat, all,out,INSERT_VALUES,SCATTER_FORWARD);
+#endif
+
+ PetscMalloc( sizeof(PetscInt)*(nproc+1), &ranges );
+ VecGetArray( out, &v );
+ for( i=0; i<nproc+1; i++ ) {
+ ranges[i] = (PetscInt)v[i];
+ }
+ VecRestoreArray( out, &v );
+
+ *_ranges = ranges;
+
+ VecScatterDestroy( scat );
+ VecDestroy( out );
+ VecDestroy( all );
+
+
+ PetscFunctionReturn(0);
+}
+
+
+/*
+Efficiency alert!!
+ This comments relates to both SROpGenerator_SimpleFinestLevel() and
+ SROpGenerator_SimpleCoarserLevel().
+
+ For O(n) setup times, we MUST provide some information concerning the
+ preallocation of the nonzero structure for the restriction operators.
+
+ As a first hack we check the spatial dimension and choose a value accordingly.
+ In doing so we have assumed that the fine grid is obtained by bisecting
+ the coarse grid. Coarse grid nodes are hiearchical. We have also assumed
+ that the elements are quads (2d) and hexs (3d).
+
+ The hack above made little effort to miminise memory usage and as such we allocate
+ the same amount of memory for the on and off diagonal parts of the restriction
+ operator. This kinda kills use in parallel.
+
+ An more accurate estimate has thus been implemented.
+*/
+//Matrix *SROpGenerator_SimpleFinestLevel( SROpGenerator *self ) {
+Mat SROpGenerator_SimpleFinestLevel( SROpGenerator *self ) {
+ FeMesh *mesh;
+ int nDims, nDofsPerNode;
+ int sideSizes[2][3];
+ int inds[2][3], offsInds[3], nOffs[3];
+ int nGlobalNodes[2];
+ int nGlobalEqs[2];
+ Grid *vertGrid, *elGrid, *grid[2], *offsGrid;
+ int nodes[8];
+ int nodeInd;
+ double dfrac;
+ int nEntries, indices[8];
+ double values[8];
+ Mat P;
+ //PETScMatrix *mat;
+ Mat mat;
+ int ii, jj, kk;
+ PetscInt o_nz, d_nz;
+ PetscInt *o_nnz, *d_nnz;
+ PetscInt sr,er, sc,ec, row_idx;
+ Vec vec_o_nnz, vec_d_nnz;
+ PetscScalar *v;
+ PetscTruth is_seq;
+ PetscInt p, proc_owner, *rranges,*cranges;
+ MPI_Comm comm;
+ PetscMPIInt nproc,rank;
+
+ /* Calculate level side lengths. */
+ mesh = self->fineVar->feMesh;
+ nDims = Mesh_GetDimSize( mesh );
+
+ /* crude estimate of number of nonzeros in the on-off diagonal portitions of the matrix */
+ o_nz = d_nz = 0;
+ if( nDims == 2 ) {
+ o_nz = d_nz = 4;
+ }
+ if( nDims==3 ) {
+ o_nz = d_nz = 8;
+ }
+
+ nDofsPerNode = self->fineVar->dofLayout->dofCounts[0]; /* ASSUME */
+ elGrid = *Mesh_GetExtension( mesh, Grid**, "elementGrid" );
+ vertGrid = *Mesh_GetExtension( mesh, Grid**, "vertexGrid" );
+ nGlobalNodes[0] = nGlobalNodes[1] = 1;
+ for( ii = 0; ii < nDims; ii++ ) {
+ sideSizes[1][ii] = elGrid->sizes[ii];
+ sideSizes[0][ii] = elGrid->sizes[ii] / 2;
+ if( sideSizes[0][ii] * 2 != elGrid->sizes[ii] ) {
+ printf( "(MG) Error: Too many levels specified for geometric multigrid.\n" );
+ printf( " Please modify mesh size or reduce number of levels.\n" );
+ exit( 1 );
+ }
+ sideSizes[1][ii]++; sideSizes[0][ii]++;
+ nGlobalNodes[1] *= sideSizes[1][ii];
+ nGlobalNodes[0] *= sideSizes[0][ii];
+ }
+
+ /* Have PETSc create the operator matrix and then extract local sizes
+ and offsets into the global vector. */
+ nGlobalEqs[1] = nGlobalNodes[1] * nDofsPerNode;
+ nGlobalEqs[0] = nGlobalNodes[0] * nDofsPerNode;
+/*
+ MatCreateMPIAIJ( MPI_COMM_WORLD,
+ self->fineVar->eqNum->localEqNumsOwnedCount, PETSC_DECIDE,
+ PETSC_DECIDE, nGlobalEqs[0],
+ o_nz, PETSC_NULL, d_nz, PETSC_NULL, &P );
+
+*/
+ MatCreate( MPI_COMM_WORLD, &P );
+ MatSetSizes( P, self->fineVar->eqNum->localEqNumsOwnedCount, PETSC_DECIDE, PETSC_DECIDE, nGlobalEqs[0] );
+ MatSetType( P, MATAIJ );
+// MatGetOwnershipRange( P, &sr, &er );
+
+ PetscObjectGetComm( (PetscObject)P, &comm );
+ MPI_Comm_size( comm, &nproc );
+ MPI_Comm_rank( comm, &rank );
+
+// printf( " sr,er = %d -> %d \n", sr, er );
+ { Vec L,R;
+ PetscInt M,N, m,n;
+
+ MatGetSize( P, &M,&N );
+ MatGetLocalSize( P, &m,&n );
+// PetscPrintf( PETSC_COMM_WORLD, "size = %D x %D \n", M, N );
+ MatGetVecs( P, &R, &L );
+ VecGetOwnershipRange( L, &sr,&er );
+ VecGetOwnershipRange( R, &sc,&ec );
+// printf( " [%d] mxn = %d x %d ; sr,er = %d -> %d ; sc,ec = %d -> %d \n", rank, m,n, sr,er, sc,ec );
+
+ _VecGetOwnershipRanges( L, &rranges );
+ _VecGetOwnershipRanges( R, &cranges );
+
+ VecDestroy( L );
+ VecDestroy( R );
+ }
+
+ PetscMalloc( sizeof(PetscInt)*(er-sr), &o_nnz );
+ PetscMalloc( sizeof(PetscInt)*(er-sr), &d_nnz );
+
+ /* Need a grid representing the coarse level. */
+ grid[0] = Grid_New();
+ offsGrid = Grid_New();
+ Grid_SetNumDims( grid[0], nDims );
+ Grid_SetNumDims( offsGrid, nDims );
+ Grid_SetSizes( grid[0], (unsigned*)(sideSizes[0]) );
+
+ /* Determine preallocation information */
+ MatGetVecs( P, PETSC_NULL, &vec_d_nnz );
+ VecDuplicate( vec_d_nnz, &vec_o_nnz );
+
+ /* Loop over fine nodes. */
+ for( ii = 0; ii < Mesh_GetLocalSize( mesh, (MeshTopology_Dim)0 ); ii++ ) {
+ nodeInd = Mesh_DomainToGlobal( mesh, (MeshTopology_Dim)0, ii );
+ Grid_Lift( vertGrid, nodeInd, (unsigned*)(inds[1]) );
+
+ /* An odd grid index means we need to interpolate from surrounding
+ coarse nodes in the current dimension. */
+ for( jj = 0; jj < nDims; jj++ ) {
+ /* Store the offsets we need to consider. */
+ nOffs[jj] = (inds[1][jj] & 1) ? 2 : 1;
+ }
+
+ /* 'Multiply' the offsets to build the set of nodes we need to
+ interpolate from. */
+ Grid_SetSizes( offsGrid, (unsigned*)nOffs );
+ for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
+ Grid_Lift( offsGrid, jj, (unsigned*)offsInds );
+ for( kk = 0; kk < nDims; kk++ )
+ inds[0][kk] = (inds[1][kk] >> 1) + offsInds[kk];
+
+ /* Store the coarse global node number. */
+ nodes[jj] = Grid_Project( grid[0], (unsigned*)(inds[0]) );
+ }
+
+ /* Insert this row into the operator matrix. */
+ nEntries = offsGrid->nPoints;
+ for( kk = 0; kk < nDofsPerNode; kk++ ) {
+ /* Skip the entire thing if it's a BC. */
+ if( self->fineVar->eqNum->destinationArray[ii][kk] == -1 )
+ continue;
+
+ row_idx = (PetscInt)(self->fineVar->eqNum->destinationArray[ii][kk]);
+
+
+ /* find owning proc */
+ proc_owner = -1;
+ for( p=0; p<nproc; p++ ) {
+ if( (row_idx>=rranges[p]) && (row_idx<rranges[p+1]) ) {
+ proc_owner = p;
+ break;
+ }
+ }
+
+
+ for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
+ indices[jj] = nodes[jj] * nDofsPerNode + kk;
+ // printf( "[%d]: (owner=%d): row=%d : c_index=%d \n", rank, proc_owner, row_idx, indices[jj] );
+ if( (row_idx>=rranges[proc_owner]) && (row_idx<rranges[proc_owner+1]) ) {
+ if( (indices[jj]>=cranges[proc_owner]) && (indices[jj]<cranges[proc_owner+1]) ) {
+ VecSetValue( vec_d_nnz, row_idx, 1.0, ADD_VALUES );
+ }
+ else {
+ VecSetValue( vec_o_nnz, row_idx, 1.0, ADD_VALUES );
+ }
+ }
+ }
+
+
+/*
+ for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
+ indices[jj] = nodes[jj] * nDofsPerNode + kk;
+ printf( "[%d]: row=%d : c_index=%d \n", rank, row_idx, indices[jj] );
+ if( (row_idx>=sr) && (row_idx<er) ) {
+ if( (indices[jj]>=sc) && (indices[jj]<ec) ) {
+ VecSetValue( vec_d_nnz, row_idx, 1.0, ADD_VALUES );
+ }
+ }
+ else {
+ VecSetValue( vec_o_nnz, row_idx, 1.0, ADD_VALUES );
+ }
+ }
+*/
+
+
+ }
+ }
+ VecAssemblyBegin( vec_d_nnz );
+ VecAssemblyEnd( vec_d_nnz );
+
+ VecAssemblyBegin( vec_o_nnz );
+ VecAssemblyEnd( vec_o_nnz );
+
+ VecGetArray( vec_d_nnz, &v );
+ for( kk=0; kk<(er-sr); kk++ ) {
+ d_nnz[kk] = (PetscInt)v[kk];
+ }
+ VecRestoreArray( vec_d_nnz, &v );
+
+ VecGetArray( vec_o_nnz, &v );
+ for( kk=0; kk<(er-sr); kk++ ) {
+ o_nnz[kk] = (PetscInt)v[kk];
+ }
+ VecRestoreArray( vec_o_nnz, &v );
+
+ PetscTypeCompare( (PetscObject)vec_o_nnz, VECSEQ, &is_seq );
+ if(nproc==1) {
+ MatSeqAIJSetPreallocation( P, PETSC_NULL, d_nnz );
+ }
+ else {
+// for( kk=0; kk<(er-sr); kk++ ) {
+// printf( "[%d]: row=%d : d_nnz=%d : o_nnz=%d \n", rank, kk+sr, d_nnz[kk], o_nnz[kk] );
+// }
+ MatMPIAIJSetPreallocation( P, PETSC_NULL, d_nnz, PETSC_NULL, o_nnz );
+
+// MatMPIAIJSetPreallocation( P, d_nz,PETSC_NULL, o_nz,PETSC_NULL );
+ }
+
+ /* Loop over fine nodes. */
+ for( ii = 0; ii < Mesh_GetLocalSize( mesh, (MeshTopology_Dim)0 ); ii++ ) {
+// if( ii%5000 == 0 ) {
+// PetscPrintf( PETSC_COMM_WORLD, "Done %d of %d \n", ii, Mesh_GetLocalSize( mesh, 0 ) );
+// }
+ nodeInd = Mesh_DomainToGlobal( mesh, (MeshTopology_Dim)0, ii );
+ Grid_Lift( vertGrid, nodeInd, (unsigned*)(inds[1]) );
+
+ /* An odd grid index means we need to interpolate from surrounding
+ coarse nodes in the current dimension. */
+ for( jj = 0; jj < nDims; jj++ ) {
+ /* Store the offsets we need to consider. */
+ nOffs[jj] = (inds[1][jj] & 1) ? 2 : 1;
+ }
+
+ /* 'Multiply' the offsets to build the set of nodes we need to
+ interpolate from. */
+ Grid_SetSizes( offsGrid, (unsigned*)nOffs );
+ for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
+ Grid_Lift( offsGrid, jj, (unsigned*)offsInds );
+ for( kk = 0; kk < nDims; kk++ )
+ inds[0][kk] = (inds[1][kk] >> 1) + offsInds[kk];
+
+ /* Store the coarse global node number. */
+ nodes[jj] = Grid_Project( grid[0], (unsigned*)(inds[0]) );
+ }
+
+ /* Insert this row into the operator matrix. */
+ dfrac = 1.0 / (double)offsGrid->nPoints;
+ nEntries = offsGrid->nPoints;
+ for( kk = 0; kk < nDofsPerNode; kk++ ) {
+ /* Skip the entire thing if it's a BC. */
+ if( self->fineVar->eqNum->destinationArray[ii][kk] == -1 )
+ continue;
+
+ for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
+ indices[jj] = nodes[jj] * nDofsPerNode + kk;
+ values[jj] = dfrac;
+ }
+ MatSetValues( P, 1, self->fineVar->eqNum->destinationArray[ii] + kk,
+ nEntries, indices, values, INSERT_VALUES );
+ }
+ }
+// PetscPrintf( PETSC_COMM_WORLD, "Done all MatSetValues \n");
+
+ /* Assemble the matrix. */
+ MatAssemblyBegin( P, MAT_FINAL_ASSEMBLY );
+ MatAssemblyEnd( P, MAT_FINAL_ASSEMBLY );
+
+/*
+ {
+ PetscInt M,N, m,n;
+ for( p=0; p<nproc; p++ ) {
+ PetscPrintf( PETSC_COMM_WORLD, "[%d]: r_range (%d->%d) ; c_range (%d->%d)\n", p, rranges[p], rranges[p+1], cranges[p], cranges[p+1] );
+ }
+
+ MatGetSize( P, &M,&N );
+ MatGetLocalSize( P, &m,&n );
+ PetscPrintf( PETSC_COMM_WORLD, "P_size = %D x %D \n", M, N );
+ MatGetOwnershipRange( P, &sr,&er );
+ printf( " [%d] mxn = %d x %d ; sr,er = %d -> %d (local rows=%d) \n", rank, m,n, sr,er, er-sr );
+ }
+ PetscViewerSetFormat( PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_ASCII_DENSE );
+ MatView( P, PETSC_VIEWER_STDOUT_WORLD );
+*/
+
+ /* Piss off those grids. */
+ Stg_Class_Delete( grid[0] );
+
+ Stg_Class_Delete(offsGrid);
+
+ VecDestroy( vec_o_nnz );
+ VecDestroy( vec_d_nnz );
+ PetscFree( o_nnz );
+ PetscFree( d_nnz );
+ PetscFree( rranges );
+ PetscFree( cranges );
+
+
+ /* Create a new matrix. */
+ //mat = PETScMatrix_New( "" );
+ //mat->petscMat = P;
+ mat = P;
+ return mat;
+}
+
+//Matrix *SROpGenerator_SimpleCoarserLevel( SROpGenerator *self, int level ) {
+Mat SROpGenerator_SimpleCoarserLevel( SROpGenerator *self, int level ) {
+ FeMesh *mesh;
+ int nDims, nDofsPerNode, rowDof;
+ int sideSizes[2][3];
+ int inds[2][3], offsInds[3], nOffs[3];
+ int nGlobalNodes[2];
+ int nGlobalEqs[2];
+ int eqRangeBegin, eqRangeEnd;
+ Grid *vertGrid, *elGrid, *grid[2], *offsGrid;
+ int nodes[8];
+ int ifrac, nodeInd;
+ double dfrac;
+ int nEntries, indices[8];
+ double values[8];
+ Mat P;
+ //PETScMatrix *mat;
+ Mat mat;
+ int ii, jj, kk;
+ PetscInt o_nz, d_nz;
+ PetscInt *o_nnz, *d_nnz;
+ PetscInt sr,er, sc,ec, row_idx;
+ Vec vec_o_nnz, vec_d_nnz;
+ PetscScalar *v;
+ PetscInt p, proc_owner, *row_ranges, *col_ranges;
+ MPI_Comm comm;
+ PetscMPIInt nproc;
+
+ /* Calculate depth fraction. */
+ ifrac = 1;
+ for( ii = 0; ii < self->nLevels - level - 1; ii++ )
+ ifrac *= 2;
+
+ /* Calculate level side lengths. */
+ mesh = self->fineVar->feMesh;
+ nDims = Mesh_GetDimSize( mesh );
+
+ /* crude estimate of number of nonzeros in the on-off diagonal portitions of the matrix */
+ o_nz = d_nz = 0;
+ if( nDims==2 ) {
+ o_nz = d_nz = 4;
+ }
+ if( nDims==3 ) {
+ o_nz = d_nz = 8;
+ }
+
+ nDofsPerNode = self->fineVar->dofLayout->dofCounts[0]; /* ASSUME */
+ elGrid = *Mesh_GetExtension( mesh, Grid**, "elementGrid" );
+ vertGrid = *Mesh_GetExtension( mesh, Grid**, "vertexGrid" );
+ nGlobalNodes[0] = nGlobalNodes[1] = 1;
+ for( ii = 0; ii < nDims; ii++ ) {
+ sideSizes[1][ii] = elGrid->sizes[ii] / ifrac;
+ sideSizes[0][ii] = elGrid->sizes[ii] / (ifrac * 2);
+ if( sideSizes[1][ii] * ifrac != elGrid->sizes[ii] ||
+ sideSizes[0][ii] * (ifrac * 2) != elGrid->sizes[ii] )
+ {
+ printf( "(MG) Error: Too many levels specified for geometric multigrid.\n" );
+ printf( " Please modify mesh size or reduce number of levels.\n" );
+ exit( 1 );
+ }
+ sideSizes[1][ii]++; sideSizes[0][ii]++;
+ nGlobalNodes[1] *= sideSizes[1][ii];
+ nGlobalNodes[0] *= sideSizes[0][ii];
+ }
+
+ /* Have PETSc create the operator matrix and then extract local sizes
+ and offsets into the global vector. */
+ nGlobalEqs[1] = nGlobalNodes[1] * nDofsPerNode;
+ nGlobalEqs[0] = nGlobalNodes[0] * nDofsPerNode;
+
+/*
+ MatCreateMPIAIJ( MPI_COMM_WORLD,
+ PETSC_DECIDE, PETSC_DECIDE, nGlobalEqs[1], nGlobalEqs[0],
+ o_nz, PETSC_NULL, d_nz, PETSC_NULL, &P );
+ MatGetOwnershipRange( P, &eqRangeBegin, &eqRangeEnd );
+*/
+ MatCreate( MPI_COMM_WORLD, &P );
+ MatSetSizes( P, PETSC_DECIDE, PETSC_DECIDE, nGlobalEqs[1], nGlobalEqs[0] );
+ MatSetType( P, MATAIJ );
+ MatGetOwnershipRange( P, &eqRangeBegin, &eqRangeEnd );
+
+ {
+ Vec L,R;
+ PetscInt M,N;
+ MatGetSize( P, &M,&N );
+// PetscPrintf( PETSC_COMM_WORLD, "size = %D x %D \n", M, N );
+ MatGetVecs( P, &R, &L );
+ VecGetOwnershipRange( L, &sr,&er );
+ VecGetOwnershipRange( R, &sc,&ec );
+// printf( " 2) sr,er = %d -> %d \n", sr, er );
+// printf( " 2) sc,ec = %d -> %d \n", sc, ec );
+
+ _VecGetOwnershipRanges( L, &row_ranges );
+ _VecGetOwnershipRanges( R, &col_ranges );
+
+ VecDestroy( L );
+ VecDestroy( R );
+ }
+
+
+ PetscMalloc( sizeof(PetscInt)*(er-sr), &o_nnz );
+ PetscMalloc( sizeof(PetscInt)*(er-sr), &d_nnz );
+
+
+
+ /* Need a grid representing the coarse level. */
+ grid[1] = Grid_New();
+ grid[0] = Grid_New();
+ offsGrid = Grid_New();
+ Grid_SetNumDims( grid[1], nDims );
+ Grid_SetNumDims( grid[0], nDims );
+ Grid_SetNumDims( offsGrid, nDims );
+ Grid_SetSizes( grid[1], (unsigned*)(sideSizes[1]) );
+ Grid_SetSizes( grid[0], (unsigned*)(sideSizes[0]) );
+
+ /* Determine preallocation */
+ MatGetVecs( P, PETSC_NULL, &vec_d_nnz );
+ VecDuplicate( vec_d_nnz, &vec_o_nnz );
+ PetscObjectGetComm( (PetscObject)P, &comm );
+ MPI_Comm_size( comm, &nproc );
+
+
+
+ /* Loop over the finer of the two levels. */
+ for( ii = eqRangeBegin; ii < eqRangeEnd; ii++ ) {
+ /* Convert the global equation number to the global node index. */
+ nodeInd = ii / nDofsPerNode;
+ rowDof = ii - nodeInd * nDofsPerNode;
+ Grid_Lift( grid[1], nodeInd, (unsigned*)(inds[1]) );
+
+ /* An odd grid index means we need to interpolate from surrounding
+ coarse nodes in the current dimension. */
+ for( jj = 0; jj < nDims; jj++ ) {
+ /* Store the offsets we need to consider. */
+ nOffs[jj] = (inds[1][jj] & 1) ? 2 : 1;
+ }
+
+ /* 'Multiply' the offsets to build the set of nodes we need to
+ interpolate from. */
+ Grid_SetSizes( offsGrid, (unsigned*)(nOffs) );
+ for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
+ Grid_Lift( offsGrid, jj, (unsigned*)(offsInds) );
+ for( kk = 0; kk < nDims; kk++ )
+ inds[0][kk] = (inds[1][kk] >> 1) + offsInds[kk];
+
+ /* Store the coarse global node number. */
+ nodes[jj] = Grid_Project( grid[0], (unsigned*)(inds[0]) );
+ }
+
+ /* Insert this row into the operator matrix. */
+ row_idx = (PetscInt)ii;
+ /* find owning proc */
+ proc_owner = -1;
+ for( p=0; p<nproc; p++ ) {
+ if( (row_idx>=row_ranges[p]) && (row_idx<row_ranges[p+1]) ) {
+ proc_owner = p;
+ break;
+ }
+ }
+/*
+ if( (row_idx>=sr) && (row_idx<er) ) {
+ for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
+ indices[jj] = nodes[jj] * nDofsPerNode + rowDof;
+ if( (indices[jj]>=sc) && (indices[jj]<ec) ) {
+ VecSetValue( vec_d_nnz, row_idx, 1.0, ADD_VALUES );
+ }
+ }
+ }
+ else {
+ VecSetValue( vec_o_nnz, row_idx, 1.0, ADD_VALUES );
+ }
+*/
+
+ for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
+ indices[jj] = nodes[jj] * nDofsPerNode + rowDof;
+// printf("ridx=%d,cidx=%d : owner:%d rrange [%d-%d] : crange [%d-%d] \n", row_idx, indices[jj], proc_owner, row_ranges[proc_owner],row_ranges[proc_owner+1], col_ranges[proc_owner], col_ranges[proc_owner+1] );
+ if( (row_idx>=row_ranges[proc_owner]) && (row_idx<row_ranges[proc_owner+1]) ) {
+ if( (indices[jj]>=col_ranges[proc_owner]) && (indices[jj]<col_ranges[proc_owner+1]) ) {
+ VecSetValue( vec_d_nnz, row_idx, 1.0, ADD_VALUES );
+ }
+ else {
+ VecSetValue( vec_o_nnz, row_idx, 1.0, ADD_VALUES );
+ }
+ }
+ }
+
+ }
+
+ VecAssemblyBegin( vec_d_nnz );
+ VecAssemblyEnd( vec_d_nnz );
+
+ VecAssemblyBegin( vec_o_nnz );
+ VecAssemblyEnd( vec_o_nnz );
+
+ VecGetArray( vec_d_nnz, &v );
+ for( kk=0; kk<(er-sr); kk++ ) {
+ d_nnz[kk] = (PetscInt)v[kk];
+ }
+ VecRestoreArray( vec_d_nnz, &v );
+
+ VecGetArray( vec_o_nnz, &v );
+ for( kk=0; kk<(er-sr); kk++ ) {
+ o_nnz[kk] = (PetscInt)v[kk];
+ }
+ VecRestoreArray( vec_o_nnz, &v );
+
+
+ if(nproc==1) {
+ MatSeqAIJSetPreallocation( P, PETSC_NULL, d_nnz );
+ }
+ else {
+ MatMPIAIJSetPreallocation( P, PETSC_NULL, d_nnz, PETSC_NULL, o_nnz );
+ }
+
+
+ /* Loop over the finer of the two levels. */
+ for( ii = eqRangeBegin; ii < eqRangeEnd; ii++ ) {
+ /* Convert the global equation number to the global node index. */
+ nodeInd = ii / nDofsPerNode;
+ rowDof = ii - nodeInd * nDofsPerNode;
+ Grid_Lift( grid[1], nodeInd, (unsigned*)(inds[1]) );
+
+ /* An odd grid index means we need to interpolate from surrounding
+ coarse nodes in the current dimension. */
+ for( jj = 0; jj < nDims; jj++ ) {
+ /* Store the offsets we need to consider. */
+ nOffs[jj] = (inds[1][jj] & 1) ? 2 : 1;
+ }
+
+ /* 'Multiply' the offsets to build the set of nodes we need to
+ interpolate from. */
+ Grid_SetSizes( offsGrid, (unsigned*)(nOffs) );
+ for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
+ Grid_Lift( offsGrid, jj, (unsigned*)(offsInds) );
+ for( kk = 0; kk < nDims; kk++ )
+ inds[0][kk] = (inds[1][kk] >> 1) + offsInds[kk];
+
+ /* Store the coarse global node number. */
+ nodes[jj] = Grid_Project( grid[0], (unsigned*)(inds[0]) );
+ }
+
+ /* Insert this row into the operator matrix. */
+ dfrac = 1.0 / (double)offsGrid->nPoints;
+ nEntries = offsGrid->nPoints;
+ for( jj = 0; jj < offsGrid->nPoints; jj++ ) {
+ indices[jj] = nodes[jj] * nDofsPerNode + rowDof;
+ values[jj] = dfrac;
+ }
+ MatSetValues( P, 1, &ii, nEntries, indices, values, INSERT_VALUES );
+ }
+
+ /* Assemble the matrix. */
+ MatAssemblyBegin( P, MAT_FINAL_ASSEMBLY );
+ MatAssemblyEnd( P, MAT_FINAL_ASSEMBLY );
+
+ /* Piss off those grids. */
+ Stg_Class_Delete( grid[0] );
+ Stg_Class_Delete( grid[1] );
+ Stg_Class_Delete( offsGrid );
+
+ VecDestroy( vec_o_nnz );
+ VecDestroy( vec_d_nnz );
+ PetscFree( o_nnz );
+ PetscFree( d_nnz );
+ PetscFree( row_ranges );
+ PetscFree( col_ranges );
+
+
+ /* Create a new matrix. */
+ //mat = PETScMatrix_New( "" );
+ //mat->petscMat = P;
+ mat = P;
+ return mat;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/SolutionVector.c
--- a/SLE/SystemSetup/src/SolutionVector.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,769 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: SolutionVector.c 1071 2008-03-12 02:23:49Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "FiniteElementContext.h"
-#include "SolutionVector.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-/* Textual name of this class */
-const Type SolutionVector_Type = "SolutionVector";
-
-static const int VALUE_TAG = 1;
-static const int VALUE_REQUEST_TAG = 2;
-
-typedef struct RequestInfo {
- Node_LocalIndex lNode_I;
- Dof_Index nodeLocalDof_I;
-} RequestInfo;
-
-void _SolutionVector_ShareValuesNotStoredLocally(
- SolutionVector* self,
- Index* reqFromOthersCounts,
- RequestInfo** reqFromOthersInfos,
- Dof_EquationNumber** reqFromOthers,
- double* localSolnVecValues );
-
-SolutionVector* SolutionVector_New( Name name, FiniteElementContext* context, MPI_Comm comm, FeVariable* feVariable ) {
- SolutionVector* self = (SolutionVector*)_SolutionVector_DefaultNew( name );
-
- self->isConstructed = True;
- _SolutionVector_Init( self, context, comm, feVariable );
-
- return self;
-}
-
-void* _SolutionVector_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(SolutionVector);
- Type type = SolutionVector_Type;
- Stg_Class_DeleteFunction* _delete = _SolutionVector_Delete;
- Stg_Class_PrintFunction* _print = _SolutionVector_Print;
- Stg_Class_CopyFunction* _copy = _SolutionVector_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _SolutionVector_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _SolutionVector_AssignFromXML;
- Stg_Component_BuildFunction* _build = _SolutionVector_Build;
- Stg_Component_InitialiseFunction* _initialise = _SolutionVector_Initialise;
- Stg_Component_ExecuteFunction* _execute = _SolutionVector_Execute;
- Stg_Component_DestroyFunction* _destroy = _SolutionVector_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL;
-
- return _SolutionVector_New( SOLUTIONVECTOR_PASSARGS );
-}
-
-SolutionVector* _SolutionVector_New( SOLUTIONVECTOR_DEFARGS ) {
- SolutionVector* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(SolutionVector) );
- self = (SolutionVector*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- /* General info */
-
- /* Virtual info */
-
- return self;
-}
-
-void _SolutionVector_Init( SolutionVector* self, FiniteElementContext* context, MPI_Comm comm, FeVariable* feVariable ) {
- /* General and Virtual info should already be set */
-
- /* SolutionVector info */
- self->context = context;
- self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type );
- self->comm = comm;
- self->feVariable = feVariable;
-}
-
-void _SolutionVector_Delete( void* solutionVector ) {
- SolutionVector* self = (SolutionVector*)solutionVector;
-
- Journal_DPrintf( self->debug, "In %s - for soln. vector %s\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
-
- /* Stg_Class_Delete parent*/
- _Stg_Component_Delete( self );
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _SolutionVector_Print( void* solutionVector, Stream* stream ) {
- SolutionVector* self = (SolutionVector*)solutionVector;
-
- /* Set the Journal for printing informations */
- Stream* solutionVectorStream = stream;
-
- /* General info */
- Journal_Printf( solutionVectorStream, "SolutionVector (ptr): %p\n", self );
-
- /* Print parent */
- _Stg_Component_Print( self, solutionVectorStream );
-
- /* Virtual info */
-
- /* SolutionVector info */
-
- Stg_Class_Print( self->feVariable, solutionVectorStream );
- Journal_Printf( solutionVectorStream, "\tComm: %u\n", self->comm );
-}
-
-
-void* _SolutionVector_Copy( const void* solutionVector, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- SolutionVector* self = (SolutionVector*)solutionVector;
- SolutionVector* newSolutionVector;
- PtrMap* map = ptrMap;
- Bool ownMap = False;
-
- if( !map ) {
- map = PtrMap_New( 10 );
- ownMap = True;
- }
-
- newSolutionVector = (SolutionVector*)_Stg_Component_Copy( self, dest, deep, nameExt, map );
-
- /* TODO: copy vector? */
- newSolutionVector->vector = self->vector;
- newSolutionVector->comm = self->comm;
-
- if( deep ) {
- newSolutionVector->debug = (Stream*)Stg_Class_Copy( self->debug, NULL, deep, nameExt, map );
- newSolutionVector->feVariable = (FeVariable*)Stg_Class_Copy( self->feVariable, NULL, deep, nameExt, map );
- }
- else {
- newSolutionVector->debug = self->debug;
- newSolutionVector->feVariable = self->feVariable;
- }
-
- if( ownMap ) {
- Stg_Class_Delete( map );
- }
-
- return (void*)newSolutionVector;
-}
-
-
-void _SolutionVector_AssignFromXML( void* solutionVector, Stg_ComponentFactory* cf, void* data ) {
- SolutionVector* self = (SolutionVector*)solutionVector;
- FeVariable* feVariable = NULL;
- FiniteElementContext* context;
-
- context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", FiniteElementContext, False, data );
- if( !context )
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
-
- feVariable = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"FeVariable", FeVariable, True, data ) ;
- _SolutionVector_Init( self, context, MPI_COMM_WORLD, (FeVariable*)feVariable );
-}
-
-
-void _SolutionVector_Build( void* solutionVector, void* data ) {
- SolutionVector* self = (SolutionVector*)solutionVector;
-
- Journal_DPrintf( self->debug, "In %s - for \"%s\"\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
-
- /* ensure variables are built */
- if( self->feVariable )
- Stg_Component_Build( self->feVariable, 0, False );
-
- /* Allocate the vector */
-// self->vector = PETScVector_New( "" );
-// Vector_SetComm( self->vector, self->comm );
-// Vector_SetLocalSize( self->vector, self->feVariable->eqNum->localEqNumsOwnedCount );
- VecCreate( self->comm, &self->vector );
- VecSetSizes( self->vector, self->feVariable->eqNum->localEqNumsOwnedCount, PETSC_DECIDE );
- VecSetFromOptions( self->vector );
-#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
- VecSetOption( self->vector, VEC_IGNORE_NEGATIVE_INDICES );
-#elif( PETSC_VERSION_MAJOR >= 3 )
- VecSetOption( self->vector, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
-#endif
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _SolutionVector_Initialise( void* solutionVector, void* data ) {
- SolutionVector* self = (SolutionVector *)solutionVector;
-
- Journal_DPrintf( self->debug, "In %s - for \"%s\"\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
- /* ensure variables are initialised */
- if( self->feVariable ) {
- Stg_Component_Initialise( self->feVariable, data, False );
- }
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _SolutionVector_Execute( void* solutionVector, void* data ) {
-}
-
-void _SolutionVector_Destroy( void* solutionVector, void* data ) {
- SolutionVector* self = (SolutionVector*)solutionVector;
-
- //FreeObject( self->vector );
- if( self->vector != PETSC_NULL )
- VecDestroy( self->vector );
-}
-
-void SolutionVector_ApplyBCsToVariables( void* solutionVector, void* data ) {
- SolutionVector* self = (SolutionVector *)solutionVector;
-
- FeVariable_ApplyBCs( self->feVariable, data );
-}
-
-/* from the depreciated Vector class */
-void _SolutionVector_VectorView( Vec v, Stream* stream ) {
- unsigned entry_i;
- PetscInt size;
- PetscScalar* array;
-
- VecGetSize( v, &size );
- VecGetArray( v, &array );
-
- Journal_Printf( stream, "%p = [", v );
- for( entry_i = 0; entry_i < size; entry_i++ )
- Journal_Printf( stream, "\t%u: \t %.12g\n", entry_i, array[entry_i] );
- Journal_Printf( stream, "];\n" );
-
- VecRestoreArray( v, &array );
-}
-
-void SolutionVector_UpdateSolutionOntoNodes( void* solutionVector ) {
- SolutionVector* self = (SolutionVector *)solutionVector;
- double* localSolnVecValues;
- Node_LocalIndex lNode_I = 0;
- Dof_Index currNodeNumDofs;
- Dof_Index nodeLocalDof_I;
- Partition_Index ownerProc;
- FeVariable* feVar = self->feVariable;
- FeMesh* feMesh = feVar->feMesh;
- MPI_Comm mpiComm;
- FeEquationNumber* eqNum = feVar->eqNum;
- Dof_EquationNumber currEqNum;
- Index indexIntoLocalSolnVecValues;
- Index* reqFromOthersCounts;
- Index* reqFromOthersSizes;
- RequestInfo** reqFromOthersInfos;
- Dof_EquationNumber** reqFromOthers;
- Comm* comm;
- Partition_Index nProc;
- Partition_Index myRank;
- Partition_Index proc_I;
- double initialGuessAtNonLocalEqNumsRatio = 0.1;
- double ratioToIncreaseRequestArraySize = 1.5;
- Index newReqFromOthersSize;
-
- Journal_DPrintf( self->debug, "In %s - for \"%s\"\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
-
- #if DEBUG
- if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
- Journal_DPrintf( self->debug, "Vector data:\n" );
- _SolutionVector_VectorView( self->vector, self->debug );
- }
- #endif
-
- comm = Mesh_GetCommTopology( feMesh, MT_VERTEX );
- mpiComm = Comm_GetMPIComm( comm );
- MPI_Comm_size( mpiComm, (int*)&nProc );
- MPI_Comm_rank( mpiComm, (int*)&myRank );
-
- /* allocate arrays for nodes that I want on each processor */
- reqFromOthersCounts = Memory_Alloc_Array( Index, nProc, "reqFromOthersCounts" );
- reqFromOthersSizes = Memory_Alloc_Array( Index, nProc, "reqFromOthersSizes" );
- reqFromOthersInfos = Memory_Alloc_Array( RequestInfo*, nProc, "reqFromOthersInfos" );
- reqFromOthers = Memory_Alloc_Array( Dof_EquationNumber*, nProc, "reqFromOthers" );
- /* Allocate the arrays of req. values from others independently, as we don't know how large they'll be */
- for ( proc_I=0; proc_I < nProc; proc_I++ ) {
- reqFromOthersCounts[proc_I] = 0;
-
- if (proc_I == myRank) continue;
-
- /* Our initial guess at number of non-local eqNums is a small ratio of the number of local dofs */
- reqFromOthersSizes[proc_I] = eqNum->localEqNumsOwnedCount * initialGuessAtNonLocalEqNumsRatio;
- /* Special case for really small meshes: make sure it's at least 1 */
- if (0 == reqFromOthersSizes[proc_I] ) {
- reqFromOthersSizes[proc_I]++;
- }
- reqFromOthersInfos[proc_I] = Memory_Alloc_Array( RequestInfo, reqFromOthersSizes[proc_I],
- "reqFromOthersInfos[proc_I]" );
- reqFromOthers[proc_I] = Memory_Alloc_Array( Dof_EquationNumber, reqFromOthersSizes[proc_I],
- "reqFromOthers[proc_I]" );
- }
-
- /* Get the locally held part of the vector */
- //Vector_GetArray( self->vector, &localSolnVecValues );
- VecGetArray( self->vector, &localSolnVecValues );
-
- for( lNode_I=0; lNode_I < Mesh_GetLocalSize( feMesh, MT_VERTEX ); lNode_I++ ) {
- currNodeNumDofs = feVar->dofLayout->dofCounts[ lNode_I ];
- Journal_DPrintfL( self->debug, 3, "getting solutions for local node %d, has %d dofs.\n", lNode_I, currNodeNumDofs );
-
- /* process each dof */
- for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
- Journal_DPrintfL( self->debug, 3, "\tdof %d: ", nodeLocalDof_I );
-
- currEqNum = eqNum->destinationArray[lNode_I][nodeLocalDof_I];
- if( currEqNum != -1 ) {
- Journal_DPrintfL( self->debug, 3, "is unconstrained, eqNum %d:", currEqNum );
-
- if( STreeMap_HasKey( eqNum->ownedMap, &currEqNum ) ) {
- indexIntoLocalSolnVecValues = *(int*)STreeMap_Map( eqNum->ownedMap, &currEqNum );
- Journal_DPrintfL( self->debug, 3, "local -> just copying value %f\n",
- localSolnVecValues[indexIntoLocalSolnVecValues] );
- DofLayout_SetValueDouble( feVar->dofLayout, lNode_I, nodeLocalDof_I,
- localSolnVecValues[indexIntoLocalSolnVecValues] );
- }
- else {
- RequestInfo* requestInfo;
-
- Journal_DPrintfL( self->debug, 3, "nonlocal -> add to req list " );
- ownerProc = FeEquationNumber_CalculateOwningProcessorOfEqNum( eqNum, currEqNum );
- Journal_DPrintfL( self->debug, 3, "from proc %d\n", ownerProc );
- /* first check count & realloc if necessary */
- if (reqFromOthersCounts[ownerProc] == reqFromOthersSizes[ownerProc] ) {
- newReqFromOthersSize = reqFromOthersSizes[ownerProc] * ratioToIncreaseRequestArraySize;
- if ( newReqFromOthersSize == reqFromOthersSizes[ownerProc] ) {
- /* Special case: always increase by at least 1 */
- newReqFromOthersSize++;
- }
- reqFromOthersSizes[ownerProc] = newReqFromOthersSize;
-
- Journal_DPrintfL( self->debug, 3, "req list from proc %d count %d now "
- "equal to size, so reallocing to size %d\n",
- ownerProc, reqFromOthersCounts[ownerProc],
- reqFromOthersSizes[ownerProc] );
-
- reqFromOthersInfos[ownerProc] = Memory_Realloc_Array(
- reqFromOthersInfos[ownerProc], RequestInfo, reqFromOthersSizes[ownerProc] );
- reqFromOthers[ownerProc] = Memory_Realloc_Array(
- reqFromOthers[ownerProc], Dof_EquationNumber, reqFromOthersSizes[ownerProc] );
- }
- requestInfo = &reqFromOthersInfos[ownerProc][ reqFromOthersCounts[ownerProc] ];
- requestInfo->lNode_I = lNode_I;
- requestInfo->nodeLocalDof_I = nodeLocalDof_I;
- reqFromOthers[ownerProc][reqFromOthersCounts[ownerProc]] = currEqNum;
- (reqFromOthersCounts[ownerProc])++;
- }
- }
- else {
- Journal_DPrintfL( self->debug, 3, "is a BC, so skipping...\n" );
- }
- }
- }
-
- if ( nProc > 1 ) {
- _SolutionVector_ShareValuesNotStoredLocally( self, reqFromOthersCounts, reqFromOthersInfos, reqFromOthers,
- localSolnVecValues );
- }
-
- for ( proc_I=0; proc_I < nProc; proc_I++ ) {
- if (proc_I == myRank) continue;
- Memory_Free( reqFromOthers[proc_I] );
- Memory_Free( reqFromOthersInfos[proc_I] );
- }
- Memory_Free( reqFromOthers );
- Memory_Free( reqFromOthersInfos );
- Memory_Free( reqFromOthersCounts );
- Memory_Free( reqFromOthersSizes );
-
- //Vector_RestoreArray( self->vector, &localSolnVecValues );
- VecRestoreArray( self->vector, &localSolnVecValues );
-
- /*
- ** Syncronise the FEVariable in question.
- */
-
- FeVariable_SyncShadowValues( feVar );
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _SolutionVector_ShareValuesNotStoredLocally(
- SolutionVector* self,
- Index* reqFromOthersCounts,
- RequestInfo** reqFromOthersInfos,
- Dof_EquationNumber** reqFromOthers,
- double* localSolnVecValues )
-{
-
- FeVariable* feVar = self->feVariable;
- FeMesh* feMesh = feVar->feMesh;
- FeEquationNumber* eqNum = feVar->eqNum;
- Comm* comm;
- MPI_Comm mpiComm;
- Partition_Index nProc;
- Partition_Index myRank;
- Partition_Index proc_I;
- Index req_I;
- Index indexIntoLocalSolnVecValues;
- MPI_Status status;
- Index* reqFromMeCounts;
- Dof_EquationNumber** reqFromMe;
- double** reqValuesFromMe;
- MPI_Request** reqValuesFromMeHandles;
- MPI_Request** reqFromOthersHandles;
- double** reqValuesFromOthers;
- MPI_Request** reqValuesFromOthersHandles;
- Bool* reqValuesFromOthersReceived;
- Partition_Index reqValueSetsFromOthersNotYetReceivedCount;
- Dof_EquationNumber totalRequestedFromOthers = 0;
- Dof_EquationNumber totalRequestedFromMe = 0;
-
- Journal_DPrintf( self->debug, "In %s - for \"%s\"\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
-
- comm = Mesh_GetCommTopology( feMesh, MT_VERTEX );
- mpiComm = Comm_GetMPIComm( comm );
- MPI_Comm_size( mpiComm, (int*)&nProc );
- MPI_Comm_rank( mpiComm, (int*)&myRank );
-
- reqFromMeCounts = Memory_Alloc_Array( Index, nProc, "reqFromMeCounts" );
- reqFromOthersHandles = Memory_Alloc_Array_Unnamed( MPI_Request*, nProc );
- reqValuesFromOthersHandles = Memory_Alloc_Array_Unnamed( MPI_Request*, nProc );
- reqValuesFromMeHandles = Memory_Alloc_Array_Unnamed( MPI_Request*, nProc );
- reqValuesFromOthers = Memory_Alloc_2DComplex( double, nProc, reqFromOthersCounts, "reqValuesFromOthers" );
- reqValuesFromOthersReceived = Memory_Alloc_Array_Unnamed( Bool, nProc );
-
- #if DEBUG
- if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
- Journal_DPrintf( self->debug, "Final list of vec values I need from other procs:\n" );
- for ( proc_I=0; proc_I < nProc; proc_I++ ) {
- if ( proc_I == myRank ) continue;
- Journal_DPrintf( self->debug, "\t%d[0-%d]: ", proc_I, reqFromOthersCounts[proc_I] );
- for ( req_I=0; req_I < reqFromOthersCounts[proc_I]; req_I++ ) {
- RequestInfo* reqInfo = &reqFromOthersInfos[proc_I][req_I];
- Journal_DPrintf( self->debug, "(lnode %d, dof %d -> %d ), ",
- reqInfo->lNode_I, reqInfo->nodeLocalDof_I,
- reqFromOthers[proc_I][req_I] );
- }
- Journal_DPrintf( self->debug, "\n" );
- }
- }
- #endif
-
- /* send out my request counts, receive the req. counts others want from me */
- MPI_Alltoall( reqFromOthersCounts, 1, MPI_UNSIGNED,
- reqFromMeCounts, 1, MPI_UNSIGNED, mpiComm );
-
- Journal_DPrintf( self->debug, "After MPI_Alltoall- counts are:\n" );
- totalRequestedFromOthers = 0;
- totalRequestedFromMe = 0;
- Stream_Indent( self->debug );
- Journal_DPrintf( self->debug, "reqFromOthersCounts: " );
- for ( proc_I=0; proc_I < nProc; proc_I++ ) {
- if ( proc_I == myRank ) continue;
- Journal_DPrintf( self->debug, "\tp%d:%d, ", proc_I, reqFromOthersCounts[proc_I] );
- totalRequestedFromOthers += reqFromOthersCounts[proc_I];
- }
- Journal_DPrintf( self->debug, "\n" );
- Journal_DPrintf( self->debug, "reqFromMeCounts: " );
- for ( proc_I=0; proc_I < nProc; proc_I++ ) {
- if ( proc_I == myRank ) continue;
- Journal_DPrintf( self->debug, "\tp%d:%d, ", proc_I, reqFromMeCounts[proc_I] );
- totalRequestedFromMe += reqFromMeCounts[proc_I];
- }
- Journal_DPrintf( self->debug, "\n" );
- Stream_UnIndent( self->debug );
-
- if ( ( totalRequestedFromOthers == 0) && (totalRequestedFromMe == 0) )
- {
- Journal_DPrintf( self->debug, "No vector values either required from others or "
- "required by others from me, therefore cleaning up memory and returning.\n" );
- Memory_Free( reqFromMeCounts );
- Memory_Free( reqFromOthersHandles );
- Memory_Free( reqValuesFromOthersHandles );
- Memory_Free( reqValuesFromMeHandles );
- Memory_Free( reqValuesFromOthers );
- Memory_Free( reqValuesFromOthersReceived );
- Stream_UnIndentBranch( StgFEM_Debug );
- return;
- }
-
- Journal_DPrintfL( self->debug, 2, "Starting non-blocking sends of my lists of vector entry indices I want from others:\n" );
- Stream_Indent( self->debug );
- for( proc_I=0; proc_I < nProc; proc_I++) {
- if ( proc_I == myRank ) continue;
-/* Journal_Printf( Journal_Register( Info_Type, (Name)"mpi" ), "!!! line %d, proc_I %d: count = %u\n", __LINE__, proc_I, reqFromOthersCounts[proc_I] ); */
- if ( reqFromOthersCounts[proc_I] > 0 ) {
- Journal_DPrintfL( self->debug, 2, "Sending to proc %d the list of %d vector entry indices I want from it:\n"
- "\t(tracking via reqFromOthersHandles[%d], tag %d)\n", proc_I,
- reqFromOthersCounts[proc_I], proc_I, VALUE_REQUEST_TAG );
-
- reqFromOthersHandles[proc_I] = Memory_Alloc_Unnamed( MPI_Request );
- MPI_Isend( reqFromOthers[proc_I], reqFromOthersCounts[proc_I], MPI_UNSIGNED,
- proc_I, VALUE_REQUEST_TAG, mpiComm, reqFromOthersHandles[proc_I] );
- }
- }
- Stream_UnIndent( self->debug );
-
-
- Journal_DPrintfL( self->debug, 2, "Starting non-blocking receive of the vector entries I want from others:\n" );
- Stream_Indent( self->debug );
- for( proc_I=0; proc_I < nProc; proc_I++) {
- if ( proc_I == myRank ) continue;
- if ( reqFromOthersCounts[proc_I] > 0 ) {
- Journal_DPrintfL( self->debug, 2, "Posting recv reqst from proc %d for the %d vector entries I want from it:\n"
- "\t(tracking via reqValuesFromOthersHandles[%d], tag %d)\n", proc_I,
- reqFromOthersCounts[proc_I], proc_I, VALUE_TAG );
- reqValuesFromOthersHandles[proc_I] = Memory_Alloc_Unnamed( MPI_Request );
- MPI_Irecv( reqValuesFromOthers[proc_I], reqFromOthersCounts[proc_I], MPI_DOUBLE,
- proc_I, VALUE_TAG, mpiComm, reqValuesFromOthersHandles[proc_I] );
- }
- }
- Stream_UnIndent( self->debug );
-
- Journal_DPrintfL( self->debug, 2, "Starting blocking receive of the lists of vector entry indices "
- "others want from me:\n" );
- Stream_Indent( self->debug );
- reqFromMe = Memory_Alloc_2DComplex( Dof_EquationNumber, nProc, reqFromMeCounts, "reqFromMe" );
- reqValuesFromMe = Memory_Alloc_2DComplex( double, nProc, reqFromMeCounts, "reqValuesFromMe" );
- for( proc_I=0; proc_I < nProc; proc_I++) {
- if ( proc_I == myRank ) continue;
-/* /Journal_Printf( Journal_Register( Info_Type, (Name)"mpi" ), "!!! line %d, proc_I %d: count = %u\n", __LINE__, proc_I, reqFromMeCounts[proc_I] ); */
- if ( reqFromMeCounts[proc_I] > 0 ) {
- MPI_Recv( reqFromMe[proc_I], reqFromMeCounts[proc_I], MPI_UNSIGNED,
- proc_I, VALUE_REQUEST_TAG, mpiComm, &status );
- Journal_DPrintfL( self->debug, 3, "Received a list of %u requested vector entry indices from proc %u, "
- "with tag %d\n", reqFromMeCounts[proc_I], proc_I, status.MPI_TAG );
- }
- }
- Stream_UnIndent( self->debug );
-
- #if DEBUG
- if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
- Journal_DPrintf( self->debug, "Final lists of vector entry indices other procs want from me are:\n" );
- Stream_Indent( self->debug );
- for ( proc_I=0; proc_I < nProc; proc_I++ ) {
- if ( proc_I == myRank ) continue;
- if ( reqFromMeCounts[proc_I] > 0 ) {
- Journal_DPrintf( self->debug, "%d[0-%d]: ", proc_I, reqFromMeCounts[proc_I] );
- for ( req_I=0; req_I < reqFromMeCounts[proc_I]; req_I++ ) {
- Journal_DPrintf( self->debug, "(eqNum %d), ", reqFromMe[proc_I][req_I] );
- }
- Journal_DPrintf( self->debug, "\n" );
- }
- }
- Stream_UnIndent( self->debug );
- }
- #endif
-
- /* for all those requested from me, non-blocking send out values */
- Journal_DPrintfL( self->debug, 2, "Beginning non-blocking send out of vector entry lists requested by others:\n" );
- Stream_Indent( self->debug );
- for( proc_I=0; proc_I < nProc; proc_I++) {
- if ( proc_I == myRank ) continue;
- if ( reqFromMeCounts[proc_I] > 0 ) {
- Journal_DPrintfL( self->debug, 3, "list to proc %d is: ", proc_I );
- for ( req_I=0; req_I < reqFromMeCounts[proc_I]; req_I++ ) {
- /* look up and fill in correct value in array */
- indexIntoLocalSolnVecValues = *(int*)STreeMap_Map( eqNum->ownedMap,
- reqFromMe[proc_I] + req_I );
- reqValuesFromMe[proc_I][req_I] = localSolnVecValues[indexIntoLocalSolnVecValues];
- Journal_DPrintfL( self->debug, 3, "%d=%f, ", reqFromMe[proc_I][req_I],
- reqValuesFromMe[proc_I][req_I] );
- }
- Journal_DPrintfL( self->debug, 3, "\n" );
- /* Non-blocking send out the now-complete list to this processor */
- reqValuesFromMeHandles[proc_I] = Memory_Alloc_Unnamed( MPI_Request );
- Journal_DPrintfL( self->debug, 2, "Sending to proc %d the list of %d vector entries they want:\n"
- "\t(tracking via reqValuesFromMe[%d], tag %d)\n", proc_I,
- reqFromMeCounts[proc_I], proc_I, VALUE_TAG );
- MPI_Isend( reqValuesFromMe[proc_I], reqFromMeCounts[proc_I], MPI_DOUBLE,
- proc_I, VALUE_TAG, mpiComm, reqValuesFromMeHandles[proc_I] );
- }
- }
- Stream_UnIndent( self->debug );
-
- Journal_DPrintfL( self->debug, 1, "Starting iterative-test receive of the vector entries I "
- "requested from others:\n" );
- /* Set up an array for keeping track of who we've received things from
- * already */
- reqValueSetsFromOthersNotYetReceivedCount = nProc-1;
- for( proc_I=0; proc_I < nProc; proc_I++) {
- if ( proc_I == myRank ) continue;
- reqValuesFromOthersReceived[proc_I] = False;
- if ( reqFromOthersCounts[proc_I] == 0 ) {
- reqValueSetsFromOthersNotYetReceivedCount--;
- }
- }
-
- #if DEBUG
- Journal_DPrintfL( self->debug, 2, "(Expecting %d receives from procs: ",
- reqValueSetsFromOthersNotYetReceivedCount );
- for( proc_I=0; proc_I < nProc; proc_I++) {
- if ( proc_I == myRank ) continue;
- if ( reqFromOthersCounts[proc_I] > 0 ) {
- Journal_DPrintfL( self->debug, 2, "%d, ", proc_I );
- }
- }
- Journal_DPrintfL( self->debug, 2, ")\n" );
- #endif
-
- Stream_Indent( self->debug );
- /* now update the values at nodes that I requested from others, as they come in */
- while ( reqValueSetsFromOthersNotYetReceivedCount ) {
- int flag = 0;
-
- Journal_DPrintfL( self->debug, 3, "%d sets still to go...\n", reqValueSetsFromOthersNotYetReceivedCount );
- for( proc_I=0; proc_I < nProc; proc_I++) {
- if ( proc_I == myRank ) continue;
-
- if ( (reqFromOthersCounts[proc_I] > 0) && (False == reqValuesFromOthersReceived[proc_I]) ) {
- MPI_Test( reqValuesFromOthersHandles[proc_I], &flag, &status );
- if ( !flag ) {
- /* No results yet from this proc -> continue to next. */
- continue;
- }
- else {
- RequestInfo* reqInfo;
- Journal_DPrintfL( self->debug, 2, "received some requested "
- "values (using reqValuesFromOthersHandles) from proc %d "
- "(with tag %d, exp %d):", proc_I, status.MPI_TAG, VALUE_TAG );
- /* go through each value received from that proc & update onto node */
- for ( req_I=0; req_I < reqFromOthersCounts[proc_I]; req_I++ ) {
- reqInfo = &reqFromOthersInfos[proc_I][req_I];
- Journal_DPrintfL( self->debug, 3, "(lnode %d, dof %d -> %d )=%f, ",
- reqInfo->lNode_I, reqInfo->nodeLocalDof_I,
- reqFromOthers[proc_I][req_I], reqValuesFromOthers[proc_I][req_I] );
- DofLayout_SetValueDouble( feVar->dofLayout, reqInfo->lNode_I, reqInfo->nodeLocalDof_I,
- reqValuesFromOthers[proc_I][req_I] );
- }
- Journal_DPrintfL( self->debug, 2, "\n" );
- reqValuesFromOthersReceived[proc_I] = True;
- reqValueSetsFromOthersNotYetReceivedCount--;
- Memory_Free( reqValuesFromOthersHandles[proc_I] );
- }
- }
- }
- }
- Stream_UnIndent( self->debug );
-
- /* MPI_Wait to be sure all sends to others have completed */
- Journal_DPrintfL( self->debug, 2, "Making sure all comms of this function finished:...\n" );
- Stream_Indent( self->debug );
-
- Journal_DPrintfL( self->debug, 2, "Confirming completion of my sends of "
- "vector entry index lists I wanted from others were received:\n" );
- Stream_Indent( self->debug );
- for( proc_I=0; proc_I < nProc; proc_I++) {
- if ( proc_I == myRank ) continue;
- if ( reqFromOthersCounts[proc_I] > 0 ) {
- MPI_Wait( reqFromOthersHandles[proc_I], MPI_STATUS_IGNORE );
- Journal_DPrintfL( self->debug, 2, "Confirmed wait on reqFromOthersHandles[%u]"
- "\n", proc_I );
- Memory_Free( reqFromOthersHandles[proc_I] );
- }
- }
- Stream_UnIndent( self->debug );
- Journal_DPrintfL( self->debug, 2, "done.\n" );
-
- Journal_DPrintfL( self->debug, 2, "Confirming completion of my sends of "
- "vector entry values requested by others were received:\n" );
- Stream_Indent( self->debug );
- for( proc_I=0; proc_I < nProc; proc_I++) {
- if ( proc_I == myRank ) continue;
- if ( reqFromMeCounts[proc_I] > 0 ) {
- MPI_Wait( reqValuesFromMeHandles[proc_I], MPI_STATUS_IGNORE );
- Journal_DPrintfL( self->debug, 2, "Confirmed wait on reqValuesFromMeHandles[%u]"
- "\n", proc_I );
- Memory_Free( reqValuesFromMeHandles[proc_I] );
- }
- }
- Stream_UnIndent( self->debug );
- Journal_DPrintfL( self->debug, 2, "done.\n" );
-
- Stream_UnIndent( self->debug );
- Journal_DPrintfL( self->debug, 2, "done.\n" );
-
- Memory_Free( reqFromMeCounts );
- Memory_Free( reqFromMe );
- Memory_Free( reqValuesFromMe );
- Memory_Free( reqValuesFromOthers );
- Memory_Free( reqValuesFromOthersReceived );
- Memory_Free( reqFromOthersHandles );
- Memory_Free( reqValuesFromOthersHandles );
- Memory_Free( reqValuesFromMeHandles );
-
- Stream_UnIndentBranch( StgFEM_Debug );
- return;
-}
-
-
-void SolutionVector_LoadCurrentFeVariableValuesOntoVector( void* solutionVector ) {
- SolutionVector* self = (SolutionVector*)solutionVector;
- FeVariable* feVar = self->feVariable;
- FeMesh* feMesh = feVar->feMesh;
- Node_LocalIndex node_lI = 0;
- Dof_Index dof_I = 0;
- double value = 0;
- Index insertionIndex = 0;
-
- for ( node_lI = 0; node_lI < FeMesh_GetNodeLocalSize( feMesh ); node_lI++ ) {
- for ( dof_I = 0; dof_I < feVar->dofLayout->dofCounts[node_lI]; dof_I++ ) {
- value = DofLayout_GetValueDouble( feVar->dofLayout, node_lI, dof_I );
- insertionIndex = feVar->eqNum->destinationArray[node_lI][dof_I];
- //Vector_InsertEntries( self->vector, 1, &insertionIndex, &value );
- VecSetValues( self->vector, 1, (PetscInt*)(&insertionIndex), &value, INSERT_VALUES );
- }
- }
-
- //Vector_AssemblyBegin( self->vector );
- //Vector_AssemblyEnd( self->vector );
- VecAssemblyBegin( self->vector );
- VecAssemblyEnd( self->vector );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/SolutionVector.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/SolutionVector.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,769 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: SolutionVector.c 1071 2008-03-12 02:23:49Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "FiniteElementContext.h"
+#include "SolutionVector.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+/* Textual name of this class */
+const Type SolutionVector_Type = "SolutionVector";
+
+static const int VALUE_TAG = 1;
+static const int VALUE_REQUEST_TAG = 2;
+
+typedef struct RequestInfo {
+ Node_LocalIndex lNode_I;
+ Dof_Index nodeLocalDof_I;
+} RequestInfo;
+
+void _SolutionVector_ShareValuesNotStoredLocally(
+ SolutionVector* self,
+ Index* reqFromOthersCounts,
+ RequestInfo** reqFromOthersInfos,
+ Dof_EquationNumber** reqFromOthers,
+ double* localSolnVecValues );
+
+SolutionVector* SolutionVector_New( Name name, FiniteElementContext* context, MPI_Comm comm, FeVariable* feVariable ) {
+ SolutionVector* self = (SolutionVector*)_SolutionVector_DefaultNew( name );
+
+ self->isConstructed = True;
+ _SolutionVector_Init( self, context, comm, feVariable );
+
+ return self;
+}
+
+void* _SolutionVector_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(SolutionVector);
+ Type type = SolutionVector_Type;
+ Stg_Class_DeleteFunction* _delete = _SolutionVector_Delete;
+ Stg_Class_PrintFunction* _print = _SolutionVector_Print;
+ Stg_Class_CopyFunction* _copy = _SolutionVector_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _SolutionVector_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _SolutionVector_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _SolutionVector_Build;
+ Stg_Component_InitialiseFunction* _initialise = _SolutionVector_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _SolutionVector_Execute;
+ Stg_Component_DestroyFunction* _destroy = _SolutionVector_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL;
+
+ return _SolutionVector_New( SOLUTIONVECTOR_PASSARGS );
+}
+
+SolutionVector* _SolutionVector_New( SOLUTIONVECTOR_DEFARGS ) {
+ SolutionVector* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(SolutionVector) );
+ self = (SolutionVector*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ /* General info */
+
+ /* Virtual info */
+
+ return self;
+}
+
+void _SolutionVector_Init( SolutionVector* self, FiniteElementContext* context, MPI_Comm comm, FeVariable* feVariable ) {
+ /* General and Virtual info should already be set */
+
+ /* SolutionVector info */
+ self->context = context;
+ self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type );
+ self->comm = comm;
+ self->feVariable = feVariable;
+}
+
+void _SolutionVector_Delete( void* solutionVector ) {
+ SolutionVector* self = (SolutionVector*)solutionVector;
+
+ Journal_DPrintf( self->debug, "In %s - for soln. vector %s\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ /* Stg_Class_Delete parent*/
+ _Stg_Component_Delete( self );
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _SolutionVector_Print( void* solutionVector, Stream* stream ) {
+ SolutionVector* self = (SolutionVector*)solutionVector;
+
+ /* Set the Journal for printing informations */
+ Stream* solutionVectorStream = stream;
+
+ /* General info */
+ Journal_Printf( solutionVectorStream, "SolutionVector (ptr): %p\n", self );
+
+ /* Print parent */
+ _Stg_Component_Print( self, solutionVectorStream );
+
+ /* Virtual info */
+
+ /* SolutionVector info */
+
+ Stg_Class_Print( self->feVariable, solutionVectorStream );
+ Journal_Printf( solutionVectorStream, "\tComm: %u\n", self->comm );
+}
+
+
+void* _SolutionVector_Copy( const void* solutionVector, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ SolutionVector* self = (SolutionVector*)solutionVector;
+ SolutionVector* newSolutionVector;
+ PtrMap* map = ptrMap;
+ Bool ownMap = False;
+
+ if( !map ) {
+ map = PtrMap_New( 10 );
+ ownMap = True;
+ }
+
+ newSolutionVector = (SolutionVector*)_Stg_Component_Copy( self, dest, deep, nameExt, map );
+
+ /* TODO: copy vector? */
+ newSolutionVector->vector = self->vector;
+ newSolutionVector->comm = self->comm;
+
+ if( deep ) {
+ newSolutionVector->debug = (Stream*)Stg_Class_Copy( self->debug, NULL, deep, nameExt, map );
+ newSolutionVector->feVariable = (FeVariable*)Stg_Class_Copy( self->feVariable, NULL, deep, nameExt, map );
+ }
+ else {
+ newSolutionVector->debug = self->debug;
+ newSolutionVector->feVariable = self->feVariable;
+ }
+
+ if( ownMap ) {
+ Stg_Class_Delete( map );
+ }
+
+ return (void*)newSolutionVector;
+}
+
+
+void _SolutionVector_AssignFromXML( void* solutionVector, Stg_ComponentFactory* cf, void* data ) {
+ SolutionVector* self = (SolutionVector*)solutionVector;
+ FeVariable* feVariable = NULL;
+ FiniteElementContext* context;
+
+ context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", FiniteElementContext, False, data );
+ if( !context )
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
+
+ feVariable = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"FeVariable", FeVariable, True, data ) ;
+ _SolutionVector_Init( self, context, MPI_COMM_WORLD, (FeVariable*)feVariable );
+}
+
+
+void _SolutionVector_Build( void* solutionVector, void* data ) {
+ SolutionVector* self = (SolutionVector*)solutionVector;
+
+ Journal_DPrintf( self->debug, "In %s - for \"%s\"\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ /* ensure variables are built */
+ if( self->feVariable )
+ Stg_Component_Build( self->feVariable, 0, False );
+
+ /* Allocate the vector */
+// self->vector = PETScVector_New( "" );
+// Vector_SetComm( self->vector, self->comm );
+// Vector_SetLocalSize( self->vector, self->feVariable->eqNum->localEqNumsOwnedCount );
+ VecCreate( self->comm, &self->vector );
+ VecSetSizes( self->vector, self->feVariable->eqNum->localEqNumsOwnedCount, PETSC_DECIDE );
+ VecSetFromOptions( self->vector );
+#if( PETSC_VERSION_MAJOR <= 2 && PETSC_VERSION_MINOR >= 3 && PETSC_VERSION_SUBMINOR >= 3 )
+ VecSetOption( self->vector, VEC_IGNORE_NEGATIVE_INDICES );
+#elif( PETSC_VERSION_MAJOR >= 3 )
+ VecSetOption( self->vector, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE );
+#endif
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _SolutionVector_Initialise( void* solutionVector, void* data ) {
+ SolutionVector* self = (SolutionVector *)solutionVector;
+
+ Journal_DPrintf( self->debug, "In %s - for \"%s\"\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+ /* ensure variables are initialised */
+ if( self->feVariable ) {
+ Stg_Component_Initialise( self->feVariable, data, False );
+ }
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _SolutionVector_Execute( void* solutionVector, void* data ) {
+}
+
+void _SolutionVector_Destroy( void* solutionVector, void* data ) {
+ SolutionVector* self = (SolutionVector*)solutionVector;
+
+ //FreeObject( self->vector );
+ if( self->vector != PETSC_NULL )
+ VecDestroy( self->vector );
+}
+
+void SolutionVector_ApplyBCsToVariables( void* solutionVector, void* data ) {
+ SolutionVector* self = (SolutionVector *)solutionVector;
+
+ FeVariable_ApplyBCs( self->feVariable, data );
+}
+
+/* from the depreciated Vector class */
+void _SolutionVector_VectorView( Vec v, Stream* stream ) {
+ unsigned entry_i;
+ PetscInt size;
+ PetscScalar* array;
+
+ VecGetSize( v, &size );
+ VecGetArray( v, &array );
+
+ Journal_Printf( stream, "%p = [", v );
+ for( entry_i = 0; entry_i < size; entry_i++ )
+ Journal_Printf( stream, "\t%u: \t %.12g\n", entry_i, array[entry_i] );
+ Journal_Printf( stream, "];\n" );
+
+ VecRestoreArray( v, &array );
+}
+
+void SolutionVector_UpdateSolutionOntoNodes( void* solutionVector ) {
+ SolutionVector* self = (SolutionVector *)solutionVector;
+ double* localSolnVecValues;
+ Node_LocalIndex lNode_I = 0;
+ Dof_Index currNodeNumDofs;
+ Dof_Index nodeLocalDof_I;
+ Partition_Index ownerProc;
+ FeVariable* feVar = self->feVariable;
+ FeMesh* feMesh = feVar->feMesh;
+ MPI_Comm mpiComm;
+ FeEquationNumber* eqNum = feVar->eqNum;
+ Dof_EquationNumber currEqNum;
+ Index indexIntoLocalSolnVecValues;
+ Index* reqFromOthersCounts;
+ Index* reqFromOthersSizes;
+ RequestInfo** reqFromOthersInfos;
+ Dof_EquationNumber** reqFromOthers;
+ Comm* comm;
+ Partition_Index nProc;
+ Partition_Index myRank;
+ Partition_Index proc_I;
+ double initialGuessAtNonLocalEqNumsRatio = 0.1;
+ double ratioToIncreaseRequestArraySize = 1.5;
+ Index newReqFromOthersSize;
+
+ Journal_DPrintf( self->debug, "In %s - for \"%s\"\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ #if DEBUG
+ if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+ Journal_DPrintf( self->debug, "Vector data:\n" );
+ _SolutionVector_VectorView( self->vector, self->debug );
+ }
+ #endif
+
+ comm = Mesh_GetCommTopology( feMesh, MT_VERTEX );
+ mpiComm = Comm_GetMPIComm( comm );
+ MPI_Comm_size( mpiComm, (int*)&nProc );
+ MPI_Comm_rank( mpiComm, (int*)&myRank );
+
+ /* allocate arrays for nodes that I want on each processor */
+ reqFromOthersCounts = Memory_Alloc_Array( Index, nProc, "reqFromOthersCounts" );
+ reqFromOthersSizes = Memory_Alloc_Array( Index, nProc, "reqFromOthersSizes" );
+ reqFromOthersInfos = Memory_Alloc_Array( RequestInfo*, nProc, "reqFromOthersInfos" );
+ reqFromOthers = Memory_Alloc_Array( Dof_EquationNumber*, nProc, "reqFromOthers" );
+ /* Allocate the arrays of req. values from others independently, as we don't know how large they'll be */
+ for ( proc_I=0; proc_I < nProc; proc_I++ ) {
+ reqFromOthersCounts[proc_I] = 0;
+
+ if (proc_I == myRank) continue;
+
+ /* Our initial guess at number of non-local eqNums is a small ratio of the number of local dofs */
+ reqFromOthersSizes[proc_I] = eqNum->localEqNumsOwnedCount * initialGuessAtNonLocalEqNumsRatio;
+ /* Special case for really small meshes: make sure it's at least 1 */
+ if (0 == reqFromOthersSizes[proc_I] ) {
+ reqFromOthersSizes[proc_I]++;
+ }
+ reqFromOthersInfos[proc_I] = Memory_Alloc_Array( RequestInfo, reqFromOthersSizes[proc_I],
+ "reqFromOthersInfos[proc_I]" );
+ reqFromOthers[proc_I] = Memory_Alloc_Array( Dof_EquationNumber, reqFromOthersSizes[proc_I],
+ "reqFromOthers[proc_I]" );
+ }
+
+ /* Get the locally held part of the vector */
+ //Vector_GetArray( self->vector, &localSolnVecValues );
+ VecGetArray( self->vector, &localSolnVecValues );
+
+ for( lNode_I=0; lNode_I < Mesh_GetLocalSize( feMesh, MT_VERTEX ); lNode_I++ ) {
+ currNodeNumDofs = feVar->dofLayout->dofCounts[ lNode_I ];
+ Journal_DPrintfL( self->debug, 3, "getting solutions for local node %d, has %d dofs.\n", lNode_I, currNodeNumDofs );
+
+ /* process each dof */
+ for ( nodeLocalDof_I = 0; nodeLocalDof_I < currNodeNumDofs; nodeLocalDof_I++ ) {
+ Journal_DPrintfL( self->debug, 3, "\tdof %d: ", nodeLocalDof_I );
+
+ currEqNum = eqNum->destinationArray[lNode_I][nodeLocalDof_I];
+ if( currEqNum != -1 ) {
+ Journal_DPrintfL( self->debug, 3, "is unconstrained, eqNum %d:", currEqNum );
+
+ if( STreeMap_HasKey( eqNum->ownedMap, &currEqNum ) ) {
+ indexIntoLocalSolnVecValues = *(int*)STreeMap_Map( eqNum->ownedMap, &currEqNum );
+ Journal_DPrintfL( self->debug, 3, "local -> just copying value %f\n",
+ localSolnVecValues[indexIntoLocalSolnVecValues] );
+ DofLayout_SetValueDouble( feVar->dofLayout, lNode_I, nodeLocalDof_I,
+ localSolnVecValues[indexIntoLocalSolnVecValues] );
+ }
+ else {
+ RequestInfo* requestInfo;
+
+ Journal_DPrintfL( self->debug, 3, "nonlocal -> add to req list " );
+ ownerProc = FeEquationNumber_CalculateOwningProcessorOfEqNum( eqNum, currEqNum );
+ Journal_DPrintfL( self->debug, 3, "from proc %d\n", ownerProc );
+ /* first check count & realloc if necessary */
+ if (reqFromOthersCounts[ownerProc] == reqFromOthersSizes[ownerProc] ) {
+ newReqFromOthersSize = reqFromOthersSizes[ownerProc] * ratioToIncreaseRequestArraySize;
+ if ( newReqFromOthersSize == reqFromOthersSizes[ownerProc] ) {
+ /* Special case: always increase by at least 1 */
+ newReqFromOthersSize++;
+ }
+ reqFromOthersSizes[ownerProc] = newReqFromOthersSize;
+
+ Journal_DPrintfL( self->debug, 3, "req list from proc %d count %d now "
+ "equal to size, so reallocing to size %d\n",
+ ownerProc, reqFromOthersCounts[ownerProc],
+ reqFromOthersSizes[ownerProc] );
+
+ reqFromOthersInfos[ownerProc] = Memory_Realloc_Array(
+ reqFromOthersInfos[ownerProc], RequestInfo, reqFromOthersSizes[ownerProc] );
+ reqFromOthers[ownerProc] = Memory_Realloc_Array(
+ reqFromOthers[ownerProc], Dof_EquationNumber, reqFromOthersSizes[ownerProc] );
+ }
+ requestInfo = &reqFromOthersInfos[ownerProc][ reqFromOthersCounts[ownerProc] ];
+ requestInfo->lNode_I = lNode_I;
+ requestInfo->nodeLocalDof_I = nodeLocalDof_I;
+ reqFromOthers[ownerProc][reqFromOthersCounts[ownerProc]] = currEqNum;
+ (reqFromOthersCounts[ownerProc])++;
+ }
+ }
+ else {
+ Journal_DPrintfL( self->debug, 3, "is a BC, so skipping...\n" );
+ }
+ }
+ }
+
+ if ( nProc > 1 ) {
+ _SolutionVector_ShareValuesNotStoredLocally( self, reqFromOthersCounts, reqFromOthersInfos, reqFromOthers,
+ localSolnVecValues );
+ }
+
+ for ( proc_I=0; proc_I < nProc; proc_I++ ) {
+ if (proc_I == myRank) continue;
+ Memory_Free( reqFromOthers[proc_I] );
+ Memory_Free( reqFromOthersInfos[proc_I] );
+ }
+ Memory_Free( reqFromOthers );
+ Memory_Free( reqFromOthersInfos );
+ Memory_Free( reqFromOthersCounts );
+ Memory_Free( reqFromOthersSizes );
+
+ //Vector_RestoreArray( self->vector, &localSolnVecValues );
+ VecRestoreArray( self->vector, &localSolnVecValues );
+
+ /*
+ ** Syncronise the FEVariable in question.
+ */
+
+ FeVariable_SyncShadowValues( feVar );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _SolutionVector_ShareValuesNotStoredLocally(
+ SolutionVector* self,
+ Index* reqFromOthersCounts,
+ RequestInfo** reqFromOthersInfos,
+ Dof_EquationNumber** reqFromOthers,
+ double* localSolnVecValues )
+{
+
+ FeVariable* feVar = self->feVariable;
+ FeMesh* feMesh = feVar->feMesh;
+ FeEquationNumber* eqNum = feVar->eqNum;
+ Comm* comm;
+ MPI_Comm mpiComm;
+ Partition_Index nProc;
+ Partition_Index myRank;
+ Partition_Index proc_I;
+ Index req_I;
+ Index indexIntoLocalSolnVecValues;
+ MPI_Status status;
+ Index* reqFromMeCounts;
+ Dof_EquationNumber** reqFromMe;
+ double** reqValuesFromMe;
+ MPI_Request** reqValuesFromMeHandles;
+ MPI_Request** reqFromOthersHandles;
+ double** reqValuesFromOthers;
+ MPI_Request** reqValuesFromOthersHandles;
+ Bool* reqValuesFromOthersReceived;
+ Partition_Index reqValueSetsFromOthersNotYetReceivedCount;
+ Dof_EquationNumber totalRequestedFromOthers = 0;
+ Dof_EquationNumber totalRequestedFromMe = 0;
+
+ Journal_DPrintf( self->debug, "In %s - for \"%s\"\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ comm = Mesh_GetCommTopology( feMesh, MT_VERTEX );
+ mpiComm = Comm_GetMPIComm( comm );
+ MPI_Comm_size( mpiComm, (int*)&nProc );
+ MPI_Comm_rank( mpiComm, (int*)&myRank );
+
+ reqFromMeCounts = Memory_Alloc_Array( Index, nProc, "reqFromMeCounts" );
+ reqFromOthersHandles = Memory_Alloc_Array_Unnamed( MPI_Request*, nProc );
+ reqValuesFromOthersHandles = Memory_Alloc_Array_Unnamed( MPI_Request*, nProc );
+ reqValuesFromMeHandles = Memory_Alloc_Array_Unnamed( MPI_Request*, nProc );
+ reqValuesFromOthers = Memory_Alloc_2DComplex( double, nProc, reqFromOthersCounts, "reqValuesFromOthers" );
+ reqValuesFromOthersReceived = Memory_Alloc_Array_Unnamed( Bool, nProc );
+
+ #if DEBUG
+ if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
+ Journal_DPrintf( self->debug, "Final list of vec values I need from other procs:\n" );
+ for ( proc_I=0; proc_I < nProc; proc_I++ ) {
+ if ( proc_I == myRank ) continue;
+ Journal_DPrintf( self->debug, "\t%d[0-%d]: ", proc_I, reqFromOthersCounts[proc_I] );
+ for ( req_I=0; req_I < reqFromOthersCounts[proc_I]; req_I++ ) {
+ RequestInfo* reqInfo = &reqFromOthersInfos[proc_I][req_I];
+ Journal_DPrintf( self->debug, "(lnode %d, dof %d -> %d ), ",
+ reqInfo->lNode_I, reqInfo->nodeLocalDof_I,
+ reqFromOthers[proc_I][req_I] );
+ }
+ Journal_DPrintf( self->debug, "\n" );
+ }
+ }
+ #endif
+
+ /* send out my request counts, receive the req. counts others want from me */
+ MPI_Alltoall( reqFromOthersCounts, 1, MPI_UNSIGNED,
+ reqFromMeCounts, 1, MPI_UNSIGNED, mpiComm );
+
+ Journal_DPrintf( self->debug, "After MPI_Alltoall- counts are:\n" );
+ totalRequestedFromOthers = 0;
+ totalRequestedFromMe = 0;
+ Stream_Indent( self->debug );
+ Journal_DPrintf( self->debug, "reqFromOthersCounts: " );
+ for ( proc_I=0; proc_I < nProc; proc_I++ ) {
+ if ( proc_I == myRank ) continue;
+ Journal_DPrintf( self->debug, "\tp%d:%d, ", proc_I, reqFromOthersCounts[proc_I] );
+ totalRequestedFromOthers += reqFromOthersCounts[proc_I];
+ }
+ Journal_DPrintf( self->debug, "\n" );
+ Journal_DPrintf( self->debug, "reqFromMeCounts: " );
+ for ( proc_I=0; proc_I < nProc; proc_I++ ) {
+ if ( proc_I == myRank ) continue;
+ Journal_DPrintf( self->debug, "\tp%d:%d, ", proc_I, reqFromMeCounts[proc_I] );
+ totalRequestedFromMe += reqFromMeCounts[proc_I];
+ }
+ Journal_DPrintf( self->debug, "\n" );
+ Stream_UnIndent( self->debug );
+
+ if ( ( totalRequestedFromOthers == 0) && (totalRequestedFromMe == 0) )
+ {
+ Journal_DPrintf( self->debug, "No vector values either required from others or "
+ "required by others from me, therefore cleaning up memory and returning.\n" );
+ Memory_Free( reqFromMeCounts );
+ Memory_Free( reqFromOthersHandles );
+ Memory_Free( reqValuesFromOthersHandles );
+ Memory_Free( reqValuesFromMeHandles );
+ Memory_Free( reqValuesFromOthers );
+ Memory_Free( reqValuesFromOthersReceived );
+ Stream_UnIndentBranch( StgFEM_Debug );
+ return;
+ }
+
+ Journal_DPrintfL( self->debug, 2, "Starting non-blocking sends of my lists of vector entry indices I want from others:\n" );
+ Stream_Indent( self->debug );
+ for( proc_I=0; proc_I < nProc; proc_I++) {
+ if ( proc_I == myRank ) continue;
+/* Journal_Printf( Journal_Register( Info_Type, (Name)"mpi" ), "!!! line %d, proc_I %d: count = %u\n", __LINE__, proc_I, reqFromOthersCounts[proc_I] ); */
+ if ( reqFromOthersCounts[proc_I] > 0 ) {
+ Journal_DPrintfL( self->debug, 2, "Sending to proc %d the list of %d vector entry indices I want from it:\n"
+ "\t(tracking via reqFromOthersHandles[%d], tag %d)\n", proc_I,
+ reqFromOthersCounts[proc_I], proc_I, VALUE_REQUEST_TAG );
+
+ reqFromOthersHandles[proc_I] = Memory_Alloc_Unnamed( MPI_Request );
+ MPI_Isend( reqFromOthers[proc_I], reqFromOthersCounts[proc_I], MPI_UNSIGNED,
+ proc_I, VALUE_REQUEST_TAG, mpiComm, reqFromOthersHandles[proc_I] );
+ }
+ }
+ Stream_UnIndent( self->debug );
+
+
+ Journal_DPrintfL( self->debug, 2, "Starting non-blocking receive of the vector entries I want from others:\n" );
+ Stream_Indent( self->debug );
+ for( proc_I=0; proc_I < nProc; proc_I++) {
+ if ( proc_I == myRank ) continue;
+ if ( reqFromOthersCounts[proc_I] > 0 ) {
+ Journal_DPrintfL( self->debug, 2, "Posting recv reqst from proc %d for the %d vector entries I want from it:\n"
+ "\t(tracking via reqValuesFromOthersHandles[%d], tag %d)\n", proc_I,
+ reqFromOthersCounts[proc_I], proc_I, VALUE_TAG );
+ reqValuesFromOthersHandles[proc_I] = Memory_Alloc_Unnamed( MPI_Request );
+ MPI_Irecv( reqValuesFromOthers[proc_I], reqFromOthersCounts[proc_I], MPI_DOUBLE,
+ proc_I, VALUE_TAG, mpiComm, reqValuesFromOthersHandles[proc_I] );
+ }
+ }
+ Stream_UnIndent( self->debug );
+
+ Journal_DPrintfL( self->debug, 2, "Starting blocking receive of the lists of vector entry indices "
+ "others want from me:\n" );
+ Stream_Indent( self->debug );
+ reqFromMe = Memory_Alloc_2DComplex( Dof_EquationNumber, nProc, reqFromMeCounts, "reqFromMe" );
+ reqValuesFromMe = Memory_Alloc_2DComplex( double, nProc, reqFromMeCounts, "reqValuesFromMe" );
+ for( proc_I=0; proc_I < nProc; proc_I++) {
+ if ( proc_I == myRank ) continue;
+/* /Journal_Printf( Journal_Register( Info_Type, (Name)"mpi" ), "!!! line %d, proc_I %d: count = %u\n", __LINE__, proc_I, reqFromMeCounts[proc_I] ); */
+ if ( reqFromMeCounts[proc_I] > 0 ) {
+ MPI_Recv( reqFromMe[proc_I], reqFromMeCounts[proc_I], MPI_UNSIGNED,
+ proc_I, VALUE_REQUEST_TAG, mpiComm, &status );
+ Journal_DPrintfL( self->debug, 3, "Received a list of %u requested vector entry indices from proc %u, "
+ "with tag %d\n", reqFromMeCounts[proc_I], proc_I, status.MPI_TAG );
+ }
+ }
+ Stream_UnIndent( self->debug );
+
+ #if DEBUG
+ if ( Stream_IsPrintableLevel( self->debug, 2 ) ) {
+ Journal_DPrintf( self->debug, "Final lists of vector entry indices other procs want from me are:\n" );
+ Stream_Indent( self->debug );
+ for ( proc_I=0; proc_I < nProc; proc_I++ ) {
+ if ( proc_I == myRank ) continue;
+ if ( reqFromMeCounts[proc_I] > 0 ) {
+ Journal_DPrintf( self->debug, "%d[0-%d]: ", proc_I, reqFromMeCounts[proc_I] );
+ for ( req_I=0; req_I < reqFromMeCounts[proc_I]; req_I++ ) {
+ Journal_DPrintf( self->debug, "(eqNum %d), ", reqFromMe[proc_I][req_I] );
+ }
+ Journal_DPrintf( self->debug, "\n" );
+ }
+ }
+ Stream_UnIndent( self->debug );
+ }
+ #endif
+
+ /* for all those requested from me, non-blocking send out values */
+ Journal_DPrintfL( self->debug, 2, "Beginning non-blocking send out of vector entry lists requested by others:\n" );
+ Stream_Indent( self->debug );
+ for( proc_I=0; proc_I < nProc; proc_I++) {
+ if ( proc_I == myRank ) continue;
+ if ( reqFromMeCounts[proc_I] > 0 ) {
+ Journal_DPrintfL( self->debug, 3, "list to proc %d is: ", proc_I );
+ for ( req_I=0; req_I < reqFromMeCounts[proc_I]; req_I++ ) {
+ /* look up and fill in correct value in array */
+ indexIntoLocalSolnVecValues = *(int*)STreeMap_Map( eqNum->ownedMap,
+ reqFromMe[proc_I] + req_I );
+ reqValuesFromMe[proc_I][req_I] = localSolnVecValues[indexIntoLocalSolnVecValues];
+ Journal_DPrintfL( self->debug, 3, "%d=%f, ", reqFromMe[proc_I][req_I],
+ reqValuesFromMe[proc_I][req_I] );
+ }
+ Journal_DPrintfL( self->debug, 3, "\n" );
+ /* Non-blocking send out the now-complete list to this processor */
+ reqValuesFromMeHandles[proc_I] = Memory_Alloc_Unnamed( MPI_Request );
+ Journal_DPrintfL( self->debug, 2, "Sending to proc %d the list of %d vector entries they want:\n"
+ "\t(tracking via reqValuesFromMe[%d], tag %d)\n", proc_I,
+ reqFromMeCounts[proc_I], proc_I, VALUE_TAG );
+ MPI_Isend( reqValuesFromMe[proc_I], reqFromMeCounts[proc_I], MPI_DOUBLE,
+ proc_I, VALUE_TAG, mpiComm, reqValuesFromMeHandles[proc_I] );
+ }
+ }
+ Stream_UnIndent( self->debug );
+
+ Journal_DPrintfL( self->debug, 1, "Starting iterative-test receive of the vector entries I "
+ "requested from others:\n" );
+ /* Set up an array for keeping track of who we've received things from
+ * already */
+ reqValueSetsFromOthersNotYetReceivedCount = nProc-1;
+ for( proc_I=0; proc_I < nProc; proc_I++) {
+ if ( proc_I == myRank ) continue;
+ reqValuesFromOthersReceived[proc_I] = False;
+ if ( reqFromOthersCounts[proc_I] == 0 ) {
+ reqValueSetsFromOthersNotYetReceivedCount--;
+ }
+ }
+
+ #if DEBUG
+ Journal_DPrintfL( self->debug, 2, "(Expecting %d receives from procs: ",
+ reqValueSetsFromOthersNotYetReceivedCount );
+ for( proc_I=0; proc_I < nProc; proc_I++) {
+ if ( proc_I == myRank ) continue;
+ if ( reqFromOthersCounts[proc_I] > 0 ) {
+ Journal_DPrintfL( self->debug, 2, "%d, ", proc_I );
+ }
+ }
+ Journal_DPrintfL( self->debug, 2, ")\n" );
+ #endif
+
+ Stream_Indent( self->debug );
+ /* now update the values at nodes that I requested from others, as they come in */
+ while ( reqValueSetsFromOthersNotYetReceivedCount ) {
+ int flag = 0;
+
+ Journal_DPrintfL( self->debug, 3, "%d sets still to go...\n", reqValueSetsFromOthersNotYetReceivedCount );
+ for( proc_I=0; proc_I < nProc; proc_I++) {
+ if ( proc_I == myRank ) continue;
+
+ if ( (reqFromOthersCounts[proc_I] > 0) && (False == reqValuesFromOthersReceived[proc_I]) ) {
+ MPI_Test( reqValuesFromOthersHandles[proc_I], &flag, &status );
+ if ( !flag ) {
+ /* No results yet from this proc -> continue to next. */
+ continue;
+ }
+ else {
+ RequestInfo* reqInfo;
+ Journal_DPrintfL( self->debug, 2, "received some requested "
+ "values (using reqValuesFromOthersHandles) from proc %d "
+ "(with tag %d, exp %d):", proc_I, status.MPI_TAG, VALUE_TAG );
+ /* go through each value received from that proc & update onto node */
+ for ( req_I=0; req_I < reqFromOthersCounts[proc_I]; req_I++ ) {
+ reqInfo = &reqFromOthersInfos[proc_I][req_I];
+ Journal_DPrintfL( self->debug, 3, "(lnode %d, dof %d -> %d )=%f, ",
+ reqInfo->lNode_I, reqInfo->nodeLocalDof_I,
+ reqFromOthers[proc_I][req_I], reqValuesFromOthers[proc_I][req_I] );
+ DofLayout_SetValueDouble( feVar->dofLayout, reqInfo->lNode_I, reqInfo->nodeLocalDof_I,
+ reqValuesFromOthers[proc_I][req_I] );
+ }
+ Journal_DPrintfL( self->debug, 2, "\n" );
+ reqValuesFromOthersReceived[proc_I] = True;
+ reqValueSetsFromOthersNotYetReceivedCount--;
+ Memory_Free( reqValuesFromOthersHandles[proc_I] );
+ }
+ }
+ }
+ }
+ Stream_UnIndent( self->debug );
+
+ /* MPI_Wait to be sure all sends to others have completed */
+ Journal_DPrintfL( self->debug, 2, "Making sure all comms of this function finished:...\n" );
+ Stream_Indent( self->debug );
+
+ Journal_DPrintfL( self->debug, 2, "Confirming completion of my sends of "
+ "vector entry index lists I wanted from others were received:\n" );
+ Stream_Indent( self->debug );
+ for( proc_I=0; proc_I < nProc; proc_I++) {
+ if ( proc_I == myRank ) continue;
+ if ( reqFromOthersCounts[proc_I] > 0 ) {
+ MPI_Wait( reqFromOthersHandles[proc_I], MPI_STATUS_IGNORE );
+ Journal_DPrintfL( self->debug, 2, "Confirmed wait on reqFromOthersHandles[%u]"
+ "\n", proc_I );
+ Memory_Free( reqFromOthersHandles[proc_I] );
+ }
+ }
+ Stream_UnIndent( self->debug );
+ Journal_DPrintfL( self->debug, 2, "done.\n" );
+
+ Journal_DPrintfL( self->debug, 2, "Confirming completion of my sends of "
+ "vector entry values requested by others were received:\n" );
+ Stream_Indent( self->debug );
+ for( proc_I=0; proc_I < nProc; proc_I++) {
+ if ( proc_I == myRank ) continue;
+ if ( reqFromMeCounts[proc_I] > 0 ) {
+ MPI_Wait( reqValuesFromMeHandles[proc_I], MPI_STATUS_IGNORE );
+ Journal_DPrintfL( self->debug, 2, "Confirmed wait on reqValuesFromMeHandles[%u]"
+ "\n", proc_I );
+ Memory_Free( reqValuesFromMeHandles[proc_I] );
+ }
+ }
+ Stream_UnIndent( self->debug );
+ Journal_DPrintfL( self->debug, 2, "done.\n" );
+
+ Stream_UnIndent( self->debug );
+ Journal_DPrintfL( self->debug, 2, "done.\n" );
+
+ Memory_Free( reqFromMeCounts );
+ Memory_Free( reqFromMe );
+ Memory_Free( reqValuesFromMe );
+ Memory_Free( reqValuesFromOthers );
+ Memory_Free( reqValuesFromOthersReceived );
+ Memory_Free( reqFromOthersHandles );
+ Memory_Free( reqValuesFromOthersHandles );
+ Memory_Free( reqValuesFromMeHandles );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+ return;
+}
+
+
+void SolutionVector_LoadCurrentFeVariableValuesOntoVector( void* solutionVector ) {
+ SolutionVector* self = (SolutionVector*)solutionVector;
+ FeVariable* feVar = self->feVariable;
+ FeMesh* feMesh = feVar->feMesh;
+ Node_LocalIndex node_lI = 0;
+ Dof_Index dof_I = 0;
+ double value = 0;
+ Index insertionIndex = 0;
+
+ for ( node_lI = 0; node_lI < FeMesh_GetNodeLocalSize( feMesh ); node_lI++ ) {
+ for ( dof_I = 0; dof_I < feVar->dofLayout->dofCounts[node_lI]; dof_I++ ) {
+ value = DofLayout_GetValueDouble( feVar->dofLayout, node_lI, dof_I );
+ insertionIndex = feVar->eqNum->destinationArray[node_lI][dof_I];
+ //Vector_InsertEntries( self->vector, 1, &insertionIndex, &value );
+ VecSetValues( self->vector, 1, (PetscInt*)(&insertionIndex), &value, INSERT_VALUES );
+ }
+ }
+
+ //Vector_AssemblyBegin( self->vector );
+ //Vector_AssemblyEnd( self->vector );
+ VecAssemblyBegin( self->vector );
+ VecAssemblyEnd( self->vector );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/StiffnessMatrix.c
--- a/SLE/SystemSetup/src/StiffnessMatrix.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2909 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: StiffnessMatrix.c 1210 2008-08-25 01:17:12Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-#include <mpi.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "FiniteElementContext.h"
-#include "StiffnessMatrix.h"
-#include "StiffnessMatrixTerm.h"
-#include "SystemLinearEquations.h"
-#include "EntryPoint.h"
-#include "SolutionVector.h"
-#include "ForceVector.h"
-#include "Assembler.h"
-
-void __StiffnessMatrix_NewAssemble( void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context );
-void StiffnessMatrix_NewAssemble( void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context );
-Bool StiffnessMatrix_ZeroBCsAsm_RowR( void* stiffMat, Assembler* assm );
-Bool StiffnessMatrix_ZeroBCsAsm_ColR( void* stiffMat, Assembler* assm );
-Bool StiffnessMatrix_BCAsm_ColR( void* stiffMat, Assembler* assm );
-Bool StiffnessMatrix_TransBCAsm_ColR( void* stiffMat, Assembler* assm );
-Bool StiffnessMatrix_DiagBCsAsm_RowR( void* stiffMat, Assembler* assm );
-
-
-/* Textual name of this class */
-const Type StiffnessMatrix_Type = "StiffnessMatrix";
-
-/** First part of name for build entry point */
-static const char StiffnessMatrix_assembleStiffnessMatrixStr[] = "assembleStiffnessMatrix";
-
-
-void* StiffnessMatrix_DefaultNew( Name name )
-{
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(StiffnessMatrix);
- Type type = StiffnessMatrix_Type;
- Stg_Class_DeleteFunction* _delete = _StiffnessMatrix_Delete;
- Stg_Class_PrintFunction* _print = _StiffnessMatrix_Print;
- Stg_Class_CopyFunction* _copy = _StiffnessMatrix_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = StiffnessMatrix_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _StiffnessMatrix_AssignFromXML;
- Stg_Component_BuildFunction* _build = _StiffnessMatrix_Build;
- Stg_Component_InitialiseFunction* _initialise = _StiffnessMatrix_Initialise;
- Stg_Component_ExecuteFunction* _execute = _StiffnessMatrix_Execute;
- Stg_Component_DestroyFunction* _destroy = _StiffnessMatrix_Destroy;
- Bool initFlag = False;
- StiffnessMatrix_CalculateNonZeroEntriesFunction* _calculateNonZeroEntries = StiffnessMatrix_CalcNonZeros;
- void* rowVariable = NULL;
- void* columnVariable = NULL;
- void* rhs = NULL;
- Stg_Component* applicationDepInfo = NULL;
- Dimension_Index dim = 0;
- Bool isNonLinear = False;
- Bool allowZeroElementContributions = False;
- void* entryPoint_Register = NULL;
- MPI_Comm comm = 0;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _StiffnessMatrix_New( STIFFNESSMATRIX_PASSARGS );
-}
-
-
-StiffnessMatrix* StiffnessMatrix_New(
- Name name,
- void* rowVariable,
- void* columnVariable,
- void* rhs,
- Stg_Component* applicationDepInfo,
- Dimension_Index dim,
- Bool isNonLinear,
- Bool allowZeroElementContributions,
- void* entryPoint_Register,
- MPI_Comm comm )
-{
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(StiffnessMatrix);
- Type type = StiffnessMatrix_Type;
- Stg_Class_DeleteFunction* _delete = _StiffnessMatrix_Delete;
- Stg_Class_PrintFunction* _print = _StiffnessMatrix_Print;
- Stg_Class_CopyFunction* _copy = _StiffnessMatrix_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = StiffnessMatrix_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _StiffnessMatrix_AssignFromXML;
- Stg_Component_BuildFunction* _build = _StiffnessMatrix_Build;
- Stg_Component_InitialiseFunction* _initialise = _StiffnessMatrix_Initialise;
- Stg_Component_ExecuteFunction* _execute = _StiffnessMatrix_Execute;
- Stg_Component_DestroyFunction* _destroy = _StiffnessMatrix_Destroy;
- Bool initFlag = True;
- StiffnessMatrix_CalculateNonZeroEntriesFunction* _calculateNonZeroEntries = StiffnessMatrix_CalcNonZeros;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _StiffnessMatrix_New( STIFFNESSMATRIX_PASSARGS );
-}
-
-
-StiffnessMatrix* _StiffnessMatrix_New( STIFFNESSMATRIX_DEFARGS )
-{
- StiffnessMatrix* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(StiffnessMatrix) );
- /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
- /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
- and so should be set to ZERO in any children of this class. */
- nameAllocationType = NON_GLOBAL;
-
- self = (StiffnessMatrix*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- /* General info */
-
- /* Virtual functions */
- self->_calculateNonZeroEntries = _calculateNonZeroEntries;
-
- if( initFlag ){
- _StiffnessMatrix_Init( self, rowVariable, columnVariable, rhs, applicationDepInfo, dim,
- isNonLinear, allowZeroElementContributions, entryPoint_Register, comm );
- }
-
- return self;
-}
-
-void _StiffnessMatrix_Init(
- StiffnessMatrix* self,
- void* rowVariable,
- void* columnVariable,
- void* rhs,
- Stg_Component* applicationDepInfo,
- Dimension_Index dim,
- Bool isNonLinear,
- Bool allowZeroElementContributions,
- void* entryPoint_Register,
- MPI_Comm comm )
-{
- Stream* error = Journal_Register( ErrorStream_Type, (Name)self->type );
- Stream* stream;
-
- /* General and Virtual info should already be set */
- stream = Journal_Register( Info_Type, (Name)self->type );
- Stream_SetPrintingRank( stream, 0 );
-
- /* StiffnessMatrix info */
- self->isConstructed = True;
- self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type );
- Journal_Firewall( (rowVariable != NULL), error, "Error: NULL row FeVariable provided to \"%s\" %s.\n", self->name, self->type );
-
- self->rowVariable = (FeVariable*)rowVariable;
- Journal_Firewall( (columnVariable != NULL), error, "Error: NULL column FeVariable provided to \"%s\" %s.\n", self->name, self->type );
-
- self->columnVariable = (FeVariable*)columnVariable;
- Journal_Firewall( (rhs != NULL), error, "Error: NULL rhs ForceVector provided to \"%s\" %s.\n", self->name, self->type );
-
- self->rhs = (ForceVector*)rhs;
- self->applicationDepInfo = applicationDepInfo;
- self->comm = comm;
- self->dim = dim;
- self->isNonLinear = isNonLinear;
- self->allowZeroElementContributions = allowZeroElementContributions;
-
- self->rowLocalSize = 0;
- self->colLocalSize = 0;
- self->nonZeroCount = 0;
- self->diagonalNonZeroCount = 0;
- self->offDiagonalNonZeroCount = 0;
- self->diagonalNonZeroIndices = NULL;
- self->offDiagonalNonZeroIndices = NULL;
-
- self->entryPoint_Register = (EntryPoint_Register*)entryPoint_Register;
-
- Stg_asprintf( &self->_assembleStiffnessMatrixEPName, "%s-%s", self->name, StiffnessMatrix_assembleStiffnessMatrixStr );
- self->assembleStiffnessMatrix = FeEntryPoint_New( self->_assembleStiffnessMatrixEPName, FeEntryPoint_AssembleStiffnessMatrix_CastType );
-
- EntryPoint_Register_Add( self->entryPoint_Register, self->assembleStiffnessMatrix );
-
- self->stiffnessMatrixTermList = Stg_ObjectList_New();
-
- /* Set default function for Global Stiffness Matrix Assembly */
- EP_ReplaceAll( self->assembleStiffnessMatrix, __StiffnessMatrix_NewAssemble );
-
- /* We need some assembler contexts. */
- self->zeroBCsAsm = Assembler_New();
- self->bcAsm = Assembler_New();
- self->transBCAsm = Assembler_New();
-
- if( rowVariable == columnVariable )
- self->diagBCsAsm = Assembler_New();
-
- self->elStiffMat = NULL;
- self->bcVals = NULL;
- self->nRowDofs = 0;
- self->nColDofs = 0;
- self->transRHS = NULL;
-
- self->rowInc = IArray_New();
- self->colInc = IArray_New();
-
- self->nModifyCBs = 0;
- self->modifyCBs = NULL;
-
- self->matrix = PETSC_NULL;
- /* self->shellMatrix = NULL; */
- /* self->useShellMatrix = False; */
-}
-
-void _StiffnessMatrix_Delete( void* stiffnessMatrix ) {
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
- /* Stg_Class_Delete parent*/
- _Stg_Component_Delete( self );
-
-}
-
-void _StiffnessMatrix_Print( void* stiffnessMatrix, Stream* stream ) {
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
-
- /* Set the Journal for printing informations */
- Stream* stiffnessMatrixStream = stream;
-
- /* General info */
- Journal_Printf( stiffnessMatrixStream, "StiffnessMatrix (ptr): %p\n", self );
-
- /* Print parent */
- _Stg_Component_Print( self, stiffnessMatrixStream );
-
- /* Virtual info */
- Journal_Printf( stiffnessMatrixStream, "\t_build (func ptr): %p\n", self->_build );
-
- Journal_Printf( stiffnessMatrixStream, "\tassembleStiffnessMatrix e.p. (ptr): %p\n", self->assembleStiffnessMatrix );
- EntryPoint_PrintConcise( self->assembleStiffnessMatrix, stream );
-
- /* StiffnessMatrix info */
- Journal_Printf( stiffnessMatrixStream, "\trowVariable (ptr): %p\n", self->rowVariable );
- Journal_Printf( stiffnessMatrixStream, "\t\tvariable name: %s\n", self->rowVariable->name );
- Journal_Printf( stiffnessMatrixStream, "\tcolumnVariable (ptr): %p\n", self->columnVariable );
- Journal_Printf( stiffnessMatrixStream, "\t\tvariable name: %s\n", self->columnVariable->name );
- Journal_Printf( stiffnessMatrixStream, "\tMatrix (ptr): %p\n", self->matrix );
- Journal_Printf( stiffnessMatrixStream, "\tComm: %u\n", self->comm );
- Journal_Printf( stiffnessMatrixStream, "\trowLocalSize: %u\n", self->rowLocalSize );
- Journal_Printf( stiffnessMatrixStream, "\tcolLocalSize: %u\n", self->colLocalSize );
- Journal_Printf( stiffnessMatrixStream, "\tnonZeroCount: %u\n", self->nonZeroCount );
- Journal_Printf( stiffnessMatrixStream, "\tisNonLinear: %s\n", StG_BoolToStringMap[self->isNonLinear] );
- Journal_Printf( stiffnessMatrixStream, "\tallowZeroElementContributions: %s\n", StG_BoolToStringMap[self->allowZeroElementContributions] );
-}
-
-void* _StiffnessMatrix_Copy( const void* stiffnessMatrix, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
- StiffnessMatrix* newStiffnessMatrix;
- PtrMap* map = ptrMap;
- Bool ownMap = False;
-
- if( !map ) {
- map = PtrMap_New( 10 );
- ownMap = True;
- }
-
- newStiffnessMatrix = (StiffnessMatrix*)_Stg_Component_Copy( self, dest, deep, nameExt, map );
-
- /* Virtual functions */
- newStiffnessMatrix->_calculateNonZeroEntries = self->_calculateNonZeroEntries;
-
- /* TODO: copy matrix */
- newStiffnessMatrix->matrix = self->matrix;
-/* newStiffnessMatrix->shellMatrix = self->shellMatrix; */
- newStiffnessMatrix->entryPoint_Register = self->entryPoint_Register;
- newStiffnessMatrix->comm = self->comm;
- newStiffnessMatrix->rowLocalSize = self->rowLocalSize;
- newStiffnessMatrix->colLocalSize = self->colLocalSize;
- newStiffnessMatrix->dim = self->dim;
- newStiffnessMatrix->nonZeroCount = self->nonZeroCount;
- newStiffnessMatrix->diagonalNonZeroCount = self->diagonalNonZeroCount;
- newStiffnessMatrix->offDiagonalNonZeroCount = self->offDiagonalNonZeroCount;
-
- if( deep ) {
- newStiffnessMatrix->debug = (Stream*)Stg_Class_Copy( self->debug, NULL, deep, nameExt, map );
- newStiffnessMatrix->rowVariable = (FeVariable*)Stg_Class_Copy( self->rowVariable, NULL, deep, nameExt, map );
- newStiffnessMatrix->columnVariable = (FeVariable*)Stg_Class_Copy( self->columnVariable, NULL, deep, nameExt, map );
- newStiffnessMatrix->rhs =(ForceVector*)Stg_Class_Copy( self->rhs, NULL, deep, nameExt, map );
- newStiffnessMatrix->assembleStiffnessMatrix = (FeEntryPoint*)Stg_Class_Copy( self->assembleStiffnessMatrix, NULL, deep, nameExt, map );
-
- if( self->_assembleStiffnessMatrixEPName ) {
- if( nameExt ) {
- Stg_asprintf( &newStiffnessMatrix->_assembleStiffnessMatrixEPName, "%s%s",
- self->_assembleStiffnessMatrixEPName, nameExt );
- }
- else {
- newStiffnessMatrix->_assembleStiffnessMatrixEPName = StG_Strdup( self->_assembleStiffnessMatrixEPName );
- }
- }
- else {
- newStiffnessMatrix->_assembleStiffnessMatrixEPName = NULL;
- }
-
- /* Arrays */
- if( (newStiffnessMatrix->diagonalNonZeroIndices = (Index*)PtrMap_Find( map, self->diagonalNonZeroIndices )) == NULL ) {
- if( self->diagonalNonZeroIndices ) {
- newStiffnessMatrix->diagonalNonZeroIndices = Memory_Alloc_Array( Index,
- newStiffnessMatrix->rowLocalSize, "diagonalNonZeroIndices" );
- memcpy( newStiffnessMatrix->diagonalNonZeroIndices, self->diagonalNonZeroIndices,
- newStiffnessMatrix->rowLocalSize * sizeof( Index ) );
- PtrMap_Append( map, self->diagonalNonZeroIndices, newStiffnessMatrix->diagonalNonZeroIndices );
- }
- else {
- newStiffnessMatrix->diagonalNonZeroIndices = NULL;
- }
- }
-
- if( (newStiffnessMatrix->offDiagonalNonZeroIndices = (Index*)PtrMap_Find( map, self->offDiagonalNonZeroIndices )) == NULL ) {
- if( self->offDiagonalNonZeroIndices ) {
- newStiffnessMatrix->offDiagonalNonZeroIndices = Memory_Alloc_Array( Index,
- newStiffnessMatrix->rowLocalSize, "diagonalNonZeroIndices" );
- memcpy( newStiffnessMatrix->offDiagonalNonZeroIndices, self->offDiagonalNonZeroIndices,
- newStiffnessMatrix->rowLocalSize * sizeof( Index ) );
- PtrMap_Append( map, self->offDiagonalNonZeroIndices, newStiffnessMatrix->offDiagonalNonZeroIndices );
- }
- else {
- newStiffnessMatrix->offDiagonalNonZeroIndices = NULL;
- }
- }
- }
- else {
- newStiffnessMatrix->debug = self->debug;
- newStiffnessMatrix->rowVariable = self->rowVariable;
- newStiffnessMatrix->columnVariable = self->columnVariable;
- newStiffnessMatrix->rhs = self->rhs;
- newStiffnessMatrix->diagonalNonZeroIndices = self->diagonalNonZeroIndices;
- newStiffnessMatrix->offDiagonalNonZeroIndices = self->offDiagonalNonZeroIndices;
- }
-
- if( ownMap ) {
- Stg_Class_Delete( map );
- }
-
- return (void*)newStiffnessMatrix;
-}
-
-void _StiffnessMatrix_AssignFromXML( void* stiffnessMatrix, Stg_ComponentFactory* cf, void* data ) {
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
- Stream* stream;
- FeVariable* rowVar = NULL;
- FeVariable* colVar = NULL;
- ForceVector* fVector = NULL;
- Stg_Component* applicationDepInfo = NULL;
- void* entryPointRegister = NULL;
- Dimension_Index dim = 0;
- Bool isNonLinear;
- Bool allowZeroElementContributions;
-
- self->context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", FiniteElementContext, False, data );
- if( !self->context )
- self->context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
-
- rowVar = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"RowVariable", FeVariable, True, data );
- colVar = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ColumnVariable", FeVariable, True, data );
- fVector = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"RHS", ForceVector, False, data );
- applicationDepInfo = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ApplicationDepInfo", Stg_Component, False, data);
-
- entryPointRegister = self->context->entryPoint_Register;
- assert( entryPointRegister );
-
- dim = Stg_ComponentFactory_GetRootDictUnsignedInt( cf, (Dictionary_Entry_Key)"dim", 0 );
- assert( dim );
-
- isNonLinear = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"isNonLinear", False );
-
- /* Default is to allow zero element contributions - to allow backward compatibility */
- allowZeroElementContributions = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"allowZeroElementContributions", True );
-
- _StiffnessMatrix_Init(
- self,
- rowVar,
- colVar,
- fVector,
- applicationDepInfo,
- dim,
- isNonLinear,
- allowZeroElementContributions,
- entryPointRegister,
- 0 );
-
- /* Do we need to use the transpose? */
- self->transRHS = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"transposeRHS", ForceVector, False, data );
-
- /* Read the matrix type from the dictionary. */
-/* self->shellMatrix = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"matrix", PETScShellMatrix, False, data ); */
-/* if( !self->shellMatrix ) { */
-/* self->useShellMatrix = False; */
-/* } */
-/* else { */
-/* EP_ReplaceAll( self->assembleStiffnessMatrix, StiffnessMatrix_ShellAssembly ); */
-
-/* self->useShellMatrix = True; */
-/* } */
-
- /* Setup the stream. */
- stream = Journal_Register( Info_Type, (Name)self->type );
- if( Dictionary_GetBool_WithDefault( cf->rootDict, (Dictionary_Entry_Key)"watchAll", False ) == True )
- Stream_SetPrintingRank( stream, STREAM_ALL_RANKS );
- else {
- unsigned rankToWatch;
-
- rankToWatch = Dictionary_GetUnsignedInt_WithDefault( cf->rootDict, "rankToWatch", 0 );
- Stream_SetPrintingRank( stream, rankToWatch );
- }
-}
-
-void _StiffnessMatrix_Build( void* stiffnessMatrix, void* data ) {
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
-
- Journal_DPrintf( self->debug, "In %s - for matrix %s\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
-
- /* ensure variables are built */
- if( self->rowVariable )
- Stg_Component_Build( self->rowVariable, data, False );
-
- /* If we don't have a communicator, grab one off the mesh. */
- if( !self->comm ) {
- self->comm = Mesh_GetCommTopology( self->rowVariable->feMesh, MT_VERTEX )->mpiComm;
- Journal_Firewall( (self->comm != 0), self->debug, "Error: NULL Comm provided to \"%s\" %s.\n",
- self->name, self->type );
- }
-
- if( self->columnVariable )
- Stg_Component_Build( self->columnVariable, data, False );
-
- /* ensure the rhs vector is built */
- Stg_Component_Build( self->rhs, data, False );
-
-
-/* if( self->useShellMatrix ) */
-/* Stg_Component_Build( self->shellMatrix, data, False ); */
-
-#if DEBUG
- if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
- Journal_DPrintf( self->debug, "Row variable(%s) I.D. array calc. as:\n", self->rowVariable->name );
- FeEquationNumber_PrintDestinationArray( self->rowVariable->eqNum, self->debug );
- Journal_DPrintf( self->debug, "Column variable(%s) I.D. array calc. as:\n", self->columnVariable->name );
- FeEquationNumber_PrintDestinationArray( self->columnVariable->eqNum, self->debug );
- }
-#endif
-
- /* update the row and column sizes for the variables */
- self->rowLocalSize = self->rowVariable->eqNum->localEqNumsOwnedCount;
- assert( self->rowLocalSize );
- self->colLocalSize = self->columnVariable->eqNum->localEqNumsOwnedCount;
- assert( self->colLocalSize );
-
- /* update the number of non zero entries from the finite element variables */
- StiffnessMatrix_CalcNonZeros( self );
-
- Journal_DPrintf( self->debug, "row(%s) localSize = %d : col(%s) localSize = %d \n", self->rowVariable->name,
- self->rowLocalSize, self->columnVariable->name, self->colLocalSize );
-
- /* assert( self->nonZeroCount ); */
-
- StiffnessMatrix_RefreshMatrix( self );
-
- Journal_DPrintf( self->debug, "Matrix allocated.\n" );
-
- Assembler_SetVariables( self->zeroBCsAsm, self->rowVariable, self->columnVariable );
- Assembler_SetCallbacks( self->zeroBCsAsm, NULL, StiffnessMatrix_ZeroBCsAsm_RowR, NULL,
- StiffnessMatrix_ZeroBCsAsm_ColR, NULL,
- self );
- Assembler_SetVariables( self->bcAsm, self->rowVariable, self->columnVariable );
- Assembler_SetCallbacks( self->bcAsm,
- NULL,
- NULL, NULL,
- StiffnessMatrix_BCAsm_ColR, NULL,
- self );
- Assembler_SetVariables( self->transBCAsm, self->columnVariable, self->rowVariable );
- Assembler_SetCallbacks( self->transBCAsm,
- NULL,
- NULL, NULL,
- StiffnessMatrix_TransBCAsm_ColR, NULL,
- self );
- if( self->rowVariable == self->columnVariable ) {
- Assembler_SetVariables( self->diagBCsAsm, self->rowVariable, self->columnVariable );
- Assembler_SetCallbacks( self->diagBCsAsm,
- NULL,
- StiffnessMatrix_DiagBCsAsm_RowR, NULL,
- NULL, NULL,
- self );
- }
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _StiffnessMatrix_Initialise( void* stiffnessMatrix, void* data ) {
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
-
- Journal_DPrintf( self->debug, "In %s - for matrix %s\n", __func__, self->name );
- /* ensure variables are initialised */
- if( self->rowVariable )
- Stg_Component_Initialise( self->rowVariable, data, False );
-
- if( self->columnVariable )
- Stg_Component_Initialise( self->columnVariable, data, False );
-
- /* ensure the rhs vector is built */
- Stg_Component_Initialise( self->rhs, data, False );
-
-/* if( self->useShellMatrix ) */
-/* Stg_Component_Initialise( self->shellMatrix, data, False ); */
-}
-
-
-void _StiffnessMatrix_Execute( void* stiffnessMatrix, void* data ) {
-}
-
-void _StiffnessMatrix_Destroy( void* stiffnessMatrix, void* data ) {
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
-
- Journal_DPrintf( self->debug, "In %s - for matrix %s\n", __func__, self->name );
- MatDestroy( self->matrix );
- FreeObject( self->stiffnessMatrixTermList );
- FreeArray( self->_assembleStiffnessMatrixEPName );
- FreeArray( self->diagonalNonZeroIndices );
- FreeArray( self->offDiagonalNonZeroIndices );
- FreeObject( self->zeroBCsAsm );
- FreeObject( self->bcAsm );
- FreeObject( self->transBCAsm );
- FreeObject( self->diagBCsAsm );
- /* Don't delete entry points: E.P. register will delete them automatically */
- NewClass_Delete( self->rowInc );
- NewClass_Delete( self->colInc );
-
-
-}
-
-void StiffnessMatrix_CalculateNonZeroEntries( void* stiffnessMatrix ) {
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
-
- self->_calculateNonZeroEntries( self );
-}
-
-void _StiffnessMatrix_CalculateNonZeroEntries( void* stiffnessMatrix ) {
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
- FeMesh* rFeMesh = self->rowVariable->feMesh;
- FeMesh* cFeMesh = self->columnVariable->feMesh;
- Dof_EquationNumber currMatrixRow = 0;
- Node_LocalIndex rowNode_lI = 0;
- Index activeEqsAtCurrRowNodeCount = 0;
-#ifdef DEBUG
- unsigned int totalNonZeroEntries = 0;
-#endif
-
- Journal_DPrintf( self->debug, "In %s - for matrix %s\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
-
- assert ( self->rowVariable );
- assert ( self->columnVariable );
-
- Journal_DPrintfL( self->debug, 1, "row nodeLocalCount %d\n", FeMesh_GetNodeLocalSize( rFeMesh ) );
- Journal_DPrintfL( self->debug, 1, "column nodeLocalCount %d\n", FeMesh_GetNodeLocalSize( cFeMesh ) );
-
- self->diagonalNonZeroIndices = Memory_Alloc_Array ( Index, self->rowLocalSize, "diagonalNonZeroIndices" );
- self->offDiagonalNonZeroIndices = Memory_Alloc_Array ( Index, self->rowLocalSize, "offDiagonalNonZeroIndices" );
- for ( rowNode_lI = 0; rowNode_lI < self->rowLocalSize; rowNode_lI++ ) {
- self->diagonalNonZeroIndices[rowNode_lI] = 0;
- self->offDiagonalNonZeroIndices[rowNode_lI] = 0;
- }
-
- for( rowNode_lI = 0; rowNode_lI < FeMesh_GetNodeLocalSize( rFeMesh ); rowNode_lI++ ) {
- _StiffnessMatrix_CalcAndUpdateNonZeroEntriesAtRowNode( self, rowNode_lI, currMatrixRow, activeEqsAtCurrRowNodeCount );
- }
-
-#ifdef DEBUG
- for ( rowNode_lI = 0; rowNode_lI < self->rowLocalSize; rowNode_lI++ ) {
- totalNonZeroEntries += self->diagonalNonZeroIndices[rowNode_lI];
- totalNonZeroEntries += self->offDiagonalNonZeroIndices[rowNode_lI];
- }
-
- Journal_DPrintfL( self->debug, 1, "Calculated %d non-zero entries in Matrix (results in %d bytes storage)\n",
- totalNonZeroEntries, totalNonZeroEntries * sizeof(double) );
-#endif
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _StiffnessMatrix_CalcAndUpdateNonZeroEntriesAtRowNode(
- StiffnessMatrix* self,
- Node_LocalIndex rowNode_lI,
- Dof_EquationNumber currMatrixRow,
- Index activeEqsAtCurrRowNode )
-{
- FeMesh* rFeMesh = self->rowVariable->feMesh;
- FeMesh* cFeMesh = self->columnVariable->feMesh;
- DofLayout* colDofLayout = self->columnVariable->dofLayout;
- FeEquationNumber* rowEqNum = self->rowVariable->eqNum;
- FeEquationNumber* colEqNum = self->columnVariable->eqNum;
- Element_Index rowNodeElement_I = 0;
- Element_DomainIndex element_dI = 0;
- Node_DomainIndex colNode_dI = 0;
- Dof_Index colNodeDof_I = 0;
- Index* countTableToAdjust = 0;
- Dof_EquationNumber currColEqNum = 0;
- Node_DomainIndex* uniqueRelatedColNodes = NULL;
- Node_Index uniqueRelatedColNodesCount = 0;
- Node_Index uniqueRelatedColNodes_AllocCount = 0;
- Node_Index uniqueRelatedColNode_I = 0;
- Dof_Index currNodeDof_I = 0;
- Dof_EquationNumber currDofMatrixRow = 0;
- unsigned nNodeInc, *nodeInc;
-
- Journal_DPrintfL( self->debug, 3, "In %s - for row local node %d\n", __func__, rowNode_lI );
- Stream_Indent( self->debug );
-
- FeMesh_GetNodeElements( rFeMesh, rowNode_lI, self->rowInc );
- nNodeInc = IArray_GetSize( self->rowInc );
- nodeInc = (unsigned*)IArray_GetPtr( self->rowInc );
- for ( rowNodeElement_I = 0; rowNodeElement_I < nNodeInc; rowNodeElement_I++ ) {
- unsigned nElInc;
-
- /* note the dI (domain index) - some of these elements may be in shadow space */
- element_dI = nodeInc[rowNodeElement_I];
-
- nElInc = FeMesh_GetElementNodeSize( cFeMesh, element_dI );
- uniqueRelatedColNodes_AllocCount += nElInc;
- }
-
- Journal_DPrintfL( self->debug, 3, "Calculated the max possible number of unique related nodes as %d\n",
- uniqueRelatedColNodes_AllocCount );
- uniqueRelatedColNodes = Memory_Alloc_Array( Node_DomainIndex, uniqueRelatedColNodes_AllocCount, "uniqueRelatedColNodes" );
-
- _StiffnessMatrix_CalculatedListOfUniqueRelatedColNodes( self, rowNode_lI, uniqueRelatedColNodes, &uniqueRelatedColNodesCount);
-
- Journal_DPrintfL( self->debug, 3, "Searching the %d unique related col nodes for active dofs\n",
- uniqueRelatedColNodesCount );
- Stream_Indent( self->debug );
- for ( uniqueRelatedColNode_I = 0; uniqueRelatedColNode_I < uniqueRelatedColNodesCount; uniqueRelatedColNode_I++ ) {
- colNode_dI = uniqueRelatedColNodes[uniqueRelatedColNode_I];
-
- Journal_DPrintfL( self->debug, 3, "col node_dI %d: has %d dofs\n", colNode_dI, colDofLayout->dofCounts[colNode_dI] );
- Stream_Indent( self->debug );
- for ( colNodeDof_I = 0; colNodeDof_I < colDofLayout->dofCounts[colNode_dI]; colNodeDof_I++ ) {
-
- currColEqNum = colEqNum->destinationArray[colNode_dI][colNodeDof_I];
- Journal_DPrintfL( self->debug, 3, "dof %d: ", colNodeDof_I );
- if ( currColEqNum == -1 ) {
- Journal_DPrintfL( self->debug, 3, "is a BC.\n" );
- }
- else {
- if( STreeMap_HasKey( colEqNum->ownedMap, &currColEqNum ) ) {
- Journal_DPrintfL( self->debug, 3, "is diagonal (eq %d)\n", currColEqNum );
- countTableToAdjust = self->diagonalNonZeroIndices;
- }
- else {
- Journal_DPrintfL( self->debug, 3, "is off-diagonal (eq %d)\n", currColEqNum );
- countTableToAdjust = self->offDiagonalNonZeroIndices;
- }
-
- for ( currNodeDof_I = 0; currNodeDof_I < self->rowVariable->dofLayout->dofCounts[rowNode_lI]; currNodeDof_I++) {
- if ( -1 != rowEqNum->destinationArray[rowNode_lI][currNodeDof_I] ) {
- currDofMatrixRow = *(int*)STreeMap_Map(
- rowEqNum->ownedMap,
- rowEqNum->destinationArray[rowNode_lI] + currNodeDof_I );
-
- /* Because of periodic BCs, the eq num may be lower than the normal
- * lowest held on this processor, so we need to check this */
- if ( currDofMatrixRow >= self->rowLocalSize ) {
- Journal_DPrintfL( self->debug, 3, "Found currDofMatRow(=%d) >= self->rowLocalSize(=%d) : for "
- "rowNode_lI=%d, currMatRow=%d, colNode_dI=%d, colNodeDof_I = %d, "
- "currNodeDof_I = %d\n", currDofMatrixRow,
- self->rowLocalSize, rowNode_lI, currMatrixRow,
- colNode_dI, colNodeDof_I, currNodeDof_I );
- }
- else if ( currDofMatrixRow < 0 ) {
- Journal_DPrintfL( self->debug, 3, "Found currDofMatRow(=%d) < 0 : for "
- "rowNode_lI=%d, currMatRow=%d, colNode_dI=%d, colNodeDof_I = %d, "
- "currNodeDof_I = %d\n", currDofMatrixRow,
- rowNode_lI, currMatrixRow,
- colNode_dI, colNodeDof_I, currNodeDof_I );
- }
- else {
- Journal_DPrintfL( self->debug, 3, "(incrementing app. count at row %d)\n",
- currDofMatrixRow );
-
- countTableToAdjust[ currDofMatrixRow ] += 1;
- }
- }
- }
- }
- }
- Stream_UnIndent( self->debug );
- }
- Stream_UnIndent( self->debug );
-
- Journal_DPrintfL( self->debug, 3, "diagonal count\t%d off diagonal count\t%d\n",
- self->diagonalNonZeroIndices[currMatrixRow], self->offDiagonalNonZeroIndices[currMatrixRow]);
-
- Memory_Free( uniqueRelatedColNodes );
-
-/* TODO: do we need to check that diag is set to at least 1, as the PETSc webpage on MatCreate_MPIAIJ suggests? */
-
- Stream_UnIndent( self->debug );
-}
-
-
-void _StiffnessMatrix_CalculatedListOfUniqueRelatedColNodes(
- StiffnessMatrix* self,
- Node_LocalIndex rowNode_lI,
- Node_DomainIndex* uniqueRelatedColNodes,
- Node_Index* uniqueRelatedColNodesCountPtr )
-{
- FeMesh* rFeMesh = self->rowVariable->feMesh;
- FeMesh* cFeMesh = self->columnVariable->feMesh;
- Element_Index rowNodeElement_I = 0;
- Element_DomainIndex element_dI = 0;
- Node_Index colElLocalNode_I = 0;
- Node_DomainIndex colNode_dI = 0;
- Node_Index uniqueRelatedColNode_I = 0;
- unsigned nNodeInc, *nodeInc;
-
- FeMesh_GetNodeElements( rFeMesh, rowNode_lI, self->rowInc );
- nNodeInc = IArray_GetSize( self->rowInc );
- nodeInc = (unsigned*)IArray_GetPtr( self->rowInc );
- Journal_DPrintfL( self->debug, 3, "Searching the %d elements this node belongs to for unique related col nodes:\n",
- nNodeInc );
-
- Stream_Indent( self->debug );
- for ( rowNodeElement_I = 0; rowNodeElement_I < nNodeInc; rowNodeElement_I++ ) {
- unsigned nElInc, *elInc;
-
- /* note the dI (domain index) - some of these elements may be in shadow space */
- element_dI = nodeInc[rowNodeElement_I];
-
- Journal_DPrintfL( self->debug, 3, "rowNodeElement_I: ", rowNodeElement_I );
- Journal_DPrintfL( self->debug, 3, "domain element %d\n", element_dI );
-
- Stream_Indent( self->debug );
- FeMesh_GetElementNodes( cFeMesh, element_dI, self->colInc );
- nElInc = IArray_GetSize( self->colInc );
- elInc = (unsigned*)IArray_GetPtr( self->colInc );
- Journal_DPrintfL( self->debug, 3, "Searching the %d column var nodes in this el:\n", nElInc );
- for ( colElLocalNode_I =0; colElLocalNode_I < nElInc; colElLocalNode_I++ ) {
- colNode_dI = elInc[colElLocalNode_I];
-
- Journal_DPrintfL( self->debug, 3, "Col domain node %d: ", colNode_dI );
- for ( uniqueRelatedColNode_I = 0; uniqueRelatedColNode_I < (*uniqueRelatedColNodesCountPtr); uniqueRelatedColNode_I++ )
- {
- if ( colNode_dI == uniqueRelatedColNodes[uniqueRelatedColNode_I] ) {
- Journal_DPrintfL( self->debug, 3, "already in list -> skip to next.\n" );
- break;
- }
- }
- if ( uniqueRelatedColNode_I == (*uniqueRelatedColNodesCountPtr) ) {
- Journal_DPrintfL( self->debug, 3, "is unique so far -> add to list.\n" );
- uniqueRelatedColNodes[uniqueRelatedColNode_I] = colNode_dI;
- (*uniqueRelatedColNodesCountPtr)++;
- }
- }
- Stream_UnIndent( self->debug );
- }
- Stream_UnIndent( self->debug );
-}
-
-
-void StiffnessMatrix_Assemble( void* stiffnessMatrix, Bool bcRemoveQuery, void* _sle, void* _context ) {
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
- int ii;
-
- StiffnessMatrix_RefreshMatrix( self );
-
- Journal_DPrintf( self->debug, "In %s - for matrix \"%s\" - calling the \"%s\" E.P.\n", __func__, self->name,
- self->assembleStiffnessMatrix->name );
- /* Call the Entry point directly from the base class */
- /* Note that it may be empty: this is deliberate. */
- ((FeEntryPoint_AssembleStiffnessMatrix_CallFunction*)EntryPoint_GetRun( self->assembleStiffnessMatrix ))(
- self->assembleStiffnessMatrix,
- self,
- bcRemoveQuery,
- _sle,
- _context );
-
- /* Run all the modify callbacks. */
- for( ii = 0; ii < self->nModifyCBs; ii++ ) {
- void* callback = self->modifyCBs[ii].callback;
- void* object = self->modifyCBs[ii].object;
- ((void(*)(void*))callback)( object );
- }
-}
-
-
-void StiffnessMatrix_GlobalAssembly_General( void* stiffnessMatrix, Bool bcRemoveQuery, void* _sle, void* _context )
-{
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
- SystemLinearEquations* sle = (SystemLinearEquations*)_sle;
- FiniteElementContext* context = (FiniteElementContext*)_context;
-
- FeVariable* feVars[MAX_FE_VARS]; /* Set later */
- Index numFeVars = 2;
- Index feVar_I;
-
- /* Location Matrix for a single element - may be a ptr into full LM array */
- Dof_EquationNumber** elementLM[MAX_FE_VARS];
- /* Number of dofs at an element: required for matrix assembly */
- Dof_Index* totalDofsThisElement[MAX_FE_VARS];
- Dof_Index* totalDofsPrevElement[MAX_FE_VARS];
- /* The actual element stiffness matrix values, per element: filled in by this class's entry point */
- double** elStiffMatToAdd = NULL;
-
- /* counts and indices used in building per-element locationMatrix and BC info */
- Element_LocalIndex nLocalElements;
- Element_LocalIndex element_lI;
- Node_ElementLocalIndex nodeCountThisEl;
- /* Shortcut to node IDs at a particular element */
- Element_Nodes nodeIdsThisEl;
-
- /* related to correction of BCs */
- Bool makeBC_Corrections_row = False;
- Bool modifiedRHS_Vec_cont = False;
- Dof_Index* bcLM_Id[ MAX_FE_VARS ] = { NULL, NULL };
- double* bcValues[ MAX_FE_VARS ] = { NULL, NULL };
- int nBC_NodalDof[ MAX_FE_VARS ] = { 0, 0 };
- double* h2Add = NULL;
-
- /* For output printing */
- double outputPercentage = 10; /* Controls how often to give a status update of assembly progress*/
- int outputInterval;
- double startTime, totalTime;
- double matAddingStart;
- double matAddingTime = 0;
- double elStiffMatBuildStart;
- double elStiffMatBuildTime = 0;
- Bool updateRHS;
- MPI_Comm comm;
-
-/* Mat matrix = ( self->useShellMatrix ) ? self->shellMatrix->matrix : self->matrix; */
- Mat matrix = self->matrix;
-
- /* Do some type checking */
- assert( !sle || Stg_CheckType( sle, SystemLinearEquations ) );
- assert( self->rhs || self->transRHS );
-
- feVars[0] = self->rowVariable;
- feVars[1] = self->columnVariable;
-
- /* Get communicator. */
- comm = Mesh_GetCommTopology( feVars[0]->feMesh, MT_VERTEX )->mpiComm;
-
- startTime = MPI_Wtime();
-
- Journal_DPrintf( self->debug, "In %s - for matrix \"%s\"\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
-
- Journal_Firewall( Stg_ObjectList_Count( self->stiffnessMatrixTermList ) != 0,
- Journal_Register( Error_Type, (Name)self->type ),
- "Error in func %s for %s '%s' - No StiffnessMatrixTerms registered.\n",
- __func__, self->type, self->name );
-
- totalDofsThisElement[ROW_VAR] = Memory_Alloc( Dof_Index, "el nodal dofs" );
- totalDofsPrevElement[ROW_VAR] = Memory_Alloc( Dof_Index, "el nodal dofs (prev element)" );
- *totalDofsPrevElement[ROW_VAR] = 0;
- /* check if row variable and col variable are the same */
- if ( self->rowVariable == self->columnVariable ) {
- numFeVars = 1;
- Journal_DPrintfL( self->debug, 2, "Detected both row and column FeVariable to assemble over are \"%s\", "
- "so only processing once per element.\n", self->rowVariable->name );
- /* since Row and Col FeVars are same, set LM_col and totalDofsThisElement to be same as row ones */
- totalDofsThisElement[COL_VAR] = totalDofsThisElement[ROW_VAR];
- totalDofsPrevElement[COL_VAR] = totalDofsPrevElement[ROW_VAR];
- }
- else {
- Journal_DPrintfL( self->debug, 2, "Since row FeVariable \"%s\" and column FeVariable \"%s\" to assemble over "
- "are different, processing both per element.\n", self->rowVariable->name, self->columnVariable->name );
- totalDofsThisElement[COL_VAR] = Memory_Alloc( Dof_Index, "el nodal dofs (col)" );
- totalDofsPrevElement[COL_VAR] = Memory_Alloc( Dof_Index, "el nodal dofs (col) (prev element)" );
- *totalDofsPrevElement[COL_VAR] = 0;
- }
-
- /* Assumes that both row and col variables have same number of variables */
- nLocalElements = FeMesh_GetElementLocalSize( feVars[ROW_VAR]->feMesh );
-
- /* Initialise matrix */
- MatZeroEntries( matrix );
-
- outputInterval = (int)( (outputPercentage/100.0)*(double)(nLocalElements) );
- if( outputInterval == 0 ) { outputInterval = nLocalElements; }
-
- for( element_lI = 0; element_lI < nLocalElements; element_lI++ ) {
-
- /* This loop is how we handle the possiblity of different row-column variables: if both variables are
- * the same, then numFeVars is set to 1 and the loop only progresses through once.
- -- PatrickSunter 13 September 2004 */
- for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
- FeEquationNumber* feEqNum = feVars[feVar_I]->eqNum;
- DofLayout* dofLayout = feVars[feVar_I]->dofLayout;
- Dof_Index dofCountLastNode;
- unsigned nDofsThisEl;
- unsigned n_i;
-
- /* Get the local node ids */
- FeMesh_GetElementNodes( feVars[feVar_I]->feMesh, element_lI,
- self->rowInc );
- nodeCountThisEl = IArray_GetSize( self->rowInc );
- nodeIdsThisEl = (unsigned*)IArray_GetPtr( self->rowInc );
-
- /* Set value of elementLM: will automatically use large one if built */
- elementLM[feVar_I] = FeEquationNumber_BuildOneElementLocationMatrix( feEqNum, element_lI );
-
- /* work out number of dofs at the node, based on LM */
- dofCountLastNode = dofLayout->dofCounts[nodeIdsThisEl[nodeCountThisEl-1]];
- nDofsThisEl = dofLayout->dofCounts[nodeIdsThisEl[0]];
- for( n_i = 1; n_i < nodeCountThisEl; n_i++ )
- nDofsThisEl += dofLayout->dofCounts[nodeIdsThisEl[n_i]];
- *totalDofsThisElement[feVar_I] = nDofsThisEl;
-/*
- *totalDofsThisElement[feVar_I] = &elementLM[feVar_I][nodeCountThisEl-1][dofCountLastNode-1]
- - &elementLM[feVar_I][0][0] + 1;
-*/
-
- if ( *totalDofsThisElement[feVar_I] > *totalDofsPrevElement[feVar_I] ) {
- Journal_DPrintfL( self->debug, 2, "Reallocating bcLM_Id and bcValues for fe var \"%s\" "
- "to size %d\n", feVars[feVar_I]->name, *totalDofsThisElement[feVar_I] );
-
- if ( bcLM_Id[feVar_I] ) Memory_Free( bcLM_Id[feVar_I] );
- bcLM_Id[feVar_I] = Memory_Alloc_Array( Dof_Index, *totalDofsThisElement[feVar_I], "bcLM_Id" );
-
- if ( bcValues[feVar_I] ) Memory_Free( bcValues[feVar_I] );
- bcValues[feVar_I] = Memory_Alloc_Array( double, *totalDofsThisElement[feVar_I], "bcValues" );
- }
- }
-
- /* Reallocate el stiff mat and other arrays if necessary */
- if ( (*totalDofsThisElement[ROW_VAR] != *totalDofsPrevElement[ROW_VAR]) ||
- (*totalDofsThisElement[COL_VAR] != *totalDofsPrevElement[COL_VAR]) )
- {
- if (h2Add) Memory_Free( h2Add );
- Journal_DPrintfL( self->debug, 2, "Reallocating h2Add to size %d\n",
- *totalDofsThisElement[COL_VAR] );
- h2Add = Memory_Alloc_Array( double, *totalDofsThisElement[COL_VAR], "h2Add" );
-
- if (elStiffMatToAdd) Memory_Free( elStiffMatToAdd );
- Journal_DPrintfL( self->debug, 2, "Reallocating elStiffMatToAdd to size %d*%d\n",
- *totalDofsThisElement[ROW_VAR], *totalDofsThisElement[COL_VAR] );
- elStiffMatToAdd = Memory_Alloc_2DArray( double, *totalDofsThisElement[ROW_VAR], *totalDofsThisElement[COL_VAR], (Name)"elStiffMatToAdd" );
- }
-
- /* Initialise the elStiffMat to zero */
- /* Note we have to dereference the ptr once ... so we don't clobber the ptrs, just the values */
- memset( elStiffMatToAdd[0], 0, sizeof(double) * *totalDofsThisElement[ROW_VAR] * *totalDofsThisElement[COL_VAR] );
-
- /* Assemble this element's element stiffness matrix: call the entry point */
- elStiffMatBuildStart = MPI_Wtime();
- StiffnessMatrix_AssembleElement( self, element_lI, sle, context, elStiffMatToAdd );
- elStiffMatBuildTime += MPI_Wtime() - elStiffMatBuildStart;
- if ( False == self->allowZeroElementContributions ) {
- StiffnessMatrix_CheckElementAssembly( self, element_lI, elStiffMatToAdd, *totalDofsThisElement[ROW_VAR],
- *totalDofsThisElement[COL_VAR] );
- }
-
- /* This loop is how we handle the possiblity of different row-column variables: if both variables are
- * the same, then numFeVars is set to 1 and the loop only progresses through once.
- -- PatrickSunter 13 September 2004 */
- for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
- /* Reset from previous calculation */
- nBC_NodalDof[feVar_I] = 0;
- makeBC_Corrections_row = False;
-
- /* Check if we want to build table of corrected BC info for the matrix */
- if( bcRemoveQuery == True ) {
- unsigned nNodeInc, *nodeInc;
-
- FeMesh_GetElementNodes( feVars[feVar_I]->feMesh, element_lI,
- self->rowInc );
- nNodeInc = IArray_GetSize( self->rowInc );
- nodeInc = (unsigned*)IArray_GetPtr( self->rowInc );
- _StiffnessMatrix_UpdateBC_CorrectionTables(
- self,
- feVars[feVar_I]->eqNum,
- feVars[feVar_I]->dofLayout,
- elementLM[feVar_I],
- nNodeInc,
- nodeInc,
- bcLM_Id[feVar_I],
- bcValues[feVar_I],
- &(nBC_NodalDof[feVar_I]) );
- }
- }
-
- /* If there is only one feVar, use the same LM for both row and col insertion */
- if ( numFeVars == 1 ) elementLM[COL_VAR] = elementLM[ROW_VAR];
-
-/*
- #if DEBUG
- if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
- Journal_DPrintf( self->debug, "Handling Element %d:\n", element_lI );
- for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
- FeEquationNumber_PrintElementLocationMatrix( feVars[feVar_I]->eqNum,
- elementLM[feVar_I], element_lI, self->debug );
-
- }
-
- Journal_DPrintf( self->debug, "El stiff Mat about to be added:\n" );
- _StiffnessMatrix_PrintElementStiffnessMatrix( self, element_lI, elementLM[ROW_VAR],
- elementLM[COL_VAR], elStiffMatToAdd );
- }
- #endif
-*/
-
-
- /*
- ** Need to make corrections to the RHS before filling in the matrix. This is because we may modify the
- ** element matrix values before they get there.
- */
-
- /* Set flag for making corrcetions to rhs from bc's */
- if( nBC_NodalDof[ROW_VAR] != 0 ) {
- makeBC_Corrections_row = True;
- modifiedRHS_Vec_cont = True; /* this guy only needs to be toggled once */
- }
-
- if( makeBC_Corrections_row == True && bcRemoveQuery ) {
- _StiffnessMatrix_CorrectForceVectorWithOneElementsBoundaryConditions(
- self,
- elementLM,
- h2Add,
- elStiffMatToAdd,
- totalDofsThisElement,
- bcLM_Id,
- bcValues,
- nBC_NodalDof[ROW_VAR],
- element_lI );
- }
-
- /*
- ** If not keeping BCs in, we may need to zero some of these element values, or set them to one.
- */
-
- if( (!self->rowVariable || !self->rowVariable->eqNum->removeBCs) &&
- (!self->columnVariable || !self->columnVariable->eqNum->removeBCs) )
- {
- FeEquationNumber* rowEqNum = self->rowVariable->eqNum;
- FeEquationNumber* colEqNum = self->columnVariable->eqNum;
- unsigned nRows = *totalDofsThisElement[ROW_VAR];
- unsigned row_i;
-
- /* Loop over elementLM rows */
- for( row_i = 0; row_i < nRows; row_i++ ) {
- unsigned rowEqInd;
-
- rowEqInd = *(int*)STreeMap_Map( rowEqNum->ownedMap,
- elementLM[ROW_VAR][0] + row_i );
-
- /* If row is bc */
- if( STree_Has( rowEqNum->bcEqNums, &rowEqInd ) ) {
- unsigned nCols = *totalDofsThisElement[COL_VAR];
- unsigned col_i;
-
- /* Loop over elementLM cols */
- for( col_i = 0; col_i < nCols; col_i++ ) {
- unsigned colEqInd;
-
- colEqInd = *(int*)STreeMap_Map( colEqNum->ownedMap,
- elementLM[COL_VAR][0] + col_i );
-
- /* If col is bc */
- if( STree_Has( colEqNum->bcEqNums, &colEqInd ) ) {
- elStiffMatToAdd[0][row_i * nCols + col_i] = 0.0;
- }
- else {
- elStiffMatToAdd[0][row_i * nCols + col_i] = 0.0;
- }
- }
- }
- else {
- unsigned nCols = *totalDofsThisElement[COL_VAR];
- unsigned col_i;
-
- for( col_i = 0; col_i < nCols; col_i++ ) {
- unsigned colEqInd = elementLM[COL_VAR][0][col_i];
-
- /* If col is bc */
- if( STree_Has( colEqNum->bcEqNums, &colEqInd ) ) {
- elStiffMatToAdd[0][row_i * nCols + col_i] = 0.0;
- }
- }
- }
- }
- }
-
- /* Add to the global matrix. */
- matAddingStart = MPI_Wtime();
- MatSetValues( matrix, *totalDofsThisElement[ROW_VAR], elementLM[ROW_VAR][0], *totalDofsThisElement[COL_VAR],
- elementLM[COL_VAR][0], elStiffMatToAdd[0], ADD_VALUES );
- matAddingTime += MPI_Wtime() - matAddingStart;
-
-
-#if DEBUG
- if( element_lI % outputInterval == 0 ) {
- Journal_DPrintfL( self->debug, 2, "done %d percent of global element stiffness assembly (general) \n",
- (int)(100.0*((double)element_lI/(double)nLocalElements)) );
- }
-#endif
-
- for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
- /* Save the number of dofs in this element */
- *totalDofsPrevElement[feVar_I] = *totalDofsThisElement[feVar_I];
- /* If we haven't built the big LM for all elements, free the temporary one */
- if ( False == feVars[feVar_I]->eqNum->locationMatrixBuilt ) {
- Memory_Free( elementLM[feVar_I] );
- }
- }
- }
-
-/* //////////////////////////////////////////////////////// */
- MatAssemblyBegin( matrix, MAT_FINAL_ASSEMBLY );
- MatAssemblyEnd( matrix, MAT_FINAL_ASSEMBLY );
-
- MPI_Allreduce( &modifiedRHS_Vec_cont, &updateRHS, 1, MPI_UNSIGNED, MPI_LOR, comm );
- if( updateRHS == True && bcRemoveQuery ) {
- /* stuff was submitted to vec (at least once) and needs to be assembled */
- VecAssemblyBegin( self->rhs->vector );
- VecAssemblyEnd( self->rhs->vector );
- }
-/* //////////////////////////////////////////////////////// */
-
- /*
- ** If keeping BCs in, modify the RHS to reflect BCs.
- */
-
- if( (!self->rowVariable || !self->rowVariable->eqNum->removeBCs) &&
- (!self->columnVariable || !self->columnVariable->eqNum->removeBCs) )
- {
- FeEquationNumber* colEqNum = self->columnVariable->eqNum;
- FeMesh* feMesh = self->columnVariable->feMesh;
- DofLayout* dofLayout = self->columnVariable->dofLayout;
- unsigned nNodes = FeMesh_GetNodeLocalSize( feMesh );
- unsigned node_i;
-
- /* What to do if they aren't the same? */
- assert( self->rowVariable == self->columnVariable );
-
- for( node_i = 0; node_i < nNodes; node_i++ ) {
- unsigned nDofs = dofLayout->dofCounts[node_i];
- unsigned dof_i;
-
- for( dof_i = 0; dof_i < nDofs; dof_i++ ) {
- unsigned eqInd = colEqNum->destinationArray[node_i][dof_i];
- int localEq;
-
- localEq = *(int*)STreeMap_Map( colEqNum->ownedMap, &eqInd );
- if( STree_Has( colEqNum->bcEqNums, &localEq ) ) {
- double bcVal = DofLayout_GetValueDouble( dofLayout, node_i, dof_i );
- double one = 1.0;
-
- VecSetValues( self->rhs->vector, 1, (PetscInt*)(&eqInd), &bcVal, INSERT_VALUES );
- MatSetValues( matrix, 1, (PetscInt*)(&eqInd), 1, (PetscInt*)(&eqInd), &one, INSERT_VALUES );
- }
- }
- }
-
- /* Need to reassemble. */
- MatAssemblyBegin( matrix, MAT_FINAL_ASSEMBLY );
- MatAssemblyEnd( matrix, MAT_FINAL_ASSEMBLY );
- VecAssemblyBegin( self->rhs->vector );
- VecAssemblyEnd( self->rhs->vector );
- }
-
- for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
- Memory_Free( totalDofsThisElement[feVar_I] );
- Memory_Free( totalDofsPrevElement[feVar_I] );
- Memory_Free( bcLM_Id[feVar_I] );
- Memory_Free( bcValues[feVar_I] );
- }
- Memory_Free( elStiffMatToAdd );
- Memory_Free( h2Add );
-
- totalTime = MPI_Wtime() - startTime;
- Journal_DPrintfL( self->debug, 2, "Total time used by %s: %.5g s\n", __func__, totalTime );
- Journal_DPrintfL( self->debug, 2, "Of which %.5g s spend building elStiffMats\n", elStiffMatBuildTime );
- Journal_DPrintfL( self->debug, 2, "And %.5g s spend adding to global matrix\n", matAddingTime );
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-
-void _make_dirichlet_corrections_to_rhs(
- int nr, int rows_to_keep[],
- int nc, int cols_to_keep[],
- double **ke, int n_cols, double bc_vals[],
- double rhs[] )
-{
- int i,j,I,J;
-
- for( i=0; i<nr; i++ ) {
- I = rows_to_keep[i];
- rhs[I] = 0.0;
-
- for( j=0; j<nc; j++ ) {
- J = cols_to_keep[j];
- rhs[I] = rhs[I] - ke[I][J] * bc_vals[J];
- }
- }
-
-}
-
-void _make_dirichlet_corrections_to_rhs_transpose(
- int nr, int rows_to_keep[],
- int nc, int cols_to_keep[],
- double **ke, int n_cols,
- double bc_vals[], double rhs[] )
-{
- int i,j,I,J;
-
- for( i=0; i<nr; i++ ) {
- I = rows_to_keep[i];
- rhs[I] = 0.0;
-
- for( j=0; j<nc; j++ ) {
- J = cols_to_keep[j];
-
- rhs[I] = rhs[I] - ke[J][I] * bc_vals[J];
- }
- }
-
-}
-
-#define LEOrder( i,i_d,i_dof ) ( (i)*(i_dof) + (i_d) )
-void _get_bc_values( FeVariable *colVar, int npe, int ndof, int el_nodes[], double bc_vals[] )
-{
- double bc;
- int n, d, n_i;
-
- for( n=0; n<npe; n++ ) {
- n_i = el_nodes[n];
- for( d=0; d<ndof; d++ ) {
- /* query node index to see if it is has a dirichlet boundary condition */
- if( FeVariable_IsBC( colVar, n_i, d) == True ) {
- bc = DofLayout_GetValueDouble( colVar->dofLayout, n_i, d );
- bc_vals[ LEOrder(n,d,ndof) ] = bc;
- }
- /* end bc query */
- }
- }
-}
-
-struct StiffMatAss_Log {
- char *ass_type; /* one of { OPERATOR_ONLY, OPERATOR_WITH_BC_CORRECTIONS, OPERATOR_WITH_BC_CORRECTIONS_FROM_OP_TRANS, OP_BC_CORRECTIONS_ONLY, OP_BC_CORRECTIONS_FROM_OP_TRANS_ONLY } */
- double total_TIME;
- double cumulative_el_stiff_mat_ass_TIME;
- double parallel_assembly_TIME;
- double element_insertion_TIME;
- int nr, nc;
- int local_nr, local_nc;
- int elements_assembled_for_bc_correction;
- int elements_assembled;
-
- /* local timer info */
- double dt_element_assembly, dt_total, dt_parallel_assembly, dt_el_insert;
- double t0_element_assembly, t0_total, t0_parallel_assembly, t0_el_insert;
-};
-
-#define StiffMatAssLog_UpdateElementsAssembled( log ) (log)->elements_assembled++
-#define StiffMatAssLog_UpdateElementsAssembledForBC_Corrections( log ) (log)->elements_assembled_for_bc_correction++
-#define StiffMatAssLog_InitTimer_TotalTime( log ) (log)->t0_total = MPI_Wtime()
-#define StiffMatAssLog_InitTimer_ElementAssembly( log ) (log)->t0_element_assembly = MPI_Wtime()
-#define StiffMatAssLog_InitTimer_ParallelAssembly( log ) (log)->t0_parallel_assembly = MPI_Wtime()
-#define StiffMatAssLog_InitTimer_ElementInsertion( log ) (log)->t0_el_insert = MPI_Wtime()
-
-inline void StiffMatAssLog_AccumulateTime_Total( struct StiffMatAss_Log *log )
-{
- log->dt_total = MPI_Wtime() - log->t0_total;
- log->total_TIME = log->total_TIME + log->dt_total;
-}
-
-inline void StiffMatAssLog_AccumulateTime_ElementAssembly( struct StiffMatAss_Log* log )
-{
- log->dt_element_assembly = MPI_Wtime() - log->t0_element_assembly;
- log->cumulative_el_stiff_mat_ass_TIME = log->cumulative_el_stiff_mat_ass_TIME + log->dt_element_assembly;
-}
-
-
-inline void StiffMatAssLog_AccumulateTime_ParallelAssembly( struct StiffMatAss_Log *log )
-{
- log->dt_parallel_assembly = MPI_Wtime() - log->t0_parallel_assembly;
- log->parallel_assembly_TIME = log->parallel_assembly_TIME + log->dt_parallel_assembly;
-}
-
-inline void StiffMatAssLog_AccumulateTime_ElementInsertion( struct StiffMatAss_Log *log )
-{
- log->dt_el_insert = MPI_Wtime() - log->t0_el_insert;
- log->element_insertion_TIME = log->element_insertion_TIME + log->dt_el_insert;
-}
-
-inline void StiffMatAssLog_GetOperatorDimensions( struct StiffMatAss_Log *log, Mat matrix )
-{
- MatGetSize( matrix, (PetscInt*)(&log->nr), (PetscInt*)(&log->nc) );
- MatGetLocalSize( matrix, (PetscInt*)(&log->local_nr), (PetscInt*)(&log->local_nc) );
-}
-
-void StiffMatAssLog_Delete( struct StiffMatAss_Log** _log )
-{
- struct StiffMatAss_Log *log = *_log;
-
- if( log->ass_type != NULL ) free( log->ass_type );
- free( log );
- log = NULL;
-
- *_log = log;
-}
-
-void StiffMatAssLog_Init( struct StiffMatAss_Log *log, const char type_name[] )
-{
- if( log->ass_type != NULL ) free( log->ass_type );
- asprintf( &log->ass_type, "%s", type_name );
-
- /* reset timers and counter */
- log->total_TIME = 0.0;
- log->cumulative_el_stiff_mat_ass_TIME = 0.0;
- log->parallel_assembly_TIME = 0.0;
- log->element_insertion_TIME = 0.0;
- log->nr = log->nc = 0;
- log->local_nr = log->local_nc = 0;
- log->elements_assembled_for_bc_correction = 0;
- log->elements_assembled = 0;
-}
-
-struct StiffMatAss_Log* StiffMatAssLog_New( void )
-{
- struct StiffMatAss_Log *log;
-
- log = (struct StiffMatAss_Log*)malloc( sizeof(struct StiffMatAss_Log) );
- log->ass_type = NULL;
-
- StiffMatAssLog_Init( log, "UNINITIALISED" );
-
- return log;
-}
-
-
-void StiffMatAssLog_Report_min_max( MPI_Comm comm, double local_val, double *min, double *max )
-{
- MPI_Reduce ( &local_val, min, 1, MPI_DOUBLE, MPI_MIN, 0, comm );
- MPI_Reduce ( &local_val, max, 1, MPI_DOUBLE, MPI_MAX, 0, comm );
-}
-
-void StiffMatAssLog_Report_sequential( StiffnessMatrix *self, struct StiffMatAss_Log *log )
-{
- Journal_PrintfL( self->debug, 1, "GlobalStiffnessMatrix Assembly Report: %s \n", self->name );
- Journal_PrintfL( self->debug, 1, " Assembly type: %s \n", log->ass_type );
- Journal_PrintfL( self->debug, 1, " Operator dimensions: %d x %d (global) \n", log->nr, log->nc );
- Journal_PrintfL( self->debug, 1, " Total time: %6.6e (sec)\n", log->total_TIME );
- Journal_PrintfL( self->debug, 1, " Assembling element stiffness matrices: %6.6e (sec)\n", log->cumulative_el_stiff_mat_ass_TIME );
- Journal_PrintfL( self->debug, 1, " Parallel assembly: %6.6e (sec)\n", log->parallel_assembly_TIME );
- Journal_PrintfL( self->debug, 1, " Element insertion: %6.6e (sec)\n", log->element_insertion_TIME );
- Journal_PrintfL( self->debug, 1, " Element stiffness matrices assembled for operator: %d \n", log->elements_assembled );
- Journal_PrintfL( self->debug, 1, " Element stiffness matrices assembled for bc corrections: %d \n", log->elements_assembled_for_bc_correction );
-}
-
-void StiffMatAssLog_Report_parallel( StiffnessMatrix *self, struct StiffMatAss_Log *log )
-{
- double min, max;
- int sum_i;
- MPI_Comm comm = self->comm;
- int init_stream_rank;
-
- /* change stream to only print on rank 0 */
- init_stream_rank = Stream_GetPrintingRank( self->debug );
- Stream_SetPrintingRank( self->debug, 0 );
-
- Journal_PrintfL( self->debug, 1, "GlobalStiffnessMatrix Assembly Report: %s \n", self->name );
- Journal_PrintfL( self->debug, 1, " Assembly type: %s \n", log->ass_type );
- Journal_PrintfL( self->debug, 1, " Operator dimensions: %d x %d (global) \n", log->nr, log->nc );
-
- MPI_Reduce ( &log->elements_assembled, &sum_i, 1, MPI_INT, MPI_SUM, 0, comm );
- Journal_PrintfL( self->debug, 1, " Element stiffness matrices assembled for operator: %d (total) \n", sum_i );
-
- MPI_Reduce ( &log->elements_assembled_for_bc_correction, &sum_i, 1, MPI_INT, MPI_SUM, 0, comm );
- Journal_PrintfL( self->debug, 1, " Element stiffness matrices assembled for bc corrections: %d (total) \n", sum_i );
-
- Journal_PrintfL( self->debug, 1, " min / max (sec)\n" );
-
- StiffMatAssLog_Report_min_max( comm, log->total_TIME, &min, &max );
- Journal_PrintfL( self->debug, 1, " Total time: %6.6e / %6.6e (sec)\n", min, max );
-
- StiffMatAssLog_Report_min_max( comm, log->cumulative_el_stiff_mat_ass_TIME, &min, &max );
- Journal_PrintfL( self->debug, 1, " Assembling element stiffness matrices: %6.6e / %6.6e (sec)\n", min, max );
-
- StiffMatAssLog_Report_min_max( comm, log->parallel_assembly_TIME, &min, &max );
- Journal_PrintfL( self->debug, 1, " Parallel assembly: %6.6e / %6.6e (sec)\n", min, max );
-
- StiffMatAssLog_Report_min_max( comm, log->element_insertion_TIME, &min, &max );
- Journal_PrintfL( self->debug, 1, " Element insertion: %6.6e / %6.6e (sec)\n", min, max );
-
-
- /* reset printing rank of stream */
- Stream_SetPrintingRank( self->debug, init_stream_rank );
-}
-
-void StiffMatAssLog_Report( StiffnessMatrix *self, struct StiffMatAss_Log *log )
-{
- int size;
-
- MPI_Comm_size( self->comm, &size );
- if( size == 1 ) {
- StiffMatAssLog_Report_sequential( self, log );
- }
- else {
- StiffMatAssLog_Report_parallel( self, log );
- }
-}
-
-
-void _StiffMatAss( struct StiffMatAss_Log *log, void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context ) {
-
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
- SystemLinearEquations* sle = (SystemLinearEquations*)_sle;
- FeVariable *rowVar, *colVar;
- FeMesh *rowMesh, *colMesh;
- FeEquationNumber *rowEqNum, *colEqNum;
- DofLayout *rowDofs, *colDofs;
- unsigned nRowEls;
- unsigned nRowNodes, *rowNodes;
- unsigned nColNodes, *colNodes;
- unsigned maxDofs, maxRCDofs, nDofs, nRowDofs, nColDofs;
- double** elStiffMat;
-/* Mat matrix = ( self->useShellMatrix ) ? self->shellMatrix->matrix : self->matrix; */
- Mat matrix = self->matrix;
- unsigned e_i, n_i;
-
- int c_dof, r_dof;
-
- assert( self && Stg_CheckType( self, StiffnessMatrix ) );
-
- StiffMatAssLog_Init( log, "OPERATOR_ONLY" );
- StiffMatAssLog_InitTimer_TotalTime( log );
-
- rowVar = self->rowVariable;
- colVar = self->columnVariable ? self->columnVariable : rowVar;
- rowEqNum = rowVar->eqNum;
- colEqNum = colVar->eqNum;
- rowMesh = rowVar->feMesh;
- colMesh = colVar->feMesh;
- rowDofs = rowVar->dofLayout;
- colDofs = colVar->dofLayout;
- nRowEls = FeMesh_GetElementLocalSize( rowMesh );
- assert( (rowVar == colVar) ? !self->transRHS : 1 );
-
- //matrix = self->matrix;
- elStiffMat = NULL;
- maxDofs = 0;
-
-
-
- StiffMatAssLog_GetOperatorDimensions( log, matrix );
- /* Begin assembling each element. */
- for( e_i = 0; e_i < nRowEls; e_i++ ) {
- FeMesh_GetElementNodes( rowMesh, e_i, self->rowInc );
- nRowNodes = IArray_GetSize( self->rowInc );
- rowNodes = (unsigned*)IArray_GetPtr( self->rowInc );
- FeMesh_GetElementNodes( colMesh, e_i, self->colInc );
- nColNodes = IArray_GetSize( self->colInc );
- colNodes = (unsigned*)IArray_GetPtr( self->colInc );
-
- /* Do we need more space to assemble this element? */
- nRowDofs = 0;
- for( n_i = 0; n_i < nRowNodes; n_i++ ) {
- nRowDofs += rowDofs->dofCounts[rowNodes[n_i]];
- r_dof = rowDofs->dofCounts[rowNodes[n_i]];
- }
- nColDofs = 0;
- for( n_i = 0; n_i < nColNodes; n_i++ ) {
- nColDofs += colDofs->dofCounts[colNodes[n_i]];
- c_dof = colDofs->dofCounts[colNodes[n_i]];
- }
- nDofs = nRowDofs * nColDofs;
- self->nRowDofs = nRowDofs;
- self->nColDofs = nColDofs;
- if( nDofs > maxDofs ) {
- maxRCDofs = (nRowDofs > nColDofs) ? nRowDofs : nColDofs;
- elStiffMat = ReallocArray2D( elStiffMat, double, nRowDofs, nColDofs );
-
- maxDofs = nDofs;
- self->elStiffMat = elStiffMat;
- }
-
-
- /* Assemble the element. */
- memset( elStiffMat[0], 0, nDofs * sizeof(double) );
- StiffMatAssLog_InitTimer_ElementAssembly( log );
- StiffnessMatrix_AssembleElement( self, e_i, sle, (FiniteElementContext*)_context, elStiffMat );
- StiffMatAssLog_AccumulateTime_ElementAssembly( log );
-
-
- /* If keeping BCs in, zero corresponding entries in the element stiffness matrix. */
- if( !rowEqNum->removeBCs || !colEqNum->removeBCs )
- Assembler_LoopMatrixElement( self->zeroBCsAsm, e_i );
-
- /* Add to stiffness matrix. */
- StiffMatAssLog_InitTimer_ElementInsertion( log );
- MatSetValues( matrix,
- nRowDofs, (PetscInt*)rowEqNum->locationMatrix[e_i][0],
- nColDofs, (PetscInt*)colEqNum->locationMatrix[e_i][0],
- elStiffMat[0], INSERT_VALUES );
-
- StiffMatAssLog_AccumulateTime_ElementInsertion( log ); /* update time */
- StiffMatAssLog_UpdateElementsAssembled( log ); /* update counter */
- }
-
-
- /* If keeping BCs in and rows and columnns use the same variable, put ones in all BC'd diagonals. */
- if( !colEqNum->removeBCs && rowVar == colVar )
- Assembler_LoopMatrixDiagonal( self->diagBCsAsm );
-
- /* Start matrix assembly */
- StiffMatAssLog_InitTimer_ParallelAssembly( log );
- MatAssemblyBegin( matrix, MAT_FINAL_ASSEMBLY );
- MatAssemblyEnd( matrix, MAT_FINAL_ASSEMBLY );
- StiffMatAssLog_AccumulateTime_ParallelAssembly( log );
-
- FreeArray( elStiffMat );
-
- StiffMatAssLog_AccumulateTime_Total( log );
-
-}
-
-void _StiffMatAss_vector_corrections( struct StiffMatAss_Log *log, void *stiffnessMatrix, Bool removeBCs, void *_sle, void *_context ) {
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
- SystemLinearEquations* sle = (SystemLinearEquations*)_sle;
- FeVariable *rowVar, *colVar;
- FeMesh *rowMesh, *colMesh;
- FeEquationNumber *rowEqNum, *colEqNum;
- DofLayout *rowDofs, *colDofs;
- unsigned nRowEls;
- unsigned nRowNodes, *rowNodes;
- unsigned nColNodes, *colNodes;
- unsigned maxDofs, maxRCDofs, nDofs, nRowDofs, nColDofs;
- double** elStiffMat;
- double* bcVals;
-/* Mat matrix = ( self->useShellMatrix ) ? self->shellMatrix->matrix : self->matrix; */
- Mat matrix = self->matrix;
- Vec vector, transVector;
- unsigned e_i, n_i;
-
- unsigned bc_cnt = 0;
- int *row_index_to_keep, *col_index_to_keep;
- int n_rows, n_cols;
- int same_variables;
- int c_dof, r_dof;
- double *rhs;
- int has_col_bc, has_row_bc;
- int eq_num;
-
- assert( self && Stg_CheckType( self, StiffnessMatrix ) );
-
- StiffMatAssLog_Init( log, "OPERATOR_WITH_BC_CORRECTIONS" );
- StiffMatAssLog_InitTimer_TotalTime( log );
-
- rowVar = self->rowVariable;
- colVar = self->columnVariable ? self->columnVariable : rowVar;
- rowEqNum = rowVar->eqNum;
- colEqNum = colVar->eqNum;
- rowMesh = rowVar->feMesh;
- colMesh = colVar->feMesh;
- rowDofs = rowVar->dofLayout;
- colDofs = colVar->dofLayout;
- nRowEls = FeMesh_GetElementLocalSize( rowMesh );
- assert( (rowVar == colVar) ? !self->transRHS : 1 );
-
- //matrix = self->matrix;
- vector = self->rhs ? self->rhs->vector : NULL;
- transVector = self->transRHS ? self->transRHS->vector : NULL;
- elStiffMat = NULL;
- bcVals = NULL;
- maxDofs = 0;
-
- col_index_to_keep = NULL;
- row_index_to_keep = NULL;
- rhs = NULL;
-
- same_variables = 0;
- if( rowMesh == colMesh ) {
- same_variables = 1;
-// printf("Detected same variables in assembly VECTOR_CORRECTIONS\n");
- }
-
- assert( vector ); /* If we are in here then vector must be valid */
-
-
- bc_cnt = 0;
-
- StiffMatAssLog_GetOperatorDimensions( log, matrix );
- /* Begin assembling each element. */
- for( e_i = 0; e_i < nRowEls; e_i++ ) {
- FeMesh_GetElementNodes( rowMesh, e_i, self->rowInc );
- nRowNodes = IArray_GetSize( self->rowInc );
- rowNodes = (unsigned*)IArray_GetPtr( self->rowInc );
- FeMesh_GetElementNodes( colMesh, e_i, self->colInc );
- nColNodes = IArray_GetSize( self->colInc );
- colNodes = (unsigned*)IArray_GetPtr( self->colInc );
-
- /* Do we need more space to assemble this element? */
- nRowDofs = 0;
- for( n_i = 0; n_i < nRowNodes; n_i++ ) {
- nRowDofs += rowDofs->dofCounts[rowNodes[n_i]];
- r_dof = rowDofs->dofCounts[rowNodes[n_i]];
- }
- nColDofs = 0;
- for( n_i = 0; n_i < nColNodes; n_i++ ) {
- nColDofs += colDofs->dofCounts[colNodes[n_i]];
- c_dof = colDofs->dofCounts[colNodes[n_i]];
- }
- nDofs = nRowDofs * nColDofs;
- self->nRowDofs = nRowDofs;
- self->nColDofs = nColDofs;
- if( nDofs > maxDofs ) {
- maxRCDofs = (nRowDofs > nColDofs) ? nRowDofs : nColDofs;
- elStiffMat = ReallocArray2D( elStiffMat, double, nRowDofs, nColDofs );
- bcVals = ReallocArray( bcVals, double, maxRCDofs );
- rhs = ReallocArray( rhs, double, maxRCDofs );
-
- col_index_to_keep = ReallocArray( col_index_to_keep, int, maxRCDofs );
- row_index_to_keep = ReallocArray( row_index_to_keep, int, maxRCDofs );
-
- maxDofs = nDofs;
- self->elStiffMat = elStiffMat;
- self->bcVals = bcVals;
- }
-
- /* check for presence of bc's */
- n_rows = n_cols = 0;
- has_row_bc = has_col_bc = 0;
-
-
- for( n_i=0; n_i<nColDofs; n_i++ ) {
- eq_num = colEqNum->locationMatrix[e_i][0][n_i];
- if( colEqNum->locationMatrix[e_i][0][n_i] < 0 ) {
- col_index_to_keep[ n_cols ] = n_i;
- n_cols++;
- has_col_bc = 1;
- }
- }
- for( n_i=0; n_i<nRowDofs; n_i++ ) {
- if( rowEqNum->locationMatrix[e_i][0][n_i] >= 0 ) {
- row_index_to_keep[ n_rows ] = n_i;
- n_rows++;
- has_row_bc = 1;
- }
- }
-
- if( has_col_bc == 0 ) continue;
-
- /* Assemble the element. */
- memset( elStiffMat[0], 0, nDofs * sizeof(double) );
- StiffMatAssLog_InitTimer_ElementAssembly( log );
-
- StiffnessMatrix_AssembleElement( self, e_i, sle, (FiniteElementContext*)_context, elStiffMat );
-
- StiffMatAssLog_AccumulateTime_ElementAssembly( log ); /* update time */
- StiffMatAssLog_UpdateElementsAssembled( log ); /* update counter */
-
-
- /* If keeping BCs in, zero corresponding entries in the element stiffness matrix. */
- if( !rowEqNum->removeBCs || !colEqNum->removeBCs )
- Assembler_LoopMatrixElement( self->zeroBCsAsm, e_i );
-
-
- if( (has_col_bc==1) ) {
- /* int I; */
- memset( rhs, 0, maxRCDofs * sizeof(double) );
-
- _get_bc_values( colVar, nColNodes, c_dof, (int*)colNodes, bcVals );
- _make_dirichlet_corrections_to_rhs( n_rows, row_index_to_keep, n_cols, col_index_to_keep, elStiffMat, -1, bcVals, rhs );
-/*
- printf("f: e = %d \n", e_i );
-
- for( I=0; I<nRowDofs; I++ ) {
- printf(" I=%d : %d -- bcval = %f : rhs = %f \n", I, rowEqNum->locationMatrix[e_i][0][I], bcVals[I], rhs[I] );
- }
-*/
- VecSetValues( vector, nRowDofs, (PetscInt*)rowEqNum->locationMatrix[e_i][0], rhs, ADD_VALUES );
- StiffMatAssLog_UpdateElementsAssembledForBC_Corrections( log );
- bc_cnt++;
- }
-
-
- /* Add to stiffness matrix. */
- /*
- StiffMatAssLog_InitTimer_ElementInsertion( log );
- Matrix_AddEntries( matrix,
- nRowDofs, (unsigned*)rowEqNum->locationMatrix[e_i][0],
- nColDofs, (unsigned*)colEqNum->locationMatrix[e_i][0],
- elStiffMat[0] );
- StiffMatAssLog_AccumulateTime_ElementInsertion( log );
- */
- }
-
- StiffMatAssLog_InitTimer_ParallelAssembly( log );
- /* Start assembling vectors. */
- VecAssemblyBegin( vector );
-
- /* If keeping BCs in and rows and columnns use the same variable, put ones in all BC'd diagonals. */
-// if( !colEqNum->removeBCs && rowVar == colVar )
-// Assembler_LoopMatrixDiagonal( self->diagBCsAsm );
-
- /* Start matrix assembly */
- //Matrix_AssemblyBegin( matrix );
-
- /* Finalise matrix and vector assembly */
- VecAssemblyEnd( vector );
- //Matrix_AssemblyEnd( matrix );
- StiffMatAssLog_AccumulateTime_ParallelAssembly( log );
-
-// printf("Applied vector modifications using %u of %u elements \n", bc_cnt, nRowEls );
- FreeArray( elStiffMat );
- FreeArray( bcVals );
- FreeArray( row_index_to_keep );
- FreeArray( col_index_to_keep );
- FreeArray( rhs );
-
- StiffMatAssLog_AccumulateTime_Total( log );
-
-/*
- {
- PETScVector* self = (PETScVector*)vector;
- printf("f = \n");
- VecView( self->petscVec, PETSC_VIEWER_STDOUT_WORLD );
- }
-*/
-
-}
-
-
-
-
-void _StiffMatAss_vector_corrections_from_transpose( struct StiffMatAss_Log *log, void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context ) {
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
- SystemLinearEquations* sle = (SystemLinearEquations*)_sle;
- FeVariable *rowVar, *colVar;
- FeMesh *rowMesh, *colMesh;
- FeEquationNumber *rowEqNum, *colEqNum;
- DofLayout *rowDofs, *colDofs;
- unsigned nRowEls;
- unsigned nRowNodes, *rowNodes;
- unsigned nColNodes, *colNodes;
- unsigned maxDofs, maxRCDofs, nDofs, nRowDofs, nColDofs;
- double** elStiffMat;
- double* bcVals;
-/* Mat matrix = ( self->useShellMatrix ) ? self->shellMatrix->matrix : self->matrix; */
- Mat matrix = self->matrix;
- Vec transVector;
- unsigned e_i, n_i;
-
- unsigned bc_cnt = 0;
- int *row_index_to_keep, *col_index_to_keep;
- int n_rows, n_cols;
- int same_variables;
- int c_dof, r_dof;
- double *rhs;
- int has_col_bc, has_row_bc;
- int eq_num;
-
- assert( self && Stg_CheckType( self, StiffnessMatrix ) );
- StiffMatAssLog_Init( log, "OPERATOR_WITH_BC_CORRECTIONS_FROM_OP_TRANS" );
- StiffMatAssLog_InitTimer_TotalTime( log );
-
- rowVar = self->rowVariable;
- colVar = self->columnVariable ? self->columnVariable : rowVar;
- rowEqNum = rowVar->eqNum;
- colEqNum = colVar->eqNum;
- rowMesh = rowVar->feMesh;
- colMesh = colVar->feMesh;
- rowDofs = rowVar->dofLayout;
- colDofs = colVar->dofLayout;
- nRowEls = FeMesh_GetElementLocalSize( rowMesh );
- assert( (rowVar == colVar) ? !self->transRHS : 1 );
-
- //matrix = self->matrix;
- transVector = self->transRHS ? self->transRHS->vector : NULL;
- elStiffMat = NULL;
- bcVals = NULL;
- maxDofs = 0;
-
- col_index_to_keep = NULL;
- row_index_to_keep = NULL;
- rhs = NULL;
-
-
- same_variables = 0;
- if( rowMesh == colMesh ) {
- same_variables = 1;
- // printf("Detected same variables in assembly VECTOR CORRECTIONS FROM TRANSPOSE \n");
- }
- assert( transVector ); /* If we are in this function than transVector must be valid */
-
- bc_cnt = 0;
-
-
- StiffMatAssLog_GetOperatorDimensions( log, matrix );
- /* Begin assembling each element. */
- for( e_i = 0; e_i < nRowEls; e_i++ ) {
- FeMesh_GetElementNodes( rowMesh, e_i, self->rowInc );
- nRowNodes = IArray_GetSize( self->rowInc );
- rowNodes = (unsigned*)IArray_GetPtr( self->rowInc );
- FeMesh_GetElementNodes( colMesh, e_i, self->colInc );
- nColNodes = IArray_GetSize( self->colInc );
- colNodes = (unsigned*)IArray_GetPtr( self->colInc );
-
- /* Do we need more space to assemble this element? */
- nRowDofs = 0;
- for( n_i = 0; n_i < nRowNodes; n_i++ ) {
- nRowDofs += rowDofs->dofCounts[rowNodes[n_i]];
- r_dof = rowDofs->dofCounts[rowNodes[n_i]];
- }
- nColDofs = 0;
- for( n_i = 0; n_i < nColNodes; n_i++ ) {
- nColDofs += colDofs->dofCounts[colNodes[n_i]];
- c_dof = colDofs->dofCounts[colNodes[n_i]];
- }
- nDofs = nRowDofs * nColDofs;
- self->nRowDofs = nRowDofs;
- self->nColDofs = nColDofs;
- if( nDofs > maxDofs ) {
- maxRCDofs = (nRowDofs > nColDofs) ? nRowDofs : nColDofs;
- elStiffMat = ReallocArray2D( elStiffMat, double, nRowDofs, nColDofs );
- bcVals = ReallocArray( bcVals, double, maxRCDofs );
- rhs = ReallocArray( rhs, double, maxRCDofs );
-
- col_index_to_keep = ReallocArray( col_index_to_keep, int, maxRCDofs );
- row_index_to_keep = ReallocArray( row_index_to_keep, int, maxRCDofs );
-
- maxDofs = nDofs;
- self->elStiffMat = elStiffMat;
- self->bcVals = bcVals;
- }
-
- /* check for presence of bc's */
- n_rows = n_cols = 0;
- has_row_bc = has_col_bc = 0;
-
- /* cause this is the transpose function, we make corrections on the bc's if there are applied to the row variable */
- for( n_i=0; n_i<nColDofs; n_i++ ) {
- eq_num = colEqNum->locationMatrix[e_i][0][n_i];
- if( colEqNum->locationMatrix[e_i][0][n_i] >= 0 ) {
- col_index_to_keep[ n_cols ] = n_i;
- n_cols++;
- has_col_bc = 1;
- }
- }
-
- for( n_i=0; n_i<nRowDofs; n_i++ ) {
- if( rowEqNum->locationMatrix[e_i][0][n_i] < 0 ) {
- row_index_to_keep[ n_rows ] = n_i;
- n_rows++;
- has_row_bc = 1;
- }
- }
-
-
- if( has_row_bc == 0 ) continue;
-
-
-
- /* Initialise the element stiffness matrix */
- memset( elStiffMat[0], 0, nDofs * sizeof(double) );
- /*
- for( si=0; si<nRowDofs; si++ )
- for( sj=0; sj<nColDofs; sj++ )
- elStiffMat[si][sj] = 0.0;
- */
-
- /* Assemble the element stiffness matrix */
- StiffMatAssLog_InitTimer_ElementAssembly( log );
-
- StiffnessMatrix_AssembleElement( self, e_i, sle, (FiniteElementContext*)_context, elStiffMat );
-
- StiffMatAssLog_AccumulateTime_ElementAssembly( log );
- StiffMatAssLog_UpdateElementsAssembled( log );
-
-
- /* If keeping BCs in, zero corresponding entries in the element stiffness matrix. */
- if( !rowEqNum->removeBCs || !colEqNum->removeBCs )
- Assembler_LoopMatrixElement( self->zeroBCsAsm, e_i );
-
- if( (has_row_bc==1) ) {
- /* int I; */
- memset( rhs, 0, maxRCDofs * sizeof(double) );
- /*
- for( II=0; II<maxRCDofs; II++ ) {
- bcVals[II] = rhs[II] = 0.0;
- }
- */
- _get_bc_values( rowVar, nRowNodes, r_dof, (int*)rowNodes, bcVals );
-
- _make_dirichlet_corrections_to_rhs_transpose( n_cols, col_index_to_keep, n_rows, row_index_to_keep, elStiffMat, -1, bcVals, rhs );
-/*
- printf("h: e = %d \n", e_i );
- for( I=0; I<nColDofs; I++ ) {
- printf(" I=%d : %d -- bcval = %f : rhs = %f\n", I, colEqNum->locationMatrix[e_i][0][I], bcVals[I], rhs[I] );
- }
-*/
-
- VecSetValues( transVector, nColDofs, colEqNum->locationMatrix[e_i][0], rhs, INSERT_VALUES );
- StiffMatAssLog_UpdateElementsAssembledForBC_Corrections( log );
- bc_cnt++;
- }
-
- /* Add to stiffness matrix. */
-/*
- StiffMatAssLog_InitTimer_ElementInsertion(log);
- Matrix_AddEntries( matrix,
- nRowDofs, (unsigned*)rowEqNum->locationMatrix[e_i][0],
- nColDofs, (unsigned*)colEqNum->locationMatrix[e_i][0],
- elStiffMat[0] );
- StiffMatAssLog_AccumulateTime_ElementInsertion( log );
-*/
- }
-
-
- StiffMatAssLog_InitTimer_ParallelAssembly( log );
- /* Start assembling vectors. */
- VecAssemblyBegin( transVector );
-
-
- /* If keeping BCs in and rows and columnns use the same variable, put ones in all BC'd diagonals. */
-// if( !colEqNum->removeBCs && rowVar == colVar )
-// Assembler_LoopMatrixDiagonal( self->diagBCsAsm );
-
- /* Start matrix assembly */
-// Matrix_AssemblyBegin( matrix );
-
- /* Finalise matrix and vector assembly */
- VecAssemblyEnd( transVector );
-// Matrix_AssemblyEnd( matrix );
- StiffMatAssLog_AccumulateTime_ParallelAssembly( log );
-
-// printf("Applied vector modifications using %u of %u elements \n", bc_cnt, nRowEls );
- FreeArray( elStiffMat );
- FreeArray( bcVals );
- FreeArray( row_index_to_keep );
- FreeArray( col_index_to_keep );
- FreeArray( rhs );
-
- StiffMatAssLog_AccumulateTime_Total( log );
-/*
- {
- PETScVector* self = (PETScVector*)transVector;
- printf("h = \n");
- VecView( self->petscVec, PETSC_VIEWER_STDOUT_WORLD );
- }
-*/
-}
-
-
-//void __StiffnessMatrix_NewAssemble( void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context );
-void StiffnessMatrix_NewAssemble( void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context ) {
- StiffnessMatrix *self = (StiffnessMatrix*)stiffnessMatrix;
- Vec vector, transVector;
- struct StiffMatAss_Log *log;
-
- vector = self->rhs ? self->rhs->vector : NULL;
- transVector = self->transRHS ? self->transRHS->vector : NULL;
-
- log = StiffMatAssLog_New();
-
-
- _StiffMatAss( log, stiffnessMatrix, removeBCs, _sle, (FiniteElementContext*)_context );
- StiffMatAssLog_Report( self, log );
-
- if( vector ) {
- _StiffMatAss_vector_corrections( log, stiffnessMatrix, removeBCs, _sle, (FiniteElementContext*)_context );
- StiffMatAssLog_Report( self, log );
- }
- if( transVector ) {
- _StiffMatAss_vector_corrections_from_transpose( log, stiffnessMatrix, removeBCs, _sle, (FiniteElementContext*)_context );
- StiffMatAssLog_Report( self, log );
- }
- // __StiffnessMatrix_NewAssemble( stiffnessMatrix, removeBCs, _sle, _context );
- StiffMatAssLog_Delete( &log );
-}
-
-#if 0
-void StiffnessMatrix_SetEqsToUnity( StiffnessMatrix* self, const STreeNode* node ) {
- static const double one = 1.0;
-
- if( !node ) return;
- StiffnessMatrix_SetEqsToUnity( self, node->left );
- Matrix_AddEntries( self->matrix, 1, (int*)node->data, 1, (int*)node->data, (double*)&one );
- StiffnessMatrix_SetEqsToUnity( self, node->right );
-}
-#endif
-
-
-/* Callback version */
-void __StiffnessMatrix_NewAssemble( void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context ) {
- static const double one = 1.0;
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
- SystemLinearEquations* sle = (SystemLinearEquations*)_sle;
- FeVariable *rowVar, *colVar;
- FeMesh *rowMesh, *colMesh;
- FeEquationNumber *rowEqNum, *colEqNum;
- DofLayout *rowDofs, *colDofs;
- unsigned nRowEls;
- unsigned nRowNodes, *rowNodes;
- unsigned nColNodes, *colNodes;
- unsigned maxDofs, maxRCDofs, nDofs, nRowDofs, nColDofs;
- double** elStiffMat;
- double* bcVals;
-/* Mat matrix = ( self->useShellMatrix ) ? self->shellMatrix->matrix : self->matrix; */
- Mat matrix = self->matrix;
- Vec vector, transVector;
- int nRowNodeDofs, nColNodeDofs;
- int rowInd, colInd;
- double bc;
- unsigned e_i, n_i, dof_i, n_j, dof_j;
-
- assert( self && Stg_CheckType( self, StiffnessMatrix ) );
-
- rowVar = self->rowVariable;
- colVar = self->columnVariable ? self->columnVariable : rowVar;
- rowEqNum = rowVar->eqNum;
- colEqNum = colVar->eqNum;
- rowMesh = rowVar->feMesh;
- colMesh = colVar->feMesh;
- rowDofs = rowVar->dofLayout;
- colDofs = colVar->dofLayout;
- nRowEls = FeMesh_GetElementLocalSize( rowMesh );
- assert( (rowVar == colVar) ? !self->transRHS : 1 );
-
- //matrix = self->matrix;
- vector = self->rhs ? self->rhs->vector : NULL;
- transVector = self->transRHS ? self->transRHS->vector : NULL;
- elStiffMat = NULL;
- bcVals = NULL;
- maxDofs = 0;
-
- /* Begin assembling each element. */
- for( e_i = 0; e_i < nRowEls; e_i++ ) {
- FeMesh_GetElementNodes( rowMesh, e_i, self->rowInc );
- nRowNodes = IArray_GetSize( self->rowInc );
- rowNodes = (unsigned*)IArray_GetPtr( self->rowInc );
- FeMesh_GetElementNodes( colMesh, e_i, self->colInc );
- nColNodes = IArray_GetSize( self->colInc );
- colNodes = (unsigned*)IArray_GetPtr( self->colInc );
-
- /* Do we need more space to assemble this element? */
- nRowDofs = 0;
- for( n_i = 0; n_i < nRowNodes; n_i++ )
- nRowDofs += rowDofs->dofCounts[rowNodes[n_i]];
- nColDofs = 0;
- for( n_i = 0; n_i < nColNodes; n_i++ )
- nColDofs += colDofs->dofCounts[colNodes[n_i]];
- nDofs = nRowDofs * nColDofs;
- self->nRowDofs = nRowDofs;
- self->nColDofs = nColDofs;
- if( nDofs > maxDofs ) {
- maxRCDofs = (nRowDofs > nColDofs) ? nRowDofs : nColDofs;
- elStiffMat = ReallocArray2D( elStiffMat, double, nRowDofs, nColDofs );
- bcVals = ReallocArray( bcVals, double, maxRCDofs );
- maxDofs = nDofs;
- self->elStiffMat = elStiffMat;
- self->bcVals = bcVals;
- }
-
- /* Assemble the element. */
- memset( elStiffMat[0], 0, nDofs * sizeof(double) );
- StiffnessMatrix_AssembleElement( self, e_i, sle, (FiniteElementContext*)_context, elStiffMat );
-
- /* Correct for BCs providing I'm not keeping them in. */
- if( vector && removeBCs ) {
- memset( bcVals, 0, nRowDofs * sizeof(double) );
-
- rowInd = 0;
- for( n_i = 0; n_i < nRowNodes; n_i++ ) {
- nRowNodeDofs = rowDofs->dofCounts[rowNodes[n_i]];
- for( dof_i = 0; dof_i < nRowNodeDofs; dof_i++ ) {
- if( !FeVariable_IsBC( rowVar, rowNodes[n_i], dof_i ) ) {
- colInd = 0;
- for( n_j = 0; n_j < nColNodes; n_j++ ) {
- nColNodeDofs = colDofs->dofCounts[colNodes[n_j]];
- for( dof_j = 0; dof_j < nColNodeDofs; dof_j++ ) {
- if( FeVariable_IsBC( colVar, colNodes[n_j], dof_j ) ) {
- bc = DofLayout_GetValueDouble( colDofs, colNodes[n_j], dof_j );
- bcVals[rowInd] -= bc * elStiffMat[rowInd][colInd];
- }
- colInd++;
- }
- }
- }
- rowInd++;
- }
- }
-
- //Vector_AddEntries( vector, nRowDofs, (unsigned*)rowEqNum->locationMatrix[e_i][0], bcVals );
- VecSetValues( vector, nRowDofs, rowEqNum->locationMatrix[e_i][0], bcVals, ADD_VALUES );
- }
- if( transVector && removeBCs ) {
- memset( bcVals, 0, nColDofs * sizeof(double) );
-
- colInd = 0;
- for( n_i = 0; n_i < nColNodes; n_i++ ) {
- nColNodeDofs = colDofs->dofCounts[colNodes[n_i]];
- for( dof_i = 0; dof_i < nColNodeDofs; dof_i++ ) {
- if( !FeVariable_IsBC( colVar, colNodes[n_i], dof_i ) ) {
- rowInd = 0;
- for( n_j = 0; n_j < nRowNodes; n_j++ ) {
- nRowNodeDofs = rowDofs->dofCounts[rowNodes[n_j]];
- for( dof_j = 0; dof_j < nRowNodeDofs; dof_j++ ) {
- if( FeVariable_IsBC( rowVar, rowNodes[n_j], dof_j ) ) {
- bc = DofLayout_GetValueDouble( rowDofs, rowNodes[n_j], dof_j );
- bcVals[colInd] -= bc * elStiffMat[rowInd][colInd];
- }
- rowInd++;
- }
- }
- }
- colInd++;
- }
- }
-
- VecSetValues( transVector, nColDofs, colEqNum->locationMatrix[e_i][0], bcVals, ADD_VALUES );
- }
-
- /* If keeping BCs in, zero corresponding entries in the element stiffness matrix. */
- if( !rowEqNum->removeBCs || !colEqNum->removeBCs ) {
- rowInd = 0;
- for( n_i = 0; n_i < nRowNodes; n_i++ ) {
- nRowNodeDofs = rowDofs->dofCounts[rowNodes[n_i]];
- for( dof_i = 0; dof_i < nRowNodeDofs; dof_i++ ) {
- if( FeVariable_IsBC( rowVar, rowNodes[n_i], dof_i ) ) {
- memset( elStiffMat[rowInd], 0, nColDofs * sizeof(double) );
- }
- else {
- colInd = 0;
- for( n_j = 0; n_j < nColNodes; n_j++ ) {
- nColNodeDofs = colDofs->dofCounts[colNodes[n_j]];
- for( dof_j = 0; dof_j < nColNodeDofs; dof_j++ ) {
- if( FeVariable_IsBC( colVar, colNodes[n_j], dof_j ) )
- elStiffMat[rowInd][colInd] = 0.0;
- colInd++;
- }
- }
- }
- rowInd++;
- }
- }
- }
-
- /* Add to stiffness matrix. */
- MatSetValues( matrix,
- nRowDofs, rowEqNum->locationMatrix[e_i][0],
- nColDofs, colEqNum->locationMatrix[e_i][0],
- elStiffMat[0], ADD_VALUES );
- }
-
- FreeArray( elStiffMat );
- FreeArray( bcVals );
-
- /* If keeping BCs in and rows and columnns use the same variable, put ones in all BC'd diagonals. */
- if( !colEqNum->removeBCs && rowVar == colVar ) {
- for( n_i = 0; n_i < FeMesh_GetNodeLocalSize( colMesh ); n_i++ ) {
- nColNodeDofs = colDofs->dofCounts[n_i];
- for( dof_i = 0; dof_i < nColNodeDofs; dof_i++ ) {
- if( FeVariable_IsBC( colVar, n_i, dof_i ) ) {
- MatSetValues( self->matrix,
- 1, colEqNum->destinationArray[n_i] + dof_i,
- 1, colEqNum->destinationArray[n_i] + dof_i,
- (double*)&one, ADD_VALUES );
- }
- }
- }
-
-#if 0
- StiffnessMatrix_SetEqsToUnity( self, rowEqNum, STree_GetRoot( rowEqNum->ownedMap ) );
-#endif
- }
-
- /* Reassemble the matrix and vectors. */
- MatAssemblyBegin( matrix, MAT_FINAL_ASSEMBLY );
- MatAssemblyEnd( matrix, MAT_FINAL_ASSEMBLY );
- if( vector ) {
- VecAssemblyBegin( vector );
- VecAssemblyEnd( vector );
- }
- if( transVector) {
- VecAssemblyBegin( transVector );
- VecAssemblyEnd( transVector );
- }
-
- MatAssemblyBegin( matrix, MAT_FINAL_ASSEMBLY );
- MatAssemblyEnd( matrix, MAT_FINAL_ASSEMBLY );
-}
-
-/* void StiffnessMatrix_ShellAssembly( void* stiffnessMatrix, Bool removeBCs, void* data ) { */
-/* StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix; */
-/* Vec rhs; */
-/* FeVariable *rowVar, *colVar; */
-/* FeMesh *rowMesh, *colMesh; */
-/* FeEquationNumber *rowEqNum, *colEqNum; */
-/* DofLayout *rowDofs, *colDofs; */
-/* unsigned nRowEls; */
-/* unsigned nRowNodes, *rowNodes; */
-/* unsigned nColNodes, *colNodes; */
-/* unsigned maxDofs, nDofs, nRowDofs, nColDofs; */
-/* double** elStiffMat; */
-/* double* values; */
-/* unsigned* indices; */
-/* unsigned curRow, curCol; */
-/* unsigned colEq; */
-/* double bc; */
-/* unsigned e_i, n_i, n_j, dof_i, dof_j; */
-
-/* assert( self && Stg_CheckType( self, StiffnessMatrix ) ); */
-
-/* /\* The whole point of this routine is to remove the BCs. *\/ */
-/* if( !removeBCs ) */
-/* return; */
-
-/* rhs = self->rhs->vector; */
-/* rowVar = self->rowVariable; */
-/* colVar = self->columnVariable ? self->columnVariable : rowVar; */
-/* if( rowVar != colVar ) { */
-/* FeVariable* tmp = rowVar; */
-/* rowVar = colVar; */
-/* colVar = tmp; */
-/* } */
-/* rowEqNum = rowVar->eqNum; */
-/* colEqNum = colVar->eqNum; */
-/* rowMesh = rowVar->feMesh; */
-/* colMesh = colVar->feMesh; */
-/* rowDofs = rowVar->dofLayout; */
-/* colDofs = colVar->dofLayout; */
-/* nRowEls = FeMesh_GetElementLocalSize( rowMesh ); */
-/* elStiffMat = NULL; */
-/* values = NULL; */
-/* indices = NULL; */
-/* maxDofs = 0; */
-
-/* for( e_i = 0; e_i < nRowEls; e_i++ ) { */
-/* FeMesh_GetElementNodes( rowMesh, e_i, self->rowInc ); */
-/* nRowNodes = IArray_GetSize( self->rowInc ); */
-/* rowNodes = IArray_GetPtr( self->rowInc ); */
-/* FeMesh_GetElementNodes( colMesh, e_i, self->colInc ); */
-/* nColNodes = IArray_GetSize( self->colInc ); */
-/* colNodes = IArray_GetPtr( self->colInc ); */
-
-/* /\* If none of the column equations on this element have BCs then skip it. *\/ */
-/* for( n_i = 0; n_i < nRowNodes; n_i++ ) { */
-/* for( dof_i = 0; dof_i < rowDofs->dofCounts[rowNodes[n_i]]; dof_i++ ) { */
-/* if( rowEqNum->locationMatrix[e_i][n_i][dof_i] == (unsigned)-1 ) */
-/* continue; */
-/* for( n_j = 0; n_j < nColNodes; n_j++ ) { */
-/* for( dof_j = 0; dof_j < colDofs->dofCounts[colNodes[n_j]]; dof_j++ ) { */
-/* if( colEqNum->locationMatrix[e_i][n_j][dof_j] == (unsigned)-1 ) */
-/* break; */
-/* } */
-/* if( dof_j < colDofs->dofCounts[colNodes[n_j]] ) */
-/* break; */
-/* } */
-/* if( n_j < nColNodes ) */
-/* break; */
-/* } */
-/* if( dof_i < rowDofs->dofCounts[rowNodes[n_i]] ) */
-/* break; */
-/* } */
-/* if( n_i == nRowNodes ) */
-/* continue; */
-
-/* /\* Do we need more space to assemble this element? *\/ */
-/* nRowDofs = 0; */
-/* for( n_i = 0; n_i < nRowNodes; n_i++ ) */
-/* nRowDofs += rowDofs->dofCounts[rowNodes[n_i]]; */
-/* nColDofs = 0; */
-/* for( n_i = 0; n_i < nColNodes; n_i++ ) */
-/* nColDofs += colDofs->dofCounts[colNodes[n_i]]; */
-/* nDofs = nRowDofs * nColDofs; */
-/* if( nDofs > maxDofs ) { */
-/* #if 0 */
-/* elStiffMat = ReallocArray2D( elStiffMat, double, nRowDofs, nColDofs ); */
-/* #endif */
-/* values = ReallocArray( values, double, nDofs ); */
-/* indices = ReallocArray( indices, unsigned, nDofs ); */
-/* maxDofs = nDofs; */
-/* } */
-
-/* #if 0 */
-/* /\* Assemble the element. *\/ */
-/* memset( &elStiffMat[0][0], 0, nDofs * sizeof(double) ); */
-/* StiffnessMatrix_AssembleElement( self, e_i, sle, elStiffMat ); */
-/* #endif */
-
-/* elStiffMat = ((PETScShellMatrix*)self->matrix)->elStiffMat; assert( elStiffMat ); */
-
-/* /\* Update the force vector with BCs. *\/ */
-/* curRow = 0; */
-/* memset( values, 0, nDofs * sizeof(double) ); */
-/* for( n_i = 0; n_i < nRowNodes; n_i++ ) { */
-/* for( dof_i = 0; dof_i < rowDofs->dofCounts[rowNodes[n_i]]; dof_i++ ) { */
-/* indices[curRow] = rowEqNum->locationMatrix[e_i][n_i][dof_i]; */
-/* if( indices[curRow] == (unsigned)-1 ) { */
-/* curRow++; */
-/* continue; */
-/* } */
-
-/* curCol = 0; */
-/* for( n_j = 0; n_j < nColNodes; n_j++ ) { */
-/* for( dof_j = 0; dof_j < colDofs->dofCounts[colNodes[n_j]]; dof_j++ ) { */
-/* colEq = colEqNum->locationMatrix[e_i][n_j][dof_j]; */
-/* if( colEq != (unsigned)-1 ) { */
-/* curCol++; */
-/* continue; */
-/* } */
-
-/* bc = DofLayout_GetValueDouble( colDofs, colNodes[n_j], dof_j ); */
-/* values[curRow] -= elStiffMat[curRow][curCol] * bc; */
-
-/* curCol++; */
-/* } */
-/* } */
-
-/* curRow++; */
-/* } */
-/* } */
-
-/* VecSetValues( rhs, curRow, indices, values, ADD_VALUES ); */
-/* } */
-
-/* FreeArray( values ); */
-/* FreeArray( indices ); */
-
-/* VecAssemblyBegin( rhs ); */
-/* VecAssemblyEnd( rhs ); */
-/* } */
-
-
-
-/* +++ PRIVATE FUNCTIONS +++ */
-
-void _StiffnessMatrix_UpdateBC_CorrectionTables(
- StiffnessMatrix* self,
- FeEquationNumber* eqNum,
- DofLayout* dofLayout,
- Dof_EquationNumber** elementLM,
- Node_ElementLocalIndex nodeCountThisEl,
- Element_Nodes nodeIdsThisEl,
- Dof_Index* bcLM_Id,
- double* bcValues,
- int* nBC_NodalDofPtr )
-{
- Node_ElementLocalIndex node_elLocalI = 0;
- Node_LocalIndex node_lI = 0;
- Dof_Index* dofCounts = dofLayout->dofCounts;
- Dof_Index dofCountThisNode=0;
- Dof_Index dof_nodeLocalI=0;
- unsigned pos = 0;
-
- for( node_elLocalI = 0; node_elLocalI < nodeCountThisEl; node_elLocalI++ ) {
- node_lI = nodeIdsThisEl[node_elLocalI];
- dofCountThisNode = dofCounts[node_lI];
-
- for( dof_nodeLocalI = 0; dof_nodeLocalI < dofCountThisNode; dof_nodeLocalI++ ) {
- Bool isBC = False;
-
- /* Can only use 'elementLM' if FeEquationNumber has been told to remove BCs. Otherwise
- we'll need to determine if the VariableCondition has a value specified for this
- node/dof. - Luke */
- if( elementLM[node_elLocalI][dof_nodeLocalI] != (unsigned)-1 ) {
- unsigned lEqNum;
-
- lEqNum = *(int*)STreeMap_Map( eqNum->ownedMap,
- elementLM[node_elLocalI] + dof_nodeLocalI );
-
- if( eqNum->bcEqNums && STree_Has( eqNum->bcEqNums, &lEqNum ) ) {
- isBC = True;
- }
- }
- else {
- isBC = True;
- }
-
- if ( isBC ) {
- /* offset into the elementStiffness matrix */
- bcLM_Id[ *nBC_NodalDofPtr ] = pos;
-/*
- bcLM_Id[ *nBC_NodalDofPtr ] = &elementLM[node_elLocalI][dof_nodeLocalI] - &elementLM[0][0];
-*/
-
-/* get bc values from the bc_layout */
- bcValues[ *nBC_NodalDofPtr ] = DofLayout_GetValueDouble( dofLayout, node_lI, dof_nodeLocalI );
-
- Journal_DPrintfL( self->debug, 3, "bcValues[%d]: at &LM[0][0] + %d=%d, is %f\n",
- *nBC_NodalDofPtr, bcLM_Id[ *nBC_NodalDofPtr ],
- elementLM[0][ bcLM_Id[ *nBC_NodalDofPtr ] ],
- bcValues[ *nBC_NodalDofPtr ] );
-
- (*nBC_NodalDofPtr)++;
- }
-
- /* Move to next element stiffness matrix entry. */
- pos++;
- }
- }
-}
-
-
-void _StiffnessMatrix_CorrectForceVectorWithOneElementsBoundaryConditions(
- StiffnessMatrix* self,
- Dof_EquationNumber** elementLM[MAX_FE_VARS],
- double* h2Add,
- double** elStiffMatToAdd,
- Dof_Index* totalDofsThisElement[MAX_FE_VARS],
- Dof_Index* bcLM_Id[MAX_FE_VARS],
- double* bcValues[MAX_FE_VARS],
- int nBC_NodalDof_Row,
- unsigned elementInd /* NEW ONE */ )
-{
-#if 0
- int rowEqId;
- double bc_value;
- Dof_Index colDof_elLocalI;
-#endif
-
- memset( h2Add, 0, (*totalDofsThisElement[COL_VAR]) * sizeof(double) );
-
- /*
- ** Something fishy is up with BC corrections, adding this for now.
- */
-
- if( self->rowVariable != self->columnVariable ) {
- Mesh *rowMesh, *colMesh;
- FeEquationNumber *rowEqNum, *colEqNum;
- DofLayout *rowDofs, *colDofs;
- unsigned nRowElNodes, *rowElNodes, nColElNodes, *colElNodes;
- unsigned nRowDofs, nColDofs;
- unsigned dofI, dofJ, elIndI, elIndJ;
- double bcValue;
- unsigned n_i, n_j, d_i, d_j;
-
- rowMesh = (Mesh*)self->rowVariable->feMesh;
- colMesh = (Mesh*)self->columnVariable->feMesh;
- rowEqNum = self->rowVariable->eqNum;
- colEqNum = self->columnVariable->eqNum;
- rowDofs = rowEqNum->dofLayout;
- colDofs = colEqNum->dofLayout;
- Mesh_GetIncidence( rowMesh, Mesh_GetDimSize( rowMesh ), elementInd, MT_VERTEX, self->rowInc );
- nRowElNodes = IArray_GetSize( self->rowInc );
- rowElNodes = (unsigned*)IArray_GetPtr( self->rowInc );
- Mesh_GetIncidence( colMesh, Mesh_GetDimSize( colMesh ), elementInd, MT_VERTEX, self->colInc );
- nColElNodes = IArray_GetSize( self->colInc );
- colElNodes = (unsigned*)IArray_GetPtr( self->colInc );
- nRowDofs = rowDofs->dofCounts[0];
- nColDofs = colDofs->dofCounts[0];
-
- for( n_i = 0; n_i < nColElNodes; n_i++ ) {
- for( d_i = 0; d_i < nColDofs; d_i++ ) {
- dofI = colEqNum->locationMatrix[elementInd][n_i][d_i];
- if( dofI == -1 )
- continue;
-
- elIndI = n_i * nColDofs + d_i;
- for( n_j = 0; n_j < nRowElNodes; n_j++ ) {
- for( d_j = 0; d_j < nRowDofs; d_j++ ) {
- dofJ = rowEqNum->locationMatrix[elementInd][n_j][d_j];
- if( dofJ != -1 )
- continue;
-
- elIndJ = n_j * nRowDofs + d_j;
- bcValue = DofLayout_GetValueDouble( rowDofs, rowElNodes[n_j], d_j );
- h2Add[elIndI] -= elStiffMatToAdd[elIndJ][elIndI] * bcValue;
- }
- }
- }
- }
- }
- else {
- Mesh *rowMesh, *colMesh;
- FeEquationNumber *rowEqNum, *colEqNum;
- DofLayout *rowDofs, *colDofs;
- unsigned nRowElNodes, *rowElNodes, nColElNodes, *colElNodes;
- unsigned nRowDofs, nColDofs;
- unsigned dofI, dofJ, elIndI, elIndJ;
- double bcValue;
- unsigned n_i, n_j, d_i, d_j;
-
- rowMesh = (Mesh*)self->rowVariable->feMesh;
- colMesh = (Mesh*)self->columnVariable->feMesh;
- rowEqNum = self->rowVariable->eqNum;
- colEqNum = self->columnVariable->eqNum;
- rowDofs = rowEqNum->dofLayout;
- colDofs = colEqNum->dofLayout;
- Mesh_GetIncidence( rowMesh, Mesh_GetDimSize( rowMesh ), elementInd, MT_VERTEX, self->rowInc );
- nRowElNodes = IArray_GetSize( self->rowInc );
- rowElNodes = (unsigned*)IArray_GetPtr( self->rowInc );
- Mesh_GetIncidence( colMesh, Mesh_GetDimSize( colMesh ), elementInd, MT_VERTEX, self->colInc );
- nColElNodes = IArray_GetSize( self->colInc );
- colElNodes = (unsigned*)IArray_GetPtr( self->colInc );
- nRowDofs = rowDofs->dofCounts[0];
- nColDofs = colDofs->dofCounts[0];
-
- for( n_i = 0; n_i < nRowElNodes; n_i++ ) {
- for( d_i = 0; d_i < nRowDofs; d_i++ ) {
- dofI = rowEqNum->locationMatrix[elementInd][n_i][d_i];
- if( dofI == -1 )
- continue;
-
- elIndI = n_i * nRowDofs + d_i;
- for( n_j = 0; n_j < nColElNodes; n_j++ ) {
- for( d_j = 0; d_j < nColDofs; d_j++ ) {
- dofJ = colEqNum->locationMatrix[elementInd][n_j][d_j];
- if( dofJ != -1 )
- continue;
-
- elIndJ = n_j * nColDofs + d_j;
- bcValue = DofLayout_GetValueDouble( colDofs, colElNodes[n_j], d_j );
- h2Add[elIndI] -= elStiffMatToAdd[elIndI][elIndJ] * bcValue;
- }
- }
- }
- }
- }
-
-#if 0
- for( colDof_elLocalI=0; colDof_elLocalI < *totalDofsThisElement[COL_VAR]; colDof_elLocalI++ ) {
- double sum = 0.0;
-
- for( bcDof_I=0; bcDof_I < nBC_NodalDof_Row; bcDof_I++ ) {
- rowEqId = bcLM_Id[ROW_VAR][bcDof_I];
- bc_value = bcValues[ROW_VAR][bcDof_I];
-/* printf("bc_value = %f \n",bc_value ); */
-
- /* this index is gets us to the right */
- sum = sum - ( elStiffMatToAdd[rowEqId][colDof_elLocalI] * bc_value );
- }
- h2Add[colDof_elLocalI] = sum;
- }
-#endif
-
- VecSetValues( self->rhs->vector, *totalDofsThisElement[COL_VAR], elementLM[COL_VAR][0], h2Add, ADD_VALUES );
-
- /* assume that K is symetric, so corrections are made with KTrans.
- this allows us to use this func with G, when we want velocity
- corrections from GTrans to appear in H.
- */
-
- /*
- for( bcDof_I=0; bcDof_I < nBC_NodalDof_row; bcDof_I++ ) {
- rowEqId = bcLM_Id[ROW_VAR][bcDof_I];
- bc_value = bcValues[ROW_VAR][bcDof_I];
- printf("bc_value = %f \n",bc_value );
-
- printf("bc value = %f \n",bc_value );
- correct = 0;
- for( colDof_elLocalI=0; colDof_elLocalI< *totalDofsThisElement[COL_VAR]; colDof_elLocalI++ ) {
- h2Add[correct] = h2Add[correct]
- - elStiffMatToAdd[rowEqId* (*totalDofsThisElement[COL_VAR]) + colDof_elLocalI] * bc_value;
- hIdx[correct] = elementLM[COL_VAR][0][ colDof_elLocalI ];
-
- correct = correct + 1;
- }
- }
- Vector_AddTo( self->rhs->vector, correct, hIdx, h2Add );
- */
-
- /* does not work */
- /*for( rowDof_elLocalI=0; rowDof_elLocalI < *totalDofsThisElement[ROW_VAR]; rowDof_elLocalI++ ) {
- double sum = 0.0;
- for( rowDof_elLocalI=0; rowDof_elLocalI<nBC_NodalDof[ROW_VAR]; rowDof_elLocalI++ ) {
- colEqId = bcLM_Id[COL_VAR][rowDof_elLocalI];
- bc_value = bcValues[COL_VAR][rowDof_elLocalI];
-
- sum = sum + elStiffMatToAdd[ i* (*totalDofsThisElement[COL_VAR]) + colEqId] * bc_value;
- }
- h2Add[rowDof_elLocalI] = -sum;
- }
- Vector_AddTo( self->rhs->vector, *totalDofsThisElement[ROW_VAR], elementLM[ROW_VAR][0], h2Add ); */
-}
-
-void _StiffnessMatrix_PrintElementStiffnessMatrix(
- StiffnessMatrix* self,
- Element_LocalIndex element_lI,
- Dof_EquationNumber** rowElementLM,
- Dof_EquationNumber** colElementLM,
- double** elStiffMatToAdd )
-{
- FeMesh* rFeMesh = self->rowVariable->feMesh;
- FeMesh* cFeMesh = self->columnVariable->feMesh;
- Dof_Index rowDofsPerNode;
- Dof_Index colDofsPerNode;
- Node_LocalIndex rowNodesThisEl;
- Node_LocalIndex colNodesThisEl;
- Node_LocalIndex rowNode_I, colNode_I;
- Dof_Index rowDof_I, colDof_I;
- Index rowIndex, colIndex;
- unsigned nRowElInc, *rowElInc;
- unsigned nColElInc, *colElInc;
-
- FeMesh_GetElementNodes( rFeMesh, element_lI, self->rowInc );
- nRowElInc = IArray_GetSize( self->rowInc );
- rowElInc = (unsigned*)IArray_GetPtr( self->rowInc );
- FeMesh_GetElementNodes( cFeMesh, element_lI, self->colInc );
- nColElInc = IArray_GetSize( self->colInc );
- colElInc = (unsigned*)IArray_GetPtr( self->colInc );
-
- rowDofsPerNode = self->rowVariable->dofLayout->dofCounts[rowElInc[0]];
- colDofsPerNode = self->columnVariable->dofLayout->dofCounts[colElInc[0]];
- rowNodesThisEl = nRowElInc;
- colNodesThisEl = nColElInc;
-
- for ( rowNode_I=0; rowNode_I < rowNodesThisEl; rowNode_I++ ) {
- for ( rowDof_I = 0; rowDof_I < rowDofsPerNode; rowDof_I++ ) {
- for ( colNode_I=0; colNode_I < colNodesThisEl; colNode_I++ ) {
- for ( colDof_I = 0; colDof_I < colDofsPerNode; colDof_I++ ) {
- rowIndex = rowNode_I*rowDofsPerNode + rowDof_I;
- colIndex = colNode_I*colDofsPerNode + colDof_I;
-
- Journal_DPrintf( self->debug, "Row [%d][%d], Col [%d][%d] (LM (%4d,%4d)) = %.3f\n",
- rowNode_I, rowDof_I,
- colNode_I, colDof_I,
- rowElementLM[rowNode_I][rowDof_I],
- colElementLM[colNode_I][colDof_I],
- elStiffMatToAdd[rowIndex][colIndex] );
- }
- }
- }
- }
-}
-
-void StiffnessMatrix_AssembleElement(
- void* stiffnessMatrix,
- Element_LocalIndex element_lI,
- SystemLinearEquations* sle,
- FiniteElementContext* context,
- double** elStiffMatToAdd )
-{
- StiffnessMatrix* self = (StiffnessMatrix*) stiffnessMatrix;
- Index stiffnessMatrixTermCount = Stg_ObjectList_Count( self->stiffnessMatrixTermList );
- Index stiffnessMatrixTerm_I;
- StiffnessMatrixTerm* stiffnessMatrixTerm;
-
- for ( stiffnessMatrixTerm_I = 0 ; stiffnessMatrixTerm_I < stiffnessMatrixTermCount ; stiffnessMatrixTerm_I++ ) {
- stiffnessMatrixTerm = (StiffnessMatrixTerm*) Stg_ObjectList_At( self->stiffnessMatrixTermList, stiffnessMatrixTerm_I );
- StiffnessMatrixTerm_AssembleElement( stiffnessMatrixTerm, self, element_lI, sle, context, elStiffMatToAdd );
- }
-}
-
-void StiffnessMatrix_CheckElementAssembly(
- void* stiffnessMatrix,
- Element_LocalIndex element_lI,
- double** elStiffMatToAdd,
- Index elStiffMatToAddRowSize,
- Index elStiffMatToAddColSize )
-{
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
- Bool atLeastOneNonZeroElementContributionEntry = False;
- Index elStiffMat_rowI = 0;
- Index elStiffMat_colI = 0;
- Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
-
- for ( elStiffMat_colI = 0; elStiffMat_colI < elStiffMatToAddColSize; elStiffMat_colI++ ) {
- for ( elStiffMat_rowI = 0; elStiffMat_rowI < elStiffMatToAddColSize; elStiffMat_rowI++ ) {
- if ( elStiffMatToAdd[elStiffMat_rowI][elStiffMat_colI] != 0.0 ) {
- atLeastOneNonZeroElementContributionEntry = True;
- break;
- }
- }
- if ( atLeastOneNonZeroElementContributionEntry == True ) {
- break;
- }
- }
-
- Journal_Firewall( atLeastOneNonZeroElementContributionEntry == True, errorStream,
- "Error - in %s(): while assembling matrix \"%s\", for element %u - elStiffMatToAdd assembled at this "
- "element is all zeros."
- "Did you register a stiffnessMatrixTerm? Is there at least one integration point in this "
- "element?\n", __func__, self->name, element_lI );
-}
-
-void StiffnessMatrix_AddStiffnessMatrixTerm( void* stiffnessMatrix, StiffnessMatrixTerm* stiffnessMatrixTerm ) {
- StiffnessMatrix* self = (StiffnessMatrix*) stiffnessMatrix;
-
- stiffnessMatrixTerm = Stg_CheckType( stiffnessMatrixTerm, StiffnessMatrixTerm );
- Stg_ObjectList_Append( self->stiffnessMatrixTermList, stiffnessMatrixTerm );
-}
-
-void StiffnessMatrix_RefreshMatrix( StiffnessMatrix* self ) {
- int nProcs;
-
- assert( self && Stg_CheckType( self, StiffnessMatrix ) );
-
- /* Note: I'd like to make this a dereference, just in case there is another class still using
- the old matrix, but that'd require two matrices to exist at one time; i.e. lots of memory.
- Keeping it as a free just means that other classes need to assume they never own the matrix. */
- /*if( self->useShellMatrix ) {
- PETScShellMatrix_SetComm( self->shellMatrix, self->comm );
- PETScShellMatrix_SetLocalSize( self->shellMatrix, self->rowLocalSize, self->colLocalSize );
- PETScShellMatrix_SetNonZeroStructure( self->shellMatrix, self->nonZeroCount, self->diagonalNonZeroIndices, self->offDiagonalNonZeroIndices );
- }
- else { */
- if( self->matrix != PETSC_NULL )
- MatDestroy( self->matrix );
-
- MatCreate( self->comm, &self->matrix );
- MatSetSizes( self->matrix, self->rowLocalSize, self->colLocalSize, PETSC_DETERMINE, PETSC_DETERMINE );
- MatSetFromOptions( self->matrix );
- MPI_Comm_size( self->comm, &nProcs );
-
- if( self->diagonalNonZeroIndices || self->offDiagonalNonZeroIndices ) {
- if( nProcs > 1 )
- MatMPIAIJSetPreallocation( self->matrix, PETSC_NULL, (PetscInt*)(self->diagonalNonZeroIndices), PETSC_NULL, (PetscInt*)(self->offDiagonalNonZeroIndices) );
- else
- MatSeqAIJSetPreallocation( self->matrix, PETSC_NULL, (PetscInt*)(self->diagonalNonZeroIndices) );
- }
- else {
- if( nProcs > 1 )
- MatMPIAIJSetPreallocation( self->matrix, self->nonZeroCount, PETSC_NULL, self->nonZeroCount, PETSC_NULL );
- else
- MatSeqAIJSetPreallocation( self->matrix, self->nonZeroCount, PETSC_NULL );
- }
- /*}*/
-}
-
-void StiffnessMatrix_CalcNonZeros( void* stiffnessMatrix ) {
- StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
- Stream *stream;
- FeVariable *rowVar, *colVar;
- FeMesh *rowMesh, *colMesh;
- FeEquationNumber *rowEqNum, *colEqNum;
- DofLayout *rowDofs, *colDofs;
- int nRowEqs, nColEqs;
- int nColNodes, *colNodes;
- int nNodeEls, *nodeEls;
- int *nDiagNonZeros, *nOffDiagNonZeros;
- int rowEq, colEq, localRowEq;
- int netNonZeros;
- STree *candColEqs;
- int e_i;
- int n_i, dof_i;
- int n_j, dof_j;
-
- assert( self && Stg_CheckType( self, StiffnessMatrix ) );
- assert( self->rowVariable );
-
- stream = Journal_Register( Info_Type, (Name)self->type );
- Journal_Printf( stream, "Stiffness matrix: '%s'\n", self->name );
- Stream_Indent( stream );
- Journal_Printf( stream, "Calculating number of nonzero entries...\n" );
- Stream_Indent( stream );
-
- rowVar = self->rowVariable;
- colVar = self->columnVariable ? self->columnVariable : rowVar;
- rowMesh = rowVar->feMesh;
- colMesh = colVar->feMesh;
- rowEqNum = rowVar->eqNum;
- colEqNum = colVar->eqNum;
- nRowEqs = rowEqNum->localEqNumsOwnedCount;
- nColEqs = colEqNum->localEqNumsOwnedCount;
- rowDofs = rowVar->dofLayout;
- colDofs = colVar->dofLayout;
-
- candColEqs = STree_New();
- STree_SetIntCallbacks( candColEqs );
- STree_SetItemSize( candColEqs, sizeof(int) );
- nDiagNonZeros = AllocArray( int, nRowEqs );
- nOffDiagNonZeros = AllocArray( int, nRowEqs );
- memset( nDiagNonZeros, 0, nRowEqs * sizeof(int) );
- memset( nOffDiagNonZeros, 0, nRowEqs * sizeof(int) );
- netNonZeros = 0;
-
- for( n_i = 0; n_i < FeMesh_GetNodeLocalSize( rowMesh ); n_i++ ) {
- for( dof_i = 0; dof_i < rowDofs->dofCounts[n_i]; dof_i++ ) {
- rowEq = rowEqNum->destinationArray[n_i][dof_i];
-
- if( rowEq == -1 ) continue;
- if( !STreeMap_HasKey( rowEqNum->ownedMap, &rowEq ) ) continue;
-
- localRowEq = *(int*)STreeMap_Map( rowEqNum->ownedMap, &rowEq );
- FeMesh_GetNodeElements( rowMesh, n_i, self->rowInc );
- nNodeEls = IArray_GetSize( self->rowInc );
- nodeEls = IArray_GetPtr( self->rowInc );
- STree_Clear( candColEqs );
-
- for( e_i = 0; e_i < nNodeEls; e_i++ ) {
- /* ASSUME: Row and column meshes have one-to-one element overlap. */
- FeMesh_GetElementNodes( colMesh, nodeEls[e_i], self->colInc );
- nColNodes = IArray_GetSize( self->colInc );
- colNodes = IArray_GetPtr( self->colInc );
-
- for( n_j = 0; n_j < nColNodes; n_j++ ) {
- for( dof_j = 0; dof_j < colDofs->dofCounts[colNodes[n_j]]; dof_j++ ) {
- colEq = colEqNum->destinationArray[colNodes[n_j]][dof_j];
-
- if( colEq == -1 ) continue;
- if( !STree_Has( candColEqs, &colEq ) ) {
- STree_Insert( candColEqs, &colEq );
- if( STreeMap_HasKey( colEqNum->ownedMap, &colEq ) )
- nDiagNonZeros[localRowEq]++;
- else
- nOffDiagNonZeros[localRowEq]++;
- netNonZeros++;
- }
- }
- }
- }
- }
- }
- self->diagonalNonZeroIndices = (Index*)nDiagNonZeros;
- self->offDiagonalNonZeroIndices = (Index*)nOffDiagNonZeros;
-
- {
- int tmp;
- MPI_Allreduce( &netNonZeros, &tmp, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
- netNonZeros = tmp;
- }
- Journal_Printf( stream, "Found %d nonzero entries.\n", netNonZeros );
- Journal_Printf( stream, "Done.\n" );
- Stream_UnIndent( stream );
- Stream_UnIndent( stream );
-}
-
-
-Bool StiffnessMatrix_ZeroBCsAsm_RowR( void* stiffMat, Assembler* assm ) {
- memset( ((StiffnessMatrix*)stiffMat)->elStiffMat[assm->rowInd], 0, ((StiffnessMatrix*)stiffMat)->nColDofs * sizeof(double) );
-
- return False;
-}
-
-Bool StiffnessMatrix_ZeroBCsAsm_ColR( void* stiffMat, Assembler* assm ) {
- ((StiffnessMatrix*)stiffMat)->elStiffMat[assm->rowInd][assm->colInd] = 0.0;
- return True;
-}
-
-Bool StiffnessMatrix_BCAsm_ColR( void* stiffMat, Assembler* assm ) {
- double bc;
-
- bc = DofLayout_GetValueDouble( assm->colVar->dofLayout, assm->colNodeInd, assm->colDofInd );
- ((StiffnessMatrix*)stiffMat)->bcVals[assm->rowInd] -= bc * ((StiffnessMatrix*)stiffMat)->elStiffMat[assm->rowInd][assm->colInd];
-
- return True;
-}
-
-Bool StiffnessMatrix_TransBCAsm_ColR( void* stiffMat, Assembler* assm ) {
- double bc;
-
- bc = DofLayout_GetValueDouble( assm->colVar->dofLayout, assm->colNodeInd, assm->colDofInd );
- ((StiffnessMatrix*)stiffMat)->bcVals[assm->rowInd] -= bc * ((StiffnessMatrix*)stiffMat)->elStiffMat[assm->colInd][assm->rowInd];
-
- return True;
-}
-
-Bool StiffnessMatrix_DiagBCsAsm_RowR( void* stiffMat, Assembler* assm ) {
- static const double one = 1.0;
-
- MatSetValues( ((StiffnessMatrix*)stiffMat)->matrix, 1, (PetscInt*)(&assm->rowEq), 1, (PetscInt*)(&assm->rowEq), (double*)&one, ADD_VALUES );
-
- return True;
-}
-
-void StiffnessMatrix_AddModifyCallback( StiffnessMatrix* self, void* callback, void* object ) {
- self->nModifyCBs++;
- self->modifyCBs = ReallocArray( self->modifyCBs, Callback, self->nModifyCBs );
- self->modifyCBs[self->nModifyCBs - 1].callback = callback;
- self->modifyCBs[self->nModifyCBs - 1].object = object;
-}
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/StiffnessMatrix.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/StiffnessMatrix.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,2909 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: StiffnessMatrix.c 1210 2008-08-25 01:17:12Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <mpi.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "FiniteElementContext.h"
+#include "StiffnessMatrix.h"
+#include "StiffnessMatrixTerm.h"
+#include "SystemLinearEquations.h"
+#include "EntryPoint.h"
+#include "SolutionVector.h"
+#include "ForceVector.h"
+#include "Assembler.h"
+
+void __StiffnessMatrix_NewAssemble( void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context );
+void StiffnessMatrix_NewAssemble( void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context );
+Bool StiffnessMatrix_ZeroBCsAsm_RowR( void* stiffMat, Assembler* assm );
+Bool StiffnessMatrix_ZeroBCsAsm_ColR( void* stiffMat, Assembler* assm );
+Bool StiffnessMatrix_BCAsm_ColR( void* stiffMat, Assembler* assm );
+Bool StiffnessMatrix_TransBCAsm_ColR( void* stiffMat, Assembler* assm );
+Bool StiffnessMatrix_DiagBCsAsm_RowR( void* stiffMat, Assembler* assm );
+
+
+/* Textual name of this class */
+const Type StiffnessMatrix_Type = "StiffnessMatrix";
+
+/** First part of name for build entry point */
+static const char StiffnessMatrix_assembleStiffnessMatrixStr[] = "assembleStiffnessMatrix";
+
+
+void* StiffnessMatrix_DefaultNew( Name name )
+{
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(StiffnessMatrix);
+ Type type = StiffnessMatrix_Type;
+ Stg_Class_DeleteFunction* _delete = _StiffnessMatrix_Delete;
+ Stg_Class_PrintFunction* _print = _StiffnessMatrix_Print;
+ Stg_Class_CopyFunction* _copy = _StiffnessMatrix_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = StiffnessMatrix_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _StiffnessMatrix_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _StiffnessMatrix_Build;
+ Stg_Component_InitialiseFunction* _initialise = _StiffnessMatrix_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _StiffnessMatrix_Execute;
+ Stg_Component_DestroyFunction* _destroy = _StiffnessMatrix_Destroy;
+ Bool initFlag = False;
+ StiffnessMatrix_CalculateNonZeroEntriesFunction* _calculateNonZeroEntries = StiffnessMatrix_CalcNonZeros;
+ void* rowVariable = NULL;
+ void* columnVariable = NULL;
+ void* rhs = NULL;
+ Stg_Component* applicationDepInfo = NULL;
+ Dimension_Index dim = 0;
+ Bool isNonLinear = False;
+ Bool allowZeroElementContributions = False;
+ void* entryPoint_Register = NULL;
+ MPI_Comm comm = 0;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _StiffnessMatrix_New( STIFFNESSMATRIX_PASSARGS );
+}
+
+
+StiffnessMatrix* StiffnessMatrix_New(
+ Name name,
+ void* rowVariable,
+ void* columnVariable,
+ void* rhs,
+ Stg_Component* applicationDepInfo,
+ Dimension_Index dim,
+ Bool isNonLinear,
+ Bool allowZeroElementContributions,
+ void* entryPoint_Register,
+ MPI_Comm comm )
+{
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(StiffnessMatrix);
+ Type type = StiffnessMatrix_Type;
+ Stg_Class_DeleteFunction* _delete = _StiffnessMatrix_Delete;
+ Stg_Class_PrintFunction* _print = _StiffnessMatrix_Print;
+ Stg_Class_CopyFunction* _copy = _StiffnessMatrix_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = StiffnessMatrix_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _StiffnessMatrix_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _StiffnessMatrix_Build;
+ Stg_Component_InitialiseFunction* _initialise = _StiffnessMatrix_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _StiffnessMatrix_Execute;
+ Stg_Component_DestroyFunction* _destroy = _StiffnessMatrix_Destroy;
+ Bool initFlag = True;
+ StiffnessMatrix_CalculateNonZeroEntriesFunction* _calculateNonZeroEntries = StiffnessMatrix_CalcNonZeros;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _StiffnessMatrix_New( STIFFNESSMATRIX_PASSARGS );
+}
+
+
+StiffnessMatrix* _StiffnessMatrix_New( STIFFNESSMATRIX_DEFARGS )
+{
+ StiffnessMatrix* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(StiffnessMatrix) );
+ /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
+ /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
+ and so should be set to ZERO in any children of this class. */
+ nameAllocationType = NON_GLOBAL;
+
+ self = (StiffnessMatrix*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ /* General info */
+
+ /* Virtual functions */
+ self->_calculateNonZeroEntries = _calculateNonZeroEntries;
+
+ if( initFlag ){
+ _StiffnessMatrix_Init( self, rowVariable, columnVariable, rhs, applicationDepInfo, dim,
+ isNonLinear, allowZeroElementContributions, entryPoint_Register, comm );
+ }
+
+ return self;
+}
+
+void _StiffnessMatrix_Init(
+ StiffnessMatrix* self,
+ void* rowVariable,
+ void* columnVariable,
+ void* rhs,
+ Stg_Component* applicationDepInfo,
+ Dimension_Index dim,
+ Bool isNonLinear,
+ Bool allowZeroElementContributions,
+ void* entryPoint_Register,
+ MPI_Comm comm )
+{
+ Stream* error = Journal_Register( ErrorStream_Type, (Name)self->type );
+ Stream* stream;
+
+ /* General and Virtual info should already be set */
+ stream = Journal_Register( Info_Type, (Name)self->type );
+ Stream_SetPrintingRank( stream, 0 );
+
+ /* StiffnessMatrix info */
+ self->isConstructed = True;
+ self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type );
+ Journal_Firewall( (rowVariable != NULL), error, "Error: NULL row FeVariable provided to \"%s\" %s.\n", self->name, self->type );
+
+ self->rowVariable = (FeVariable*)rowVariable;
+ Journal_Firewall( (columnVariable != NULL), error, "Error: NULL column FeVariable provided to \"%s\" %s.\n", self->name, self->type );
+
+ self->columnVariable = (FeVariable*)columnVariable;
+ Journal_Firewall( (rhs != NULL), error, "Error: NULL rhs ForceVector provided to \"%s\" %s.\n", self->name, self->type );
+
+ self->rhs = (ForceVector*)rhs;
+ self->applicationDepInfo = applicationDepInfo;
+ self->comm = comm;
+ self->dim = dim;
+ self->isNonLinear = isNonLinear;
+ self->allowZeroElementContributions = allowZeroElementContributions;
+
+ self->rowLocalSize = 0;
+ self->colLocalSize = 0;
+ self->nonZeroCount = 0;
+ self->diagonalNonZeroCount = 0;
+ self->offDiagonalNonZeroCount = 0;
+ self->diagonalNonZeroIndices = NULL;
+ self->offDiagonalNonZeroIndices = NULL;
+
+ self->entryPoint_Register = (EntryPoint_Register*)entryPoint_Register;
+
+ Stg_asprintf( &self->_assembleStiffnessMatrixEPName, "%s-%s", self->name, StiffnessMatrix_assembleStiffnessMatrixStr );
+ self->assembleStiffnessMatrix = FeEntryPoint_New( self->_assembleStiffnessMatrixEPName, FeEntryPoint_AssembleStiffnessMatrix_CastType );
+
+ EntryPoint_Register_Add( self->entryPoint_Register, self->assembleStiffnessMatrix );
+
+ self->stiffnessMatrixTermList = Stg_ObjectList_New();
+
+ /* Set default function for Global Stiffness Matrix Assembly */
+ EP_ReplaceAll( self->assembleStiffnessMatrix, __StiffnessMatrix_NewAssemble );
+
+ /* We need some assembler contexts. */
+ self->zeroBCsAsm = Assembler_New();
+ self->bcAsm = Assembler_New();
+ self->transBCAsm = Assembler_New();
+
+ if( rowVariable == columnVariable )
+ self->diagBCsAsm = Assembler_New();
+
+ self->elStiffMat = NULL;
+ self->bcVals = NULL;
+ self->nRowDofs = 0;
+ self->nColDofs = 0;
+ self->transRHS = NULL;
+
+ self->rowInc = IArray_New();
+ self->colInc = IArray_New();
+
+ self->nModifyCBs = 0;
+ self->modifyCBs = NULL;
+
+ self->matrix = PETSC_NULL;
+ /* self->shellMatrix = NULL; */
+ /* self->useShellMatrix = False; */
+}
+
+void _StiffnessMatrix_Delete( void* stiffnessMatrix ) {
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+ /* Stg_Class_Delete parent*/
+ _Stg_Component_Delete( self );
+
+}
+
+void _StiffnessMatrix_Print( void* stiffnessMatrix, Stream* stream ) {
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+
+ /* Set the Journal for printing informations */
+ Stream* stiffnessMatrixStream = stream;
+
+ /* General info */
+ Journal_Printf( stiffnessMatrixStream, "StiffnessMatrix (ptr): %p\n", self );
+
+ /* Print parent */
+ _Stg_Component_Print( self, stiffnessMatrixStream );
+
+ /* Virtual info */
+ Journal_Printf( stiffnessMatrixStream, "\t_build (func ptr): %p\n", self->_build );
+
+ Journal_Printf( stiffnessMatrixStream, "\tassembleStiffnessMatrix e.p. (ptr): %p\n", self->assembleStiffnessMatrix );
+ EntryPoint_PrintConcise( self->assembleStiffnessMatrix, stream );
+
+ /* StiffnessMatrix info */
+ Journal_Printf( stiffnessMatrixStream, "\trowVariable (ptr): %p\n", self->rowVariable );
+ Journal_Printf( stiffnessMatrixStream, "\t\tvariable name: %s\n", self->rowVariable->name );
+ Journal_Printf( stiffnessMatrixStream, "\tcolumnVariable (ptr): %p\n", self->columnVariable );
+ Journal_Printf( stiffnessMatrixStream, "\t\tvariable name: %s\n", self->columnVariable->name );
+ Journal_Printf( stiffnessMatrixStream, "\tMatrix (ptr): %p\n", self->matrix );
+ Journal_Printf( stiffnessMatrixStream, "\tComm: %u\n", self->comm );
+ Journal_Printf( stiffnessMatrixStream, "\trowLocalSize: %u\n", self->rowLocalSize );
+ Journal_Printf( stiffnessMatrixStream, "\tcolLocalSize: %u\n", self->colLocalSize );
+ Journal_Printf( stiffnessMatrixStream, "\tnonZeroCount: %u\n", self->nonZeroCount );
+ Journal_Printf( stiffnessMatrixStream, "\tisNonLinear: %s\n", StG_BoolToStringMap[self->isNonLinear] );
+ Journal_Printf( stiffnessMatrixStream, "\tallowZeroElementContributions: %s\n", StG_BoolToStringMap[self->allowZeroElementContributions] );
+}
+
+void* _StiffnessMatrix_Copy( const void* stiffnessMatrix, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+ StiffnessMatrix* newStiffnessMatrix;
+ PtrMap* map = ptrMap;
+ Bool ownMap = False;
+
+ if( !map ) {
+ map = PtrMap_New( 10 );
+ ownMap = True;
+ }
+
+ newStiffnessMatrix = (StiffnessMatrix*)_Stg_Component_Copy( self, dest, deep, nameExt, map );
+
+ /* Virtual functions */
+ newStiffnessMatrix->_calculateNonZeroEntries = self->_calculateNonZeroEntries;
+
+ /* TODO: copy matrix */
+ newStiffnessMatrix->matrix = self->matrix;
+/* newStiffnessMatrix->shellMatrix = self->shellMatrix; */
+ newStiffnessMatrix->entryPoint_Register = self->entryPoint_Register;
+ newStiffnessMatrix->comm = self->comm;
+ newStiffnessMatrix->rowLocalSize = self->rowLocalSize;
+ newStiffnessMatrix->colLocalSize = self->colLocalSize;
+ newStiffnessMatrix->dim = self->dim;
+ newStiffnessMatrix->nonZeroCount = self->nonZeroCount;
+ newStiffnessMatrix->diagonalNonZeroCount = self->diagonalNonZeroCount;
+ newStiffnessMatrix->offDiagonalNonZeroCount = self->offDiagonalNonZeroCount;
+
+ if( deep ) {
+ newStiffnessMatrix->debug = (Stream*)Stg_Class_Copy( self->debug, NULL, deep, nameExt, map );
+ newStiffnessMatrix->rowVariable = (FeVariable*)Stg_Class_Copy( self->rowVariable, NULL, deep, nameExt, map );
+ newStiffnessMatrix->columnVariable = (FeVariable*)Stg_Class_Copy( self->columnVariable, NULL, deep, nameExt, map );
+ newStiffnessMatrix->rhs =(ForceVector*)Stg_Class_Copy( self->rhs, NULL, deep, nameExt, map );
+ newStiffnessMatrix->assembleStiffnessMatrix = (FeEntryPoint*)Stg_Class_Copy( self->assembleStiffnessMatrix, NULL, deep, nameExt, map );
+
+ if( self->_assembleStiffnessMatrixEPName ) {
+ if( nameExt ) {
+ Stg_asprintf( &newStiffnessMatrix->_assembleStiffnessMatrixEPName, "%s%s",
+ self->_assembleStiffnessMatrixEPName, nameExt );
+ }
+ else {
+ newStiffnessMatrix->_assembleStiffnessMatrixEPName = StG_Strdup( self->_assembleStiffnessMatrixEPName );
+ }
+ }
+ else {
+ newStiffnessMatrix->_assembleStiffnessMatrixEPName = NULL;
+ }
+
+ /* Arrays */
+ if( (newStiffnessMatrix->diagonalNonZeroIndices = (Index*)PtrMap_Find( map, self->diagonalNonZeroIndices )) == NULL ) {
+ if( self->diagonalNonZeroIndices ) {
+ newStiffnessMatrix->diagonalNonZeroIndices = Memory_Alloc_Array( Index,
+ newStiffnessMatrix->rowLocalSize, "diagonalNonZeroIndices" );
+ memcpy( newStiffnessMatrix->diagonalNonZeroIndices, self->diagonalNonZeroIndices,
+ newStiffnessMatrix->rowLocalSize * sizeof( Index ) );
+ PtrMap_Append( map, self->diagonalNonZeroIndices, newStiffnessMatrix->diagonalNonZeroIndices );
+ }
+ else {
+ newStiffnessMatrix->diagonalNonZeroIndices = NULL;
+ }
+ }
+
+ if( (newStiffnessMatrix->offDiagonalNonZeroIndices = (Index*)PtrMap_Find( map, self->offDiagonalNonZeroIndices )) == NULL ) {
+ if( self->offDiagonalNonZeroIndices ) {
+ newStiffnessMatrix->offDiagonalNonZeroIndices = Memory_Alloc_Array( Index,
+ newStiffnessMatrix->rowLocalSize, "diagonalNonZeroIndices" );
+ memcpy( newStiffnessMatrix->offDiagonalNonZeroIndices, self->offDiagonalNonZeroIndices,
+ newStiffnessMatrix->rowLocalSize * sizeof( Index ) );
+ PtrMap_Append( map, self->offDiagonalNonZeroIndices, newStiffnessMatrix->offDiagonalNonZeroIndices );
+ }
+ else {
+ newStiffnessMatrix->offDiagonalNonZeroIndices = NULL;
+ }
+ }
+ }
+ else {
+ newStiffnessMatrix->debug = self->debug;
+ newStiffnessMatrix->rowVariable = self->rowVariable;
+ newStiffnessMatrix->columnVariable = self->columnVariable;
+ newStiffnessMatrix->rhs = self->rhs;
+ newStiffnessMatrix->diagonalNonZeroIndices = self->diagonalNonZeroIndices;
+ newStiffnessMatrix->offDiagonalNonZeroIndices = self->offDiagonalNonZeroIndices;
+ }
+
+ if( ownMap ) {
+ Stg_Class_Delete( map );
+ }
+
+ return (void*)newStiffnessMatrix;
+}
+
+void _StiffnessMatrix_AssignFromXML( void* stiffnessMatrix, Stg_ComponentFactory* cf, void* data ) {
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+ Stream* stream;
+ FeVariable* rowVar = NULL;
+ FeVariable* colVar = NULL;
+ ForceVector* fVector = NULL;
+ Stg_Component* applicationDepInfo = NULL;
+ void* entryPointRegister = NULL;
+ Dimension_Index dim = 0;
+ Bool isNonLinear;
+ Bool allowZeroElementContributions;
+
+ self->context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", FiniteElementContext, False, data );
+ if( !self->context )
+ self->context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
+
+ rowVar = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"RowVariable", FeVariable, True, data );
+ colVar = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ColumnVariable", FeVariable, True, data );
+ fVector = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"RHS", ForceVector, False, data );
+ applicationDepInfo = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ApplicationDepInfo", Stg_Component, False, data);
+
+ entryPointRegister = self->context->entryPoint_Register;
+ assert( entryPointRegister );
+
+ dim = Stg_ComponentFactory_GetRootDictUnsignedInt( cf, (Dictionary_Entry_Key)"dim", 0 );
+ assert( dim );
+
+ isNonLinear = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"isNonLinear", False );
+
+ /* Default is to allow zero element contributions - to allow backward compatibility */
+ allowZeroElementContributions = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"allowZeroElementContributions", True );
+
+ _StiffnessMatrix_Init(
+ self,
+ rowVar,
+ colVar,
+ fVector,
+ applicationDepInfo,
+ dim,
+ isNonLinear,
+ allowZeroElementContributions,
+ entryPointRegister,
+ 0 );
+
+ /* Do we need to use the transpose? */
+ self->transRHS = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"transposeRHS", ForceVector, False, data );
+
+ /* Read the matrix type from the dictionary. */
+/* self->shellMatrix = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"matrix", PETScShellMatrix, False, data ); */
+/* if( !self->shellMatrix ) { */
+/* self->useShellMatrix = False; */
+/* } */
+/* else { */
+/* EP_ReplaceAll( self->assembleStiffnessMatrix, StiffnessMatrix_ShellAssembly ); */
+
+/* self->useShellMatrix = True; */
+/* } */
+
+ /* Setup the stream. */
+ stream = Journal_Register( Info_Type, (Name)self->type );
+ if( Dictionary_GetBool_WithDefault( cf->rootDict, (Dictionary_Entry_Key)"watchAll", False ) == True )
+ Stream_SetPrintingRank( stream, STREAM_ALL_RANKS );
+ else {
+ unsigned rankToWatch;
+
+ rankToWatch = Dictionary_GetUnsignedInt_WithDefault( cf->rootDict, "rankToWatch", 0 );
+ Stream_SetPrintingRank( stream, rankToWatch );
+ }
+}
+
+void _StiffnessMatrix_Build( void* stiffnessMatrix, void* data ) {
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+
+ Journal_DPrintf( self->debug, "In %s - for matrix %s\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ /* ensure variables are built */
+ if( self->rowVariable )
+ Stg_Component_Build( self->rowVariable, data, False );
+
+ /* If we don't have a communicator, grab one off the mesh. */
+ if( !self->comm ) {
+ self->comm = Mesh_GetCommTopology( self->rowVariable->feMesh, MT_VERTEX )->mpiComm;
+ Journal_Firewall( (self->comm != 0), self->debug, "Error: NULL Comm provided to \"%s\" %s.\n",
+ self->name, self->type );
+ }
+
+ if( self->columnVariable )
+ Stg_Component_Build( self->columnVariable, data, False );
+
+ /* ensure the rhs vector is built */
+ Stg_Component_Build( self->rhs, data, False );
+
+
+/* if( self->useShellMatrix ) */
+/* Stg_Component_Build( self->shellMatrix, data, False ); */
+
+#if DEBUG
+ if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+ Journal_DPrintf( self->debug, "Row variable(%s) I.D. array calc. as:\n", self->rowVariable->name );
+ FeEquationNumber_PrintDestinationArray( self->rowVariable->eqNum, self->debug );
+ Journal_DPrintf( self->debug, "Column variable(%s) I.D. array calc. as:\n", self->columnVariable->name );
+ FeEquationNumber_PrintDestinationArray( self->columnVariable->eqNum, self->debug );
+ }
+#endif
+
+ /* update the row and column sizes for the variables */
+ self->rowLocalSize = self->rowVariable->eqNum->localEqNumsOwnedCount;
+ assert( self->rowLocalSize );
+ self->colLocalSize = self->columnVariable->eqNum->localEqNumsOwnedCount;
+ assert( self->colLocalSize );
+
+ /* update the number of non zero entries from the finite element variables */
+ StiffnessMatrix_CalcNonZeros( self );
+
+ Journal_DPrintf( self->debug, "row(%s) localSize = %d : col(%s) localSize = %d \n", self->rowVariable->name,
+ self->rowLocalSize, self->columnVariable->name, self->colLocalSize );
+
+ /* assert( self->nonZeroCount ); */
+
+ StiffnessMatrix_RefreshMatrix( self );
+
+ Journal_DPrintf( self->debug, "Matrix allocated.\n" );
+
+ Assembler_SetVariables( self->zeroBCsAsm, self->rowVariable, self->columnVariable );
+ Assembler_SetCallbacks( self->zeroBCsAsm, NULL, StiffnessMatrix_ZeroBCsAsm_RowR, NULL,
+ StiffnessMatrix_ZeroBCsAsm_ColR, NULL,
+ self );
+ Assembler_SetVariables( self->bcAsm, self->rowVariable, self->columnVariable );
+ Assembler_SetCallbacks( self->bcAsm,
+ NULL,
+ NULL, NULL,
+ StiffnessMatrix_BCAsm_ColR, NULL,
+ self );
+ Assembler_SetVariables( self->transBCAsm, self->columnVariable, self->rowVariable );
+ Assembler_SetCallbacks( self->transBCAsm,
+ NULL,
+ NULL, NULL,
+ StiffnessMatrix_TransBCAsm_ColR, NULL,
+ self );
+ if( self->rowVariable == self->columnVariable ) {
+ Assembler_SetVariables( self->diagBCsAsm, self->rowVariable, self->columnVariable );
+ Assembler_SetCallbacks( self->diagBCsAsm,
+ NULL,
+ StiffnessMatrix_DiagBCsAsm_RowR, NULL,
+ NULL, NULL,
+ self );
+ }
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _StiffnessMatrix_Initialise( void* stiffnessMatrix, void* data ) {
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+
+ Journal_DPrintf( self->debug, "In %s - for matrix %s\n", __func__, self->name );
+ /* ensure variables are initialised */
+ if( self->rowVariable )
+ Stg_Component_Initialise( self->rowVariable, data, False );
+
+ if( self->columnVariable )
+ Stg_Component_Initialise( self->columnVariable, data, False );
+
+ /* ensure the rhs vector is built */
+ Stg_Component_Initialise( self->rhs, data, False );
+
+/* if( self->useShellMatrix ) */
+/* Stg_Component_Initialise( self->shellMatrix, data, False ); */
+}
+
+
+void _StiffnessMatrix_Execute( void* stiffnessMatrix, void* data ) {
+}
+
+void _StiffnessMatrix_Destroy( void* stiffnessMatrix, void* data ) {
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+
+ Journal_DPrintf( self->debug, "In %s - for matrix %s\n", __func__, self->name );
+ MatDestroy( self->matrix );
+ FreeObject( self->stiffnessMatrixTermList );
+ FreeArray( self->_assembleStiffnessMatrixEPName );
+ FreeArray( self->diagonalNonZeroIndices );
+ FreeArray( self->offDiagonalNonZeroIndices );
+ FreeObject( self->zeroBCsAsm );
+ FreeObject( self->bcAsm );
+ FreeObject( self->transBCAsm );
+ FreeObject( self->diagBCsAsm );
+ /* Don't delete entry points: E.P. register will delete them automatically */
+ NewClass_Delete( self->rowInc );
+ NewClass_Delete( self->colInc );
+
+
+}
+
+void StiffnessMatrix_CalculateNonZeroEntries( void* stiffnessMatrix ) {
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+
+ self->_calculateNonZeroEntries( self );
+}
+
+void _StiffnessMatrix_CalculateNonZeroEntries( void* stiffnessMatrix ) {
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+ FeMesh* rFeMesh = self->rowVariable->feMesh;
+ FeMesh* cFeMesh = self->columnVariable->feMesh;
+ Dof_EquationNumber currMatrixRow = 0;
+ Node_LocalIndex rowNode_lI = 0;
+ Index activeEqsAtCurrRowNodeCount = 0;
+#ifdef DEBUG
+ unsigned int totalNonZeroEntries = 0;
+#endif
+
+ Journal_DPrintf( self->debug, "In %s - for matrix %s\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ assert ( self->rowVariable );
+ assert ( self->columnVariable );
+
+ Journal_DPrintfL( self->debug, 1, "row nodeLocalCount %d\n", FeMesh_GetNodeLocalSize( rFeMesh ) );
+ Journal_DPrintfL( self->debug, 1, "column nodeLocalCount %d\n", FeMesh_GetNodeLocalSize( cFeMesh ) );
+
+ self->diagonalNonZeroIndices = Memory_Alloc_Array ( Index, self->rowLocalSize, "diagonalNonZeroIndices" );
+ self->offDiagonalNonZeroIndices = Memory_Alloc_Array ( Index, self->rowLocalSize, "offDiagonalNonZeroIndices" );
+ for ( rowNode_lI = 0; rowNode_lI < self->rowLocalSize; rowNode_lI++ ) {
+ self->diagonalNonZeroIndices[rowNode_lI] = 0;
+ self->offDiagonalNonZeroIndices[rowNode_lI] = 0;
+ }
+
+ for( rowNode_lI = 0; rowNode_lI < FeMesh_GetNodeLocalSize( rFeMesh ); rowNode_lI++ ) {
+ _StiffnessMatrix_CalcAndUpdateNonZeroEntriesAtRowNode( self, rowNode_lI, currMatrixRow, activeEqsAtCurrRowNodeCount );
+ }
+
+#ifdef DEBUG
+ for ( rowNode_lI = 0; rowNode_lI < self->rowLocalSize; rowNode_lI++ ) {
+ totalNonZeroEntries += self->diagonalNonZeroIndices[rowNode_lI];
+ totalNonZeroEntries += self->offDiagonalNonZeroIndices[rowNode_lI];
+ }
+
+ Journal_DPrintfL( self->debug, 1, "Calculated %d non-zero entries in Matrix (results in %d bytes storage)\n",
+ totalNonZeroEntries, totalNonZeroEntries * sizeof(double) );
+#endif
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _StiffnessMatrix_CalcAndUpdateNonZeroEntriesAtRowNode(
+ StiffnessMatrix* self,
+ Node_LocalIndex rowNode_lI,
+ Dof_EquationNumber currMatrixRow,
+ Index activeEqsAtCurrRowNode )
+{
+ FeMesh* rFeMesh = self->rowVariable->feMesh;
+ FeMesh* cFeMesh = self->columnVariable->feMesh;
+ DofLayout* colDofLayout = self->columnVariable->dofLayout;
+ FeEquationNumber* rowEqNum = self->rowVariable->eqNum;
+ FeEquationNumber* colEqNum = self->columnVariable->eqNum;
+ Element_Index rowNodeElement_I = 0;
+ Element_DomainIndex element_dI = 0;
+ Node_DomainIndex colNode_dI = 0;
+ Dof_Index colNodeDof_I = 0;
+ Index* countTableToAdjust = 0;
+ Dof_EquationNumber currColEqNum = 0;
+ Node_DomainIndex* uniqueRelatedColNodes = NULL;
+ Node_Index uniqueRelatedColNodesCount = 0;
+ Node_Index uniqueRelatedColNodes_AllocCount = 0;
+ Node_Index uniqueRelatedColNode_I = 0;
+ Dof_Index currNodeDof_I = 0;
+ Dof_EquationNumber currDofMatrixRow = 0;
+ unsigned nNodeInc, *nodeInc;
+
+ Journal_DPrintfL( self->debug, 3, "In %s - for row local node %d\n", __func__, rowNode_lI );
+ Stream_Indent( self->debug );
+
+ FeMesh_GetNodeElements( rFeMesh, rowNode_lI, self->rowInc );
+ nNodeInc = IArray_GetSize( self->rowInc );
+ nodeInc = (unsigned*)IArray_GetPtr( self->rowInc );
+ for ( rowNodeElement_I = 0; rowNodeElement_I < nNodeInc; rowNodeElement_I++ ) {
+ unsigned nElInc;
+
+ /* note the dI (domain index) - some of these elements may be in shadow space */
+ element_dI = nodeInc[rowNodeElement_I];
+
+ nElInc = FeMesh_GetElementNodeSize( cFeMesh, element_dI );
+ uniqueRelatedColNodes_AllocCount += nElInc;
+ }
+
+ Journal_DPrintfL( self->debug, 3, "Calculated the max possible number of unique related nodes as %d\n",
+ uniqueRelatedColNodes_AllocCount );
+ uniqueRelatedColNodes = Memory_Alloc_Array( Node_DomainIndex, uniqueRelatedColNodes_AllocCount, "uniqueRelatedColNodes" );
+
+ _StiffnessMatrix_CalculatedListOfUniqueRelatedColNodes( self, rowNode_lI, uniqueRelatedColNodes, &uniqueRelatedColNodesCount);
+
+ Journal_DPrintfL( self->debug, 3, "Searching the %d unique related col nodes for active dofs\n",
+ uniqueRelatedColNodesCount );
+ Stream_Indent( self->debug );
+ for ( uniqueRelatedColNode_I = 0; uniqueRelatedColNode_I < uniqueRelatedColNodesCount; uniqueRelatedColNode_I++ ) {
+ colNode_dI = uniqueRelatedColNodes[uniqueRelatedColNode_I];
+
+ Journal_DPrintfL( self->debug, 3, "col node_dI %d: has %d dofs\n", colNode_dI, colDofLayout->dofCounts[colNode_dI] );
+ Stream_Indent( self->debug );
+ for ( colNodeDof_I = 0; colNodeDof_I < colDofLayout->dofCounts[colNode_dI]; colNodeDof_I++ ) {
+
+ currColEqNum = colEqNum->destinationArray[colNode_dI][colNodeDof_I];
+ Journal_DPrintfL( self->debug, 3, "dof %d: ", colNodeDof_I );
+ if ( currColEqNum == -1 ) {
+ Journal_DPrintfL( self->debug, 3, "is a BC.\n" );
+ }
+ else {
+ if( STreeMap_HasKey( colEqNum->ownedMap, &currColEqNum ) ) {
+ Journal_DPrintfL( self->debug, 3, "is diagonal (eq %d)\n", currColEqNum );
+ countTableToAdjust = self->diagonalNonZeroIndices;
+ }
+ else {
+ Journal_DPrintfL( self->debug, 3, "is off-diagonal (eq %d)\n", currColEqNum );
+ countTableToAdjust = self->offDiagonalNonZeroIndices;
+ }
+
+ for ( currNodeDof_I = 0; currNodeDof_I < self->rowVariable->dofLayout->dofCounts[rowNode_lI]; currNodeDof_I++) {
+ if ( -1 != rowEqNum->destinationArray[rowNode_lI][currNodeDof_I] ) {
+ currDofMatrixRow = *(int*)STreeMap_Map(
+ rowEqNum->ownedMap,
+ rowEqNum->destinationArray[rowNode_lI] + currNodeDof_I );
+
+ /* Because of periodic BCs, the eq num may be lower than the normal
+ * lowest held on this processor, so we need to check this */
+ if ( currDofMatrixRow >= self->rowLocalSize ) {
+ Journal_DPrintfL( self->debug, 3, "Found currDofMatRow(=%d) >= self->rowLocalSize(=%d) : for "
+ "rowNode_lI=%d, currMatRow=%d, colNode_dI=%d, colNodeDof_I = %d, "
+ "currNodeDof_I = %d\n", currDofMatrixRow,
+ self->rowLocalSize, rowNode_lI, currMatrixRow,
+ colNode_dI, colNodeDof_I, currNodeDof_I );
+ }
+ else if ( currDofMatrixRow < 0 ) {
+ Journal_DPrintfL( self->debug, 3, "Found currDofMatRow(=%d) < 0 : for "
+ "rowNode_lI=%d, currMatRow=%d, colNode_dI=%d, colNodeDof_I = %d, "
+ "currNodeDof_I = %d\n", currDofMatrixRow,
+ rowNode_lI, currMatrixRow,
+ colNode_dI, colNodeDof_I, currNodeDof_I );
+ }
+ else {
+ Journal_DPrintfL( self->debug, 3, "(incrementing app. count at row %d)\n",
+ currDofMatrixRow );
+
+ countTableToAdjust[ currDofMatrixRow ] += 1;
+ }
+ }
+ }
+ }
+ }
+ Stream_UnIndent( self->debug );
+ }
+ Stream_UnIndent( self->debug );
+
+ Journal_DPrintfL( self->debug, 3, "diagonal count\t%d off diagonal count\t%d\n",
+ self->diagonalNonZeroIndices[currMatrixRow], self->offDiagonalNonZeroIndices[currMatrixRow]);
+
+ Memory_Free( uniqueRelatedColNodes );
+
+/* TODO: do we need to check that diag is set to at least 1, as the PETSc webpage on MatCreate_MPIAIJ suggests? */
+
+ Stream_UnIndent( self->debug );
+}
+
+
+void _StiffnessMatrix_CalculatedListOfUniqueRelatedColNodes(
+ StiffnessMatrix* self,
+ Node_LocalIndex rowNode_lI,
+ Node_DomainIndex* uniqueRelatedColNodes,
+ Node_Index* uniqueRelatedColNodesCountPtr )
+{
+ FeMesh* rFeMesh = self->rowVariable->feMesh;
+ FeMesh* cFeMesh = self->columnVariable->feMesh;
+ Element_Index rowNodeElement_I = 0;
+ Element_DomainIndex element_dI = 0;
+ Node_Index colElLocalNode_I = 0;
+ Node_DomainIndex colNode_dI = 0;
+ Node_Index uniqueRelatedColNode_I = 0;
+ unsigned nNodeInc, *nodeInc;
+
+ FeMesh_GetNodeElements( rFeMesh, rowNode_lI, self->rowInc );
+ nNodeInc = IArray_GetSize( self->rowInc );
+ nodeInc = (unsigned*)IArray_GetPtr( self->rowInc );
+ Journal_DPrintfL( self->debug, 3, "Searching the %d elements this node belongs to for unique related col nodes:\n",
+ nNodeInc );
+
+ Stream_Indent( self->debug );
+ for ( rowNodeElement_I = 0; rowNodeElement_I < nNodeInc; rowNodeElement_I++ ) {
+ unsigned nElInc, *elInc;
+
+ /* note the dI (domain index) - some of these elements may be in shadow space */
+ element_dI = nodeInc[rowNodeElement_I];
+
+ Journal_DPrintfL( self->debug, 3, "rowNodeElement_I: ", rowNodeElement_I );
+ Journal_DPrintfL( self->debug, 3, "domain element %d\n", element_dI );
+
+ Stream_Indent( self->debug );
+ FeMesh_GetElementNodes( cFeMesh, element_dI, self->colInc );
+ nElInc = IArray_GetSize( self->colInc );
+ elInc = (unsigned*)IArray_GetPtr( self->colInc );
+ Journal_DPrintfL( self->debug, 3, "Searching the %d column var nodes in this el:\n", nElInc );
+ for ( colElLocalNode_I =0; colElLocalNode_I < nElInc; colElLocalNode_I++ ) {
+ colNode_dI = elInc[colElLocalNode_I];
+
+ Journal_DPrintfL( self->debug, 3, "Col domain node %d: ", colNode_dI );
+ for ( uniqueRelatedColNode_I = 0; uniqueRelatedColNode_I < (*uniqueRelatedColNodesCountPtr); uniqueRelatedColNode_I++ )
+ {
+ if ( colNode_dI == uniqueRelatedColNodes[uniqueRelatedColNode_I] ) {
+ Journal_DPrintfL( self->debug, 3, "already in list -> skip to next.\n" );
+ break;
+ }
+ }
+ if ( uniqueRelatedColNode_I == (*uniqueRelatedColNodesCountPtr) ) {
+ Journal_DPrintfL( self->debug, 3, "is unique so far -> add to list.\n" );
+ uniqueRelatedColNodes[uniqueRelatedColNode_I] = colNode_dI;
+ (*uniqueRelatedColNodesCountPtr)++;
+ }
+ }
+ Stream_UnIndent( self->debug );
+ }
+ Stream_UnIndent( self->debug );
+}
+
+
+void StiffnessMatrix_Assemble( void* stiffnessMatrix, Bool bcRemoveQuery, void* _sle, void* _context ) {
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+ int ii;
+
+ StiffnessMatrix_RefreshMatrix( self );
+
+ Journal_DPrintf( self->debug, "In %s - for matrix \"%s\" - calling the \"%s\" E.P.\n", __func__, self->name,
+ self->assembleStiffnessMatrix->name );
+ /* Call the Entry point directly from the base class */
+ /* Note that it may be empty: this is deliberate. */
+ ((FeEntryPoint_AssembleStiffnessMatrix_CallFunction*)EntryPoint_GetRun( self->assembleStiffnessMatrix ))(
+ self->assembleStiffnessMatrix,
+ self,
+ bcRemoveQuery,
+ _sle,
+ _context );
+
+ /* Run all the modify callbacks. */
+ for( ii = 0; ii < self->nModifyCBs; ii++ ) {
+ void* callback = self->modifyCBs[ii].callback;
+ void* object = self->modifyCBs[ii].object;
+ ((void(*)(void*))callback)( object );
+ }
+}
+
+
+void StiffnessMatrix_GlobalAssembly_General( void* stiffnessMatrix, Bool bcRemoveQuery, void* _sle, void* _context )
+{
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+ SystemLinearEquations* sle = (SystemLinearEquations*)_sle;
+ FiniteElementContext* context = (FiniteElementContext*)_context;
+
+ FeVariable* feVars[MAX_FE_VARS]; /* Set later */
+ Index numFeVars = 2;
+ Index feVar_I;
+
+ /* Location Matrix for a single element - may be a ptr into full LM array */
+ Dof_EquationNumber** elementLM[MAX_FE_VARS];
+ /* Number of dofs at an element: required for matrix assembly */
+ Dof_Index* totalDofsThisElement[MAX_FE_VARS];
+ Dof_Index* totalDofsPrevElement[MAX_FE_VARS];
+ /* The actual element stiffness matrix values, per element: filled in by this class's entry point */
+ double** elStiffMatToAdd = NULL;
+
+ /* counts and indices used in building per-element locationMatrix and BC info */
+ Element_LocalIndex nLocalElements;
+ Element_LocalIndex element_lI;
+ Node_ElementLocalIndex nodeCountThisEl;
+ /* Shortcut to node IDs at a particular element */
+ Element_Nodes nodeIdsThisEl;
+
+ /* related to correction of BCs */
+ Bool makeBC_Corrections_row = False;
+ Bool modifiedRHS_Vec_cont = False;
+ Dof_Index* bcLM_Id[ MAX_FE_VARS ] = { NULL, NULL };
+ double* bcValues[ MAX_FE_VARS ] = { NULL, NULL };
+ int nBC_NodalDof[ MAX_FE_VARS ] = { 0, 0 };
+ double* h2Add = NULL;
+
+ /* For output printing */
+ double outputPercentage = 10; /* Controls how often to give a status update of assembly progress*/
+ int outputInterval;
+ double startTime, totalTime;
+ double matAddingStart;
+ double matAddingTime = 0;
+ double elStiffMatBuildStart;
+ double elStiffMatBuildTime = 0;
+ Bool updateRHS;
+ MPI_Comm comm;
+
+/* Mat matrix = ( self->useShellMatrix ) ? self->shellMatrix->matrix : self->matrix; */
+ Mat matrix = self->matrix;
+
+ /* Do some type checking */
+ assert( !sle || Stg_CheckType( sle, SystemLinearEquations ) );
+ assert( self->rhs || self->transRHS );
+
+ feVars[0] = self->rowVariable;
+ feVars[1] = self->columnVariable;
+
+ /* Get communicator. */
+ comm = Mesh_GetCommTopology( feVars[0]->feMesh, MT_VERTEX )->mpiComm;
+
+ startTime = MPI_Wtime();
+
+ Journal_DPrintf( self->debug, "In %s - for matrix \"%s\"\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ Journal_Firewall( Stg_ObjectList_Count( self->stiffnessMatrixTermList ) != 0,
+ Journal_Register( Error_Type, (Name)self->type ),
+ "Error in func %s for %s '%s' - No StiffnessMatrixTerms registered.\n",
+ __func__, self->type, self->name );
+
+ totalDofsThisElement[ROW_VAR] = Memory_Alloc( Dof_Index, "el nodal dofs" );
+ totalDofsPrevElement[ROW_VAR] = Memory_Alloc( Dof_Index, "el nodal dofs (prev element)" );
+ *totalDofsPrevElement[ROW_VAR] = 0;
+ /* check if row variable and col variable are the same */
+ if ( self->rowVariable == self->columnVariable ) {
+ numFeVars = 1;
+ Journal_DPrintfL( self->debug, 2, "Detected both row and column FeVariable to assemble over are \"%s\", "
+ "so only processing once per element.\n", self->rowVariable->name );
+ /* since Row and Col FeVars are same, set LM_col and totalDofsThisElement to be same as row ones */
+ totalDofsThisElement[COL_VAR] = totalDofsThisElement[ROW_VAR];
+ totalDofsPrevElement[COL_VAR] = totalDofsPrevElement[ROW_VAR];
+ }
+ else {
+ Journal_DPrintfL( self->debug, 2, "Since row FeVariable \"%s\" and column FeVariable \"%s\" to assemble over "
+ "are different, processing both per element.\n", self->rowVariable->name, self->columnVariable->name );
+ totalDofsThisElement[COL_VAR] = Memory_Alloc( Dof_Index, "el nodal dofs (col)" );
+ totalDofsPrevElement[COL_VAR] = Memory_Alloc( Dof_Index, "el nodal dofs (col) (prev element)" );
+ *totalDofsPrevElement[COL_VAR] = 0;
+ }
+
+ /* Assumes that both row and col variables have same number of variables */
+ nLocalElements = FeMesh_GetElementLocalSize( feVars[ROW_VAR]->feMesh );
+
+ /* Initialise matrix */
+ MatZeroEntries( matrix );
+
+ outputInterval = (int)( (outputPercentage/100.0)*(double)(nLocalElements) );
+ if( outputInterval == 0 ) { outputInterval = nLocalElements; }
+
+ for( element_lI = 0; element_lI < nLocalElements; element_lI++ ) {
+
+ /* This loop is how we handle the possiblity of different row-column variables: if both variables are
+ * the same, then numFeVars is set to 1 and the loop only progresses through once.
+ -- PatrickSunter 13 September 2004 */
+ for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
+ FeEquationNumber* feEqNum = feVars[feVar_I]->eqNum;
+ DofLayout* dofLayout = feVars[feVar_I]->dofLayout;
+ Dof_Index dofCountLastNode;
+ unsigned nDofsThisEl;
+ unsigned n_i;
+
+ /* Get the local node ids */
+ FeMesh_GetElementNodes( feVars[feVar_I]->feMesh, element_lI,
+ self->rowInc );
+ nodeCountThisEl = IArray_GetSize( self->rowInc );
+ nodeIdsThisEl = (unsigned*)IArray_GetPtr( self->rowInc );
+
+ /* Set value of elementLM: will automatically use large one if built */
+ elementLM[feVar_I] = FeEquationNumber_BuildOneElementLocationMatrix( feEqNum, element_lI );
+
+ /* work out number of dofs at the node, based on LM */
+ dofCountLastNode = dofLayout->dofCounts[nodeIdsThisEl[nodeCountThisEl-1]];
+ nDofsThisEl = dofLayout->dofCounts[nodeIdsThisEl[0]];
+ for( n_i = 1; n_i < nodeCountThisEl; n_i++ )
+ nDofsThisEl += dofLayout->dofCounts[nodeIdsThisEl[n_i]];
+ *totalDofsThisElement[feVar_I] = nDofsThisEl;
+/*
+ *totalDofsThisElement[feVar_I] = &elementLM[feVar_I][nodeCountThisEl-1][dofCountLastNode-1]
+ - &elementLM[feVar_I][0][0] + 1;
+*/
+
+ if ( *totalDofsThisElement[feVar_I] > *totalDofsPrevElement[feVar_I] ) {
+ Journal_DPrintfL( self->debug, 2, "Reallocating bcLM_Id and bcValues for fe var \"%s\" "
+ "to size %d\n", feVars[feVar_I]->name, *totalDofsThisElement[feVar_I] );
+
+ if ( bcLM_Id[feVar_I] ) Memory_Free( bcLM_Id[feVar_I] );
+ bcLM_Id[feVar_I] = Memory_Alloc_Array( Dof_Index, *totalDofsThisElement[feVar_I], "bcLM_Id" );
+
+ if ( bcValues[feVar_I] ) Memory_Free( bcValues[feVar_I] );
+ bcValues[feVar_I] = Memory_Alloc_Array( double, *totalDofsThisElement[feVar_I], "bcValues" );
+ }
+ }
+
+ /* Reallocate el stiff mat and other arrays if necessary */
+ if ( (*totalDofsThisElement[ROW_VAR] != *totalDofsPrevElement[ROW_VAR]) ||
+ (*totalDofsThisElement[COL_VAR] != *totalDofsPrevElement[COL_VAR]) )
+ {
+ if (h2Add) Memory_Free( h2Add );
+ Journal_DPrintfL( self->debug, 2, "Reallocating h2Add to size %d\n",
+ *totalDofsThisElement[COL_VAR] );
+ h2Add = Memory_Alloc_Array( double, *totalDofsThisElement[COL_VAR], "h2Add" );
+
+ if (elStiffMatToAdd) Memory_Free( elStiffMatToAdd );
+ Journal_DPrintfL( self->debug, 2, "Reallocating elStiffMatToAdd to size %d*%d\n",
+ *totalDofsThisElement[ROW_VAR], *totalDofsThisElement[COL_VAR] );
+ elStiffMatToAdd = Memory_Alloc_2DArray( double, *totalDofsThisElement[ROW_VAR], *totalDofsThisElement[COL_VAR], (Name)"elStiffMatToAdd" );
+ }
+
+ /* Initialise the elStiffMat to zero */
+ /* Note we have to dereference the ptr once ... so we don't clobber the ptrs, just the values */
+ memset( elStiffMatToAdd[0], 0, sizeof(double) * *totalDofsThisElement[ROW_VAR] * *totalDofsThisElement[COL_VAR] );
+
+ /* Assemble this element's element stiffness matrix: call the entry point */
+ elStiffMatBuildStart = MPI_Wtime();
+ StiffnessMatrix_AssembleElement( self, element_lI, sle, context, elStiffMatToAdd );
+ elStiffMatBuildTime += MPI_Wtime() - elStiffMatBuildStart;
+ if ( False == self->allowZeroElementContributions ) {
+ StiffnessMatrix_CheckElementAssembly( self, element_lI, elStiffMatToAdd, *totalDofsThisElement[ROW_VAR],
+ *totalDofsThisElement[COL_VAR] );
+ }
+
+ /* This loop is how we handle the possiblity of different row-column variables: if both variables are
+ * the same, then numFeVars is set to 1 and the loop only progresses through once.
+ -- PatrickSunter 13 September 2004 */
+ for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
+ /* Reset from previous calculation */
+ nBC_NodalDof[feVar_I] = 0;
+ makeBC_Corrections_row = False;
+
+ /* Check if we want to build table of corrected BC info for the matrix */
+ if( bcRemoveQuery == True ) {
+ unsigned nNodeInc, *nodeInc;
+
+ FeMesh_GetElementNodes( feVars[feVar_I]->feMesh, element_lI,
+ self->rowInc );
+ nNodeInc = IArray_GetSize( self->rowInc );
+ nodeInc = (unsigned*)IArray_GetPtr( self->rowInc );
+ _StiffnessMatrix_UpdateBC_CorrectionTables(
+ self,
+ feVars[feVar_I]->eqNum,
+ feVars[feVar_I]->dofLayout,
+ elementLM[feVar_I],
+ nNodeInc,
+ nodeInc,
+ bcLM_Id[feVar_I],
+ bcValues[feVar_I],
+ &(nBC_NodalDof[feVar_I]) );
+ }
+ }
+
+ /* If there is only one feVar, use the same LM for both row and col insertion */
+ if ( numFeVars == 1 ) elementLM[COL_VAR] = elementLM[ROW_VAR];
+
+/*
+ #if DEBUG
+ if ( Stream_IsPrintableLevel( self->debug, 3 ) ) {
+ Journal_DPrintf( self->debug, "Handling Element %d:\n", element_lI );
+ for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
+ FeEquationNumber_PrintElementLocationMatrix( feVars[feVar_I]->eqNum,
+ elementLM[feVar_I], element_lI, self->debug );
+
+ }
+
+ Journal_DPrintf( self->debug, "El stiff Mat about to be added:\n" );
+ _StiffnessMatrix_PrintElementStiffnessMatrix( self, element_lI, elementLM[ROW_VAR],
+ elementLM[COL_VAR], elStiffMatToAdd );
+ }
+ #endif
+*/
+
+
+ /*
+ ** Need to make corrections to the RHS before filling in the matrix. This is because we may modify the
+ ** element matrix values before they get there.
+ */
+
+ /* Set flag for making corrcetions to rhs from bc's */
+ if( nBC_NodalDof[ROW_VAR] != 0 ) {
+ makeBC_Corrections_row = True;
+ modifiedRHS_Vec_cont = True; /* this guy only needs to be toggled once */
+ }
+
+ if( makeBC_Corrections_row == True && bcRemoveQuery ) {
+ _StiffnessMatrix_CorrectForceVectorWithOneElementsBoundaryConditions(
+ self,
+ elementLM,
+ h2Add,
+ elStiffMatToAdd,
+ totalDofsThisElement,
+ bcLM_Id,
+ bcValues,
+ nBC_NodalDof[ROW_VAR],
+ element_lI );
+ }
+
+ /*
+ ** If not keeping BCs in, we may need to zero some of these element values, or set them to one.
+ */
+
+ if( (!self->rowVariable || !self->rowVariable->eqNum->removeBCs) &&
+ (!self->columnVariable || !self->columnVariable->eqNum->removeBCs) )
+ {
+ FeEquationNumber* rowEqNum = self->rowVariable->eqNum;
+ FeEquationNumber* colEqNum = self->columnVariable->eqNum;
+ unsigned nRows = *totalDofsThisElement[ROW_VAR];
+ unsigned row_i;
+
+ /* Loop over elementLM rows */
+ for( row_i = 0; row_i < nRows; row_i++ ) {
+ unsigned rowEqInd;
+
+ rowEqInd = *(int*)STreeMap_Map( rowEqNum->ownedMap,
+ elementLM[ROW_VAR][0] + row_i );
+
+ /* If row is bc */
+ if( STree_Has( rowEqNum->bcEqNums, &rowEqInd ) ) {
+ unsigned nCols = *totalDofsThisElement[COL_VAR];
+ unsigned col_i;
+
+ /* Loop over elementLM cols */
+ for( col_i = 0; col_i < nCols; col_i++ ) {
+ unsigned colEqInd;
+
+ colEqInd = *(int*)STreeMap_Map( colEqNum->ownedMap,
+ elementLM[COL_VAR][0] + col_i );
+
+ /* If col is bc */
+ if( STree_Has( colEqNum->bcEqNums, &colEqInd ) ) {
+ elStiffMatToAdd[0][row_i * nCols + col_i] = 0.0;
+ }
+ else {
+ elStiffMatToAdd[0][row_i * nCols + col_i] = 0.0;
+ }
+ }
+ }
+ else {
+ unsigned nCols = *totalDofsThisElement[COL_VAR];
+ unsigned col_i;
+
+ for( col_i = 0; col_i < nCols; col_i++ ) {
+ unsigned colEqInd = elementLM[COL_VAR][0][col_i];
+
+ /* If col is bc */
+ if( STree_Has( colEqNum->bcEqNums, &colEqInd ) ) {
+ elStiffMatToAdd[0][row_i * nCols + col_i] = 0.0;
+ }
+ }
+ }
+ }
+ }
+
+ /* Add to the global matrix. */
+ matAddingStart = MPI_Wtime();
+ MatSetValues( matrix, *totalDofsThisElement[ROW_VAR], elementLM[ROW_VAR][0], *totalDofsThisElement[COL_VAR],
+ elementLM[COL_VAR][0], elStiffMatToAdd[0], ADD_VALUES );
+ matAddingTime += MPI_Wtime() - matAddingStart;
+
+
+#if DEBUG
+ if( element_lI % outputInterval == 0 ) {
+ Journal_DPrintfL( self->debug, 2, "done %d percent of global element stiffness assembly (general) \n",
+ (int)(100.0*((double)element_lI/(double)nLocalElements)) );
+ }
+#endif
+
+ for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
+ /* Save the number of dofs in this element */
+ *totalDofsPrevElement[feVar_I] = *totalDofsThisElement[feVar_I];
+ /* If we haven't built the big LM for all elements, free the temporary one */
+ if ( False == feVars[feVar_I]->eqNum->locationMatrixBuilt ) {
+ Memory_Free( elementLM[feVar_I] );
+ }
+ }
+ }
+
+/* //////////////////////////////////////////////////////// */
+ MatAssemblyBegin( matrix, MAT_FINAL_ASSEMBLY );
+ MatAssemblyEnd( matrix, MAT_FINAL_ASSEMBLY );
+
+ MPI_Allreduce( &modifiedRHS_Vec_cont, &updateRHS, 1, MPI_UNSIGNED, MPI_LOR, comm );
+ if( updateRHS == True && bcRemoveQuery ) {
+ /* stuff was submitted to vec (at least once) and needs to be assembled */
+ VecAssemblyBegin( self->rhs->vector );
+ VecAssemblyEnd( self->rhs->vector );
+ }
+/* //////////////////////////////////////////////////////// */
+
+ /*
+ ** If keeping BCs in, modify the RHS to reflect BCs.
+ */
+
+ if( (!self->rowVariable || !self->rowVariable->eqNum->removeBCs) &&
+ (!self->columnVariable || !self->columnVariable->eqNum->removeBCs) )
+ {
+ FeEquationNumber* colEqNum = self->columnVariable->eqNum;
+ FeMesh* feMesh = self->columnVariable->feMesh;
+ DofLayout* dofLayout = self->columnVariable->dofLayout;
+ unsigned nNodes = FeMesh_GetNodeLocalSize( feMesh );
+ unsigned node_i;
+
+ /* What to do if they aren't the same? */
+ assert( self->rowVariable == self->columnVariable );
+
+ for( node_i = 0; node_i < nNodes; node_i++ ) {
+ unsigned nDofs = dofLayout->dofCounts[node_i];
+ unsigned dof_i;
+
+ for( dof_i = 0; dof_i < nDofs; dof_i++ ) {
+ unsigned eqInd = colEqNum->destinationArray[node_i][dof_i];
+ int localEq;
+
+ localEq = *(int*)STreeMap_Map( colEqNum->ownedMap, &eqInd );
+ if( STree_Has( colEqNum->bcEqNums, &localEq ) ) {
+ double bcVal = DofLayout_GetValueDouble( dofLayout, node_i, dof_i );
+ double one = 1.0;
+
+ VecSetValues( self->rhs->vector, 1, (PetscInt*)(&eqInd), &bcVal, INSERT_VALUES );
+ MatSetValues( matrix, 1, (PetscInt*)(&eqInd), 1, (PetscInt*)(&eqInd), &one, INSERT_VALUES );
+ }
+ }
+ }
+
+ /* Need to reassemble. */
+ MatAssemblyBegin( matrix, MAT_FINAL_ASSEMBLY );
+ MatAssemblyEnd( matrix, MAT_FINAL_ASSEMBLY );
+ VecAssemblyBegin( self->rhs->vector );
+ VecAssemblyEnd( self->rhs->vector );
+ }
+
+ for ( feVar_I = 0; feVar_I < numFeVars; feVar_I++ ) {
+ Memory_Free( totalDofsThisElement[feVar_I] );
+ Memory_Free( totalDofsPrevElement[feVar_I] );
+ Memory_Free( bcLM_Id[feVar_I] );
+ Memory_Free( bcValues[feVar_I] );
+ }
+ Memory_Free( elStiffMatToAdd );
+ Memory_Free( h2Add );
+
+ totalTime = MPI_Wtime() - startTime;
+ Journal_DPrintfL( self->debug, 2, "Total time used by %s: %.5g s\n", __func__, totalTime );
+ Journal_DPrintfL( self->debug, 2, "Of which %.5g s spend building elStiffMats\n", elStiffMatBuildTime );
+ Journal_DPrintfL( self->debug, 2, "And %.5g s spend adding to global matrix\n", matAddingTime );
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+
+void _make_dirichlet_corrections_to_rhs(
+ int nr, int rows_to_keep[],
+ int nc, int cols_to_keep[],
+ double **ke, int n_cols, double bc_vals[],
+ double rhs[] )
+{
+ int i,j,I,J;
+
+ for( i=0; i<nr; i++ ) {
+ I = rows_to_keep[i];
+ rhs[I] = 0.0;
+
+ for( j=0; j<nc; j++ ) {
+ J = cols_to_keep[j];
+ rhs[I] = rhs[I] - ke[I][J] * bc_vals[J];
+ }
+ }
+
+}
+
+void _make_dirichlet_corrections_to_rhs_transpose(
+ int nr, int rows_to_keep[],
+ int nc, int cols_to_keep[],
+ double **ke, int n_cols,
+ double bc_vals[], double rhs[] )
+{
+ int i,j,I,J;
+
+ for( i=0; i<nr; i++ ) {
+ I = rows_to_keep[i];
+ rhs[I] = 0.0;
+
+ for( j=0; j<nc; j++ ) {
+ J = cols_to_keep[j];
+
+ rhs[I] = rhs[I] - ke[J][I] * bc_vals[J];
+ }
+ }
+
+}
+
+#define LEOrder( i,i_d,i_dof ) ( (i)*(i_dof) + (i_d) )
+void _get_bc_values( FeVariable *colVar, int npe, int ndof, int el_nodes[], double bc_vals[] )
+{
+ double bc;
+ int n, d, n_i;
+
+ for( n=0; n<npe; n++ ) {
+ n_i = el_nodes[n];
+ for( d=0; d<ndof; d++ ) {
+ /* query node index to see if it is has a dirichlet boundary condition */
+ if( FeVariable_IsBC( colVar, n_i, d) == True ) {
+ bc = DofLayout_GetValueDouble( colVar->dofLayout, n_i, d );
+ bc_vals[ LEOrder(n,d,ndof) ] = bc;
+ }
+ /* end bc query */
+ }
+ }
+}
+
+struct StiffMatAss_Log {
+ char *ass_type; /* one of { OPERATOR_ONLY, OPERATOR_WITH_BC_CORRECTIONS, OPERATOR_WITH_BC_CORRECTIONS_FROM_OP_TRANS, OP_BC_CORRECTIONS_ONLY, OP_BC_CORRECTIONS_FROM_OP_TRANS_ONLY } */
+ double total_TIME;
+ double cumulative_el_stiff_mat_ass_TIME;
+ double parallel_assembly_TIME;
+ double element_insertion_TIME;
+ int nr, nc;
+ int local_nr, local_nc;
+ int elements_assembled_for_bc_correction;
+ int elements_assembled;
+
+ /* local timer info */
+ double dt_element_assembly, dt_total, dt_parallel_assembly, dt_el_insert;
+ double t0_element_assembly, t0_total, t0_parallel_assembly, t0_el_insert;
+};
+
+#define StiffMatAssLog_UpdateElementsAssembled( log ) (log)->elements_assembled++
+#define StiffMatAssLog_UpdateElementsAssembledForBC_Corrections( log ) (log)->elements_assembled_for_bc_correction++
+#define StiffMatAssLog_InitTimer_TotalTime( log ) (log)->t0_total = MPI_Wtime()
+#define StiffMatAssLog_InitTimer_ElementAssembly( log ) (log)->t0_element_assembly = MPI_Wtime()
+#define StiffMatAssLog_InitTimer_ParallelAssembly( log ) (log)->t0_parallel_assembly = MPI_Wtime()
+#define StiffMatAssLog_InitTimer_ElementInsertion( log ) (log)->t0_el_insert = MPI_Wtime()
+
+inline void StiffMatAssLog_AccumulateTime_Total( struct StiffMatAss_Log *log )
+{
+ log->dt_total = MPI_Wtime() - log->t0_total;
+ log->total_TIME = log->total_TIME + log->dt_total;
+}
+
+inline void StiffMatAssLog_AccumulateTime_ElementAssembly( struct StiffMatAss_Log* log )
+{
+ log->dt_element_assembly = MPI_Wtime() - log->t0_element_assembly;
+ log->cumulative_el_stiff_mat_ass_TIME = log->cumulative_el_stiff_mat_ass_TIME + log->dt_element_assembly;
+}
+
+
+inline void StiffMatAssLog_AccumulateTime_ParallelAssembly( struct StiffMatAss_Log *log )
+{
+ log->dt_parallel_assembly = MPI_Wtime() - log->t0_parallel_assembly;
+ log->parallel_assembly_TIME = log->parallel_assembly_TIME + log->dt_parallel_assembly;
+}
+
+inline void StiffMatAssLog_AccumulateTime_ElementInsertion( struct StiffMatAss_Log *log )
+{
+ log->dt_el_insert = MPI_Wtime() - log->t0_el_insert;
+ log->element_insertion_TIME = log->element_insertion_TIME + log->dt_el_insert;
+}
+
+inline void StiffMatAssLog_GetOperatorDimensions( struct StiffMatAss_Log *log, Mat matrix )
+{
+ MatGetSize( matrix, (PetscInt*)(&log->nr), (PetscInt*)(&log->nc) );
+ MatGetLocalSize( matrix, (PetscInt*)(&log->local_nr), (PetscInt*)(&log->local_nc) );
+}
+
+void StiffMatAssLog_Delete( struct StiffMatAss_Log** _log )
+{
+ struct StiffMatAss_Log *log = *_log;
+
+ if( log->ass_type != NULL ) free( log->ass_type );
+ free( log );
+ log = NULL;
+
+ *_log = log;
+}
+
+void StiffMatAssLog_Init( struct StiffMatAss_Log *log, const char type_name[] )
+{
+ if( log->ass_type != NULL ) free( log->ass_type );
+ asprintf( &log->ass_type, "%s", type_name );
+
+ /* reset timers and counter */
+ log->total_TIME = 0.0;
+ log->cumulative_el_stiff_mat_ass_TIME = 0.0;
+ log->parallel_assembly_TIME = 0.0;
+ log->element_insertion_TIME = 0.0;
+ log->nr = log->nc = 0;
+ log->local_nr = log->local_nc = 0;
+ log->elements_assembled_for_bc_correction = 0;
+ log->elements_assembled = 0;
+}
+
+struct StiffMatAss_Log* StiffMatAssLog_New( void )
+{
+ struct StiffMatAss_Log *log;
+
+ log = (struct StiffMatAss_Log*)malloc( sizeof(struct StiffMatAss_Log) );
+ log->ass_type = NULL;
+
+ StiffMatAssLog_Init( log, "UNINITIALISED" );
+
+ return log;
+}
+
+
+void StiffMatAssLog_Report_min_max( MPI_Comm comm, double local_val, double *min, double *max )
+{
+ MPI_Reduce ( &local_val, min, 1, MPI_DOUBLE, MPI_MIN, 0, comm );
+ MPI_Reduce ( &local_val, max, 1, MPI_DOUBLE, MPI_MAX, 0, comm );
+}
+
+void StiffMatAssLog_Report_sequential( StiffnessMatrix *self, struct StiffMatAss_Log *log )
+{
+ Journal_PrintfL( self->debug, 1, "GlobalStiffnessMatrix Assembly Report: %s \n", self->name );
+ Journal_PrintfL( self->debug, 1, " Assembly type: %s \n", log->ass_type );
+ Journal_PrintfL( self->debug, 1, " Operator dimensions: %d x %d (global) \n", log->nr, log->nc );
+ Journal_PrintfL( self->debug, 1, " Total time: %6.6e (sec)\n", log->total_TIME );
+ Journal_PrintfL( self->debug, 1, " Assembling element stiffness matrices: %6.6e (sec)\n", log->cumulative_el_stiff_mat_ass_TIME );
+ Journal_PrintfL( self->debug, 1, " Parallel assembly: %6.6e (sec)\n", log->parallel_assembly_TIME );
+ Journal_PrintfL( self->debug, 1, " Element insertion: %6.6e (sec)\n", log->element_insertion_TIME );
+ Journal_PrintfL( self->debug, 1, " Element stiffness matrices assembled for operator: %d \n", log->elements_assembled );
+ Journal_PrintfL( self->debug, 1, " Element stiffness matrices assembled for bc corrections: %d \n", log->elements_assembled_for_bc_correction );
+}
+
+void StiffMatAssLog_Report_parallel( StiffnessMatrix *self, struct StiffMatAss_Log *log )
+{
+ double min, max;
+ int sum_i;
+ MPI_Comm comm = self->comm;
+ int init_stream_rank;
+
+ /* change stream to only print on rank 0 */
+ init_stream_rank = Stream_GetPrintingRank( self->debug );
+ Stream_SetPrintingRank( self->debug, 0 );
+
+ Journal_PrintfL( self->debug, 1, "GlobalStiffnessMatrix Assembly Report: %s \n", self->name );
+ Journal_PrintfL( self->debug, 1, " Assembly type: %s \n", log->ass_type );
+ Journal_PrintfL( self->debug, 1, " Operator dimensions: %d x %d (global) \n", log->nr, log->nc );
+
+ MPI_Reduce ( &log->elements_assembled, &sum_i, 1, MPI_INT, MPI_SUM, 0, comm );
+ Journal_PrintfL( self->debug, 1, " Element stiffness matrices assembled for operator: %d (total) \n", sum_i );
+
+ MPI_Reduce ( &log->elements_assembled_for_bc_correction, &sum_i, 1, MPI_INT, MPI_SUM, 0, comm );
+ Journal_PrintfL( self->debug, 1, " Element stiffness matrices assembled for bc corrections: %d (total) \n", sum_i );
+
+ Journal_PrintfL( self->debug, 1, " min / max (sec)\n" );
+
+ StiffMatAssLog_Report_min_max( comm, log->total_TIME, &min, &max );
+ Journal_PrintfL( self->debug, 1, " Total time: %6.6e / %6.6e (sec)\n", min, max );
+
+ StiffMatAssLog_Report_min_max( comm, log->cumulative_el_stiff_mat_ass_TIME, &min, &max );
+ Journal_PrintfL( self->debug, 1, " Assembling element stiffness matrices: %6.6e / %6.6e (sec)\n", min, max );
+
+ StiffMatAssLog_Report_min_max( comm, log->parallel_assembly_TIME, &min, &max );
+ Journal_PrintfL( self->debug, 1, " Parallel assembly: %6.6e / %6.6e (sec)\n", min, max );
+
+ StiffMatAssLog_Report_min_max( comm, log->element_insertion_TIME, &min, &max );
+ Journal_PrintfL( self->debug, 1, " Element insertion: %6.6e / %6.6e (sec)\n", min, max );
+
+
+ /* reset printing rank of stream */
+ Stream_SetPrintingRank( self->debug, init_stream_rank );
+}
+
+void StiffMatAssLog_Report( StiffnessMatrix *self, struct StiffMatAss_Log *log )
+{
+ int size;
+
+ MPI_Comm_size( self->comm, &size );
+ if( size == 1 ) {
+ StiffMatAssLog_Report_sequential( self, log );
+ }
+ else {
+ StiffMatAssLog_Report_parallel( self, log );
+ }
+}
+
+
+void _StiffMatAss( struct StiffMatAss_Log *log, void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context ) {
+
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+ SystemLinearEquations* sle = (SystemLinearEquations*)_sle;
+ FeVariable *rowVar, *colVar;
+ FeMesh *rowMesh, *colMesh;
+ FeEquationNumber *rowEqNum, *colEqNum;
+ DofLayout *rowDofs, *colDofs;
+ unsigned nRowEls;
+ unsigned nRowNodes, *rowNodes;
+ unsigned nColNodes, *colNodes;
+ unsigned maxDofs, maxRCDofs, nDofs, nRowDofs, nColDofs;
+ double** elStiffMat;
+/* Mat matrix = ( self->useShellMatrix ) ? self->shellMatrix->matrix : self->matrix; */
+ Mat matrix = self->matrix;
+ unsigned e_i, n_i;
+
+ int c_dof, r_dof;
+
+ assert( self && Stg_CheckType( self, StiffnessMatrix ) );
+
+ StiffMatAssLog_Init( log, "OPERATOR_ONLY" );
+ StiffMatAssLog_InitTimer_TotalTime( log );
+
+ rowVar = self->rowVariable;
+ colVar = self->columnVariable ? self->columnVariable : rowVar;
+ rowEqNum = rowVar->eqNum;
+ colEqNum = colVar->eqNum;
+ rowMesh = rowVar->feMesh;
+ colMesh = colVar->feMesh;
+ rowDofs = rowVar->dofLayout;
+ colDofs = colVar->dofLayout;
+ nRowEls = FeMesh_GetElementLocalSize( rowMesh );
+ assert( (rowVar == colVar) ? !self->transRHS : 1 );
+
+ //matrix = self->matrix;
+ elStiffMat = NULL;
+ maxDofs = 0;
+
+
+
+ StiffMatAssLog_GetOperatorDimensions( log, matrix );
+ /* Begin assembling each element. */
+ for( e_i = 0; e_i < nRowEls; e_i++ ) {
+ FeMesh_GetElementNodes( rowMesh, e_i, self->rowInc );
+ nRowNodes = IArray_GetSize( self->rowInc );
+ rowNodes = (unsigned*)IArray_GetPtr( self->rowInc );
+ FeMesh_GetElementNodes( colMesh, e_i, self->colInc );
+ nColNodes = IArray_GetSize( self->colInc );
+ colNodes = (unsigned*)IArray_GetPtr( self->colInc );
+
+ /* Do we need more space to assemble this element? */
+ nRowDofs = 0;
+ for( n_i = 0; n_i < nRowNodes; n_i++ ) {
+ nRowDofs += rowDofs->dofCounts[rowNodes[n_i]];
+ r_dof = rowDofs->dofCounts[rowNodes[n_i]];
+ }
+ nColDofs = 0;
+ for( n_i = 0; n_i < nColNodes; n_i++ ) {
+ nColDofs += colDofs->dofCounts[colNodes[n_i]];
+ c_dof = colDofs->dofCounts[colNodes[n_i]];
+ }
+ nDofs = nRowDofs * nColDofs;
+ self->nRowDofs = nRowDofs;
+ self->nColDofs = nColDofs;
+ if( nDofs > maxDofs ) {
+ maxRCDofs = (nRowDofs > nColDofs) ? nRowDofs : nColDofs;
+ elStiffMat = ReallocArray2D( elStiffMat, double, nRowDofs, nColDofs );
+
+ maxDofs = nDofs;
+ self->elStiffMat = elStiffMat;
+ }
+
+
+ /* Assemble the element. */
+ memset( elStiffMat[0], 0, nDofs * sizeof(double) );
+ StiffMatAssLog_InitTimer_ElementAssembly( log );
+ StiffnessMatrix_AssembleElement( self, e_i, sle, (FiniteElementContext*)_context, elStiffMat );
+ StiffMatAssLog_AccumulateTime_ElementAssembly( log );
+
+
+ /* If keeping BCs in, zero corresponding entries in the element stiffness matrix. */
+ if( !rowEqNum->removeBCs || !colEqNum->removeBCs )
+ Assembler_LoopMatrixElement( self->zeroBCsAsm, e_i );
+
+ /* Add to stiffness matrix. */
+ StiffMatAssLog_InitTimer_ElementInsertion( log );
+ MatSetValues( matrix,
+ nRowDofs, (PetscInt*)rowEqNum->locationMatrix[e_i][0],
+ nColDofs, (PetscInt*)colEqNum->locationMatrix[e_i][0],
+ elStiffMat[0], INSERT_VALUES );
+
+ StiffMatAssLog_AccumulateTime_ElementInsertion( log ); /* update time */
+ StiffMatAssLog_UpdateElementsAssembled( log ); /* update counter */
+ }
+
+
+ /* If keeping BCs in and rows and columnns use the same variable, put ones in all BC'd diagonals. */
+ if( !colEqNum->removeBCs && rowVar == colVar )
+ Assembler_LoopMatrixDiagonal( self->diagBCsAsm );
+
+ /* Start matrix assembly */
+ StiffMatAssLog_InitTimer_ParallelAssembly( log );
+ MatAssemblyBegin( matrix, MAT_FINAL_ASSEMBLY );
+ MatAssemblyEnd( matrix, MAT_FINAL_ASSEMBLY );
+ StiffMatAssLog_AccumulateTime_ParallelAssembly( log );
+
+ FreeArray( elStiffMat );
+
+ StiffMatAssLog_AccumulateTime_Total( log );
+
+}
+
+void _StiffMatAss_vector_corrections( struct StiffMatAss_Log *log, void *stiffnessMatrix, Bool removeBCs, void *_sle, void *_context ) {
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+ SystemLinearEquations* sle = (SystemLinearEquations*)_sle;
+ FeVariable *rowVar, *colVar;
+ FeMesh *rowMesh, *colMesh;
+ FeEquationNumber *rowEqNum, *colEqNum;
+ DofLayout *rowDofs, *colDofs;
+ unsigned nRowEls;
+ unsigned nRowNodes, *rowNodes;
+ unsigned nColNodes, *colNodes;
+ unsigned maxDofs, maxRCDofs, nDofs, nRowDofs, nColDofs;
+ double** elStiffMat;
+ double* bcVals;
+/* Mat matrix = ( self->useShellMatrix ) ? self->shellMatrix->matrix : self->matrix; */
+ Mat matrix = self->matrix;
+ Vec vector, transVector;
+ unsigned e_i, n_i;
+
+ unsigned bc_cnt = 0;
+ int *row_index_to_keep, *col_index_to_keep;
+ int n_rows, n_cols;
+ int same_variables;
+ int c_dof, r_dof;
+ double *rhs;
+ int has_col_bc, has_row_bc;
+ int eq_num;
+
+ assert( self && Stg_CheckType( self, StiffnessMatrix ) );
+
+ StiffMatAssLog_Init( log, "OPERATOR_WITH_BC_CORRECTIONS" );
+ StiffMatAssLog_InitTimer_TotalTime( log );
+
+ rowVar = self->rowVariable;
+ colVar = self->columnVariable ? self->columnVariable : rowVar;
+ rowEqNum = rowVar->eqNum;
+ colEqNum = colVar->eqNum;
+ rowMesh = rowVar->feMesh;
+ colMesh = colVar->feMesh;
+ rowDofs = rowVar->dofLayout;
+ colDofs = colVar->dofLayout;
+ nRowEls = FeMesh_GetElementLocalSize( rowMesh );
+ assert( (rowVar == colVar) ? !self->transRHS : 1 );
+
+ //matrix = self->matrix;
+ vector = self->rhs ? self->rhs->vector : NULL;
+ transVector = self->transRHS ? self->transRHS->vector : NULL;
+ elStiffMat = NULL;
+ bcVals = NULL;
+ maxDofs = 0;
+
+ col_index_to_keep = NULL;
+ row_index_to_keep = NULL;
+ rhs = NULL;
+
+ same_variables = 0;
+ if( rowMesh == colMesh ) {
+ same_variables = 1;
+// printf("Detected same variables in assembly VECTOR_CORRECTIONS\n");
+ }
+
+ assert( vector ); /* If we are in here then vector must be valid */
+
+
+ bc_cnt = 0;
+
+ StiffMatAssLog_GetOperatorDimensions( log, matrix );
+ /* Begin assembling each element. */
+ for( e_i = 0; e_i < nRowEls; e_i++ ) {
+ FeMesh_GetElementNodes( rowMesh, e_i, self->rowInc );
+ nRowNodes = IArray_GetSize( self->rowInc );
+ rowNodes = (unsigned*)IArray_GetPtr( self->rowInc );
+ FeMesh_GetElementNodes( colMesh, e_i, self->colInc );
+ nColNodes = IArray_GetSize( self->colInc );
+ colNodes = (unsigned*)IArray_GetPtr( self->colInc );
+
+ /* Do we need more space to assemble this element? */
+ nRowDofs = 0;
+ for( n_i = 0; n_i < nRowNodes; n_i++ ) {
+ nRowDofs += rowDofs->dofCounts[rowNodes[n_i]];
+ r_dof = rowDofs->dofCounts[rowNodes[n_i]];
+ }
+ nColDofs = 0;
+ for( n_i = 0; n_i < nColNodes; n_i++ ) {
+ nColDofs += colDofs->dofCounts[colNodes[n_i]];
+ c_dof = colDofs->dofCounts[colNodes[n_i]];
+ }
+ nDofs = nRowDofs * nColDofs;
+ self->nRowDofs = nRowDofs;
+ self->nColDofs = nColDofs;
+ if( nDofs > maxDofs ) {
+ maxRCDofs = (nRowDofs > nColDofs) ? nRowDofs : nColDofs;
+ elStiffMat = ReallocArray2D( elStiffMat, double, nRowDofs, nColDofs );
+ bcVals = ReallocArray( bcVals, double, maxRCDofs );
+ rhs = ReallocArray( rhs, double, maxRCDofs );
+
+ col_index_to_keep = ReallocArray( col_index_to_keep, int, maxRCDofs );
+ row_index_to_keep = ReallocArray( row_index_to_keep, int, maxRCDofs );
+
+ maxDofs = nDofs;
+ self->elStiffMat = elStiffMat;
+ self->bcVals = bcVals;
+ }
+
+ /* check for presence of bc's */
+ n_rows = n_cols = 0;
+ has_row_bc = has_col_bc = 0;
+
+
+ for( n_i=0; n_i<nColDofs; n_i++ ) {
+ eq_num = colEqNum->locationMatrix[e_i][0][n_i];
+ if( colEqNum->locationMatrix[e_i][0][n_i] < 0 ) {
+ col_index_to_keep[ n_cols ] = n_i;
+ n_cols++;
+ has_col_bc = 1;
+ }
+ }
+ for( n_i=0; n_i<nRowDofs; n_i++ ) {
+ if( rowEqNum->locationMatrix[e_i][0][n_i] >= 0 ) {
+ row_index_to_keep[ n_rows ] = n_i;
+ n_rows++;
+ has_row_bc = 1;
+ }
+ }
+
+ if( has_col_bc == 0 ) continue;
+
+ /* Assemble the element. */
+ memset( elStiffMat[0], 0, nDofs * sizeof(double) );
+ StiffMatAssLog_InitTimer_ElementAssembly( log );
+
+ StiffnessMatrix_AssembleElement( self, e_i, sle, (FiniteElementContext*)_context, elStiffMat );
+
+ StiffMatAssLog_AccumulateTime_ElementAssembly( log ); /* update time */
+ StiffMatAssLog_UpdateElementsAssembled( log ); /* update counter */
+
+
+ /* If keeping BCs in, zero corresponding entries in the element stiffness matrix. */
+ if( !rowEqNum->removeBCs || !colEqNum->removeBCs )
+ Assembler_LoopMatrixElement( self->zeroBCsAsm, e_i );
+
+
+ if( (has_col_bc==1) ) {
+ /* int I; */
+ memset( rhs, 0, maxRCDofs * sizeof(double) );
+
+ _get_bc_values( colVar, nColNodes, c_dof, (int*)colNodes, bcVals );
+ _make_dirichlet_corrections_to_rhs( n_rows, row_index_to_keep, n_cols, col_index_to_keep, elStiffMat, -1, bcVals, rhs );
+/*
+ printf("f: e = %d \n", e_i );
+
+ for( I=0; I<nRowDofs; I++ ) {
+ printf(" I=%d : %d -- bcval = %f : rhs = %f \n", I, rowEqNum->locationMatrix[e_i][0][I], bcVals[I], rhs[I] );
+ }
+*/
+ VecSetValues( vector, nRowDofs, (PetscInt*)rowEqNum->locationMatrix[e_i][0], rhs, ADD_VALUES );
+ StiffMatAssLog_UpdateElementsAssembledForBC_Corrections( log );
+ bc_cnt++;
+ }
+
+
+ /* Add to stiffness matrix. */
+ /*
+ StiffMatAssLog_InitTimer_ElementInsertion( log );
+ Matrix_AddEntries( matrix,
+ nRowDofs, (unsigned*)rowEqNum->locationMatrix[e_i][0],
+ nColDofs, (unsigned*)colEqNum->locationMatrix[e_i][0],
+ elStiffMat[0] );
+ StiffMatAssLog_AccumulateTime_ElementInsertion( log );
+ */
+ }
+
+ StiffMatAssLog_InitTimer_ParallelAssembly( log );
+ /* Start assembling vectors. */
+ VecAssemblyBegin( vector );
+
+ /* If keeping BCs in and rows and columnns use the same variable, put ones in all BC'd diagonals. */
+// if( !colEqNum->removeBCs && rowVar == colVar )
+// Assembler_LoopMatrixDiagonal( self->diagBCsAsm );
+
+ /* Start matrix assembly */
+ //Matrix_AssemblyBegin( matrix );
+
+ /* Finalise matrix and vector assembly */
+ VecAssemblyEnd( vector );
+ //Matrix_AssemblyEnd( matrix );
+ StiffMatAssLog_AccumulateTime_ParallelAssembly( log );
+
+// printf("Applied vector modifications using %u of %u elements \n", bc_cnt, nRowEls );
+ FreeArray( elStiffMat );
+ FreeArray( bcVals );
+ FreeArray( row_index_to_keep );
+ FreeArray( col_index_to_keep );
+ FreeArray( rhs );
+
+ StiffMatAssLog_AccumulateTime_Total( log );
+
+/*
+ {
+ PETScVector* self = (PETScVector*)vector;
+ printf("f = \n");
+ VecView( self->petscVec, PETSC_VIEWER_STDOUT_WORLD );
+ }
+*/
+
+}
+
+
+
+
+void _StiffMatAss_vector_corrections_from_transpose( struct StiffMatAss_Log *log, void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context ) {
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+ SystemLinearEquations* sle = (SystemLinearEquations*)_sle;
+ FeVariable *rowVar, *colVar;
+ FeMesh *rowMesh, *colMesh;
+ FeEquationNumber *rowEqNum, *colEqNum;
+ DofLayout *rowDofs, *colDofs;
+ unsigned nRowEls;
+ unsigned nRowNodes, *rowNodes;
+ unsigned nColNodes, *colNodes;
+ unsigned maxDofs, maxRCDofs, nDofs, nRowDofs, nColDofs;
+ double** elStiffMat;
+ double* bcVals;
+/* Mat matrix = ( self->useShellMatrix ) ? self->shellMatrix->matrix : self->matrix; */
+ Mat matrix = self->matrix;
+ Vec transVector;
+ unsigned e_i, n_i;
+
+ unsigned bc_cnt = 0;
+ int *row_index_to_keep, *col_index_to_keep;
+ int n_rows, n_cols;
+ int same_variables;
+ int c_dof, r_dof;
+ double *rhs;
+ int has_col_bc, has_row_bc;
+ int eq_num;
+
+ assert( self && Stg_CheckType( self, StiffnessMatrix ) );
+ StiffMatAssLog_Init( log, "OPERATOR_WITH_BC_CORRECTIONS_FROM_OP_TRANS" );
+ StiffMatAssLog_InitTimer_TotalTime( log );
+
+ rowVar = self->rowVariable;
+ colVar = self->columnVariable ? self->columnVariable : rowVar;
+ rowEqNum = rowVar->eqNum;
+ colEqNum = colVar->eqNum;
+ rowMesh = rowVar->feMesh;
+ colMesh = colVar->feMesh;
+ rowDofs = rowVar->dofLayout;
+ colDofs = colVar->dofLayout;
+ nRowEls = FeMesh_GetElementLocalSize( rowMesh );
+ assert( (rowVar == colVar) ? !self->transRHS : 1 );
+
+ //matrix = self->matrix;
+ transVector = self->transRHS ? self->transRHS->vector : NULL;
+ elStiffMat = NULL;
+ bcVals = NULL;
+ maxDofs = 0;
+
+ col_index_to_keep = NULL;
+ row_index_to_keep = NULL;
+ rhs = NULL;
+
+
+ same_variables = 0;
+ if( rowMesh == colMesh ) {
+ same_variables = 1;
+ // printf("Detected same variables in assembly VECTOR CORRECTIONS FROM TRANSPOSE \n");
+ }
+ assert( transVector ); /* If we are in this function than transVector must be valid */
+
+ bc_cnt = 0;
+
+
+ StiffMatAssLog_GetOperatorDimensions( log, matrix );
+ /* Begin assembling each element. */
+ for( e_i = 0; e_i < nRowEls; e_i++ ) {
+ FeMesh_GetElementNodes( rowMesh, e_i, self->rowInc );
+ nRowNodes = IArray_GetSize( self->rowInc );
+ rowNodes = (unsigned*)IArray_GetPtr( self->rowInc );
+ FeMesh_GetElementNodes( colMesh, e_i, self->colInc );
+ nColNodes = IArray_GetSize( self->colInc );
+ colNodes = (unsigned*)IArray_GetPtr( self->colInc );
+
+ /* Do we need more space to assemble this element? */
+ nRowDofs = 0;
+ for( n_i = 0; n_i < nRowNodes; n_i++ ) {
+ nRowDofs += rowDofs->dofCounts[rowNodes[n_i]];
+ r_dof = rowDofs->dofCounts[rowNodes[n_i]];
+ }
+ nColDofs = 0;
+ for( n_i = 0; n_i < nColNodes; n_i++ ) {
+ nColDofs += colDofs->dofCounts[colNodes[n_i]];
+ c_dof = colDofs->dofCounts[colNodes[n_i]];
+ }
+ nDofs = nRowDofs * nColDofs;
+ self->nRowDofs = nRowDofs;
+ self->nColDofs = nColDofs;
+ if( nDofs > maxDofs ) {
+ maxRCDofs = (nRowDofs > nColDofs) ? nRowDofs : nColDofs;
+ elStiffMat = ReallocArray2D( elStiffMat, double, nRowDofs, nColDofs );
+ bcVals = ReallocArray( bcVals, double, maxRCDofs );
+ rhs = ReallocArray( rhs, double, maxRCDofs );
+
+ col_index_to_keep = ReallocArray( col_index_to_keep, int, maxRCDofs );
+ row_index_to_keep = ReallocArray( row_index_to_keep, int, maxRCDofs );
+
+ maxDofs = nDofs;
+ self->elStiffMat = elStiffMat;
+ self->bcVals = bcVals;
+ }
+
+ /* check for presence of bc's */
+ n_rows = n_cols = 0;
+ has_row_bc = has_col_bc = 0;
+
+ /* cause this is the transpose function, we make corrections on the bc's if there are applied to the row variable */
+ for( n_i=0; n_i<nColDofs; n_i++ ) {
+ eq_num = colEqNum->locationMatrix[e_i][0][n_i];
+ if( colEqNum->locationMatrix[e_i][0][n_i] >= 0 ) {
+ col_index_to_keep[ n_cols ] = n_i;
+ n_cols++;
+ has_col_bc = 1;
+ }
+ }
+
+ for( n_i=0; n_i<nRowDofs; n_i++ ) {
+ if( rowEqNum->locationMatrix[e_i][0][n_i] < 0 ) {
+ row_index_to_keep[ n_rows ] = n_i;
+ n_rows++;
+ has_row_bc = 1;
+ }
+ }
+
+
+ if( has_row_bc == 0 ) continue;
+
+
+
+ /* Initialise the element stiffness matrix */
+ memset( elStiffMat[0], 0, nDofs * sizeof(double) );
+ /*
+ for( si=0; si<nRowDofs; si++ )
+ for( sj=0; sj<nColDofs; sj++ )
+ elStiffMat[si][sj] = 0.0;
+ */
+
+ /* Assemble the element stiffness matrix */
+ StiffMatAssLog_InitTimer_ElementAssembly( log );
+
+ StiffnessMatrix_AssembleElement( self, e_i, sle, (FiniteElementContext*)_context, elStiffMat );
+
+ StiffMatAssLog_AccumulateTime_ElementAssembly( log );
+ StiffMatAssLog_UpdateElementsAssembled( log );
+
+
+ /* If keeping BCs in, zero corresponding entries in the element stiffness matrix. */
+ if( !rowEqNum->removeBCs || !colEqNum->removeBCs )
+ Assembler_LoopMatrixElement( self->zeroBCsAsm, e_i );
+
+ if( (has_row_bc==1) ) {
+ /* int I; */
+ memset( rhs, 0, maxRCDofs * sizeof(double) );
+ /*
+ for( II=0; II<maxRCDofs; II++ ) {
+ bcVals[II] = rhs[II] = 0.0;
+ }
+ */
+ _get_bc_values( rowVar, nRowNodes, r_dof, (int*)rowNodes, bcVals );
+
+ _make_dirichlet_corrections_to_rhs_transpose( n_cols, col_index_to_keep, n_rows, row_index_to_keep, elStiffMat, -1, bcVals, rhs );
+/*
+ printf("h: e = %d \n", e_i );
+ for( I=0; I<nColDofs; I++ ) {
+ printf(" I=%d : %d -- bcval = %f : rhs = %f\n", I, colEqNum->locationMatrix[e_i][0][I], bcVals[I], rhs[I] );
+ }
+*/
+
+ VecSetValues( transVector, nColDofs, colEqNum->locationMatrix[e_i][0], rhs, INSERT_VALUES );
+ StiffMatAssLog_UpdateElementsAssembledForBC_Corrections( log );
+ bc_cnt++;
+ }
+
+ /* Add to stiffness matrix. */
+/*
+ StiffMatAssLog_InitTimer_ElementInsertion(log);
+ Matrix_AddEntries( matrix,
+ nRowDofs, (unsigned*)rowEqNum->locationMatrix[e_i][0],
+ nColDofs, (unsigned*)colEqNum->locationMatrix[e_i][0],
+ elStiffMat[0] );
+ StiffMatAssLog_AccumulateTime_ElementInsertion( log );
+*/
+ }
+
+
+ StiffMatAssLog_InitTimer_ParallelAssembly( log );
+ /* Start assembling vectors. */
+ VecAssemblyBegin( transVector );
+
+
+ /* If keeping BCs in and rows and columnns use the same variable, put ones in all BC'd diagonals. */
+// if( !colEqNum->removeBCs && rowVar == colVar )
+// Assembler_LoopMatrixDiagonal( self->diagBCsAsm );
+
+ /* Start matrix assembly */
+// Matrix_AssemblyBegin( matrix );
+
+ /* Finalise matrix and vector assembly */
+ VecAssemblyEnd( transVector );
+// Matrix_AssemblyEnd( matrix );
+ StiffMatAssLog_AccumulateTime_ParallelAssembly( log );
+
+// printf("Applied vector modifications using %u of %u elements \n", bc_cnt, nRowEls );
+ FreeArray( elStiffMat );
+ FreeArray( bcVals );
+ FreeArray( row_index_to_keep );
+ FreeArray( col_index_to_keep );
+ FreeArray( rhs );
+
+ StiffMatAssLog_AccumulateTime_Total( log );
+/*
+ {
+ PETScVector* self = (PETScVector*)transVector;
+ printf("h = \n");
+ VecView( self->petscVec, PETSC_VIEWER_STDOUT_WORLD );
+ }
+*/
+}
+
+
+//void __StiffnessMatrix_NewAssemble( void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context );
+void StiffnessMatrix_NewAssemble( void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context ) {
+ StiffnessMatrix *self = (StiffnessMatrix*)stiffnessMatrix;
+ Vec vector, transVector;
+ struct StiffMatAss_Log *log;
+
+ vector = self->rhs ? self->rhs->vector : NULL;
+ transVector = self->transRHS ? self->transRHS->vector : NULL;
+
+ log = StiffMatAssLog_New();
+
+
+ _StiffMatAss( log, stiffnessMatrix, removeBCs, _sle, (FiniteElementContext*)_context );
+ StiffMatAssLog_Report( self, log );
+
+ if( vector ) {
+ _StiffMatAss_vector_corrections( log, stiffnessMatrix, removeBCs, _sle, (FiniteElementContext*)_context );
+ StiffMatAssLog_Report( self, log );
+ }
+ if( transVector ) {
+ _StiffMatAss_vector_corrections_from_transpose( log, stiffnessMatrix, removeBCs, _sle, (FiniteElementContext*)_context );
+ StiffMatAssLog_Report( self, log );
+ }
+ // __StiffnessMatrix_NewAssemble( stiffnessMatrix, removeBCs, _sle, _context );
+ StiffMatAssLog_Delete( &log );
+}
+
+#if 0
+void StiffnessMatrix_SetEqsToUnity( StiffnessMatrix* self, const STreeNode* node ) {
+ static const double one = 1.0;
+
+ if( !node ) return;
+ StiffnessMatrix_SetEqsToUnity( self, node->left );
+ Matrix_AddEntries( self->matrix, 1, (int*)node->data, 1, (int*)node->data, (double*)&one );
+ StiffnessMatrix_SetEqsToUnity( self, node->right );
+}
+#endif
+
+
+/* Callback version */
+void __StiffnessMatrix_NewAssemble( void* stiffnessMatrix, Bool removeBCs, void* _sle, void* _context ) {
+ static const double one = 1.0;
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+ SystemLinearEquations* sle = (SystemLinearEquations*)_sle;
+ FeVariable *rowVar, *colVar;
+ FeMesh *rowMesh, *colMesh;
+ FeEquationNumber *rowEqNum, *colEqNum;
+ DofLayout *rowDofs, *colDofs;
+ unsigned nRowEls;
+ unsigned nRowNodes, *rowNodes;
+ unsigned nColNodes, *colNodes;
+ unsigned maxDofs, maxRCDofs, nDofs, nRowDofs, nColDofs;
+ double** elStiffMat;
+ double* bcVals;
+/* Mat matrix = ( self->useShellMatrix ) ? self->shellMatrix->matrix : self->matrix; */
+ Mat matrix = self->matrix;
+ Vec vector, transVector;
+ int nRowNodeDofs, nColNodeDofs;
+ int rowInd, colInd;
+ double bc;
+ unsigned e_i, n_i, dof_i, n_j, dof_j;
+
+ assert( self && Stg_CheckType( self, StiffnessMatrix ) );
+
+ rowVar = self->rowVariable;
+ colVar = self->columnVariable ? self->columnVariable : rowVar;
+ rowEqNum = rowVar->eqNum;
+ colEqNum = colVar->eqNum;
+ rowMesh = rowVar->feMesh;
+ colMesh = colVar->feMesh;
+ rowDofs = rowVar->dofLayout;
+ colDofs = colVar->dofLayout;
+ nRowEls = FeMesh_GetElementLocalSize( rowMesh );
+ assert( (rowVar == colVar) ? !self->transRHS : 1 );
+
+ //matrix = self->matrix;
+ vector = self->rhs ? self->rhs->vector : NULL;
+ transVector = self->transRHS ? self->transRHS->vector : NULL;
+ elStiffMat = NULL;
+ bcVals = NULL;
+ maxDofs = 0;
+
+ /* Begin assembling each element. */
+ for( e_i = 0; e_i < nRowEls; e_i++ ) {
+ FeMesh_GetElementNodes( rowMesh, e_i, self->rowInc );
+ nRowNodes = IArray_GetSize( self->rowInc );
+ rowNodes = (unsigned*)IArray_GetPtr( self->rowInc );
+ FeMesh_GetElementNodes( colMesh, e_i, self->colInc );
+ nColNodes = IArray_GetSize( self->colInc );
+ colNodes = (unsigned*)IArray_GetPtr( self->colInc );
+
+ /* Do we need more space to assemble this element? */
+ nRowDofs = 0;
+ for( n_i = 0; n_i < nRowNodes; n_i++ )
+ nRowDofs += rowDofs->dofCounts[rowNodes[n_i]];
+ nColDofs = 0;
+ for( n_i = 0; n_i < nColNodes; n_i++ )
+ nColDofs += colDofs->dofCounts[colNodes[n_i]];
+ nDofs = nRowDofs * nColDofs;
+ self->nRowDofs = nRowDofs;
+ self->nColDofs = nColDofs;
+ if( nDofs > maxDofs ) {
+ maxRCDofs = (nRowDofs > nColDofs) ? nRowDofs : nColDofs;
+ elStiffMat = ReallocArray2D( elStiffMat, double, nRowDofs, nColDofs );
+ bcVals = ReallocArray( bcVals, double, maxRCDofs );
+ maxDofs = nDofs;
+ self->elStiffMat = elStiffMat;
+ self->bcVals = bcVals;
+ }
+
+ /* Assemble the element. */
+ memset( elStiffMat[0], 0, nDofs * sizeof(double) );
+ StiffnessMatrix_AssembleElement( self, e_i, sle, (FiniteElementContext*)_context, elStiffMat );
+
+ /* Correct for BCs providing I'm not keeping them in. */
+ if( vector && removeBCs ) {
+ memset( bcVals, 0, nRowDofs * sizeof(double) );
+
+ rowInd = 0;
+ for( n_i = 0; n_i < nRowNodes; n_i++ ) {
+ nRowNodeDofs = rowDofs->dofCounts[rowNodes[n_i]];
+ for( dof_i = 0; dof_i < nRowNodeDofs; dof_i++ ) {
+ if( !FeVariable_IsBC( rowVar, rowNodes[n_i], dof_i ) ) {
+ colInd = 0;
+ for( n_j = 0; n_j < nColNodes; n_j++ ) {
+ nColNodeDofs = colDofs->dofCounts[colNodes[n_j]];
+ for( dof_j = 0; dof_j < nColNodeDofs; dof_j++ ) {
+ if( FeVariable_IsBC( colVar, colNodes[n_j], dof_j ) ) {
+ bc = DofLayout_GetValueDouble( colDofs, colNodes[n_j], dof_j );
+ bcVals[rowInd] -= bc * elStiffMat[rowInd][colInd];
+ }
+ colInd++;
+ }
+ }
+ }
+ rowInd++;
+ }
+ }
+
+ //Vector_AddEntries( vector, nRowDofs, (unsigned*)rowEqNum->locationMatrix[e_i][0], bcVals );
+ VecSetValues( vector, nRowDofs, rowEqNum->locationMatrix[e_i][0], bcVals, ADD_VALUES );
+ }
+ if( transVector && removeBCs ) {
+ memset( bcVals, 0, nColDofs * sizeof(double) );
+
+ colInd = 0;
+ for( n_i = 0; n_i < nColNodes; n_i++ ) {
+ nColNodeDofs = colDofs->dofCounts[colNodes[n_i]];
+ for( dof_i = 0; dof_i < nColNodeDofs; dof_i++ ) {
+ if( !FeVariable_IsBC( colVar, colNodes[n_i], dof_i ) ) {
+ rowInd = 0;
+ for( n_j = 0; n_j < nRowNodes; n_j++ ) {
+ nRowNodeDofs = rowDofs->dofCounts[rowNodes[n_j]];
+ for( dof_j = 0; dof_j < nRowNodeDofs; dof_j++ ) {
+ if( FeVariable_IsBC( rowVar, rowNodes[n_j], dof_j ) ) {
+ bc = DofLayout_GetValueDouble( rowDofs, rowNodes[n_j], dof_j );
+ bcVals[colInd] -= bc * elStiffMat[rowInd][colInd];
+ }
+ rowInd++;
+ }
+ }
+ }
+ colInd++;
+ }
+ }
+
+ VecSetValues( transVector, nColDofs, colEqNum->locationMatrix[e_i][0], bcVals, ADD_VALUES );
+ }
+
+ /* If keeping BCs in, zero corresponding entries in the element stiffness matrix. */
+ if( !rowEqNum->removeBCs || !colEqNum->removeBCs ) {
+ rowInd = 0;
+ for( n_i = 0; n_i < nRowNodes; n_i++ ) {
+ nRowNodeDofs = rowDofs->dofCounts[rowNodes[n_i]];
+ for( dof_i = 0; dof_i < nRowNodeDofs; dof_i++ ) {
+ if( FeVariable_IsBC( rowVar, rowNodes[n_i], dof_i ) ) {
+ memset( elStiffMat[rowInd], 0, nColDofs * sizeof(double) );
+ }
+ else {
+ colInd = 0;
+ for( n_j = 0; n_j < nColNodes; n_j++ ) {
+ nColNodeDofs = colDofs->dofCounts[colNodes[n_j]];
+ for( dof_j = 0; dof_j < nColNodeDofs; dof_j++ ) {
+ if( FeVariable_IsBC( colVar, colNodes[n_j], dof_j ) )
+ elStiffMat[rowInd][colInd] = 0.0;
+ colInd++;
+ }
+ }
+ }
+ rowInd++;
+ }
+ }
+ }
+
+ /* Add to stiffness matrix. */
+ MatSetValues( matrix,
+ nRowDofs, rowEqNum->locationMatrix[e_i][0],
+ nColDofs, colEqNum->locationMatrix[e_i][0],
+ elStiffMat[0], ADD_VALUES );
+ }
+
+ FreeArray( elStiffMat );
+ FreeArray( bcVals );
+
+ /* If keeping BCs in and rows and columnns use the same variable, put ones in all BC'd diagonals. */
+ if( !colEqNum->removeBCs && rowVar == colVar ) {
+ for( n_i = 0; n_i < FeMesh_GetNodeLocalSize( colMesh ); n_i++ ) {
+ nColNodeDofs = colDofs->dofCounts[n_i];
+ for( dof_i = 0; dof_i < nColNodeDofs; dof_i++ ) {
+ if( FeVariable_IsBC( colVar, n_i, dof_i ) ) {
+ MatSetValues( self->matrix,
+ 1, colEqNum->destinationArray[n_i] + dof_i,
+ 1, colEqNum->destinationArray[n_i] + dof_i,
+ (double*)&one, ADD_VALUES );
+ }
+ }
+ }
+
+#if 0
+ StiffnessMatrix_SetEqsToUnity( self, rowEqNum, STree_GetRoot( rowEqNum->ownedMap ) );
+#endif
+ }
+
+ /* Reassemble the matrix and vectors. */
+ MatAssemblyBegin( matrix, MAT_FINAL_ASSEMBLY );
+ MatAssemblyEnd( matrix, MAT_FINAL_ASSEMBLY );
+ if( vector ) {
+ VecAssemblyBegin( vector );
+ VecAssemblyEnd( vector );
+ }
+ if( transVector) {
+ VecAssemblyBegin( transVector );
+ VecAssemblyEnd( transVector );
+ }
+
+ MatAssemblyBegin( matrix, MAT_FINAL_ASSEMBLY );
+ MatAssemblyEnd( matrix, MAT_FINAL_ASSEMBLY );
+}
+
+/* void StiffnessMatrix_ShellAssembly( void* stiffnessMatrix, Bool removeBCs, void* data ) { */
+/* StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix; */
+/* Vec rhs; */
+/* FeVariable *rowVar, *colVar; */
+/* FeMesh *rowMesh, *colMesh; */
+/* FeEquationNumber *rowEqNum, *colEqNum; */
+/* DofLayout *rowDofs, *colDofs; */
+/* unsigned nRowEls; */
+/* unsigned nRowNodes, *rowNodes; */
+/* unsigned nColNodes, *colNodes; */
+/* unsigned maxDofs, nDofs, nRowDofs, nColDofs; */
+/* double** elStiffMat; */
+/* double* values; */
+/* unsigned* indices; */
+/* unsigned curRow, curCol; */
+/* unsigned colEq; */
+/* double bc; */
+/* unsigned e_i, n_i, n_j, dof_i, dof_j; */
+
+/* assert( self && Stg_CheckType( self, StiffnessMatrix ) ); */
+
+/* /\* The whole point of this routine is to remove the BCs. *\/ */
+/* if( !removeBCs ) */
+/* return; */
+
+/* rhs = self->rhs->vector; */
+/* rowVar = self->rowVariable; */
+/* colVar = self->columnVariable ? self->columnVariable : rowVar; */
+/* if( rowVar != colVar ) { */
+/* FeVariable* tmp = rowVar; */
+/* rowVar = colVar; */
+/* colVar = tmp; */
+/* } */
+/* rowEqNum = rowVar->eqNum; */
+/* colEqNum = colVar->eqNum; */
+/* rowMesh = rowVar->feMesh; */
+/* colMesh = colVar->feMesh; */
+/* rowDofs = rowVar->dofLayout; */
+/* colDofs = colVar->dofLayout; */
+/* nRowEls = FeMesh_GetElementLocalSize( rowMesh ); */
+/* elStiffMat = NULL; */
+/* values = NULL; */
+/* indices = NULL; */
+/* maxDofs = 0; */
+
+/* for( e_i = 0; e_i < nRowEls; e_i++ ) { */
+/* FeMesh_GetElementNodes( rowMesh, e_i, self->rowInc ); */
+/* nRowNodes = IArray_GetSize( self->rowInc ); */
+/* rowNodes = IArray_GetPtr( self->rowInc ); */
+/* FeMesh_GetElementNodes( colMesh, e_i, self->colInc ); */
+/* nColNodes = IArray_GetSize( self->colInc ); */
+/* colNodes = IArray_GetPtr( self->colInc ); */
+
+/* /\* If none of the column equations on this element have BCs then skip it. *\/ */
+/* for( n_i = 0; n_i < nRowNodes; n_i++ ) { */
+/* for( dof_i = 0; dof_i < rowDofs->dofCounts[rowNodes[n_i]]; dof_i++ ) { */
+/* if( rowEqNum->locationMatrix[e_i][n_i][dof_i] == (unsigned)-1 ) */
+/* continue; */
+/* for( n_j = 0; n_j < nColNodes; n_j++ ) { */
+/* for( dof_j = 0; dof_j < colDofs->dofCounts[colNodes[n_j]]; dof_j++ ) { */
+/* if( colEqNum->locationMatrix[e_i][n_j][dof_j] == (unsigned)-1 ) */
+/* break; */
+/* } */
+/* if( dof_j < colDofs->dofCounts[colNodes[n_j]] ) */
+/* break; */
+/* } */
+/* if( n_j < nColNodes ) */
+/* break; */
+/* } */
+/* if( dof_i < rowDofs->dofCounts[rowNodes[n_i]] ) */
+/* break; */
+/* } */
+/* if( n_i == nRowNodes ) */
+/* continue; */
+
+/* /\* Do we need more space to assemble this element? *\/ */
+/* nRowDofs = 0; */
+/* for( n_i = 0; n_i < nRowNodes; n_i++ ) */
+/* nRowDofs += rowDofs->dofCounts[rowNodes[n_i]]; */
+/* nColDofs = 0; */
+/* for( n_i = 0; n_i < nColNodes; n_i++ ) */
+/* nColDofs += colDofs->dofCounts[colNodes[n_i]]; */
+/* nDofs = nRowDofs * nColDofs; */
+/* if( nDofs > maxDofs ) { */
+/* #if 0 */
+/* elStiffMat = ReallocArray2D( elStiffMat, double, nRowDofs, nColDofs ); */
+/* #endif */
+/* values = ReallocArray( values, double, nDofs ); */
+/* indices = ReallocArray( indices, unsigned, nDofs ); */
+/* maxDofs = nDofs; */
+/* } */
+
+/* #if 0 */
+/* /\* Assemble the element. *\/ */
+/* memset( &elStiffMat[0][0], 0, nDofs * sizeof(double) ); */
+/* StiffnessMatrix_AssembleElement( self, e_i, sle, elStiffMat ); */
+/* #endif */
+
+/* elStiffMat = ((PETScShellMatrix*)self->matrix)->elStiffMat; assert( elStiffMat ); */
+
+/* /\* Update the force vector with BCs. *\/ */
+/* curRow = 0; */
+/* memset( values, 0, nDofs * sizeof(double) ); */
+/* for( n_i = 0; n_i < nRowNodes; n_i++ ) { */
+/* for( dof_i = 0; dof_i < rowDofs->dofCounts[rowNodes[n_i]]; dof_i++ ) { */
+/* indices[curRow] = rowEqNum->locationMatrix[e_i][n_i][dof_i]; */
+/* if( indices[curRow] == (unsigned)-1 ) { */
+/* curRow++; */
+/* continue; */
+/* } */
+
+/* curCol = 0; */
+/* for( n_j = 0; n_j < nColNodes; n_j++ ) { */
+/* for( dof_j = 0; dof_j < colDofs->dofCounts[colNodes[n_j]]; dof_j++ ) { */
+/* colEq = colEqNum->locationMatrix[e_i][n_j][dof_j]; */
+/* if( colEq != (unsigned)-1 ) { */
+/* curCol++; */
+/* continue; */
+/* } */
+
+/* bc = DofLayout_GetValueDouble( colDofs, colNodes[n_j], dof_j ); */
+/* values[curRow] -= elStiffMat[curRow][curCol] * bc; */
+
+/* curCol++; */
+/* } */
+/* } */
+
+/* curRow++; */
+/* } */
+/* } */
+
+/* VecSetValues( rhs, curRow, indices, values, ADD_VALUES ); */
+/* } */
+
+/* FreeArray( values ); */
+/* FreeArray( indices ); */
+
+/* VecAssemblyBegin( rhs ); */
+/* VecAssemblyEnd( rhs ); */
+/* } */
+
+
+
+/* +++ PRIVATE FUNCTIONS +++ */
+
+void _StiffnessMatrix_UpdateBC_CorrectionTables(
+ StiffnessMatrix* self,
+ FeEquationNumber* eqNum,
+ DofLayout* dofLayout,
+ Dof_EquationNumber** elementLM,
+ Node_ElementLocalIndex nodeCountThisEl,
+ Element_Nodes nodeIdsThisEl,
+ Dof_Index* bcLM_Id,
+ double* bcValues,
+ int* nBC_NodalDofPtr )
+{
+ Node_ElementLocalIndex node_elLocalI = 0;
+ Node_LocalIndex node_lI = 0;
+ Dof_Index* dofCounts = dofLayout->dofCounts;
+ Dof_Index dofCountThisNode=0;
+ Dof_Index dof_nodeLocalI=0;
+ unsigned pos = 0;
+
+ for( node_elLocalI = 0; node_elLocalI < nodeCountThisEl; node_elLocalI++ ) {
+ node_lI = nodeIdsThisEl[node_elLocalI];
+ dofCountThisNode = dofCounts[node_lI];
+
+ for( dof_nodeLocalI = 0; dof_nodeLocalI < dofCountThisNode; dof_nodeLocalI++ ) {
+ Bool isBC = False;
+
+ /* Can only use 'elementLM' if FeEquationNumber has been told to remove BCs. Otherwise
+ we'll need to determine if the VariableCondition has a value specified for this
+ node/dof. - Luke */
+ if( elementLM[node_elLocalI][dof_nodeLocalI] != (unsigned)-1 ) {
+ unsigned lEqNum;
+
+ lEqNum = *(int*)STreeMap_Map( eqNum->ownedMap,
+ elementLM[node_elLocalI] + dof_nodeLocalI );
+
+ if( eqNum->bcEqNums && STree_Has( eqNum->bcEqNums, &lEqNum ) ) {
+ isBC = True;
+ }
+ }
+ else {
+ isBC = True;
+ }
+
+ if ( isBC ) {
+ /* offset into the elementStiffness matrix */
+ bcLM_Id[ *nBC_NodalDofPtr ] = pos;
+/*
+ bcLM_Id[ *nBC_NodalDofPtr ] = &elementLM[node_elLocalI][dof_nodeLocalI] - &elementLM[0][0];
+*/
+
+/* get bc values from the bc_layout */
+ bcValues[ *nBC_NodalDofPtr ] = DofLayout_GetValueDouble( dofLayout, node_lI, dof_nodeLocalI );
+
+ Journal_DPrintfL( self->debug, 3, "bcValues[%d]: at &LM[0][0] + %d=%d, is %f\n",
+ *nBC_NodalDofPtr, bcLM_Id[ *nBC_NodalDofPtr ],
+ elementLM[0][ bcLM_Id[ *nBC_NodalDofPtr ] ],
+ bcValues[ *nBC_NodalDofPtr ] );
+
+ (*nBC_NodalDofPtr)++;
+ }
+
+ /* Move to next element stiffness matrix entry. */
+ pos++;
+ }
+ }
+}
+
+
+void _StiffnessMatrix_CorrectForceVectorWithOneElementsBoundaryConditions(
+ StiffnessMatrix* self,
+ Dof_EquationNumber** elementLM[MAX_FE_VARS],
+ double* h2Add,
+ double** elStiffMatToAdd,
+ Dof_Index* totalDofsThisElement[MAX_FE_VARS],
+ Dof_Index* bcLM_Id[MAX_FE_VARS],
+ double* bcValues[MAX_FE_VARS],
+ int nBC_NodalDof_Row,
+ unsigned elementInd /* NEW ONE */ )
+{
+#if 0
+ int rowEqId;
+ double bc_value;
+ Dof_Index colDof_elLocalI;
+#endif
+
+ memset( h2Add, 0, (*totalDofsThisElement[COL_VAR]) * sizeof(double) );
+
+ /*
+ ** Something fishy is up with BC corrections, adding this for now.
+ */
+
+ if( self->rowVariable != self->columnVariable ) {
+ Mesh *rowMesh, *colMesh;
+ FeEquationNumber *rowEqNum, *colEqNum;
+ DofLayout *rowDofs, *colDofs;
+ unsigned nRowElNodes, *rowElNodes, nColElNodes, *colElNodes;
+ unsigned nRowDofs, nColDofs;
+ unsigned dofI, dofJ, elIndI, elIndJ;
+ double bcValue;
+ unsigned n_i, n_j, d_i, d_j;
+
+ rowMesh = (Mesh*)self->rowVariable->feMesh;
+ colMesh = (Mesh*)self->columnVariable->feMesh;
+ rowEqNum = self->rowVariable->eqNum;
+ colEqNum = self->columnVariable->eqNum;
+ rowDofs = rowEqNum->dofLayout;
+ colDofs = colEqNum->dofLayout;
+ Mesh_GetIncidence( rowMesh, Mesh_GetDimSize( rowMesh ), elementInd, MT_VERTEX, self->rowInc );
+ nRowElNodes = IArray_GetSize( self->rowInc );
+ rowElNodes = (unsigned*)IArray_GetPtr( self->rowInc );
+ Mesh_GetIncidence( colMesh, Mesh_GetDimSize( colMesh ), elementInd, MT_VERTEX, self->colInc );
+ nColElNodes = IArray_GetSize( self->colInc );
+ colElNodes = (unsigned*)IArray_GetPtr( self->colInc );
+ nRowDofs = rowDofs->dofCounts[0];
+ nColDofs = colDofs->dofCounts[0];
+
+ for( n_i = 0; n_i < nColElNodes; n_i++ ) {
+ for( d_i = 0; d_i < nColDofs; d_i++ ) {
+ dofI = colEqNum->locationMatrix[elementInd][n_i][d_i];
+ if( dofI == -1 )
+ continue;
+
+ elIndI = n_i * nColDofs + d_i;
+ for( n_j = 0; n_j < nRowElNodes; n_j++ ) {
+ for( d_j = 0; d_j < nRowDofs; d_j++ ) {
+ dofJ = rowEqNum->locationMatrix[elementInd][n_j][d_j];
+ if( dofJ != -1 )
+ continue;
+
+ elIndJ = n_j * nRowDofs + d_j;
+ bcValue = DofLayout_GetValueDouble( rowDofs, rowElNodes[n_j], d_j );
+ h2Add[elIndI] -= elStiffMatToAdd[elIndJ][elIndI] * bcValue;
+ }
+ }
+ }
+ }
+ }
+ else {
+ Mesh *rowMesh, *colMesh;
+ FeEquationNumber *rowEqNum, *colEqNum;
+ DofLayout *rowDofs, *colDofs;
+ unsigned nRowElNodes, *rowElNodes, nColElNodes, *colElNodes;
+ unsigned nRowDofs, nColDofs;
+ unsigned dofI, dofJ, elIndI, elIndJ;
+ double bcValue;
+ unsigned n_i, n_j, d_i, d_j;
+
+ rowMesh = (Mesh*)self->rowVariable->feMesh;
+ colMesh = (Mesh*)self->columnVariable->feMesh;
+ rowEqNum = self->rowVariable->eqNum;
+ colEqNum = self->columnVariable->eqNum;
+ rowDofs = rowEqNum->dofLayout;
+ colDofs = colEqNum->dofLayout;
+ Mesh_GetIncidence( rowMesh, Mesh_GetDimSize( rowMesh ), elementInd, MT_VERTEX, self->rowInc );
+ nRowElNodes = IArray_GetSize( self->rowInc );
+ rowElNodes = (unsigned*)IArray_GetPtr( self->rowInc );
+ Mesh_GetIncidence( colMesh, Mesh_GetDimSize( colMesh ), elementInd, MT_VERTEX, self->colInc );
+ nColElNodes = IArray_GetSize( self->colInc );
+ colElNodes = (unsigned*)IArray_GetPtr( self->colInc );
+ nRowDofs = rowDofs->dofCounts[0];
+ nColDofs = colDofs->dofCounts[0];
+
+ for( n_i = 0; n_i < nRowElNodes; n_i++ ) {
+ for( d_i = 0; d_i < nRowDofs; d_i++ ) {
+ dofI = rowEqNum->locationMatrix[elementInd][n_i][d_i];
+ if( dofI == -1 )
+ continue;
+
+ elIndI = n_i * nRowDofs + d_i;
+ for( n_j = 0; n_j < nColElNodes; n_j++ ) {
+ for( d_j = 0; d_j < nColDofs; d_j++ ) {
+ dofJ = colEqNum->locationMatrix[elementInd][n_j][d_j];
+ if( dofJ != -1 )
+ continue;
+
+ elIndJ = n_j * nColDofs + d_j;
+ bcValue = DofLayout_GetValueDouble( colDofs, colElNodes[n_j], d_j );
+ h2Add[elIndI] -= elStiffMatToAdd[elIndI][elIndJ] * bcValue;
+ }
+ }
+ }
+ }
+ }
+
+#if 0
+ for( colDof_elLocalI=0; colDof_elLocalI < *totalDofsThisElement[COL_VAR]; colDof_elLocalI++ ) {
+ double sum = 0.0;
+
+ for( bcDof_I=0; bcDof_I < nBC_NodalDof_Row; bcDof_I++ ) {
+ rowEqId = bcLM_Id[ROW_VAR][bcDof_I];
+ bc_value = bcValues[ROW_VAR][bcDof_I];
+/* printf("bc_value = %f \n",bc_value ); */
+
+ /* this index is gets us to the right */
+ sum = sum - ( elStiffMatToAdd[rowEqId][colDof_elLocalI] * bc_value );
+ }
+ h2Add[colDof_elLocalI] = sum;
+ }
+#endif
+
+ VecSetValues( self->rhs->vector, *totalDofsThisElement[COL_VAR], elementLM[COL_VAR][0], h2Add, ADD_VALUES );
+
+ /* assume that K is symetric, so corrections are made with KTrans.
+ this allows us to use this func with G, when we want velocity
+ corrections from GTrans to appear in H.
+ */
+
+ /*
+ for( bcDof_I=0; bcDof_I < nBC_NodalDof_row; bcDof_I++ ) {
+ rowEqId = bcLM_Id[ROW_VAR][bcDof_I];
+ bc_value = bcValues[ROW_VAR][bcDof_I];
+ printf("bc_value = %f \n",bc_value );
+
+ printf("bc value = %f \n",bc_value );
+ correct = 0;
+ for( colDof_elLocalI=0; colDof_elLocalI< *totalDofsThisElement[COL_VAR]; colDof_elLocalI++ ) {
+ h2Add[correct] = h2Add[correct]
+ - elStiffMatToAdd[rowEqId* (*totalDofsThisElement[COL_VAR]) + colDof_elLocalI] * bc_value;
+ hIdx[correct] = elementLM[COL_VAR][0][ colDof_elLocalI ];
+
+ correct = correct + 1;
+ }
+ }
+ Vector_AddTo( self->rhs->vector, correct, hIdx, h2Add );
+ */
+
+ /* does not work */
+ /*for( rowDof_elLocalI=0; rowDof_elLocalI < *totalDofsThisElement[ROW_VAR]; rowDof_elLocalI++ ) {
+ double sum = 0.0;
+ for( rowDof_elLocalI=0; rowDof_elLocalI<nBC_NodalDof[ROW_VAR]; rowDof_elLocalI++ ) {
+ colEqId = bcLM_Id[COL_VAR][rowDof_elLocalI];
+ bc_value = bcValues[COL_VAR][rowDof_elLocalI];
+
+ sum = sum + elStiffMatToAdd[ i* (*totalDofsThisElement[COL_VAR]) + colEqId] * bc_value;
+ }
+ h2Add[rowDof_elLocalI] = -sum;
+ }
+ Vector_AddTo( self->rhs->vector, *totalDofsThisElement[ROW_VAR], elementLM[ROW_VAR][0], h2Add ); */
+}
+
+void _StiffnessMatrix_PrintElementStiffnessMatrix(
+ StiffnessMatrix* self,
+ Element_LocalIndex element_lI,
+ Dof_EquationNumber** rowElementLM,
+ Dof_EquationNumber** colElementLM,
+ double** elStiffMatToAdd )
+{
+ FeMesh* rFeMesh = self->rowVariable->feMesh;
+ FeMesh* cFeMesh = self->columnVariable->feMesh;
+ Dof_Index rowDofsPerNode;
+ Dof_Index colDofsPerNode;
+ Node_LocalIndex rowNodesThisEl;
+ Node_LocalIndex colNodesThisEl;
+ Node_LocalIndex rowNode_I, colNode_I;
+ Dof_Index rowDof_I, colDof_I;
+ Index rowIndex, colIndex;
+ unsigned nRowElInc, *rowElInc;
+ unsigned nColElInc, *colElInc;
+
+ FeMesh_GetElementNodes( rFeMesh, element_lI, self->rowInc );
+ nRowElInc = IArray_GetSize( self->rowInc );
+ rowElInc = (unsigned*)IArray_GetPtr( self->rowInc );
+ FeMesh_GetElementNodes( cFeMesh, element_lI, self->colInc );
+ nColElInc = IArray_GetSize( self->colInc );
+ colElInc = (unsigned*)IArray_GetPtr( self->colInc );
+
+ rowDofsPerNode = self->rowVariable->dofLayout->dofCounts[rowElInc[0]];
+ colDofsPerNode = self->columnVariable->dofLayout->dofCounts[colElInc[0]];
+ rowNodesThisEl = nRowElInc;
+ colNodesThisEl = nColElInc;
+
+ for ( rowNode_I=0; rowNode_I < rowNodesThisEl; rowNode_I++ ) {
+ for ( rowDof_I = 0; rowDof_I < rowDofsPerNode; rowDof_I++ ) {
+ for ( colNode_I=0; colNode_I < colNodesThisEl; colNode_I++ ) {
+ for ( colDof_I = 0; colDof_I < colDofsPerNode; colDof_I++ ) {
+ rowIndex = rowNode_I*rowDofsPerNode + rowDof_I;
+ colIndex = colNode_I*colDofsPerNode + colDof_I;
+
+ Journal_DPrintf( self->debug, "Row [%d][%d], Col [%d][%d] (LM (%4d,%4d)) = %.3f\n",
+ rowNode_I, rowDof_I,
+ colNode_I, colDof_I,
+ rowElementLM[rowNode_I][rowDof_I],
+ colElementLM[colNode_I][colDof_I],
+ elStiffMatToAdd[rowIndex][colIndex] );
+ }
+ }
+ }
+ }
+}
+
+void StiffnessMatrix_AssembleElement(
+ void* stiffnessMatrix,
+ Element_LocalIndex element_lI,
+ SystemLinearEquations* sle,
+ FiniteElementContext* context,
+ double** elStiffMatToAdd )
+{
+ StiffnessMatrix* self = (StiffnessMatrix*) stiffnessMatrix;
+ Index stiffnessMatrixTermCount = Stg_ObjectList_Count( self->stiffnessMatrixTermList );
+ Index stiffnessMatrixTerm_I;
+ StiffnessMatrixTerm* stiffnessMatrixTerm;
+
+ for ( stiffnessMatrixTerm_I = 0 ; stiffnessMatrixTerm_I < stiffnessMatrixTermCount ; stiffnessMatrixTerm_I++ ) {
+ stiffnessMatrixTerm = (StiffnessMatrixTerm*) Stg_ObjectList_At( self->stiffnessMatrixTermList, stiffnessMatrixTerm_I );
+ StiffnessMatrixTerm_AssembleElement( stiffnessMatrixTerm, self, element_lI, sle, context, elStiffMatToAdd );
+ }
+}
+
+void StiffnessMatrix_CheckElementAssembly(
+ void* stiffnessMatrix,
+ Element_LocalIndex element_lI,
+ double** elStiffMatToAdd,
+ Index elStiffMatToAddRowSize,
+ Index elStiffMatToAddColSize )
+{
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+ Bool atLeastOneNonZeroElementContributionEntry = False;
+ Index elStiffMat_rowI = 0;
+ Index elStiffMat_colI = 0;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
+
+ for ( elStiffMat_colI = 0; elStiffMat_colI < elStiffMatToAddColSize; elStiffMat_colI++ ) {
+ for ( elStiffMat_rowI = 0; elStiffMat_rowI < elStiffMatToAddColSize; elStiffMat_rowI++ ) {
+ if ( elStiffMatToAdd[elStiffMat_rowI][elStiffMat_colI] != 0.0 ) {
+ atLeastOneNonZeroElementContributionEntry = True;
+ break;
+ }
+ }
+ if ( atLeastOneNonZeroElementContributionEntry == True ) {
+ break;
+ }
+ }
+
+ Journal_Firewall( atLeastOneNonZeroElementContributionEntry == True, errorStream,
+ "Error - in %s(): while assembling matrix \"%s\", for element %u - elStiffMatToAdd assembled at this "
+ "element is all zeros."
+ "Did you register a stiffnessMatrixTerm? Is there at least one integration point in this "
+ "element?\n", __func__, self->name, element_lI );
+}
+
+void StiffnessMatrix_AddStiffnessMatrixTerm( void* stiffnessMatrix, StiffnessMatrixTerm* stiffnessMatrixTerm ) {
+ StiffnessMatrix* self = (StiffnessMatrix*) stiffnessMatrix;
+
+ stiffnessMatrixTerm = Stg_CheckType( stiffnessMatrixTerm, StiffnessMatrixTerm );
+ Stg_ObjectList_Append( self->stiffnessMatrixTermList, stiffnessMatrixTerm );
+}
+
+void StiffnessMatrix_RefreshMatrix( StiffnessMatrix* self ) {
+ int nProcs;
+
+ assert( self && Stg_CheckType( self, StiffnessMatrix ) );
+
+ /* Note: I'd like to make this a dereference, just in case there is another class still using
+ the old matrix, but that'd require two matrices to exist at one time; i.e. lots of memory.
+ Keeping it as a free just means that other classes need to assume they never own the matrix. */
+ /*if( self->useShellMatrix ) {
+ PETScShellMatrix_SetComm( self->shellMatrix, self->comm );
+ PETScShellMatrix_SetLocalSize( self->shellMatrix, self->rowLocalSize, self->colLocalSize );
+ PETScShellMatrix_SetNonZeroStructure( self->shellMatrix, self->nonZeroCount, self->diagonalNonZeroIndices, self->offDiagonalNonZeroIndices );
+ }
+ else { */
+ if( self->matrix != PETSC_NULL )
+ MatDestroy( self->matrix );
+
+ MatCreate( self->comm, &self->matrix );
+ MatSetSizes( self->matrix, self->rowLocalSize, self->colLocalSize, PETSC_DETERMINE, PETSC_DETERMINE );
+ MatSetFromOptions( self->matrix );
+ MPI_Comm_size( self->comm, &nProcs );
+
+ if( self->diagonalNonZeroIndices || self->offDiagonalNonZeroIndices ) {
+ if( nProcs > 1 )
+ MatMPIAIJSetPreallocation( self->matrix, PETSC_NULL, (PetscInt*)(self->diagonalNonZeroIndices), PETSC_NULL, (PetscInt*)(self->offDiagonalNonZeroIndices) );
+ else
+ MatSeqAIJSetPreallocation( self->matrix, PETSC_NULL, (PetscInt*)(self->diagonalNonZeroIndices) );
+ }
+ else {
+ if( nProcs > 1 )
+ MatMPIAIJSetPreallocation( self->matrix, self->nonZeroCount, PETSC_NULL, self->nonZeroCount, PETSC_NULL );
+ else
+ MatSeqAIJSetPreallocation( self->matrix, self->nonZeroCount, PETSC_NULL );
+ }
+ /*}*/
+}
+
+void StiffnessMatrix_CalcNonZeros( void* stiffnessMatrix ) {
+ StiffnessMatrix* self = (StiffnessMatrix*)stiffnessMatrix;
+ Stream *stream;
+ FeVariable *rowVar, *colVar;
+ FeMesh *rowMesh, *colMesh;
+ FeEquationNumber *rowEqNum, *colEqNum;
+ DofLayout *rowDofs, *colDofs;
+ int nRowEqs, nColEqs;
+ int nColNodes, *colNodes;
+ int nNodeEls, *nodeEls;
+ int *nDiagNonZeros, *nOffDiagNonZeros;
+ int rowEq, colEq, localRowEq;
+ int netNonZeros;
+ STree *candColEqs;
+ int e_i;
+ int n_i, dof_i;
+ int n_j, dof_j;
+
+ assert( self && Stg_CheckType( self, StiffnessMatrix ) );
+ assert( self->rowVariable );
+
+ stream = Journal_Register( Info_Type, (Name)self->type );
+ Journal_Printf( stream, "Stiffness matrix: '%s'\n", self->name );
+ Stream_Indent( stream );
+ Journal_Printf( stream, "Calculating number of nonzero entries...\n" );
+ Stream_Indent( stream );
+
+ rowVar = self->rowVariable;
+ colVar = self->columnVariable ? self->columnVariable : rowVar;
+ rowMesh = rowVar->feMesh;
+ colMesh = colVar->feMesh;
+ rowEqNum = rowVar->eqNum;
+ colEqNum = colVar->eqNum;
+ nRowEqs = rowEqNum->localEqNumsOwnedCount;
+ nColEqs = colEqNum->localEqNumsOwnedCount;
+ rowDofs = rowVar->dofLayout;
+ colDofs = colVar->dofLayout;
+
+ candColEqs = STree_New();
+ STree_SetIntCallbacks( candColEqs );
+ STree_SetItemSize( candColEqs, sizeof(int) );
+ nDiagNonZeros = AllocArray( int, nRowEqs );
+ nOffDiagNonZeros = AllocArray( int, nRowEqs );
+ memset( nDiagNonZeros, 0, nRowEqs * sizeof(int) );
+ memset( nOffDiagNonZeros, 0, nRowEqs * sizeof(int) );
+ netNonZeros = 0;
+
+ for( n_i = 0; n_i < FeMesh_GetNodeLocalSize( rowMesh ); n_i++ ) {
+ for( dof_i = 0; dof_i < rowDofs->dofCounts[n_i]; dof_i++ ) {
+ rowEq = rowEqNum->destinationArray[n_i][dof_i];
+
+ if( rowEq == -1 ) continue;
+ if( !STreeMap_HasKey( rowEqNum->ownedMap, &rowEq ) ) continue;
+
+ localRowEq = *(int*)STreeMap_Map( rowEqNum->ownedMap, &rowEq );
+ FeMesh_GetNodeElements( rowMesh, n_i, self->rowInc );
+ nNodeEls = IArray_GetSize( self->rowInc );
+ nodeEls = IArray_GetPtr( self->rowInc );
+ STree_Clear( candColEqs );
+
+ for( e_i = 0; e_i < nNodeEls; e_i++ ) {
+ /* ASSUME: Row and column meshes have one-to-one element overlap. */
+ FeMesh_GetElementNodes( colMesh, nodeEls[e_i], self->colInc );
+ nColNodes = IArray_GetSize( self->colInc );
+ colNodes = IArray_GetPtr( self->colInc );
+
+ for( n_j = 0; n_j < nColNodes; n_j++ ) {
+ for( dof_j = 0; dof_j < colDofs->dofCounts[colNodes[n_j]]; dof_j++ ) {
+ colEq = colEqNum->destinationArray[colNodes[n_j]][dof_j];
+
+ if( colEq == -1 ) continue;
+ if( !STree_Has( candColEqs, &colEq ) ) {
+ STree_Insert( candColEqs, &colEq );
+ if( STreeMap_HasKey( colEqNum->ownedMap, &colEq ) )
+ nDiagNonZeros[localRowEq]++;
+ else
+ nOffDiagNonZeros[localRowEq]++;
+ netNonZeros++;
+ }
+ }
+ }
+ }
+ }
+ }
+ self->diagonalNonZeroIndices = (Index*)nDiagNonZeros;
+ self->offDiagonalNonZeroIndices = (Index*)nOffDiagNonZeros;
+
+ {
+ int tmp;
+ MPI_Allreduce( &netNonZeros, &tmp, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD );
+ netNonZeros = tmp;
+ }
+ Journal_Printf( stream, "Found %d nonzero entries.\n", netNonZeros );
+ Journal_Printf( stream, "Done.\n" );
+ Stream_UnIndent( stream );
+ Stream_UnIndent( stream );
+}
+
+
+Bool StiffnessMatrix_ZeroBCsAsm_RowR( void* stiffMat, Assembler* assm ) {
+ memset( ((StiffnessMatrix*)stiffMat)->elStiffMat[assm->rowInd], 0, ((StiffnessMatrix*)stiffMat)->nColDofs * sizeof(double) );
+
+ return False;
+}
+
+Bool StiffnessMatrix_ZeroBCsAsm_ColR( void* stiffMat, Assembler* assm ) {
+ ((StiffnessMatrix*)stiffMat)->elStiffMat[assm->rowInd][assm->colInd] = 0.0;
+ return True;
+}
+
+Bool StiffnessMatrix_BCAsm_ColR( void* stiffMat, Assembler* assm ) {
+ double bc;
+
+ bc = DofLayout_GetValueDouble( assm->colVar->dofLayout, assm->colNodeInd, assm->colDofInd );
+ ((StiffnessMatrix*)stiffMat)->bcVals[assm->rowInd] -= bc * ((StiffnessMatrix*)stiffMat)->elStiffMat[assm->rowInd][assm->colInd];
+
+ return True;
+}
+
+Bool StiffnessMatrix_TransBCAsm_ColR( void* stiffMat, Assembler* assm ) {
+ double bc;
+
+ bc = DofLayout_GetValueDouble( assm->colVar->dofLayout, assm->colNodeInd, assm->colDofInd );
+ ((StiffnessMatrix*)stiffMat)->bcVals[assm->rowInd] -= bc * ((StiffnessMatrix*)stiffMat)->elStiffMat[assm->colInd][assm->rowInd];
+
+ return True;
+}
+
+Bool StiffnessMatrix_DiagBCsAsm_RowR( void* stiffMat, Assembler* assm ) {
+ static const double one = 1.0;
+
+ MatSetValues( ((StiffnessMatrix*)stiffMat)->matrix, 1, (PetscInt*)(&assm->rowEq), 1, (PetscInt*)(&assm->rowEq), (double*)&one, ADD_VALUES );
+
+ return True;
+}
+
+void StiffnessMatrix_AddModifyCallback( StiffnessMatrix* self, void* callback, void* object ) {
+ self->nModifyCBs++;
+ self->modifyCBs = ReallocArray( self->modifyCBs, Callback, self->nModifyCBs );
+ self->modifyCBs[self->nModifyCBs - 1].callback = callback;
+ self->modifyCBs[self->nModifyCBs - 1].object = object;
+}
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/StiffnessMatrixTerm.c
--- a/SLE/SystemSetup/src/StiffnessMatrixTerm.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,285 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: StiffnessMatrixTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "FiniteElementContext.h"
-#include "StiffnessMatrixTerm.h"
-#include "SolutionVector.h"
-#include "StiffnessMatrix.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-#include "EntryPoint.h"
-
-/* Textual name of this class */
-const Type StiffnessMatrixTerm_Type = "StiffnessMatrixTerm";
-
-StiffnessMatrixTerm* StiffnessMatrixTerm_New(
- Name name,
- FiniteElementContext* context,
- StiffnessMatrix* stiffnessMatrix,
- Swarm* integrationSwarm,
- Stg_Component* extraInfo )
-{
- StiffnessMatrixTerm* self = (StiffnessMatrixTerm*) _StiffnessMatrixTerm_DefaultNew( name );
-
- _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, extraInfo );
-
- return self;
-}
-
-StiffnessMatrixTerm* _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_DEFARGS )
-{
- StiffnessMatrixTerm* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(StiffnessMatrixTerm) );
- /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
- /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
- and so should be set to ZERO in any children of this class. */
- nameAllocationType = NON_GLOBAL;
-
- self = (StiffnessMatrixTerm*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- self->_assembleElement = _assembleElement;
-
- return self;
-}
-
-
-void _StiffnessMatrixTerm_Init(
- void* stiffnessMatrixTerm,
- FiniteElementContext* context,
- StiffnessMatrix* stiffnessMatrix,
- Swarm* integrationSwarm,
- Stg_Component* extraInfo )
-{
- StiffnessMatrixTerm* self = (StiffnessMatrixTerm*) stiffnessMatrixTerm;
-
- self->isConstructed = True;
- self->context = context;
- self->debug = Journal_MyStream( Debug_Type, self );
- self->extraInfo = extraInfo;
- self->integrationSwarm = integrationSwarm;
- self->stiffnessMatrix = stiffnessMatrix;
- self->max_nElNodes = 0; /* initialise to zero, in assembly routine it will change value */
- self->GNx = NULL;
-
- StiffnessMatrix_AddStiffnessMatrixTerm( stiffnessMatrix, self );
-}
-
-void _StiffnessMatrixTerm_Delete( void* stiffnessMatrixTerm ) {
- StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
-
- Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
-
- /* Stg_Class_Delete parent*/
- _Stg_Component_Delete( self );
-}
-
-
-void _StiffnessMatrixTerm_Print( void* stiffnessMatrixTerm, Stream* stream ) {
- StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
-
- /* General info */
- Journal_Printf( stream, "StiffnessMatrixTerm (ptr): %p\n", self );
-
- /* Print parent */
- _Stg_Component_Print( self, stream );
-
- /* StiffnessMatrixTerm info */
- Journal_Printf( stream, "\tintegrationSwarm (ptr): %p\n", self->integrationSwarm );
- Journal_Printf( stream, "\textraInfo (ptr): %p\n", self->extraInfo );
-}
-
-
-void* _StiffnessMatrixTerm_Copy( const void* stiffnessMatrixTerm, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
- StiffnessMatrixTerm* newStiffnessMatrixTerm;
- PtrMap* map = ptrMap;
- Bool ownMap = False;
-
- if( !map ) {
- map = PtrMap_New( 10 );
- ownMap = True;
- }
-
- newStiffnessMatrixTerm = (StiffnessMatrixTerm*)_Stg_Component_Copy( self, dest, deep, nameExt, map );
-
- newStiffnessMatrixTerm->extraInfo = self->extraInfo;
- if( deep ) {
- newStiffnessMatrixTerm->integrationSwarm = (Swarm*)Stg_Class_Copy( self->integrationSwarm, NULL, deep, nameExt, map );
- }
- else {
- newStiffnessMatrixTerm->integrationSwarm = self->integrationSwarm;
- }
-
- if( ownMap ) {
- Stg_Class_Delete( map );
- }
-
- return (void*)newStiffnessMatrixTerm;
-}
-
-void* _StiffnessMatrixTerm_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(StiffnessMatrixTerm);
- Type type = StiffnessMatrixTerm_Type;
- Stg_Class_DeleteFunction* _delete = _StiffnessMatrixTerm_Delete;
- Stg_Class_PrintFunction* _print = _StiffnessMatrixTerm_Print;
- Stg_Class_CopyFunction* _copy = _StiffnessMatrixTerm_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StiffnessMatrixTerm_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _StiffnessMatrixTerm_AssignFromXML;
- Stg_Component_BuildFunction* _build = _StiffnessMatrixTerm_Build;
- Stg_Component_InitialiseFunction* _initialise = _StiffnessMatrixTerm_Initialise;
- Stg_Component_ExecuteFunction* _execute = _StiffnessMatrixTerm_Execute;
- Stg_Component_DestroyFunction* _destroy = _StiffnessMatrixTerm_Destroy;
- StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _StiffnessMatrixTerm_AssembleElement;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
-}
-
-void _StiffnessMatrixTerm_AssignFromXML( void* stiffnessMatrixTerm, Stg_ComponentFactory* cf, void* data ) {
- StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
- Swarm* swarm = NULL;
- Stg_Component* extraInfo;
- StiffnessMatrix* stiffnessMatrix;
- FiniteElementContext* context;
-
- context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", FiniteElementContext, False, data );
- if( !context )
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
-
- stiffnessMatrix = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"StiffnessMatrix", StiffnessMatrix, True, data ) ;
- swarm = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Swarm", Swarm, True, data ) ;
- extraInfo = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ExtraInfo", Stg_Component, False, data );
-
- _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, swarm, extraInfo );
-}
-
-void _StiffnessMatrixTerm_Build( void* stiffnessMatrixTerm, void* data ) {
- StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
-
- Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
-
- /* ensure integrationSwarm is built */
- Stg_Component_Build( self->integrationSwarm, data, False );
-
- if ( self->extraInfo )
- Stg_Component_Build( self->extraInfo, data, False );
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _StiffnessMatrixTerm_Initialise( void* stiffnessMatrixTerm, void* data ) {
- StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
-
- Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
- Stream_IndentBranch( StgFEM_Debug );
-
- Stg_Component_Initialise( self->integrationSwarm, data, False );
- if ( self->extraInfo )
- Stg_Component_Initialise( self->extraInfo, data, False );
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-void _StiffnessMatrixTerm_Execute( void* stiffnessMatrixTerm, void* data ) {
-}
-
-void _StiffnessMatrixTerm_Destroy( void* stiffnessMatrixTerm, void* data ) {
- StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
- /* free GNx memory */
- if( self->GNx ) Memory_Free( self->GNx );
-}
-
-void StiffnessMatrixTerm_AssembleElement(
- void* stiffnessMatrixTerm,
- StiffnessMatrix* stiffnessMatrix,
- Element_LocalIndex lElement_I,
- SystemLinearEquations* sle,
- FiniteElementContext* context,
- double** elStiffMatToAdd )
-{
- StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
-
- self->_assembleElement( self, stiffnessMatrix, lElement_I, sle, context, elStiffMatToAdd );
-}
-
-void _StiffnessMatrixTerm_AssembleElement(
- void* stiffnessMatrixTerm,
- StiffnessMatrix* stiffnessMatrix,
- Element_LocalIndex lElement_I,
- SystemLinearEquations* sle,
- FiniteElementContext* context,
- double** elStiffMatToAdd )
-{
- StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
- Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
-
- Journal_Printf( errorStream, "Error in func %s for %s '%s' - "
- "This function is the default function which should never be called - "
- "Please set this virtual function with appropriate application dependent function.\n",
- __func__, self->type, self->name );
- abort();
-}
-
-void StiffnessMatrixTerm_SetAssembleElementFunction( void* stiffnessMatrixTerm, StiffnessMatrixTerm_AssembleElementFunction* assembleElementFunction ) {
- StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
-
- self->_assembleElement = assembleElementFunction;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/StiffnessMatrixTerm.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/StiffnessMatrixTerm.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,285 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: StiffnessMatrixTerm.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "FiniteElementContext.h"
+#include "StiffnessMatrixTerm.h"
+#include "SolutionVector.h"
+#include "StiffnessMatrix.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include "EntryPoint.h"
+
+/* Textual name of this class */
+const Type StiffnessMatrixTerm_Type = "StiffnessMatrixTerm";
+
+StiffnessMatrixTerm* StiffnessMatrixTerm_New(
+ Name name,
+ FiniteElementContext* context,
+ StiffnessMatrix* stiffnessMatrix,
+ Swarm* integrationSwarm,
+ Stg_Component* extraInfo )
+{
+ StiffnessMatrixTerm* self = (StiffnessMatrixTerm*) _StiffnessMatrixTerm_DefaultNew( name );
+
+ _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, integrationSwarm, extraInfo );
+
+ return self;
+}
+
+StiffnessMatrixTerm* _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_DEFARGS )
+{
+ StiffnessMatrixTerm* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(StiffnessMatrixTerm) );
+ /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
+ /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
+ and so should be set to ZERO in any children of this class. */
+ nameAllocationType = NON_GLOBAL;
+
+ self = (StiffnessMatrixTerm*)_Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ self->_assembleElement = _assembleElement;
+
+ return self;
+}
+
+
+void _StiffnessMatrixTerm_Init(
+ void* stiffnessMatrixTerm,
+ FiniteElementContext* context,
+ StiffnessMatrix* stiffnessMatrix,
+ Swarm* integrationSwarm,
+ Stg_Component* extraInfo )
+{
+ StiffnessMatrixTerm* self = (StiffnessMatrixTerm*) stiffnessMatrixTerm;
+
+ self->isConstructed = True;
+ self->context = context;
+ self->debug = Journal_MyStream( Debug_Type, self );
+ self->extraInfo = extraInfo;
+ self->integrationSwarm = integrationSwarm;
+ self->stiffnessMatrix = stiffnessMatrix;
+ self->max_nElNodes = 0; /* initialise to zero, in assembly routine it will change value */
+ self->GNx = NULL;
+
+ StiffnessMatrix_AddStiffnessMatrixTerm( stiffnessMatrix, self );
+}
+
+void _StiffnessMatrixTerm_Delete( void* stiffnessMatrixTerm ) {
+ StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
+
+ Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
+
+ /* Stg_Class_Delete parent*/
+ _Stg_Component_Delete( self );
+}
+
+
+void _StiffnessMatrixTerm_Print( void* stiffnessMatrixTerm, Stream* stream ) {
+ StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
+
+ /* General info */
+ Journal_Printf( stream, "StiffnessMatrixTerm (ptr): %p\n", self );
+
+ /* Print parent */
+ _Stg_Component_Print( self, stream );
+
+ /* StiffnessMatrixTerm info */
+ Journal_Printf( stream, "\tintegrationSwarm (ptr): %p\n", self->integrationSwarm );
+ Journal_Printf( stream, "\textraInfo (ptr): %p\n", self->extraInfo );
+}
+
+
+void* _StiffnessMatrixTerm_Copy( const void* stiffnessMatrixTerm, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
+ StiffnessMatrixTerm* newStiffnessMatrixTerm;
+ PtrMap* map = ptrMap;
+ Bool ownMap = False;
+
+ if( !map ) {
+ map = PtrMap_New( 10 );
+ ownMap = True;
+ }
+
+ newStiffnessMatrixTerm = (StiffnessMatrixTerm*)_Stg_Component_Copy( self, dest, deep, nameExt, map );
+
+ newStiffnessMatrixTerm->extraInfo = self->extraInfo;
+ if( deep ) {
+ newStiffnessMatrixTerm->integrationSwarm = (Swarm*)Stg_Class_Copy( self->integrationSwarm, NULL, deep, nameExt, map );
+ }
+ else {
+ newStiffnessMatrixTerm->integrationSwarm = self->integrationSwarm;
+ }
+
+ if( ownMap ) {
+ Stg_Class_Delete( map );
+ }
+
+ return (void*)newStiffnessMatrixTerm;
+}
+
+void* _StiffnessMatrixTerm_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(StiffnessMatrixTerm);
+ Type type = StiffnessMatrixTerm_Type;
+ Stg_Class_DeleteFunction* _delete = _StiffnessMatrixTerm_Delete;
+ Stg_Class_PrintFunction* _print = _StiffnessMatrixTerm_Print;
+ Stg_Class_CopyFunction* _copy = _StiffnessMatrixTerm_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StiffnessMatrixTerm_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _StiffnessMatrixTerm_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _StiffnessMatrixTerm_Build;
+ Stg_Component_InitialiseFunction* _initialise = _StiffnessMatrixTerm_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _StiffnessMatrixTerm_Execute;
+ Stg_Component_DestroyFunction* _destroy = _StiffnessMatrixTerm_Destroy;
+ StiffnessMatrixTerm_AssembleElementFunction* _assembleElement = _StiffnessMatrixTerm_AssembleElement;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _StiffnessMatrixTerm_New( STIFFNESSMATRIXTERM_PASSARGS );
+}
+
+void _StiffnessMatrixTerm_AssignFromXML( void* stiffnessMatrixTerm, Stg_ComponentFactory* cf, void* data ) {
+ StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
+ Swarm* swarm = NULL;
+ Stg_Component* extraInfo;
+ StiffnessMatrix* stiffnessMatrix;
+ FiniteElementContext* context;
+
+ context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", FiniteElementContext, False, data );
+ if( !context )
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
+
+ stiffnessMatrix = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"StiffnessMatrix", StiffnessMatrix, True, data ) ;
+ swarm = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Swarm", Swarm, True, data ) ;
+ extraInfo = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"ExtraInfo", Stg_Component, False, data );
+
+ _StiffnessMatrixTerm_Init( self, context, stiffnessMatrix, swarm, extraInfo );
+}
+
+void _StiffnessMatrixTerm_Build( void* stiffnessMatrixTerm, void* data ) {
+ StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
+
+ Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ /* ensure integrationSwarm is built */
+ Stg_Component_Build( self->integrationSwarm, data, False );
+
+ if ( self->extraInfo )
+ Stg_Component_Build( self->extraInfo, data, False );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _StiffnessMatrixTerm_Initialise( void* stiffnessMatrixTerm, void* data ) {
+ StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
+
+ Journal_DPrintf( self->debug, "In %s - for %s\n", __func__, self->name );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ Stg_Component_Initialise( self->integrationSwarm, data, False );
+ if ( self->extraInfo )
+ Stg_Component_Initialise( self->extraInfo, data, False );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+void _StiffnessMatrixTerm_Execute( void* stiffnessMatrixTerm, void* data ) {
+}
+
+void _StiffnessMatrixTerm_Destroy( void* stiffnessMatrixTerm, void* data ) {
+ StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
+ /* free GNx memory */
+ if( self->GNx ) Memory_Free( self->GNx );
+}
+
+void StiffnessMatrixTerm_AssembleElement(
+ void* stiffnessMatrixTerm,
+ StiffnessMatrix* stiffnessMatrix,
+ Element_LocalIndex lElement_I,
+ SystemLinearEquations* sle,
+ FiniteElementContext* context,
+ double** elStiffMatToAdd )
+{
+ StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
+
+ self->_assembleElement( self, stiffnessMatrix, lElement_I, sle, context, elStiffMatToAdd );
+}
+
+void _StiffnessMatrixTerm_AssembleElement(
+ void* stiffnessMatrixTerm,
+ StiffnessMatrix* stiffnessMatrix,
+ Element_LocalIndex lElement_I,
+ SystemLinearEquations* sle,
+ FiniteElementContext* context,
+ double** elStiffMatToAdd )
+{
+ StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
+
+ Journal_Printf( errorStream, "Error in func %s for %s '%s' - "
+ "This function is the default function which should never be called - "
+ "Please set this virtual function with appropriate application dependent function.\n",
+ __func__, self->type, self->name );
+ abort();
+}
+
+void StiffnessMatrixTerm_SetAssembleElementFunction( void* stiffnessMatrixTerm, StiffnessMatrixTerm_AssembleElementFunction* assembleElementFunction ) {
+ StiffnessMatrixTerm* self = (StiffnessMatrixTerm*)stiffnessMatrixTerm;
+
+ self->_assembleElement = assembleElementFunction;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/SystemLinearEquations.c
--- a/SLE/SystemSetup/src/SystemLinearEquations.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1408 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student Monash University, VPAC. (davidm at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: SystemLinearEquations.c 1230 2008-09-15 01:44:43Z DavidLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <petsc.h>
-#include <petscvec.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "units.h"
-#include "types.h"
-#include "shortcuts.h"
-#include "SystemLinearEquations.h"
-#include "SLE_Solver.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-#include "StiffnessMatrix.h"
-#include "SolutionVector.h"
-#include "ForceVector.h"
-#include "FiniteElementContext.h"
-
-
-/* Textual name of this class */
-const Type SystemLinearEquations_Type = "SystemLinearEquations";
-
-/** Constructor */
-SystemLinearEquations* SystemLinearEquations_New(
- Name name,
- SLE_Solver* solver,
- void* nlSolver,
- FiniteElementContext* context,
- Bool isNonLinear,
- double nonLinearTolerance,
- Iteration_Index nonLinearMaxIterations,
- Bool killNonConvergent,
- EntryPoint_Register* entryPoint_Register,
- MPI_Comm comm )
-{
- SystemLinearEquations* self = (SystemLinearEquations*)_SystemLinearEquations_DefaultNew( name );
-
- self->isConstructed = True;
- _SystemLinearEquations_Init(
- self,
- solver,
- nlSolver,
- context,
- False, /* TODO: A hack put in place for setting the convergence stream to 'off' if the SLE class is created from within the code, not via an xml */
- isNonLinear,
- nonLinearTolerance,
- nonLinearMaxIterations,
- killNonConvergent,
- 1, /* TODO : hack for setting the minimum number of iterations to 1- same hack as above */
- "",
- "",
- entryPoint_Register,
- comm );
-
- return self;
-}
-
-/* Creation implementation / Virtual constructor */
-SystemLinearEquations* _SystemLinearEquations_New( SYSTEMLINEAREQUATIONS_DEFARGS )
-{
- SystemLinearEquations* self;
-
- /* Allocate memory */
- assert( _sizeOfSelf >= sizeof(SystemLinearEquations) );
- /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
- /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
- and so should be set to ZERO in any children of this class. */
- nameAllocationType = NON_GLOBAL;
-
- self = (SystemLinearEquations*) _Stg_Component_New( STG_COMPONENT_PASSARGS );
-
- /* Virtual info */
- self->_LM_Setup = _LM_Setup;
- self->_matrixSetup = _matrixSetup;
- self->_vectorSetup = _vectorSetup;
- self->_updateSolutionOntoNodes = _updateSolutionOntoNodes;
- self->_mgSelectStiffMats = _mgSelectStiffMats;
-
- self->_sleFormFunction = NULL;
-
- return self;
-}
-
-void _SystemLinearEquations_Init(
- void* sle,
- SLE_Solver* solver,
- void* nlSolver,
- FiniteElementContext* context,
- Bool makeConvergenceFile,
- Bool isNonLinear,
- double nonLinearTolerance,
- Iteration_Index nonLinearMaxIterations,
- Bool killNonConvergent,
- Iteration_Index nonLinearMinIterations,
- Name nonLinearSolutionType,
- Name optionsPrefix,
- EntryPoint_Register* entryPoint_Register,
- MPI_Comm comm )
-{
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
- char* filename;
- char* optionsName;
-
- self->extensionManager = ExtensionManager_New_OfExistingObject( self->name, self );
-
- self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type );
- self->info = Journal_MyStream( Info_Type, self );
- /* Note: currently we're sending self->info to the master proc only so there's not too much
- identical timing info printed. May want to fine-tune later so that some info does get
- printed on all procs. */
- Stream_SetPrintingRank( self->info, 0 );
-
- self->makeConvergenceFile = makeConvergenceFile;
- if ( self->makeConvergenceFile ) {
- self->convergenceStream = Journal_Register( InfoStream_Type, (Name)"Convergence Info" );
- Stg_asprintf( &filename, "Convergence.dat" );
- Stream_RedirectFile_WithPrependedPath( self->convergenceStream, context->outputPath, filename );
- Stream_SetPrintingRank( self->convergenceStream, 0 );
- Memory_Free( filename );
- Journal_Printf( self->convergenceStream , "Timestep\tIteration\tResidual\tTolerance\n" );
- }
-
- self->comm = comm;
- self->solver = solver;
- self->nlSolver = (SNES)nlSolver;
- self->stiffnessMatrices = Stg_ObjectList_New();
- self->forceVectors = Stg_ObjectList_New();
- self->solutionVectors = Stg_ObjectList_New();
- self->bcRemoveQuery = True;
- self->context = context;
-
- /* Init NonLinear Stuff */
- self->nonLinearSolutionType = nonLinearSolutionType; /* This will never got propogated through to _Initialise->SetToNonLinear if we keep it in the loop */
- if ( isNonLinear ) {
- self->nonLinearSolutionType = nonLinearSolutionType;
- SystemLinearEquations_SetToNonLinear( self );
- }
- self->nonLinearTolerance = nonLinearTolerance;
- self->nonLinearMaxIterations = nonLinearMaxIterations;
- self->killNonConvergent = killNonConvergent;
- self->nonLinearMinIterations = nonLinearMinIterations;
- self->curResidual = 0.0;
- self->curSolveTime = 0.0;
- /* _ /0 */
- optionsName = Memory_Alloc_Array_Unnamed( char, strlen(optionsPrefix) + 1 + 1 );
- sprintf( optionsName, "%s_", optionsPrefix );
- self->optionsPrefix = optionsName;
-
- /* BEGIN LUKE'S FRICTIONAL BCS BIT */
- Stg_asprintf( &self->nlSetupEPName, "%s-nlSetupEP", self->name );
- self->nlSetupEP = EntryPoint_New( self->nlSetupEPName, EntryPoint_2VoidPtr_CastType );
- Stg_asprintf( &self->nlEPName, "%s-nlEP", self->name );
- self->nlEP = EntryPoint_New( self->nlEPName, EntryPoint_2VoidPtr_CastType );
- Stg_asprintf( &self->nlEPName, "%s-postNlEP", self->name );
- self->postNlEP = EntryPoint_New( self->postNlEPName, EntryPoint_2VoidPtr_CastType );
- Stg_asprintf( &self->nlConvergedEPName, "%s-nlConvergedEP", self->name );
- self->nlConvergedEP = EntryPoint_New( self->nlConvergedEPName, EntryPoint_2VoidPtr_CastType );
- /* END LUKE'S FRICTIONAL BCS BIT */
- self->nlFormJacobian = False;
- self->nlCurIterate = PETSC_NULL;
-
- /* Initialise MG stuff. */
- self->mgEnabled = False;
- self->mgUpdate = True;
- self->nMGHandles = 0;
- self->mgHandles = NULL;
-
- /* Create Execute Entry Point */
- Stg_asprintf( &self->executeEPName, "%s-execute", self->name );
- self->executeEP = EntryPoint_New( self->executeEPName, EntryPoint_2VoidPtr_CastType );
-
- /* Add default hooks to Execute E.P. */
- EntryPoint_Append( self->executeEP, "BC_Setup", (void*)SystemLinearEquations_BC_Setup, self->type);
- EntryPoint_Append( self->executeEP, "LM_Setup", (void*)SystemLinearEquations_LM_Setup, self->type);
- EntryPoint_Append( self->executeEP, "IntegrationSetup", (void*)SystemLinearEquations_IntegrationSetup, self->type );
- EntryPoint_Append( self->executeEP, "ZeroAllVectors", (void*)SystemLinearEquations_ZeroAllVectors, self->type);
- EntryPoint_Append( self->executeEP, "MatrixSetup", (void*)SystemLinearEquations_MatrixSetup, self->type);
- EntryPoint_Append( self->executeEP, "VectorSetup", (void*)SystemLinearEquations_VectorSetup, self->type);
- EntryPoint_Append( self->executeEP, "ExecuteSolver", (void*)SystemLinearEquations_ExecuteSolver, self->type);
- EntryPoint_Append( self->executeEP, "UpdateSolutionOntoNodes",(void*)SystemLinearEquations_UpdateSolutionOntoNodes,self->type);
-
- /* Create Integration Setup EP */
- Stg_asprintf( &self->integrationSetupEPName, "%s-integrationSetup", self->name );
- self->integrationSetupEP = EntryPoint_New( self->integrationSetupEPName, EntryPoint_Class_VoidPtr_CastType );
-
- if ( entryPoint_Register )
- EntryPoint_Register_Add( entryPoint_Register, self->executeEP );
- self->entryPoint_Register = entryPoint_Register;
-
- /* Add SLE to Context */
- if ( context )
- FiniteElementContext_AddSLE( context, self );
-}
-
-void _SystemLinearEquations_Delete( void* sle ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- /* delete parent */
- _Stg_Component_Delete( self );
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-void _SystemLinearEquations_Print( void* sle, Stream* stream ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- /* General info */
- Journal_Printf( stream, "SystemLinearEquations (ptr): %p\n", self );
- _Stg_Component_Print( self, stream );
-
- /* Virtual info */
- Stg_Class_Print( self->stiffnessMatrices, stream );
- Stg_Class_Print( self->forceVectors, stream );
- Stg_Class_Print( self->solutionVectors, stream );
-
- /* other info */
- Journal_PrintPointer( stream, self->extensionManager );
- Journal_Printf( stream, "\tcomm: %u\n", self->comm );
- Journal_Printf( stream, "\tsolver (ptr): %p\n", self->solver );
- Stg_Class_Print( self->solver, stream );
-}
-
-void* _SystemLinearEquations_Copy( const void* sle, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
- SystemLinearEquations* newSLE;
- PtrMap* map = ptrMap;
- Bool ownMap = False;
-
- if( !map ) {
- map = PtrMap_New( 10 );
- ownMap = True;
- }
-
- newSLE = (SystemLinearEquations*)_Stg_Component_Copy( sle, dest, deep, nameExt, map );
-
- /* Virtual methods */
- newSLE->_LM_Setup = self->_LM_Setup;
- newSLE->_matrixSetup = self->_matrixSetup;
- newSLE->_vectorSetup = self->_vectorSetup;
- newSLE->_mgSelectStiffMats = self->_mgSelectStiffMats;
-
- newSLE->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, newSLE->type );
- newSLE->comm = self->comm;
-
- if( deep ) {
- newSLE->solver = (SLE_Solver*)Stg_Class_Copy( self->solver, NULL, deep, nameExt, map );
- newSLE->stiffnessMatrices = (StiffnessMatrixList*)Stg_Class_Copy( self->stiffnessMatrices, NULL, deep, nameExt, map );
- newSLE->forceVectors = (ForceVectorList*)Stg_Class_Copy( self->forceVectors, NULL, deep, nameExt, map );
- newSLE->solutionVectors = (SolutionVectorList*)Stg_Class_Copy( self->solutionVectors, NULL, deep, nameExt, map );
- if( (newSLE->extensionManager = (ExtensionManager*)PtrMap_Find( map, self->extensionManager )) == NULL ) {
- newSLE->extensionManager = (ExtensionManager*)Stg_Class_Copy( self->extensionManager, NULL, deep, nameExt, map );
- PtrMap_Append( map, self->extensionManager, newSLE->extensionManager );
- }
- }
- else {
- newSLE->solver = self->solver;
- newSLE->stiffnessMatrices = self->stiffnessMatrices;
- newSLE->forceVectors = self->forceVectors;
- newSLE->solutionVectors = self->solutionVectors;
- }
-
- if( ownMap ) {
- Stg_Class_Delete( map );
- }
-
- return newSLE;
-}
-
-void* _SystemLinearEquations_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(SystemLinearEquations);
- Type type = SystemLinearEquations_Type;
- Stg_Class_DeleteFunction* _delete = _SystemLinearEquations_Delete;
- Stg_Class_PrintFunction* _print = _SystemLinearEquations_Print;
- Stg_Class_CopyFunction* _copy = _SystemLinearEquations_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _SystemLinearEquations_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _SystemLinearEquations_AssignFromXML;
- Stg_Component_BuildFunction* _build = _SystemLinearEquations_Build;
- Stg_Component_InitialiseFunction* _initialise = _SystemLinearEquations_Initialise;
- Stg_Component_ExecuteFunction* _execute = _SystemLinearEquations_Execute;
- Stg_Component_DestroyFunction* _destroy = _SystemLinearEquations_Destroy;
- SystemLinearEquations_LM_SetupFunction* _LM_Setup = _SystemLinearEquations_LM_Setup;
- SystemLinearEquations_MatrixSetupFunction* _matrixSetup = _SystemLinearEquations_MatrixSetup;
- SystemLinearEquations_VectorSetupFunction* _vectorSetup = _SystemLinearEquations_VectorSetup;
- SystemLinearEquations_UpdateSolutionOntoNodesFunc* _updateSolutionOntoNodes = _SystemLinearEquations_UpdateSolutionOntoNodes;
- SystemLinearEquations_MG_SelectStiffMatsFunc* _mgSelectStiffMats = _SystemLinearEquations_MG_SelectStiffMats;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _SystemLinearEquations_New( SYSTEMLINEAREQUATIONS_PASSARGS );
-}
-
-void _SystemLinearEquations_AssignFromXML( void* sle, Stg_ComponentFactory* cf, void* data ){
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
- SLE_Solver* solver = NULL;
- void* entryPointRegister = NULL;
- FiniteElementContext* context = NULL;
- double nonLinearTolerance;
- Iteration_Index nonLinearMaxIterations;
- Bool isNonLinear;
- Bool killNonConvergent;
- Bool makeConvergenceFile;
- Iteration_Index nonLinearMinIterations;
- Name nonLinearSolutionType;
- SNES nlSolver = NULL;
- Name optionsPrefix;
-
- solver = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)SLE_Solver_Type, SLE_Solver, False, data ) ;
-
- makeConvergenceFile = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"makeConvergenceFile", False );
- isNonLinear = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"isNonLinear", False );
- nonLinearTolerance = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"nonLinearTolerance", 0.01 );
- nonLinearMaxIterations = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"nonLinearMaxIterations", 500 );
- killNonConvergent = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"killNonConvergent", True );
- nonLinearMinIterations = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"nonLinearMinIterations", 1 );
- nonLinearSolutionType = Stg_ComponentFactory_GetString( cf, self->name, (Dictionary_Entry_Key)"nonLinearSolutionType", "default" );
- optionsPrefix = Stg_ComponentFactory_GetString( cf, self->name, (Dictionary_Entry_Key)"optionsPrefix", "" );
-
- /* Read some value for Picard */
- self->picard_form_function_type = Stg_ComponentFactory_GetString( cf, self->name, (Dictionary_Entry_Key)"picard_FormFunctionType", "PicardFormFunction_KSPResidual" );
-
- self->alpha = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"picard_alpha", 1.0 );
- self->rtol = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"picard_rtol", 1.0e-8 );
- self->abstol = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"picard_atol", 1.0e-50 );
- self->xtol = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"picard_xtol", 1.0e-8 );
- self->picard_monitor = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"picard_ActivateMonitor", False );
-
- context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", FiniteElementContext, False, data );
- if( !context )
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
-
- entryPointRegister = context->entryPoint_Register;
- assert( entryPointRegister );
-
- if( isNonLinear ) {
- SNESCreate( context->communicator, &nlSolver );
- self->linearSolveInitGuess = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"linearSolveInitialGuess", False );
- }
-
- _SystemLinearEquations_Init(
- self,
- solver,
- nlSolver,
- context,
- makeConvergenceFile,
- isNonLinear,
- nonLinearTolerance,
- nonLinearMaxIterations,
- killNonConvergent,
- nonLinearMinIterations,
- nonLinearSolutionType,
- optionsPrefix,
- (EntryPoint_Register*)entryPointRegister,
- MPI_COMM_WORLD );
-
- VecCreate( self->comm, &self->X );
- VecCreate( self->comm, &self->F );
- MatCreate( self->comm, &self->A );
- MatCreate( self->comm, &self->J );
-}
-
-/* Build */
-void _SystemLinearEquations_Build( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
- Index index;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- /* build the matrices */
- for ( index = 0; index < self->stiffnessMatrices->count; index++ ) {
- /* Update rowSize and colSize if boundary conditions have been applied */
- Stg_Component_Build( self->stiffnessMatrices->data[index], _context, False );
- }
-
- /* and the vectors */
- for ( index = 0; index < self->forceVectors->count; index++ ) {
- /* Build the force vectors - includes updateing matrix size based on Dofs */
- Stg_Component_Build( self->forceVectors->data[index], _context, False );
- }
-
- /* and the solutions */
- for ( index = 0; index < self->solutionVectors->count; index++ ) {
- /* Build the force vectors - includes updateing matrix size based on Dofs */
- Stg_Component_Build( self->solutionVectors->data[index], _context, False );
- }
-
- /* lastly, the solver - if required */
- if( self->solver )
- Stg_Component_Build( self->solver, self, False );
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _SystemLinearEquations_Initialise( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
- Index index;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- /* initialise the matrices */
- for ( index = 0; index < self->stiffnessMatrices->count; index++ ) {
- /* Update rowSize and colSize if boundary conditions have been applied */
- Stg_Component_Initialise( self->stiffnessMatrices->data[index], _context, False );
- }
-
- /* and the vectors */
- for ( index = 0; index < self->forceVectors->count; index++ ) {
- /* Initialise the force vectors - includes updateing matrix size based on Dofs */
- Stg_Component_Initialise( self->forceVectors->data[index], _context, False );
- }
-
- /* and the solutions */
- for ( index = 0; index < self->solutionVectors->count; index++ ) {
- /* Initialise the force vectors - includes updateing matrix size based on Dofs */
- Stg_Component_Initialise( self->solutionVectors->data[index], _context, False );
- }
-
- /* Check to see if any of the components need to make the SLE non-linear */
- SystemLinearEquations_CheckIfNonLinear( self );
-
- /* Setup Location Matrix */
- SystemLinearEquations_LM_Setup( self, _context );
-
- /* lastly, the solver, if required */
- if( self->solver )
- Stg_Component_Initialise( self->solver, self, False );
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void _SystemLinearEquations_Execute( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- _EntryPoint_Run_2VoidPtr( self->executeEP, sle, _context );
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void SystemLinearEquations_ExecuteSolver( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
- double wallTime;
- /* Actually run the solver to get the new values into the SolutionVectors */
-
- Journal_Printf(self->info,"Linear solver (%s) \n",self->executeEPName);
-
- wallTime = MPI_Wtime();
- if( self->solver )
- Stg_Component_Execute( self->solver, self, True );
-
- self->curSolveTime = MPI_Wtime() - wallTime;
- Journal_Printf(self->info,"Linear solver (%s), solution time %6.6e (secs)\n",self->executeEPName, self->curSolveTime);
-
-}
-
-void _SystemLinearEquations_Destroy( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- /* BEGIN LUKE'S FRICTIONAL BCS BIT */
- Memory_Free( self->nlSetupEPName );
- Memory_Free( self->nlEPName );
- Memory_Free( self->postNlEPName );
- Memory_Free( self->nlConvergedEPName );
- /* END LUKE'S FRICTIONAL BCS BIT */
- Memory_Free( self->executeEPName );
-
- Stg_Class_Delete( self->extensionManager );
-
- Stg_Class_Delete( self->stiffnessMatrices );
- Stg_Class_Delete( self->forceVectors );
- Stg_Class_Delete( self->solutionVectors );
-
- Memory_Free( self->optionsPrefix );
-
- VecDestroy( self->X );
- VecDestroy( self->F );
- MatDestroy( self->A );
- MatDestroy( self->J );
-
- /* Free the the MG handles. */
- FreeArray( self->mgHandles );
-}
-
-void SystemLinearEquations_BC_Setup( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
- Index index;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- for ( index = 0; index < self->solutionVectors->count; index++ ) {
- SolutionVector_ApplyBCsToVariables( self->solutionVectors->data[index], _context );
- }
-}
-
-
-void SystemLinearEquations_LM_Setup( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- self->_LM_Setup( self, _context );
-}
-
-void SystemLinearEquations_IntegrationSetup( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- _EntryPoint_Run_Class_VoidPtr( self->integrationSetupEP, _context );
-}
-
-void _SystemLinearEquations_LM_Setup( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
- Index index;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
- /* For each feVariable of each stiffness matrix, build the LM */
- for ( index = 0; index < self->stiffnessMatrices->count; index++ ) {
- StiffnessMatrix* sm = (StiffnessMatrix*)self->stiffnessMatrices->data[index];
-
- FeEquationNumber_BuildLocationMatrix( sm->rowVariable->eqNum );
- FeEquationNumber_BuildLocationMatrix( sm->columnVariable->eqNum );
- }
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-void SystemLinearEquations_MatrixSetup( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- self->_matrixSetup( self, _context );
-}
-
-void _SystemLinearEquations_MatrixSetup( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
- FiniteElementContext* context = (FiniteElementContext*)_context;
- Index index;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
- for ( index = 0; index < self->stiffnessMatrices->count; index++ ) {
- StiffnessMatrix_Assemble( self->stiffnessMatrices->data[index], self->bcRemoveQuery, self, context );
- }
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void SystemLinearEquations_VectorSetup( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- self->_vectorSetup( self, _context );
-}
-
-void _SystemLinearEquations_VectorSetup( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
- Index index;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
- for ( index = 0; index < self->forceVectors->count; index++ ) {
- ForceVector_Assemble( self->forceVectors->data[index] );
- }
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-Index _SystemLinearEquations_AddStiffnessMatrix( void* sle, StiffnessMatrix* stiffnessMatrix ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- return SystemLinearEquations_AddStiffnessMatrix( self, stiffnessMatrix );
-}
-
-StiffnessMatrix* _SystemLinearEquations_GetStiffnessMatrix( void* sle, Name stiffnessMatrixName ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- return SystemLinearEquations_GetStiffnessMatrix( self, stiffnessMatrixName );
-}
-
-Index _SystemLinearEquations_AddForceVector( void* sle, ForceVector* forceVector ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- return SystemLinearEquations_AddForceVector( self, forceVector );
-}
-
-ForceVector* _SystemLinearEquations_GetForceVector( void* sle, Name forceVectorName ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- return SystemLinearEquations_GetForceVector( self, forceVectorName );
-}
-
-Index _SystemLinearEquations_AddSolutionVector( void* sle, SolutionVector* solutionVector ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- return SystemLinearEquations_AddSolutionVector( self, solutionVector );
-}
-
-SolutionVector* _SystemLinearEquations_GetSolutionVector( void* sle, Name solutionVectorName ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- return SystemLinearEquations_GetSolutionVector( self, solutionVectorName );
-}
-
-void SystemLinearEquations_UpdateSolutionOntoNodes( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- self->_updateSolutionOntoNodes( self, _context );
-}
-
-void _SystemLinearEquations_UpdateSolutionOntoNodes( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
- SolutionVector_Index solnVec_I;
- SolutionVector* currentSolnVec;
-
- for ( solnVec_I=0; solnVec_I < self->solutionVectors->count; solnVec_I++ ) {
- currentSolnVec = (SolutionVector*)self->solutionVectors->data[solnVec_I];
- SolutionVector_UpdateSolutionOntoNodes( currentSolnVec );
- }
-}
-
-void SystemLinearEquations_ZeroAllVectors( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
- Index index;
- ForceVector* forceVector;
-
- Journal_DPrintf( self->debug, "In %s\n", __func__ );
- for ( index = 0; index < self->forceVectors->count; index++ ) {
- forceVector = (ForceVector*) self->forceVectors->data[index];
-
- VecSet( forceVector->vector, 0.0 );
- }
-}
-
-/* need to do this before the SLE specific function to set up the
-pre conditioners is called (beginning of solve) */
-void SystemLinearEquations_NewtonInitialise( void* _context, void* data ) {
- FiniteElementContext* context = (FiniteElementContext*)_context;
- SystemLinearEquations* sle = (SystemLinearEquations*)context->slEquations->data[0];
- SNES snes;
- SNES oldSnes = sle->nlSolver;
-
- /* don't assume that a snes is being used for initial guess, check for this!!! */
- if( oldSnes && context->timeStep == 1 && !sle->linearSolveInitGuess )
- SNESDestroy( oldSnes );
-
- SNESCreate( sle->comm, &snes );
-
- sle->nlSolver = snes;
- sle->_setFFunc( &sle->F, context );
-
- SNESSetJacobian( snes, sle->J, sle->P, sle->_buildJ, sle->buildJContext );
- SNESSetFunction( snes, sle->F, sle->_buildF, sle->buildFContext );
-
- /* configure the KSP */
- sle->_configureNLSolverFunc( snes, context );
-}
-
-/* do this after the pre conditoiners have been set up in the problem specific SLE */
-void SystemLinearEquations_NewtonExecute( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*) sle;
- SNES snes = self->nlSolver;
-
- SNESSetOptionsPrefix( snes, self->optionsPrefix );
- SNESSetFromOptions( snes );
- SNESSolve( snes, PETSC_NULL, self->X );
-}
-
-/* do this at end of solve step */
-void SystemLinearEquations_NewtonFinalise( void* _context, void* data ) {
- FiniteElementContext* context = (FiniteElementContext*)_context;
- SystemLinearEquations* sle = (SystemLinearEquations*)context->slEquations->data[0];
- SNES snes = sle->nlSolver;
-
- sle->_updateOldFields( &sle->X, context );
-
- SNESDestroy( snes );
-}
-
-void SystemLinearEquations_NewtonMFFDExecute( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*) sle;
- Vec F;
-
- VecDuplicate( SystemLinearEquations_GetSolutionVectorAt( self, 0 )->vector, &F );
-
- /* creates the nonlinear solver */
- if( self->nlSolver != PETSC_NULL )
- SNESDestroy( self->nlSolver );
- SNESCreate( self->comm, &self->nlSolver );
- SNESSetFunction( self->nlSolver, F, self->_buildF, _context );
-
- // set J (jacobian)
-
- // set F (residual vector)
-
- // call non linear solver func (SNES wrapper)
-}
-
-void SystemLinearEquations_NonLinearExecute( void* sle, void* _context ) {
- SystemLinearEquations* self = (SystemLinearEquations*) sle;
- Vec previousVector;
- Vec currentVector;
- double residual;
- double tolerance = self->nonLinearTolerance;
- Iteration_Index maxIterations = self->nonLinearMaxIterations;
- Bool converged;
- Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
- double wallTime;
- Iteration_Index minIterations = self->nonLinearMinIterations;
- SLE_Solver* solver;
-
- PetscScalar currVecNorm, prevVecNorm;
-
- Journal_Printf( self->info, "In %s\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- wallTime = MPI_Wtime();
-
- /* First Solve */
- /* setting the nonlinear stuff */
- //START OF NONLINEAR ITERATION!!!!!
- /* first get current timestep */
- solver = self->solver;
- solver->currenttimestep = self->context->timeStep;
- /* if current timestep is not the same as previous timestep, then reset all variables back to zero and update previous timestep */
- if(solver->currenttimestep != solver->previoustimestep){
- //update prev timestep
- solver->previoustimestep = solver->currenttimestep;
- solver->nonlinearitsinitialtime = 0;
- solver->nonlinearitsendtime = 0;
- solver->totalnonlinearitstime = 0;
- solver->totalnumnonlinearits = 0;
- solver->avgtimenonlinearits = 0;
- solver->inneritsinitialtime = 0;
- solver->outeritsinitialtime = 0;
- solver->inneritsendtime = 0;
- solver->outeritsendtime = 0;
- solver->totalinneritstime = 0;
- solver->totalouteritstime = 0;
- solver->totalnuminnerits = 0;
- solver->totalnumouterits = 0;
- solver->avgnuminnerits = 0;
- solver->avgnumouterits = 0;
- solver->avgtimeinnerits = 0;
- solver->avgtimeouterits = 0;
- }
-
- self->nonLinearIteration_I = 0;
- Journal_Printf(self->info,"\nNon linear solver - iteration %d\n", self->nonLinearIteration_I);
-
- /* More of Luke's stuff. I need an entry point for a non-linear setup operation. */
- _EntryPoint_Run_2VoidPtr( self->nlSetupEP, sle, _context );
-
- /*Don't know if we should include this but the timing of the outer and inner iterations starts here so it makes sense to count this one? */
- solver->nonlinearitsinitialtime = MPI_Wtime();
-
- self->linearExecute( self, _context );
- self->hasExecuted = True;
-
- solver->nonlinearitsendtime = MPI_Wtime();
- solver->totalnonlinearitstime = solver->totalnonlinearitstime + (-solver->nonlinearitsinitialtime + solver->nonlinearitsendtime);
- /* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */
- solver->nonlinearitsinitialtime = 0;
- solver->nonlinearitsendtime = 0;
- /*
- ** Include an entry point to do some kind of post-non-linear-iteration operation. */
- _EntryPoint_Run_2VoidPtr( self->postNlEP, sle, _context );
-
- /* TODO - Give option which solution vector to test */
- currentVector = SystemLinearEquations_GetSolutionVectorAt( self, 0 )->vector;
- VecDuplicate( currentVector, &previousVector );
-
- for ( self->nonLinearIteration_I = 1 ; self->nonLinearIteration_I < maxIterations ; self->nonLinearIteration_I++ ) {
- /* get initial wall time for nonlinear loop */
- solver->nonlinearitsinitialtime = MPI_Wtime();
-
- /*
- ** BEGIN LUKE'S FRICTIONAL BCS BIT
- **
- ** Adding an interface for allowing other components to add some form of non-linearity to the system.
- ** This is with a focus on frictional BCs, where we want to examine the stress field and modify
- ** traction BCs to enforce friction rules. - Luke 18/07/2007
- */
-
- _EntryPoint_Run_2VoidPtr( self->nlEP, sle, _context );
-
- /*
- ** END LUKE'S FRICTIONAL BCS BIT
- */
-
-
- //Vector_CopyEntries( currentVector, previousVector );
- VecCopy( currentVector, previousVector );
-
- Journal_Printf(self->info,"Non linear solver - iteration %d\n", self->nonLinearIteration_I);
-
- self->linearExecute( self, _context );
-// PetscPrintf( PETSC_COMM_WORLD, "|Xn+1| = %12.12e \n", Vector_L2Norm(SystemLinearEquations_GetSolutionVectorAt(self,1)->vector) );
-
- /* Calculate Residual */
- VecAXPY( previousVector, -1.0, currentVector );
- VecNorm( previousVector, NORM_2, &prevVecNorm );
- VecNorm( currentVector, NORM_2, &currVecNorm );
- residual = ((double)prevVecNorm) / ((double)currVecNorm);
-
- self->curResidual = residual;
-
- /*
- ** Include an entry point to do some kind of post-non-linear-iteration operation. */
- _EntryPoint_Run_2VoidPtr( self->postNlEP, sle, _context );
-
- Journal_Printf( self->info, "In func %s: Iteration %u of %u - Residual %.5g - Tolerance = %.5g\n",
- __func__, self->nonLinearIteration_I, maxIterations, residual, tolerance );
- if ( self->makeConvergenceFile ) {
- Journal_Printf( self->convergenceStream, "%d\t\t%d\t\t%.5g\t\t%.5g\n",
- self->context->timeStep, self->nonLinearIteration_I, residual, tolerance );
- }
-
- /* Check if residual is below tolerance */
- converged = (residual < tolerance) ? True : False;
-
- Journal_Printf(self->info,"Non linear solver - Residual %.8e; Tolerance %.4e%s%s - %6.6e (secs)\n\n", residual, tolerance,
- (converged) ? " - Converged" : " - Not converged",
- (self->nonLinearIteration_I < maxIterations) ? "" : " - Reached iteration limit",
- MPI_Wtime() - wallTime );
- //END OF NONLINEAR ITERATION LOOP!!!
-
- /* add the outer loop iterations to the total outer iterations */
- solver->totalnumnonlinearits = solver->totalnumnonlinearits++;
- /*get wall time for end of outer loop*/
- solver->nonlinearitsendtime = MPI_Wtime();
- /* add time to total time inner its: */
- solver->totalnonlinearitstime = solver->totalnonlinearitstime + (-solver->nonlinearitsinitialtime + solver->nonlinearitsendtime);
- //printf("totalnumnonlinearits before converging is %d totalnonlinearitstime is %g, totalouteritstime is %g and totalinneritstime is %g\n",solver->totalnumnonlinearits,solver->totalnonlinearitstime,solver->totalouteritstime,solver->totalinneritstime);
-
- /* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */
- solver->nonlinearitsinitialtime = 0;
- solver->nonlinearitsendtime = 0;
- if ( (converged) && (self->nonLinearIteration_I>=minIterations) ) {
- int result;
-
- /* Adding in another entry point so we can insert out own custom
- convergeance checks. For example, with frictional boundary
- conditions we need to ensure envery node was gone from the
- original searching state to a fixed slipping or sticking state. */
- _EntryPoint_Run_2VoidPtr( self->nlConvergedEP, _context, &converged );
- MPI_Allreduce( &converged, &result, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD );
- if( result )
- break;
- }
- }
-
- /* Print Info */
- if ( converged ) {
- Journal_Printf( self->info, "In func %s: Converged after %u iterations.\n",
- __func__, self->nonLinearIteration_I );
- }
- else {
- Journal_Printf( errorStream, "In func %s: Failed to converge after %u iterations.\n",
- __func__, self->nonLinearIteration_I);
- if ( self->killNonConvergent ) {
- abort();
- }
- }
-
- Stream_UnIndentBranch( StgFEM_Debug );
-
- VecDestroy( previousVector );
-
- /*Set all the printout variables */
- if( solver->totalnumnonlinearits ) {
- solver->avgtimenonlinearits = (solver->totalnonlinearitstime - solver->totalouteritstime)/solver->totalnumnonlinearits;
- solver->avgnumouterits = solver->totalnumouterits/solver->totalnumnonlinearits;
- }
- if( solver->totalnumouterits ) {
- solver->avgnuminnerits = solver->totalnuminnerits/solver->totalnumouterits;
- solver->avgtimeouterits = (solver->totalouteritstime - solver->totalinneritstime)/solver->totalnumouterits;
- }
- if( solver->totalnuminnerits )
- solver->avgtimeinnerits = solver->totalinneritstime/solver->totalnuminnerits;
- //printf("totalnumnonlinearits = %d, avgnumouterits %d, avgnuminnerits %d\n",solver->totalnumnonlinearits, solver->avgnumouterits, solver->avgnuminnerits);
-
-}
-
-void SystemLinearEquations_AddNonLinearSetupEP( void* sle, Name name, EntryPoint_2VoidPtr_Cast func ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- SystemLinearEquations_SetToNonLinear( self );
- EntryPoint_Append( self->nlSetupEP, (char*)name, (void*)func, self->type );
-}
-
-void SystemLinearEquations_AddPostNonLinearEP( void* sle, Name name, EntryPoint_2VoidPtr_Cast func ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- EntryPoint_Append( self->postNlEP, (char*)name, (void*)func, self->type );
-}
-
-void SystemLinearEquations_AddNonLinearConvergedEP( void* sle,
- Name name,
- EntryPoint_2VoidPtr_Cast func )
-{
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- SystemLinearEquations_SetToNonLinear( self );
- EntryPoint_Append( self->nlConvergedEP, (char*)name, (void*)func, self->type );
-}
-
-/*
-Computes
- F1 := A(x) x -b = -r,
- where r = b - A(x) x
-*/
-//void SystemLinearEquations_SNESPicardFormalResidual( void *someSLE, Vector *stg_X, Vector *stg_F, void *_context )
-void SystemLinearEquations_SNESPicardFormalResidual( void *someSLE, Vec X, Vec F, void *_context )
-{
- SystemLinearEquations *sle = (SystemLinearEquations*)someSLE;
- SLE_Solver *solver = (SLE_Solver*)sle->solver;
- Stream* errorStream = Journal_Register( Error_Type, (Name)sle->type );
-
- Journal_Printf( errorStream, " **** SystemLinearEquations_SNESPicardFormalResidual: This option is un-tested and does not yet function correctly. \n");
- Journal_Printf( errorStream, " **** Use the default form function or specify --components.XXX.picard_FormFunctionType=PicardFormFunction_KSPResidual instead. \n");
- Journal_Printf( errorStream, " **** [Dave May - 12 May, 2008] \n");
- abort();
-
- solver->_formResidual( (void*)sle, (void*)solver, F );
-}
-
-/*
-Computes
- F2 := x - A(x)^{-1} b
-*/
-#if 0
-void SystemLinearEquations_SNESPicardKSPResidual( void *someSLE, Vector *stg_X, Vector *stg_F, void *_context )
-{
- SystemLinearEquations *sle = (SystemLinearEquations*)someSLE;
- SLE_Solver *solver = (SLE_Solver*)sle->solver;
- Vec F,X,Xcopy;
- PetscReal norm;
-
- F = StgVectorGetPetscVec( stg_F );
- X = StgVectorGetPetscVec( stg_X );
-
- VecDuplicate( X, &Xcopy );
- VecCopy( X, Xcopy );
-
- VecCopy( X, F ); /* F <- X */
-// VecNorm( X, NORM_2, &norm );
-// PetscPrintf(PETSC_COMM_WORLD," |X|_pre = %5.5e \n", norm );
- sle->linearExecute( sle, _context ); /* X = A^{-1} b */
- X = StgVectorGetPetscVec( stg_X );
-// VecNorm( X, NORM_2, &norm );
-// PetscPrintf(PETSC_COMM_WORLD," |X|_post = %5.5e \n", norm );
-
- VecAXPY( F, -1.0, X ); /* F <- X - F */
-// VecNorm( F, NORM_2, &norm );
-// PetscPrintf(PETSC_COMM_WORLD," |F|_post = %5.5e \n", norm );
-
- VecCopy( Xcopy, X );
- VecDestroy( Xcopy );
-}
-#endif
-
-/*
-stg_X must not get modified by this function !!
-*/
-void SystemLinearEquations_SNESPicardKSPResidual( void *someSLE, Vec X, Vec F, void *_context )
-{
- SystemLinearEquations *sle = (SystemLinearEquations*)someSLE;
- SLE_Solver *solver = (SLE_Solver*)sle->solver;
- Vec Xstar;
- PetscReal norm,norms;
-
- solver->_getSolution( sle, solver, &Xstar );
-
- /* Map most current solution into stg object, vec->mesh */
- VecCopy( X, Xstar ); /* X* <- X */
- /* Map onto nodes */
- SystemLinearEquations_UpdateSolutionOntoNodes( someSLE, _context );
-
- VecNorm( X, NORM_2, &norm );
- VecNorm( Xstar, NORM_2, &norms );
-// PetscPrintf(PETSC_COMM_WORLD," |X| = %12.12e : |x*| = %12.12e <pre>\n", norm, norms );
-
- sle->linearExecute( sle, _context ); /* X* = A^{-1} b */
-
- VecNorm( X, NORM_2, &norm );
- VecNorm( Xstar, NORM_2, &norms );
-// PetscPrintf(PETSC_COMM_WORLD," |X| = %12.12e : |x*| = %12.12e <post> \n", norm, norms );
-
- VecWAXPY( F, -1.0, Xstar, X ); /* F = -X* + X */
-}
-
-void SLEComputeFunction( void *someSLE, Vec X, Vec F, void *_context )
-{
- SystemLinearEquations *sle = (SystemLinearEquations*)someSLE;
-
- if (sle->_sleFormFunction!=NULL) {
- sle->_sleFormFunction( sle, X, F, _context );
- }
- else {
- SETERRABORT( sle->comm, PETSC_ERR_SUP, "SLEComputeFunction in not valid" );
- }
-}
-
-void SLE_SNESMonitor( void *sle, PetscInt iter, PetscReal fnorm )
-{
- PetscPrintf( PETSC_COMM_WORLD, " %.4d SLE_NS Function norm %12.12e --------------------------------------------------------------------------------\n", iter, fnorm );
-}
-
-void SLE_SNESMonitor2( void *sle, PetscInt iter, PetscReal fnorm0, PetscReal fnorm, PetscReal dX, PetscReal X1 )
-{
- if(iter==0) {
- PetscPrintf( PETSC_COMM_WORLD, " SLE_NS it |F| |F|/|F0| |X1-X0| |X1-X0|/|X1| \n" );
- }
- PetscPrintf( PETSC_COMM_WORLD, " SLE_NS %1.4d %2.4e %2.4e %2.4e %2.4e \n", iter, fnorm, fnorm/fnorm0, dX, dX/X1 );
-}
-
-void _monitor_progress( PetscReal initial, PetscReal target, PetscReal current, PetscReal *p )
-{
- PetscReal p0;
-
- p0 = log10(initial) - log10(target);
- *p = 100.0 * ( 1.0 - (log10(current)-log10(target)) / p0 );
-}
-
-void SLE_SNESMonitorProgress( void *sle,
- PetscInt iter,
- PetscReal fnorm0, PetscReal fnorm, PetscReal dX, PetscReal X1,
- PetscReal fatol, PetscReal frtol, PetscReal xtol )
-{
- PetscReal f_abs_s, f_abs_e, v1, p1;
- PetscReal f_rel_s, f_rel_e, v2, p2;
- PetscReal x_del_s, x_del_e, v3, p3;
-
- if(iter==0) {
- PetscPrintf( PETSC_COMM_WORLD, " SLE_NS it |F| |F|/|F0| |X1-X0|/|X1| \n" );
- }
-
- f_abs_s = fnorm0;
- f_abs_e = fatol;
- v1 = fnorm;
- _monitor_progress( f_abs_s, f_abs_e, v1, &p1 );
-
- f_rel_s = fnorm0;
- f_rel_e = fnorm0 * frtol;
- v2 = fnorm;
- _monitor_progress( f_rel_s, f_rel_e, v2, &p2 );
-
- x_del_s = 1.0;
- x_del_e = xtol;
- v3 = dX/X1;
- _monitor_progress( x_del_s, x_del_e, v3, &p3 );
-
- PetscPrintf( PETSC_COMM_WORLD, " SLE_NS %1.4d %2.4e [%2.0f%%] %2.4e [%2.0f%%] %2.4e [%2.0f%%] \n", iter, fnorm,p1, fnorm/fnorm0,p2, dX/X1,p3 );
-}
-
-
-void SLE_SNESConverged(
- PetscReal snes_abstol, PetscReal snes_rtol, PetscReal snes_ttol, PetscReal snes_xtol,
- PetscInt it,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason )
-{
- /* PetscErrorCode ierr; */
-
- *reason = SNES_CONVERGED_ITERATING;
-
- if (!it) {
- /* set parameter for default relative tolerance convergence test */
- snes_ttol = fnorm*snes_rtol;
- }
- if (fnorm != fnorm) {
-// ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRV(ierr);
- *reason = SNES_DIVERGED_FNORM_NAN;
- } else if (fnorm < snes_abstol) {
-// ierr = PetscInfo2(snes,"Converged due to function norm %G < %G\n",fnorm,snes_abstol);CHKERRV(ierr);
- *reason = SNES_CONVERGED_FNORM_ABS;
- }
-// } else if (snes->nfuncs >= snes->max_funcs) {
-// ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRV(ierr);
-// *reason = SNES_DIVERGED_FUNCTION_COUNT;
-// }
-
- if (it && !*reason) {
- if (fnorm <= snes_ttol) {
-// ierr = PetscInfo2(snes,"Converged due to function norm %G < %G (relative tolerance)\n",fnorm,snes_ttol);CHKERRV(ierr);
- *reason = SNES_CONVERGED_FNORM_RELATIVE;
- } else if (pnorm < snes_xtol*xnorm) {
-// ierr = PetscInfo3(snes,"Converged due to small update length: %G < %G * %G\n",pnorm,snes_xtol,xnorm);CHKERRV(ierr);
- *reason = SNES_CONVERGED_PNORM_RELATIVE;
- }
- }
-}
-
-
-#if defined(PETSC_HAVE_ISINF) && defined(PETSC_HAVE_ISNAN)
-#define PetscIsInfOrNanScalar(a) (isinf(PetscAbsScalar(a)) || isnan(PetscAbsScalar(a)))
-#define PetscIsInfOrNanReal(a) (isinf(a) || isnan(a))
-#elif defined(PETSC_HAVE__FINITE) && defined(PETSC_HAVE__ISNAN)
-#if defined(PETSC_HAVE_FLOAT_H)
-#include "float.h" /* windows defines _finite() in float.h */
-#endif
-#define PetscIsInfOrNanScalar(a) (!_finite(PetscAbsScalar(a)) || _isnan(PetscAbsScalar(a)))
-#define PetscIsInfOrNanReal(a) (!_finite(a) || _isnan(a))
-#else
-#define PetscIsInfOrNanScalar(a) ((a - a) != 0.0)
-#define PetscIsInfOrNanReal(a) ((a - a) != 0.0)
-#endif
-
-/*
-This will be replaced by SNESPicard in petsc 2.4.0.
-*/
-
-void SystemLinearEquations_PicardExecute( void *sle, void *_context )
-{
- SystemLinearEquations *self = (SystemLinearEquations*)sle;
- SLE_Solver *solver = (SLE_Solver*)self->solver;
-
- Vec X, Y, F, Xstar,delta_X;
- PetscReal alpha = 1.0;
- PetscReal fnorm,norm_X,pnorm,fnorm0;
- PetscInt i;
- PetscErrorCode ierr;
- SNESConvergedReason snes_reason;
-
- PetscReal snes_norm;
- PetscInt snes_iter;
-
- PetscReal snes_ttol, snes_rtol, snes_abstol, snes_xtol;
- PetscInt snes_maxits;
-
- PetscTruth monitor_flg;
-
- /* setup temporary some vectors */
- solver->_getSolution( self, solver, &Xstar );
-
- VecDuplicate( Xstar, &X );
- VecDuplicate( X, &F );
- VecDuplicate( F, &Y );
- VecDuplicate( F, &delta_X );
-
- /* Get some values from dictionary */
- snes_maxits = (PetscInt)self->nonLinearMaxIterations;
- snes_ttol = 0.0;
- snes_rtol = (PetscReal)self->rtol;
- snes_abstol = (PetscReal)self->abstol;
- snes_xtol = (PetscReal)self->xtol;
- monitor_flg = PETSC_FALSE;
- if (self->picard_monitor==True) { monitor_flg = PETSC_TRUE; }
- alpha = (PetscReal)self->alpha;
-
- snes_reason = SNES_CONVERGED_ITERATING;
-
- /* Map X <- X* */
- VecCopy( Xstar, X ); // Vector_CopyEntries( currentVector, previousVector );
-
- /* Get an initial guess if |X| ~ 0, by solving the linear problem */
- VecNorm( X, NORM_2, &norm_X );
- if (norm_X <1.0e-20) {
- if (monitor_flg==PETSC_TRUE)
- PetscPrintf( PETSC_COMM_WORLD, "SLE_Picard: Computing an initial guess for X from the linear problem\n");
-
- self->linearExecute( sle, _context ); /* X* = A^{-1} b */
- self->hasExecuted = True;
-
- /* Map X <- X* */
- VecCopy( Xstar, X );
- VecNorm( X, NORM_2, &norm_X );
- }
-
-
- snes_iter = 0;
- snes_norm = 0;
- //SLEComputeFunction( sle, stg_X, stg_F, _context );
- SLEComputeFunction( sle, X, F, _context );
- ierr = VecNorm(F, NORM_2, &fnorm);CHKERRV(ierr); /* fnorm <- ||F|| */
- fnorm0 = fnorm;
- if( PetscIsInfOrNanReal(fnorm) ) SETERRABORT( self->comm,PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
-
- snes_norm = fnorm;
- if(monitor_flg==PETSC_TRUE) {
- /* SLE_SNESMonitor(sle,0,fnorm); */
- /* SLE_SNESMonitor2(sle,0,fnorm0,fnorm, norm_X, norm_X ); */
- SLE_SNESMonitorProgress( sle, snes_iter, fnorm0, fnorm, norm_X, norm_X, snes_abstol, snes_rtol, snes_xtol );
- }
-
- /* set parameter for default relative tolerance convergence test */
- snes_ttol = fnorm*snes_rtol;
- /* test convergence */
- SLE_SNESConverged( snes_abstol,snes_rtol,snes_ttol,snes_xtol , 0,norm_X,0.0,fnorm,&snes_reason);
- if (snes_reason) return;
-
- for(i = 0; i < snes_maxits; i++) {
- /* Update guess Y = X^n - F(X^n) */
- ierr = VecWAXPY(Y, -1.0, F, X);CHKERRV(ierr);
-
- VecCopy( X, delta_X ); /* delta_X <- X */
-
- /* X^{n+1} = (1 - \alpha) X^n + alpha Y */
- ierr = VecAXPBY(X, alpha, 1 - alpha, Y);CHKERRV(ierr);
- VecNorm( X, NORM_2, &norm_X );
-/* PetscPrintf( PETSC_COMM_WORLD, " Xn+1 = %12.12e \n", norm_X ); */
-
- VecAYPX( delta_X, -1.0, X ); /* delta_X <- Xn+1 - delta_X */
- VecNorm( delta_X, NORM_2, &pnorm );
-
- /* Compute F(X^{new}) */
- SLEComputeFunction( sle, X, F, _context );
- ierr = VecNorm(F, NORM_2, &fnorm);CHKERRV(ierr);
- if( PetscIsInfOrNanReal(fnorm) ) SETERRABORT( self->comm,PETSC_ERR_FP,"Infinite or not-a-number generated norm");
-
- /* Monitor convergence */
- snes_iter = i+1;
- snes_norm = fnorm;
- if (monitor_flg==PETSC_TRUE) {
- /* SLE_SNESMonitor(sle,snes_iter,snes_norm); */
- /* SLE_SNESMonitor2(sle,snes_iter,fnorm0,fnorm, pnorm, norm_X ); */
- SLE_SNESMonitorProgress( sle, snes_iter, fnorm0, fnorm, pnorm, norm_X, snes_abstol, snes_rtol, snes_xtol );
- }
-
- /* Test for convergence */
- SLE_SNESConverged( snes_abstol,snes_rtol,snes_ttol,snes_xtol , snes_iter,norm_X,pnorm,fnorm,&snes_reason);
- if (snes_reason) break;
- }
- if (i == snes_maxits) {
-// ierr = PetscInfo1(snes, "Maximum number of iterations has been reached: %D\n", maxits);CHKERRV(ierr);
- if (!snes_reason) snes_reason = SNES_DIVERGED_MAX_IT;
- }
-
- /* If monitoring, report reason converged */
- if (monitor_flg==PETSC_TRUE)
- PetscPrintf( PETSC_COMM_WORLD, "Nonlinear solve converged due to %s \n", SNESConvergedReasons[snes_reason] );
-
- VecDestroy( X );
- VecDestroy( F );
- VecDestroy( Y );
- VecDestroy( delta_X );
-
-}
-
-
-///////////////
-
-void SystemLinearEquations_AddNonLinearEP( void* sle, Name name, EntryPoint_2VoidPtr_Cast func ) {
- SystemLinearEquations* self = (SystemLinearEquations*)sle;
-
- SystemLinearEquations_SetToNonLinear( self );
- EntryPoint_Append( self->nlEP, (char*)name, (void*)func, self->type );
-}
-
-
-
-void SystemLinearEquations_SetToNonLinear( void* sle ) {
- SystemLinearEquations* self = (SystemLinearEquations*) sle;
- Hook* nonLinearInitHook = NULL;
- Hook* nonLinearFinaliseHook = NULL;
- FiniteElementContext* context = NULL;
-
- assert( self );
- if ( self->isNonLinear )
- return;
-
- self->isNonLinear = True;
-
- self->linearExecute = self->_execute;
- self->_execute = SystemLinearEquations_NonLinearExecute;
-
- if( self->nonLinearSolutionType ) {
- if( !strcmp( self->nonLinearSolutionType, "default" ) ) {
- self->_execute = SystemLinearEquations_NonLinearExecute;
- }
-
- if( !strcmp( self->nonLinearSolutionType, "MatrixFreeNewton" ) )
- self->_execute = SystemLinearEquations_NewtonMFFDExecute;
-
- if( !strcmp( self->nonLinearSolutionType, "Newton" ) ) {
- context = self->context;
-
- nonLinearInitHook = Hook_New( "NewtonInitialise",
- (void*)SystemLinearEquations_NewtonInitialise, self->name );
- _EntryPoint_PrependHook_AlwaysFirst( Context_GetEntryPoint( context, AbstractContext_EP_Solve ),
- nonLinearInitHook );
- nonLinearFinaliseHook = Hook_New( "NewtonFinalise",
- (void*)SystemLinearEquations_NewtonFinalise, self->name );
- _EntryPoint_AppendHook_AlwaysLast( Context_GetEntryPoint( context, AbstractContext_EP_Solve ),
- nonLinearFinaliseHook );
- self->_execute = SystemLinearEquations_NewtonExecute;
- }
-
- if (!strcmp( self->nonLinearSolutionType, "Picard") ) {
- /* set function pointer for execute */
- self->_execute = SystemLinearEquations_PicardExecute;
-
- /* set form function */
- if (!strcmp(self->picard_form_function_type,"PicardFormFunction_KSPResidual") ) {
- self->_sleFormFunction = SystemLinearEquations_SNESPicardKSPResidual;
- }
- else if (!strcmp(self->picard_form_function_type,"PicardFormFunction_FormalResidual") ) {
- self->_sleFormFunction = SystemLinearEquations_SNESPicardFormalResidual;
- }
- else {
- Stream *errorStream = Journal_Register( Error_Type, (Name)self->type );
-
- Journal_Printf( errorStream, "Unknown the Picard FormFunction type %s is unrecognised. .\n", self->picard_form_function_type );
- Journal_Printf( errorStream, "Supported types include <PicardFormFunction_FormalResidual, PicardFormFunction_KSPResidual> \n" );
- abort();
-
- }
- }
- }
-}
-
-void SystemLinearEquations_CheckIfNonLinear( void* sle ) {
- SystemLinearEquations* self = (SystemLinearEquations*) sle;
- Index index;
-
- for ( index = 0; index < self->stiffnessMatrices->count; index++ ) {
- StiffnessMatrix* stiffnessMatrix = SystemLinearEquations_GetStiffnessMatrixAt( self, index );
-
- if ( stiffnessMatrix->isNonLinear )
- SystemLinearEquations_SetToNonLinear( self );
-
- /* TODO CHECK FOR FORCE VECTORS */
- }
-}
-
-/*
-** All the MG functions and their general implementations.
-*/
-
-void SystemLinearEquations_MG_Enable( void* _sle ) {
- SystemLinearEquations* self = (SystemLinearEquations*)_sle;
-
- if( !self->isBuilt ) {
- Journal_Printf(self->info, "Warning: SLE has not been built, can't enable multi-grid.\n" );
- return;
- }
-
- self->mgEnabled = True;
-}
-
-
-void SystemLinearEquations_MG_SelectStiffMats( void* _sle, unsigned* nSMs, StiffnessMatrix*** sms ) {
- SystemLinearEquations* self = (SystemLinearEquations*)_sle;
-
- assert( self->_mgSelectStiffMats );
- self->_mgSelectStiffMats( self, nSMs, sms );
-}
-
-
-void _SystemLinearEquations_MG_SelectStiffMats( void* _sle, unsigned* nSMs, StiffnessMatrix*** sms ) {
- SystemLinearEquations* self = (SystemLinearEquations*)_sle;
-
- /*
- ** As we have nothing else to go on, attempt to apply MG to all stiffness matrices in the list.
- */
-
- {
- unsigned sm_i;
-
- *nSMs = 0;
- for( sm_i = 0; sm_i < self->stiffnessMatrices->count; sm_i++ ) {
- StiffnessMatrix* sm = ((StiffnessMatrix**)self->stiffnessMatrices->data)[sm_i];
-
- /* Add this one to the list. */
- *sms = Memory_Realloc_Array( *sms, StiffnessMatrix*, (*nSMs) + 1 );
- (*sms)[*nSMs] = sm;
- (*nSMs)++;
- }
- }
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/src/SystemLinearEquations.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/src/SystemLinearEquations.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,1408 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student Monash University, VPAC. (davidm at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: SystemLinearEquations.c 1230 2008-09-15 01:44:43Z DavidLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <petsc.h>
+#include <petscvec.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "units.h"
+#include "types.h"
+#include "shortcuts.h"
+#include "SystemLinearEquations.h"
+#include "SLE_Solver.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+
+#include "StiffnessMatrix.h"
+#include "SolutionVector.h"
+#include "ForceVector.h"
+#include "FiniteElementContext.h"
+
+
+/* Textual name of this class */
+const Type SystemLinearEquations_Type = "SystemLinearEquations";
+
+/** Constructor */
+SystemLinearEquations* SystemLinearEquations_New(
+ Name name,
+ SLE_Solver* solver,
+ void* nlSolver,
+ FiniteElementContext* context,
+ Bool isNonLinear,
+ double nonLinearTolerance,
+ Iteration_Index nonLinearMaxIterations,
+ Bool killNonConvergent,
+ EntryPoint_Register* entryPoint_Register,
+ MPI_Comm comm )
+{
+ SystemLinearEquations* self = (SystemLinearEquations*)_SystemLinearEquations_DefaultNew( name );
+
+ self->isConstructed = True;
+ _SystemLinearEquations_Init(
+ self,
+ solver,
+ nlSolver,
+ context,
+ False, /* TODO: A hack put in place for setting the convergence stream to 'off' if the SLE class is created from within the code, not via an xml */
+ isNonLinear,
+ nonLinearTolerance,
+ nonLinearMaxIterations,
+ killNonConvergent,
+ 1, /* TODO : hack for setting the minimum number of iterations to 1- same hack as above */
+ "",
+ "",
+ entryPoint_Register,
+ comm );
+
+ return self;
+}
+
+/* Creation implementation / Virtual constructor */
+SystemLinearEquations* _SystemLinearEquations_New( SYSTEMLINEAREQUATIONS_DEFARGS )
+{
+ SystemLinearEquations* self;
+
+ /* Allocate memory */
+ assert( _sizeOfSelf >= sizeof(SystemLinearEquations) );
+ /* The following terms are parameters that have been passed into this function but are being set before being passed onto the parent */
+ /* This means that any values of these parameters that are passed into this function are not passed onto the parent function
+ and so should be set to ZERO in any children of this class. */
+ nameAllocationType = NON_GLOBAL;
+
+ self = (SystemLinearEquations*) _Stg_Component_New( STG_COMPONENT_PASSARGS );
+
+ /* Virtual info */
+ self->_LM_Setup = _LM_Setup;
+ self->_matrixSetup = _matrixSetup;
+ self->_vectorSetup = _vectorSetup;
+ self->_updateSolutionOntoNodes = _updateSolutionOntoNodes;
+ self->_mgSelectStiffMats = _mgSelectStiffMats;
+
+ self->_sleFormFunction = NULL;
+
+ return self;
+}
+
+void _SystemLinearEquations_Init(
+ void* sle,
+ SLE_Solver* solver,
+ void* nlSolver,
+ FiniteElementContext* context,
+ Bool makeConvergenceFile,
+ Bool isNonLinear,
+ double nonLinearTolerance,
+ Iteration_Index nonLinearMaxIterations,
+ Bool killNonConvergent,
+ Iteration_Index nonLinearMinIterations,
+ Name nonLinearSolutionType,
+ Name optionsPrefix,
+ EntryPoint_Register* entryPoint_Register,
+ MPI_Comm comm )
+{
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+ char* filename;
+ char* optionsName;
+
+ self->extensionManager = ExtensionManager_New_OfExistingObject( self->name, self );
+
+ self->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, self->type );
+ self->info = Journal_MyStream( Info_Type, self );
+ /* Note: currently we're sending self->info to the master proc only so there's not too much
+ identical timing info printed. May want to fine-tune later so that some info does get
+ printed on all procs. */
+ Stream_SetPrintingRank( self->info, 0 );
+
+ self->makeConvergenceFile = makeConvergenceFile;
+ if ( self->makeConvergenceFile ) {
+ self->convergenceStream = Journal_Register( InfoStream_Type, (Name)"Convergence Info" );
+ Stg_asprintf( &filename, "Convergence.dat" );
+ Stream_RedirectFile_WithPrependedPath( self->convergenceStream, context->outputPath, filename );
+ Stream_SetPrintingRank( self->convergenceStream, 0 );
+ Memory_Free( filename );
+ Journal_Printf( self->convergenceStream , "Timestep\tIteration\tResidual\tTolerance\n" );
+ }
+
+ self->comm = comm;
+ self->solver = solver;
+ self->nlSolver = (SNES)nlSolver;
+ self->stiffnessMatrices = Stg_ObjectList_New();
+ self->forceVectors = Stg_ObjectList_New();
+ self->solutionVectors = Stg_ObjectList_New();
+ self->bcRemoveQuery = True;
+ self->context = context;
+
+ /* Init NonLinear Stuff */
+ self->nonLinearSolutionType = nonLinearSolutionType; /* This will never got propogated through to _Initialise->SetToNonLinear if we keep it in the loop */
+ if ( isNonLinear ) {
+ self->nonLinearSolutionType = nonLinearSolutionType;
+ SystemLinearEquations_SetToNonLinear( self );
+ }
+ self->nonLinearTolerance = nonLinearTolerance;
+ self->nonLinearMaxIterations = nonLinearMaxIterations;
+ self->killNonConvergent = killNonConvergent;
+ self->nonLinearMinIterations = nonLinearMinIterations;
+ self->curResidual = 0.0;
+ self->curSolveTime = 0.0;
+ /* _ /0 */
+ optionsName = Memory_Alloc_Array_Unnamed( char, strlen(optionsPrefix) + 1 + 1 );
+ sprintf( optionsName, "%s_", optionsPrefix );
+ self->optionsPrefix = optionsName;
+
+ /* BEGIN LUKE'S FRICTIONAL BCS BIT */
+ Stg_asprintf( &self->nlSetupEPName, "%s-nlSetupEP", self->name );
+ self->nlSetupEP = EntryPoint_New( self->nlSetupEPName, EntryPoint_2VoidPtr_CastType );
+ Stg_asprintf( &self->nlEPName, "%s-nlEP", self->name );
+ self->nlEP = EntryPoint_New( self->nlEPName, EntryPoint_2VoidPtr_CastType );
+ Stg_asprintf( &self->nlEPName, "%s-postNlEP", self->name );
+ self->postNlEP = EntryPoint_New( self->postNlEPName, EntryPoint_2VoidPtr_CastType );
+ Stg_asprintf( &self->nlConvergedEPName, "%s-nlConvergedEP", self->name );
+ self->nlConvergedEP = EntryPoint_New( self->nlConvergedEPName, EntryPoint_2VoidPtr_CastType );
+ /* END LUKE'S FRICTIONAL BCS BIT */
+ self->nlFormJacobian = False;
+ self->nlCurIterate = PETSC_NULL;
+
+ /* Initialise MG stuff. */
+ self->mgEnabled = False;
+ self->mgUpdate = True;
+ self->nMGHandles = 0;
+ self->mgHandles = NULL;
+
+ /* Create Execute Entry Point */
+ Stg_asprintf( &self->executeEPName, "%s-execute", self->name );
+ self->executeEP = EntryPoint_New( self->executeEPName, EntryPoint_2VoidPtr_CastType );
+
+ /* Add default hooks to Execute E.P. */
+ EntryPoint_Append( self->executeEP, "BC_Setup", (void*)SystemLinearEquations_BC_Setup, self->type);
+ EntryPoint_Append( self->executeEP, "LM_Setup", (void*)SystemLinearEquations_LM_Setup, self->type);
+ EntryPoint_Append( self->executeEP, "IntegrationSetup", (void*)SystemLinearEquations_IntegrationSetup, self->type );
+ EntryPoint_Append( self->executeEP, "ZeroAllVectors", (void*)SystemLinearEquations_ZeroAllVectors, self->type);
+ EntryPoint_Append( self->executeEP, "MatrixSetup", (void*)SystemLinearEquations_MatrixSetup, self->type);
+ EntryPoint_Append( self->executeEP, "VectorSetup", (void*)SystemLinearEquations_VectorSetup, self->type);
+ EntryPoint_Append( self->executeEP, "ExecuteSolver", (void*)SystemLinearEquations_ExecuteSolver, self->type);
+ EntryPoint_Append( self->executeEP, "UpdateSolutionOntoNodes",(void*)SystemLinearEquations_UpdateSolutionOntoNodes,self->type);
+
+ /* Create Integration Setup EP */
+ Stg_asprintf( &self->integrationSetupEPName, "%s-integrationSetup", self->name );
+ self->integrationSetupEP = EntryPoint_New( self->integrationSetupEPName, EntryPoint_Class_VoidPtr_CastType );
+
+ if ( entryPoint_Register )
+ EntryPoint_Register_Add( entryPoint_Register, self->executeEP );
+ self->entryPoint_Register = entryPoint_Register;
+
+ /* Add SLE to Context */
+ if ( context )
+ FiniteElementContext_AddSLE( context, self );
+}
+
+void _SystemLinearEquations_Delete( void* sle ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ /* delete parent */
+ _Stg_Component_Delete( self );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+void _SystemLinearEquations_Print( void* sle, Stream* stream ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ /* General info */
+ Journal_Printf( stream, "SystemLinearEquations (ptr): %p\n", self );
+ _Stg_Component_Print( self, stream );
+
+ /* Virtual info */
+ Stg_Class_Print( self->stiffnessMatrices, stream );
+ Stg_Class_Print( self->forceVectors, stream );
+ Stg_Class_Print( self->solutionVectors, stream );
+
+ /* other info */
+ Journal_PrintPointer( stream, self->extensionManager );
+ Journal_Printf( stream, "\tcomm: %u\n", self->comm );
+ Journal_Printf( stream, "\tsolver (ptr): %p\n", self->solver );
+ Stg_Class_Print( self->solver, stream );
+}
+
+void* _SystemLinearEquations_Copy( const void* sle, void* dest, Bool deep, Name nameExt, PtrMap* ptrMap ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+ SystemLinearEquations* newSLE;
+ PtrMap* map = ptrMap;
+ Bool ownMap = False;
+
+ if( !map ) {
+ map = PtrMap_New( 10 );
+ ownMap = True;
+ }
+
+ newSLE = (SystemLinearEquations*)_Stg_Component_Copy( sle, dest, deep, nameExt, map );
+
+ /* Virtual methods */
+ newSLE->_LM_Setup = self->_LM_Setup;
+ newSLE->_matrixSetup = self->_matrixSetup;
+ newSLE->_vectorSetup = self->_vectorSetup;
+ newSLE->_mgSelectStiffMats = self->_mgSelectStiffMats;
+
+ newSLE->debug = Stream_RegisterChild( StgFEM_SLE_SystemSetup_Debug, newSLE->type );
+ newSLE->comm = self->comm;
+
+ if( deep ) {
+ newSLE->solver = (SLE_Solver*)Stg_Class_Copy( self->solver, NULL, deep, nameExt, map );
+ newSLE->stiffnessMatrices = (StiffnessMatrixList*)Stg_Class_Copy( self->stiffnessMatrices, NULL, deep, nameExt, map );
+ newSLE->forceVectors = (ForceVectorList*)Stg_Class_Copy( self->forceVectors, NULL, deep, nameExt, map );
+ newSLE->solutionVectors = (SolutionVectorList*)Stg_Class_Copy( self->solutionVectors, NULL, deep, nameExt, map );
+ if( (newSLE->extensionManager = (ExtensionManager*)PtrMap_Find( map, self->extensionManager )) == NULL ) {
+ newSLE->extensionManager = (ExtensionManager*)Stg_Class_Copy( self->extensionManager, NULL, deep, nameExt, map );
+ PtrMap_Append( map, self->extensionManager, newSLE->extensionManager );
+ }
+ }
+ else {
+ newSLE->solver = self->solver;
+ newSLE->stiffnessMatrices = self->stiffnessMatrices;
+ newSLE->forceVectors = self->forceVectors;
+ newSLE->solutionVectors = self->solutionVectors;
+ }
+
+ if( ownMap ) {
+ Stg_Class_Delete( map );
+ }
+
+ return newSLE;
+}
+
+void* _SystemLinearEquations_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(SystemLinearEquations);
+ Type type = SystemLinearEquations_Type;
+ Stg_Class_DeleteFunction* _delete = _SystemLinearEquations_Delete;
+ Stg_Class_PrintFunction* _print = _SystemLinearEquations_Print;
+ Stg_Class_CopyFunction* _copy = _SystemLinearEquations_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _SystemLinearEquations_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _SystemLinearEquations_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _SystemLinearEquations_Build;
+ Stg_Component_InitialiseFunction* _initialise = _SystemLinearEquations_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _SystemLinearEquations_Execute;
+ Stg_Component_DestroyFunction* _destroy = _SystemLinearEquations_Destroy;
+ SystemLinearEquations_LM_SetupFunction* _LM_Setup = _SystemLinearEquations_LM_Setup;
+ SystemLinearEquations_MatrixSetupFunction* _matrixSetup = _SystemLinearEquations_MatrixSetup;
+ SystemLinearEquations_VectorSetupFunction* _vectorSetup = _SystemLinearEquations_VectorSetup;
+ SystemLinearEquations_UpdateSolutionOntoNodesFunc* _updateSolutionOntoNodes = _SystemLinearEquations_UpdateSolutionOntoNodes;
+ SystemLinearEquations_MG_SelectStiffMatsFunc* _mgSelectStiffMats = _SystemLinearEquations_MG_SelectStiffMats;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _SystemLinearEquations_New( SYSTEMLINEAREQUATIONS_PASSARGS );
+}
+
+void _SystemLinearEquations_AssignFromXML( void* sle, Stg_ComponentFactory* cf, void* data ){
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+ SLE_Solver* solver = NULL;
+ void* entryPointRegister = NULL;
+ FiniteElementContext* context = NULL;
+ double nonLinearTolerance;
+ Iteration_Index nonLinearMaxIterations;
+ Bool isNonLinear;
+ Bool killNonConvergent;
+ Bool makeConvergenceFile;
+ Iteration_Index nonLinearMinIterations;
+ Name nonLinearSolutionType;
+ SNES nlSolver = NULL;
+ Name optionsPrefix;
+
+ solver = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)SLE_Solver_Type, SLE_Solver, False, data ) ;
+
+ makeConvergenceFile = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"makeConvergenceFile", False );
+ isNonLinear = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"isNonLinear", False );
+ nonLinearTolerance = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"nonLinearTolerance", 0.01 );
+ nonLinearMaxIterations = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"nonLinearMaxIterations", 500 );
+ killNonConvergent = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"killNonConvergent", True );
+ nonLinearMinIterations = Stg_ComponentFactory_GetUnsignedInt( cf, self->name, (Dictionary_Entry_Key)"nonLinearMinIterations", 1 );
+ nonLinearSolutionType = Stg_ComponentFactory_GetString( cf, self->name, (Dictionary_Entry_Key)"nonLinearSolutionType", "default" );
+ optionsPrefix = Stg_ComponentFactory_GetString( cf, self->name, (Dictionary_Entry_Key)"optionsPrefix", "" );
+
+ /* Read some value for Picard */
+ self->picard_form_function_type = Stg_ComponentFactory_GetString( cf, self->name, (Dictionary_Entry_Key)"picard_FormFunctionType", "PicardFormFunction_KSPResidual" );
+
+ self->alpha = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"picard_alpha", 1.0 );
+ self->rtol = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"picard_rtol", 1.0e-8 );
+ self->abstol = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"picard_atol", 1.0e-50 );
+ self->xtol = Stg_ComponentFactory_GetDouble( cf, self->name, (Dictionary_Entry_Key)"picard_xtol", 1.0e-8 );
+ self->picard_monitor = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"picard_ActivateMonitor", False );
+
+ context = Stg_ComponentFactory_ConstructByKey( cf, self->name, (Dictionary_Entry_Key)"Context", FiniteElementContext, False, data );
+ if( !context )
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
+
+ entryPointRegister = context->entryPoint_Register;
+ assert( entryPointRegister );
+
+ if( isNonLinear ) {
+ SNESCreate( context->communicator, &nlSolver );
+ self->linearSolveInitGuess = Stg_ComponentFactory_GetBool( cf, self->name, (Dictionary_Entry_Key)"linearSolveInitialGuess", False );
+ }
+
+ _SystemLinearEquations_Init(
+ self,
+ solver,
+ nlSolver,
+ context,
+ makeConvergenceFile,
+ isNonLinear,
+ nonLinearTolerance,
+ nonLinearMaxIterations,
+ killNonConvergent,
+ nonLinearMinIterations,
+ nonLinearSolutionType,
+ optionsPrefix,
+ (EntryPoint_Register*)entryPointRegister,
+ MPI_COMM_WORLD );
+
+ VecCreate( self->comm, &self->X );
+ VecCreate( self->comm, &self->F );
+ MatCreate( self->comm, &self->A );
+ MatCreate( self->comm, &self->J );
+}
+
+/* Build */
+void _SystemLinearEquations_Build( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+ Index index;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ /* build the matrices */
+ for ( index = 0; index < self->stiffnessMatrices->count; index++ ) {
+ /* Update rowSize and colSize if boundary conditions have been applied */
+ Stg_Component_Build( self->stiffnessMatrices->data[index], _context, False );
+ }
+
+ /* and the vectors */
+ for ( index = 0; index < self->forceVectors->count; index++ ) {
+ /* Build the force vectors - includes updateing matrix size based on Dofs */
+ Stg_Component_Build( self->forceVectors->data[index], _context, False );
+ }
+
+ /* and the solutions */
+ for ( index = 0; index < self->solutionVectors->count; index++ ) {
+ /* Build the force vectors - includes updateing matrix size based on Dofs */
+ Stg_Component_Build( self->solutionVectors->data[index], _context, False );
+ }
+
+ /* lastly, the solver - if required */
+ if( self->solver )
+ Stg_Component_Build( self->solver, self, False );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _SystemLinearEquations_Initialise( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+ Index index;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ /* initialise the matrices */
+ for ( index = 0; index < self->stiffnessMatrices->count; index++ ) {
+ /* Update rowSize and colSize if boundary conditions have been applied */
+ Stg_Component_Initialise( self->stiffnessMatrices->data[index], _context, False );
+ }
+
+ /* and the vectors */
+ for ( index = 0; index < self->forceVectors->count; index++ ) {
+ /* Initialise the force vectors - includes updateing matrix size based on Dofs */
+ Stg_Component_Initialise( self->forceVectors->data[index], _context, False );
+ }
+
+ /* and the solutions */
+ for ( index = 0; index < self->solutionVectors->count; index++ ) {
+ /* Initialise the force vectors - includes updateing matrix size based on Dofs */
+ Stg_Component_Initialise( self->solutionVectors->data[index], _context, False );
+ }
+
+ /* Check to see if any of the components need to make the SLE non-linear */
+ SystemLinearEquations_CheckIfNonLinear( self );
+
+ /* Setup Location Matrix */
+ SystemLinearEquations_LM_Setup( self, _context );
+
+ /* lastly, the solver, if required */
+ if( self->solver )
+ Stg_Component_Initialise( self->solver, self, False );
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void _SystemLinearEquations_Execute( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ _EntryPoint_Run_2VoidPtr( self->executeEP, sle, _context );
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void SystemLinearEquations_ExecuteSolver( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+ double wallTime;
+ /* Actually run the solver to get the new values into the SolutionVectors */
+
+ Journal_Printf(self->info,"Linear solver (%s) \n",self->executeEPName);
+
+ wallTime = MPI_Wtime();
+ if( self->solver )
+ Stg_Component_Execute( self->solver, self, True );
+
+ self->curSolveTime = MPI_Wtime() - wallTime;
+ Journal_Printf(self->info,"Linear solver (%s), solution time %6.6e (secs)\n",self->executeEPName, self->curSolveTime);
+
+}
+
+void _SystemLinearEquations_Destroy( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ /* BEGIN LUKE'S FRICTIONAL BCS BIT */
+ Memory_Free( self->nlSetupEPName );
+ Memory_Free( self->nlEPName );
+ Memory_Free( self->postNlEPName );
+ Memory_Free( self->nlConvergedEPName );
+ /* END LUKE'S FRICTIONAL BCS BIT */
+ Memory_Free( self->executeEPName );
+
+ Stg_Class_Delete( self->extensionManager );
+
+ Stg_Class_Delete( self->stiffnessMatrices );
+ Stg_Class_Delete( self->forceVectors );
+ Stg_Class_Delete( self->solutionVectors );
+
+ Memory_Free( self->optionsPrefix );
+
+ VecDestroy( self->X );
+ VecDestroy( self->F );
+ MatDestroy( self->A );
+ MatDestroy( self->J );
+
+ /* Free the the MG handles. */
+ FreeArray( self->mgHandles );
+}
+
+void SystemLinearEquations_BC_Setup( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+ Index index;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ for ( index = 0; index < self->solutionVectors->count; index++ ) {
+ SolutionVector_ApplyBCsToVariables( self->solutionVectors->data[index], _context );
+ }
+}
+
+
+void SystemLinearEquations_LM_Setup( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ self->_LM_Setup( self, _context );
+}
+
+void SystemLinearEquations_IntegrationSetup( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ _EntryPoint_Run_Class_VoidPtr( self->integrationSetupEP, _context );
+}
+
+void _SystemLinearEquations_LM_Setup( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+ Index index;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+ /* For each feVariable of each stiffness matrix, build the LM */
+ for ( index = 0; index < self->stiffnessMatrices->count; index++ ) {
+ StiffnessMatrix* sm = (StiffnessMatrix*)self->stiffnessMatrices->data[index];
+
+ FeEquationNumber_BuildLocationMatrix( sm->rowVariable->eqNum );
+ FeEquationNumber_BuildLocationMatrix( sm->columnVariable->eqNum );
+ }
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+void SystemLinearEquations_MatrixSetup( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ self->_matrixSetup( self, _context );
+}
+
+void _SystemLinearEquations_MatrixSetup( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+ FiniteElementContext* context = (FiniteElementContext*)_context;
+ Index index;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+ for ( index = 0; index < self->stiffnessMatrices->count; index++ ) {
+ StiffnessMatrix_Assemble( self->stiffnessMatrices->data[index], self->bcRemoveQuery, self, context );
+ }
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void SystemLinearEquations_VectorSetup( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ self->_vectorSetup( self, _context );
+}
+
+void _SystemLinearEquations_VectorSetup( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+ Index index;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+ for ( index = 0; index < self->forceVectors->count; index++ ) {
+ ForceVector_Assemble( self->forceVectors->data[index] );
+ }
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+Index _SystemLinearEquations_AddStiffnessMatrix( void* sle, StiffnessMatrix* stiffnessMatrix ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ return SystemLinearEquations_AddStiffnessMatrix( self, stiffnessMatrix );
+}
+
+StiffnessMatrix* _SystemLinearEquations_GetStiffnessMatrix( void* sle, Name stiffnessMatrixName ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ return SystemLinearEquations_GetStiffnessMatrix( self, stiffnessMatrixName );
+}
+
+Index _SystemLinearEquations_AddForceVector( void* sle, ForceVector* forceVector ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ return SystemLinearEquations_AddForceVector( self, forceVector );
+}
+
+ForceVector* _SystemLinearEquations_GetForceVector( void* sle, Name forceVectorName ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ return SystemLinearEquations_GetForceVector( self, forceVectorName );
+}
+
+Index _SystemLinearEquations_AddSolutionVector( void* sle, SolutionVector* solutionVector ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ return SystemLinearEquations_AddSolutionVector( self, solutionVector );
+}
+
+SolutionVector* _SystemLinearEquations_GetSolutionVector( void* sle, Name solutionVectorName ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ return SystemLinearEquations_GetSolutionVector( self, solutionVectorName );
+}
+
+void SystemLinearEquations_UpdateSolutionOntoNodes( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ self->_updateSolutionOntoNodes( self, _context );
+}
+
+void _SystemLinearEquations_UpdateSolutionOntoNodes( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+ SolutionVector_Index solnVec_I;
+ SolutionVector* currentSolnVec;
+
+ for ( solnVec_I=0; solnVec_I < self->solutionVectors->count; solnVec_I++ ) {
+ currentSolnVec = (SolutionVector*)self->solutionVectors->data[solnVec_I];
+ SolutionVector_UpdateSolutionOntoNodes( currentSolnVec );
+ }
+}
+
+void SystemLinearEquations_ZeroAllVectors( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+ Index index;
+ ForceVector* forceVector;
+
+ Journal_DPrintf( self->debug, "In %s\n", __func__ );
+ for ( index = 0; index < self->forceVectors->count; index++ ) {
+ forceVector = (ForceVector*) self->forceVectors->data[index];
+
+ VecSet( forceVector->vector, 0.0 );
+ }
+}
+
+/* need to do this before the SLE specific function to set up the
+pre conditioners is called (beginning of solve) */
+void SystemLinearEquations_NewtonInitialise( void* _context, void* data ) {
+ FiniteElementContext* context = (FiniteElementContext*)_context;
+ SystemLinearEquations* sle = (SystemLinearEquations*)context->slEquations->data[0];
+ SNES snes;
+ SNES oldSnes = sle->nlSolver;
+
+ /* don't assume that a snes is being used for initial guess, check for this!!! */
+ if( oldSnes && context->timeStep == 1 && !sle->linearSolveInitGuess )
+ SNESDestroy( oldSnes );
+
+ SNESCreate( sle->comm, &snes );
+
+ sle->nlSolver = snes;
+ sle->_setFFunc( &sle->F, context );
+
+ SNESSetJacobian( snes, sle->J, sle->P, sle->_buildJ, sle->buildJContext );
+ SNESSetFunction( snes, sle->F, sle->_buildF, sle->buildFContext );
+
+ /* configure the KSP */
+ sle->_configureNLSolverFunc( snes, context );
+}
+
+/* do this after the pre conditoiners have been set up in the problem specific SLE */
+void SystemLinearEquations_NewtonExecute( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*) sle;
+ SNES snes = self->nlSolver;
+
+ SNESSetOptionsPrefix( snes, self->optionsPrefix );
+ SNESSetFromOptions( snes );
+ SNESSolve( snes, PETSC_NULL, self->X );
+}
+
+/* do this at end of solve step */
+void SystemLinearEquations_NewtonFinalise( void* _context, void* data ) {
+ FiniteElementContext* context = (FiniteElementContext*)_context;
+ SystemLinearEquations* sle = (SystemLinearEquations*)context->slEquations->data[0];
+ SNES snes = sle->nlSolver;
+
+ sle->_updateOldFields( &sle->X, context );
+
+ SNESDestroy( snes );
+}
+
+void SystemLinearEquations_NewtonMFFDExecute( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*) sle;
+ Vec F;
+
+ VecDuplicate( SystemLinearEquations_GetSolutionVectorAt( self, 0 )->vector, &F );
+
+ /* creates the nonlinear solver */
+ if( self->nlSolver != PETSC_NULL )
+ SNESDestroy( self->nlSolver );
+ SNESCreate( self->comm, &self->nlSolver );
+ SNESSetFunction( self->nlSolver, F, self->_buildF, _context );
+
+ // set J (jacobian)
+
+ // set F (residual vector)
+
+ // call non linear solver func (SNES wrapper)
+}
+
+void SystemLinearEquations_NonLinearExecute( void* sle, void* _context ) {
+ SystemLinearEquations* self = (SystemLinearEquations*) sle;
+ Vec previousVector;
+ Vec currentVector;
+ double residual;
+ double tolerance = self->nonLinearTolerance;
+ Iteration_Index maxIterations = self->nonLinearMaxIterations;
+ Bool converged;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)self->type );
+ double wallTime;
+ Iteration_Index minIterations = self->nonLinearMinIterations;
+ SLE_Solver* solver;
+
+ PetscScalar currVecNorm, prevVecNorm;
+
+ Journal_Printf( self->info, "In %s\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ wallTime = MPI_Wtime();
+
+ /* First Solve */
+ /* setting the nonlinear stuff */
+ //START OF NONLINEAR ITERATION!!!!!
+ /* first get current timestep */
+ solver = self->solver;
+ solver->currenttimestep = self->context->timeStep;
+ /* if current timestep is not the same as previous timestep, then reset all variables back to zero and update previous timestep */
+ if(solver->currenttimestep != solver->previoustimestep){
+ //update prev timestep
+ solver->previoustimestep = solver->currenttimestep;
+ solver->nonlinearitsinitialtime = 0;
+ solver->nonlinearitsendtime = 0;
+ solver->totalnonlinearitstime = 0;
+ solver->totalnumnonlinearits = 0;
+ solver->avgtimenonlinearits = 0;
+ solver->inneritsinitialtime = 0;
+ solver->outeritsinitialtime = 0;
+ solver->inneritsendtime = 0;
+ solver->outeritsendtime = 0;
+ solver->totalinneritstime = 0;
+ solver->totalouteritstime = 0;
+ solver->totalnuminnerits = 0;
+ solver->totalnumouterits = 0;
+ solver->avgnuminnerits = 0;
+ solver->avgnumouterits = 0;
+ solver->avgtimeinnerits = 0;
+ solver->avgtimeouterits = 0;
+ }
+
+ self->nonLinearIteration_I = 0;
+ Journal_Printf(self->info,"\nNon linear solver - iteration %d\n", self->nonLinearIteration_I);
+
+ /* More of Luke's stuff. I need an entry point for a non-linear setup operation. */
+ _EntryPoint_Run_2VoidPtr( self->nlSetupEP, sle, _context );
+
+ /*Don't know if we should include this but the timing of the outer and inner iterations starts here so it makes sense to count this one? */
+ solver->nonlinearitsinitialtime = MPI_Wtime();
+
+ self->linearExecute( self, _context );
+ self->hasExecuted = True;
+
+ solver->nonlinearitsendtime = MPI_Wtime();
+ solver->totalnonlinearitstime = solver->totalnonlinearitstime + (-solver->nonlinearitsinitialtime + solver->nonlinearitsendtime);
+ /* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */
+ solver->nonlinearitsinitialtime = 0;
+ solver->nonlinearitsendtime = 0;
+ /*
+ ** Include an entry point to do some kind of post-non-linear-iteration operation. */
+ _EntryPoint_Run_2VoidPtr( self->postNlEP, sle, _context );
+
+ /* TODO - Give option which solution vector to test */
+ currentVector = SystemLinearEquations_GetSolutionVectorAt( self, 0 )->vector;
+ VecDuplicate( currentVector, &previousVector );
+
+ for ( self->nonLinearIteration_I = 1 ; self->nonLinearIteration_I < maxIterations ; self->nonLinearIteration_I++ ) {
+ /* get initial wall time for nonlinear loop */
+ solver->nonlinearitsinitialtime = MPI_Wtime();
+
+ /*
+ ** BEGIN LUKE'S FRICTIONAL BCS BIT
+ **
+ ** Adding an interface for allowing other components to add some form of non-linearity to the system.
+ ** This is with a focus on frictional BCs, where we want to examine the stress field and modify
+ ** traction BCs to enforce friction rules. - Luke 18/07/2007
+ */
+
+ _EntryPoint_Run_2VoidPtr( self->nlEP, sle, _context );
+
+ /*
+ ** END LUKE'S FRICTIONAL BCS BIT
+ */
+
+
+ //Vector_CopyEntries( currentVector, previousVector );
+ VecCopy( currentVector, previousVector );
+
+ Journal_Printf(self->info,"Non linear solver - iteration %d\n", self->nonLinearIteration_I);
+
+ self->linearExecute( self, _context );
+// PetscPrintf( PETSC_COMM_WORLD, "|Xn+1| = %12.12e \n", Vector_L2Norm(SystemLinearEquations_GetSolutionVectorAt(self,1)->vector) );
+
+ /* Calculate Residual */
+ VecAXPY( previousVector, -1.0, currentVector );
+ VecNorm( previousVector, NORM_2, &prevVecNorm );
+ VecNorm( currentVector, NORM_2, &currVecNorm );
+ residual = ((double)prevVecNorm) / ((double)currVecNorm);
+
+ self->curResidual = residual;
+
+ /*
+ ** Include an entry point to do some kind of post-non-linear-iteration operation. */
+ _EntryPoint_Run_2VoidPtr( self->postNlEP, sle, _context );
+
+ Journal_Printf( self->info, "In func %s: Iteration %u of %u - Residual %.5g - Tolerance = %.5g\n",
+ __func__, self->nonLinearIteration_I, maxIterations, residual, tolerance );
+ if ( self->makeConvergenceFile ) {
+ Journal_Printf( self->convergenceStream, "%d\t\t%d\t\t%.5g\t\t%.5g\n",
+ self->context->timeStep, self->nonLinearIteration_I, residual, tolerance );
+ }
+
+ /* Check if residual is below tolerance */
+ converged = (residual < tolerance) ? True : False;
+
+ Journal_Printf(self->info,"Non linear solver - Residual %.8e; Tolerance %.4e%s%s - %6.6e (secs)\n\n", residual, tolerance,
+ (converged) ? " - Converged" : " - Not converged",
+ (self->nonLinearIteration_I < maxIterations) ? "" : " - Reached iteration limit",
+ MPI_Wtime() - wallTime );
+ //END OF NONLINEAR ITERATION LOOP!!!
+
+ /* add the outer loop iterations to the total outer iterations */
+ solver->totalnumnonlinearits = solver->totalnumnonlinearits++;
+ /*get wall time for end of outer loop*/
+ solver->nonlinearitsendtime = MPI_Wtime();
+ /* add time to total time inner its: */
+ solver->totalnonlinearitstime = solver->totalnonlinearitstime + (-solver->nonlinearitsinitialtime + solver->nonlinearitsendtime);
+ //printf("totalnumnonlinearits before converging is %d totalnonlinearitstime is %g, totalouteritstime is %g and totalinneritstime is %g\n",solver->totalnumnonlinearits,solver->totalnonlinearitstime,solver->totalouteritstime,solver->totalinneritstime);
+
+ /* reset initial time and end time for inner its back to 0 - probs don't need to do this but just in case */
+ solver->nonlinearitsinitialtime = 0;
+ solver->nonlinearitsendtime = 0;
+ if ( (converged) && (self->nonLinearIteration_I>=minIterations) ) {
+ int result;
+
+ /* Adding in another entry point so we can insert out own custom
+ convergeance checks. For example, with frictional boundary
+ conditions we need to ensure envery node was gone from the
+ original searching state to a fixed slipping or sticking state. */
+ _EntryPoint_Run_2VoidPtr( self->nlConvergedEP, _context, &converged );
+ MPI_Allreduce( &converged, &result, 1, MPI_INT, MPI_LOR, MPI_COMM_WORLD );
+ if( result )
+ break;
+ }
+ }
+
+ /* Print Info */
+ if ( converged ) {
+ Journal_Printf( self->info, "In func %s: Converged after %u iterations.\n",
+ __func__, self->nonLinearIteration_I );
+ }
+ else {
+ Journal_Printf( errorStream, "In func %s: Failed to converge after %u iterations.\n",
+ __func__, self->nonLinearIteration_I);
+ if ( self->killNonConvergent ) {
+ abort();
+ }
+ }
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+
+ VecDestroy( previousVector );
+
+ /*Set all the printout variables */
+ if( solver->totalnumnonlinearits ) {
+ solver->avgtimenonlinearits = (solver->totalnonlinearitstime - solver->totalouteritstime)/solver->totalnumnonlinearits;
+ solver->avgnumouterits = solver->totalnumouterits/solver->totalnumnonlinearits;
+ }
+ if( solver->totalnumouterits ) {
+ solver->avgnuminnerits = solver->totalnuminnerits/solver->totalnumouterits;
+ solver->avgtimeouterits = (solver->totalouteritstime - solver->totalinneritstime)/solver->totalnumouterits;
+ }
+ if( solver->totalnuminnerits )
+ solver->avgtimeinnerits = solver->totalinneritstime/solver->totalnuminnerits;
+ //printf("totalnumnonlinearits = %d, avgnumouterits %d, avgnuminnerits %d\n",solver->totalnumnonlinearits, solver->avgnumouterits, solver->avgnuminnerits);
+
+}
+
+void SystemLinearEquations_AddNonLinearSetupEP( void* sle, Name name, EntryPoint_2VoidPtr_Cast func ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ SystemLinearEquations_SetToNonLinear( self );
+ EntryPoint_Append( self->nlSetupEP, (char*)name, (void*)func, self->type );
+}
+
+void SystemLinearEquations_AddPostNonLinearEP( void* sle, Name name, EntryPoint_2VoidPtr_Cast func ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ EntryPoint_Append( self->postNlEP, (char*)name, (void*)func, self->type );
+}
+
+void SystemLinearEquations_AddNonLinearConvergedEP( void* sle,
+ Name name,
+ EntryPoint_2VoidPtr_Cast func )
+{
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ SystemLinearEquations_SetToNonLinear( self );
+ EntryPoint_Append( self->nlConvergedEP, (char*)name, (void*)func, self->type );
+}
+
+/*
+Computes
+ F1 := A(x) x -b = -r,
+ where r = b - A(x) x
+*/
+//void SystemLinearEquations_SNESPicardFormalResidual( void *someSLE, Vector *stg_X, Vector *stg_F, void *_context )
+void SystemLinearEquations_SNESPicardFormalResidual( void *someSLE, Vec X, Vec F, void *_context )
+{
+ SystemLinearEquations *sle = (SystemLinearEquations*)someSLE;
+ SLE_Solver *solver = (SLE_Solver*)sle->solver;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)sle->type );
+
+ Journal_Printf( errorStream, " **** SystemLinearEquations_SNESPicardFormalResidual: This option is un-tested and does not yet function correctly. \n");
+ Journal_Printf( errorStream, " **** Use the default form function or specify --components.XXX.picard_FormFunctionType=PicardFormFunction_KSPResidual instead. \n");
+ Journal_Printf( errorStream, " **** [Dave May - 12 May, 2008] \n");
+ abort();
+
+ solver->_formResidual( (void*)sle, (void*)solver, F );
+}
+
+/*
+Computes
+ F2 := x - A(x)^{-1} b
+*/
+#if 0
+void SystemLinearEquations_SNESPicardKSPResidual( void *someSLE, Vector *stg_X, Vector *stg_F, void *_context )
+{
+ SystemLinearEquations *sle = (SystemLinearEquations*)someSLE;
+ SLE_Solver *solver = (SLE_Solver*)sle->solver;
+ Vec F,X,Xcopy;
+ PetscReal norm;
+
+ F = StgVectorGetPetscVec( stg_F );
+ X = StgVectorGetPetscVec( stg_X );
+
+ VecDuplicate( X, &Xcopy );
+ VecCopy( X, Xcopy );
+
+ VecCopy( X, F ); /* F <- X */
+// VecNorm( X, NORM_2, &norm );
+// PetscPrintf(PETSC_COMM_WORLD," |X|_pre = %5.5e \n", norm );
+ sle->linearExecute( sle, _context ); /* X = A^{-1} b */
+ X = StgVectorGetPetscVec( stg_X );
+// VecNorm( X, NORM_2, &norm );
+// PetscPrintf(PETSC_COMM_WORLD," |X|_post = %5.5e \n", norm );
+
+ VecAXPY( F, -1.0, X ); /* F <- X - F */
+// VecNorm( F, NORM_2, &norm );
+// PetscPrintf(PETSC_COMM_WORLD," |F|_post = %5.5e \n", norm );
+
+ VecCopy( Xcopy, X );
+ VecDestroy( Xcopy );
+}
+#endif
+
+/*
+stg_X must not get modified by this function !!
+*/
+void SystemLinearEquations_SNESPicardKSPResidual( void *someSLE, Vec X, Vec F, void *_context )
+{
+ SystemLinearEquations *sle = (SystemLinearEquations*)someSLE;
+ SLE_Solver *solver = (SLE_Solver*)sle->solver;
+ Vec Xstar;
+ PetscReal norm,norms;
+
+ solver->_getSolution( sle, solver, &Xstar );
+
+ /* Map most current solution into stg object, vec->mesh */
+ VecCopy( X, Xstar ); /* X* <- X */
+ /* Map onto nodes */
+ SystemLinearEquations_UpdateSolutionOntoNodes( someSLE, _context );
+
+ VecNorm( X, NORM_2, &norm );
+ VecNorm( Xstar, NORM_2, &norms );
+// PetscPrintf(PETSC_COMM_WORLD," |X| = %12.12e : |x*| = %12.12e <pre>\n", norm, norms );
+
+ sle->linearExecute( sle, _context ); /* X* = A^{-1} b */
+
+ VecNorm( X, NORM_2, &norm );
+ VecNorm( Xstar, NORM_2, &norms );
+// PetscPrintf(PETSC_COMM_WORLD," |X| = %12.12e : |x*| = %12.12e <post> \n", norm, norms );
+
+ VecWAXPY( F, -1.0, Xstar, X ); /* F = -X* + X */
+}
+
+void SLEComputeFunction( void *someSLE, Vec X, Vec F, void *_context )
+{
+ SystemLinearEquations *sle = (SystemLinearEquations*)someSLE;
+
+ if (sle->_sleFormFunction!=NULL) {
+ sle->_sleFormFunction( sle, X, F, _context );
+ }
+ else {
+ SETERRABORT( sle->comm, PETSC_ERR_SUP, "SLEComputeFunction in not valid" );
+ }
+}
+
+void SLE_SNESMonitor( void *sle, PetscInt iter, PetscReal fnorm )
+{
+ PetscPrintf( PETSC_COMM_WORLD, " %.4d SLE_NS Function norm %12.12e --------------------------------------------------------------------------------\n", iter, fnorm );
+}
+
+void SLE_SNESMonitor2( void *sle, PetscInt iter, PetscReal fnorm0, PetscReal fnorm, PetscReal dX, PetscReal X1 )
+{
+ if(iter==0) {
+ PetscPrintf( PETSC_COMM_WORLD, " SLE_NS it |F| |F|/|F0| |X1-X0| |X1-X0|/|X1| \n" );
+ }
+ PetscPrintf( PETSC_COMM_WORLD, " SLE_NS %1.4d %2.4e %2.4e %2.4e %2.4e \n", iter, fnorm, fnorm/fnorm0, dX, dX/X1 );
+}
+
+void _monitor_progress( PetscReal initial, PetscReal target, PetscReal current, PetscReal *p )
+{
+ PetscReal p0;
+
+ p0 = log10(initial) - log10(target);
+ *p = 100.0 * ( 1.0 - (log10(current)-log10(target)) / p0 );
+}
+
+void SLE_SNESMonitorProgress( void *sle,
+ PetscInt iter,
+ PetscReal fnorm0, PetscReal fnorm, PetscReal dX, PetscReal X1,
+ PetscReal fatol, PetscReal frtol, PetscReal xtol )
+{
+ PetscReal f_abs_s, f_abs_e, v1, p1;
+ PetscReal f_rel_s, f_rel_e, v2, p2;
+ PetscReal x_del_s, x_del_e, v3, p3;
+
+ if(iter==0) {
+ PetscPrintf( PETSC_COMM_WORLD, " SLE_NS it |F| |F|/|F0| |X1-X0|/|X1| \n" );
+ }
+
+ f_abs_s = fnorm0;
+ f_abs_e = fatol;
+ v1 = fnorm;
+ _monitor_progress( f_abs_s, f_abs_e, v1, &p1 );
+
+ f_rel_s = fnorm0;
+ f_rel_e = fnorm0 * frtol;
+ v2 = fnorm;
+ _monitor_progress( f_rel_s, f_rel_e, v2, &p2 );
+
+ x_del_s = 1.0;
+ x_del_e = xtol;
+ v3 = dX/X1;
+ _monitor_progress( x_del_s, x_del_e, v3, &p3 );
+
+ PetscPrintf( PETSC_COMM_WORLD, " SLE_NS %1.4d %2.4e [%2.0f%%] %2.4e [%2.0f%%] %2.4e [%2.0f%%] \n", iter, fnorm,p1, fnorm/fnorm0,p2, dX/X1,p3 );
+}
+
+
+void SLE_SNESConverged(
+ PetscReal snes_abstol, PetscReal snes_rtol, PetscReal snes_ttol, PetscReal snes_xtol,
+ PetscInt it,PetscReal xnorm,PetscReal pnorm,PetscReal fnorm,SNESConvergedReason *reason )
+{
+ /* PetscErrorCode ierr; */
+
+ *reason = SNES_CONVERGED_ITERATING;
+
+ if (!it) {
+ /* set parameter for default relative tolerance convergence test */
+ snes_ttol = fnorm*snes_rtol;
+ }
+ if (fnorm != fnorm) {
+// ierr = PetscInfo(snes,"Failed to converged, function norm is NaN\n");CHKERRV(ierr);
+ *reason = SNES_DIVERGED_FNORM_NAN;
+ } else if (fnorm < snes_abstol) {
+// ierr = PetscInfo2(snes,"Converged due to function norm %G < %G\n",fnorm,snes_abstol);CHKERRV(ierr);
+ *reason = SNES_CONVERGED_FNORM_ABS;
+ }
+// } else if (snes->nfuncs >= snes->max_funcs) {
+// ierr = PetscInfo2(snes,"Exceeded maximum number of function evaluations: %D > %D\n",snes->nfuncs,snes->max_funcs);CHKERRV(ierr);
+// *reason = SNES_DIVERGED_FUNCTION_COUNT;
+// }
+
+ if (it && !*reason) {
+ if (fnorm <= snes_ttol) {
+// ierr = PetscInfo2(snes,"Converged due to function norm %G < %G (relative tolerance)\n",fnorm,snes_ttol);CHKERRV(ierr);
+ *reason = SNES_CONVERGED_FNORM_RELATIVE;
+ } else if (pnorm < snes_xtol*xnorm) {
+// ierr = PetscInfo3(snes,"Converged due to small update length: %G < %G * %G\n",pnorm,snes_xtol,xnorm);CHKERRV(ierr);
+ *reason = SNES_CONVERGED_PNORM_RELATIVE;
+ }
+ }
+}
+
+
+#if defined(PETSC_HAVE_ISINF) && defined(PETSC_HAVE_ISNAN)
+#define PetscIsInfOrNanScalar(a) (isinf(PetscAbsScalar(a)) || isnan(PetscAbsScalar(a)))
+#define PetscIsInfOrNanReal(a) (isinf(a) || isnan(a))
+#elif defined(PETSC_HAVE__FINITE) && defined(PETSC_HAVE__ISNAN)
+#if defined(PETSC_HAVE_FLOAT_H)
+#include "float.h" /* windows defines _finite() in float.h */
+#endif
+#define PetscIsInfOrNanScalar(a) (!_finite(PetscAbsScalar(a)) || _isnan(PetscAbsScalar(a)))
+#define PetscIsInfOrNanReal(a) (!_finite(a) || _isnan(a))
+#else
+#define PetscIsInfOrNanScalar(a) ((a - a) != 0.0)
+#define PetscIsInfOrNanReal(a) ((a - a) != 0.0)
+#endif
+
+/*
+This will be replaced by SNESPicard in petsc 2.4.0.
+*/
+
+void SystemLinearEquations_PicardExecute( void *sle, void *_context )
+{
+ SystemLinearEquations *self = (SystemLinearEquations*)sle;
+ SLE_Solver *solver = (SLE_Solver*)self->solver;
+
+ Vec X, Y, F, Xstar,delta_X;
+ PetscReal alpha = 1.0;
+ PetscReal fnorm,norm_X,pnorm,fnorm0;
+ PetscInt i;
+ PetscErrorCode ierr;
+ SNESConvergedReason snes_reason;
+
+ PetscReal snes_norm;
+ PetscInt snes_iter;
+
+ PetscReal snes_ttol, snes_rtol, snes_abstol, snes_xtol;
+ PetscInt snes_maxits;
+
+ PetscTruth monitor_flg;
+
+ /* setup temporary some vectors */
+ solver->_getSolution( self, solver, &Xstar );
+
+ VecDuplicate( Xstar, &X );
+ VecDuplicate( X, &F );
+ VecDuplicate( F, &Y );
+ VecDuplicate( F, &delta_X );
+
+ /* Get some values from dictionary */
+ snes_maxits = (PetscInt)self->nonLinearMaxIterations;
+ snes_ttol = 0.0;
+ snes_rtol = (PetscReal)self->rtol;
+ snes_abstol = (PetscReal)self->abstol;
+ snes_xtol = (PetscReal)self->xtol;
+ monitor_flg = PETSC_FALSE;
+ if (self->picard_monitor==True) { monitor_flg = PETSC_TRUE; }
+ alpha = (PetscReal)self->alpha;
+
+ snes_reason = SNES_CONVERGED_ITERATING;
+
+ /* Map X <- X* */
+ VecCopy( Xstar, X ); // Vector_CopyEntries( currentVector, previousVector );
+
+ /* Get an initial guess if |X| ~ 0, by solving the linear problem */
+ VecNorm( X, NORM_2, &norm_X );
+ if (norm_X <1.0e-20) {
+ if (monitor_flg==PETSC_TRUE)
+ PetscPrintf( PETSC_COMM_WORLD, "SLE_Picard: Computing an initial guess for X from the linear problem\n");
+
+ self->linearExecute( sle, _context ); /* X* = A^{-1} b */
+ self->hasExecuted = True;
+
+ /* Map X <- X* */
+ VecCopy( Xstar, X );
+ VecNorm( X, NORM_2, &norm_X );
+ }
+
+
+ snes_iter = 0;
+ snes_norm = 0;
+ //SLEComputeFunction( sle, stg_X, stg_F, _context );
+ SLEComputeFunction( sle, X, F, _context );
+ ierr = VecNorm(F, NORM_2, &fnorm);CHKERRV(ierr); /* fnorm <- ||F|| */
+ fnorm0 = fnorm;
+ if( PetscIsInfOrNanReal(fnorm) ) SETERRABORT( self->comm,PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
+
+ snes_norm = fnorm;
+ if(monitor_flg==PETSC_TRUE) {
+ /* SLE_SNESMonitor(sle,0,fnorm); */
+ /* SLE_SNESMonitor2(sle,0,fnorm0,fnorm, norm_X, norm_X ); */
+ SLE_SNESMonitorProgress( sle, snes_iter, fnorm0, fnorm, norm_X, norm_X, snes_abstol, snes_rtol, snes_xtol );
+ }
+
+ /* set parameter for default relative tolerance convergence test */
+ snes_ttol = fnorm*snes_rtol;
+ /* test convergence */
+ SLE_SNESConverged( snes_abstol,snes_rtol,snes_ttol,snes_xtol , 0,norm_X,0.0,fnorm,&snes_reason);
+ if (snes_reason) return;
+
+ for(i = 0; i < snes_maxits; i++) {
+ /* Update guess Y = X^n - F(X^n) */
+ ierr = VecWAXPY(Y, -1.0, F, X);CHKERRV(ierr);
+
+ VecCopy( X, delta_X ); /* delta_X <- X */
+
+ /* X^{n+1} = (1 - \alpha) X^n + alpha Y */
+ ierr = VecAXPBY(X, alpha, 1 - alpha, Y);CHKERRV(ierr);
+ VecNorm( X, NORM_2, &norm_X );
+/* PetscPrintf( PETSC_COMM_WORLD, " Xn+1 = %12.12e \n", norm_X ); */
+
+ VecAYPX( delta_X, -1.0, X ); /* delta_X <- Xn+1 - delta_X */
+ VecNorm( delta_X, NORM_2, &pnorm );
+
+ /* Compute F(X^{new}) */
+ SLEComputeFunction( sle, X, F, _context );
+ ierr = VecNorm(F, NORM_2, &fnorm);CHKERRV(ierr);
+ if( PetscIsInfOrNanReal(fnorm) ) SETERRABORT( self->comm,PETSC_ERR_FP,"Infinite or not-a-number generated norm");
+
+ /* Monitor convergence */
+ snes_iter = i+1;
+ snes_norm = fnorm;
+ if (monitor_flg==PETSC_TRUE) {
+ /* SLE_SNESMonitor(sle,snes_iter,snes_norm); */
+ /* SLE_SNESMonitor2(sle,snes_iter,fnorm0,fnorm, pnorm, norm_X ); */
+ SLE_SNESMonitorProgress( sle, snes_iter, fnorm0, fnorm, pnorm, norm_X, snes_abstol, snes_rtol, snes_xtol );
+ }
+
+ /* Test for convergence */
+ SLE_SNESConverged( snes_abstol,snes_rtol,snes_ttol,snes_xtol , snes_iter,norm_X,pnorm,fnorm,&snes_reason);
+ if (snes_reason) break;
+ }
+ if (i == snes_maxits) {
+// ierr = PetscInfo1(snes, "Maximum number of iterations has been reached: %D\n", maxits);CHKERRV(ierr);
+ if (!snes_reason) snes_reason = SNES_DIVERGED_MAX_IT;
+ }
+
+ /* If monitoring, report reason converged */
+ if (monitor_flg==PETSC_TRUE)
+ PetscPrintf( PETSC_COMM_WORLD, "Nonlinear solve converged due to %s \n", SNESConvergedReasons[snes_reason] );
+
+ VecDestroy( X );
+ VecDestroy( F );
+ VecDestroy( Y );
+ VecDestroy( delta_X );
+
+}
+
+
+///////////////
+
+void SystemLinearEquations_AddNonLinearEP( void* sle, Name name, EntryPoint_2VoidPtr_Cast func ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)sle;
+
+ SystemLinearEquations_SetToNonLinear( self );
+ EntryPoint_Append( self->nlEP, (char*)name, (void*)func, self->type );
+}
+
+
+
+void SystemLinearEquations_SetToNonLinear( void* sle ) {
+ SystemLinearEquations* self = (SystemLinearEquations*) sle;
+ Hook* nonLinearInitHook = NULL;
+ Hook* nonLinearFinaliseHook = NULL;
+ FiniteElementContext* context = NULL;
+
+ assert( self );
+ if ( self->isNonLinear )
+ return;
+
+ self->isNonLinear = True;
+
+ self->linearExecute = self->_execute;
+ self->_execute = SystemLinearEquations_NonLinearExecute;
+
+ if( self->nonLinearSolutionType ) {
+ if( !strcmp( self->nonLinearSolutionType, "default" ) ) {
+ self->_execute = SystemLinearEquations_NonLinearExecute;
+ }
+
+ if( !strcmp( self->nonLinearSolutionType, "MatrixFreeNewton" ) )
+ self->_execute = SystemLinearEquations_NewtonMFFDExecute;
+
+ if( !strcmp( self->nonLinearSolutionType, "Newton" ) ) {
+ context = self->context;
+
+ nonLinearInitHook = Hook_New( "NewtonInitialise",
+ (void*)SystemLinearEquations_NewtonInitialise, self->name );
+ _EntryPoint_PrependHook_AlwaysFirst( Context_GetEntryPoint( context, AbstractContext_EP_Solve ),
+ nonLinearInitHook );
+ nonLinearFinaliseHook = Hook_New( "NewtonFinalise",
+ (void*)SystemLinearEquations_NewtonFinalise, self->name );
+ _EntryPoint_AppendHook_AlwaysLast( Context_GetEntryPoint( context, AbstractContext_EP_Solve ),
+ nonLinearFinaliseHook );
+ self->_execute = SystemLinearEquations_NewtonExecute;
+ }
+
+ if (!strcmp( self->nonLinearSolutionType, "Picard") ) {
+ /* set function pointer for execute */
+ self->_execute = SystemLinearEquations_PicardExecute;
+
+ /* set form function */
+ if (!strcmp(self->picard_form_function_type,"PicardFormFunction_KSPResidual") ) {
+ self->_sleFormFunction = SystemLinearEquations_SNESPicardKSPResidual;
+ }
+ else if (!strcmp(self->picard_form_function_type,"PicardFormFunction_FormalResidual") ) {
+ self->_sleFormFunction = SystemLinearEquations_SNESPicardFormalResidual;
+ }
+ else {
+ Stream *errorStream = Journal_Register( Error_Type, (Name)self->type );
+
+ Journal_Printf( errorStream, "Unknown the Picard FormFunction type %s is unrecognised. .\n", self->picard_form_function_type );
+ Journal_Printf( errorStream, "Supported types include <PicardFormFunction_FormalResidual, PicardFormFunction_KSPResidual> \n" );
+ abort();
+
+ }
+ }
+ }
+}
+
+void SystemLinearEquations_CheckIfNonLinear( void* sle ) {
+ SystemLinearEquations* self = (SystemLinearEquations*) sle;
+ Index index;
+
+ for ( index = 0; index < self->stiffnessMatrices->count; index++ ) {
+ StiffnessMatrix* stiffnessMatrix = SystemLinearEquations_GetStiffnessMatrixAt( self, index );
+
+ if ( stiffnessMatrix->isNonLinear )
+ SystemLinearEquations_SetToNonLinear( self );
+
+ /* TODO CHECK FOR FORCE VECTORS */
+ }
+}
+
+/*
+** All the MG functions and their general implementations.
+*/
+
+void SystemLinearEquations_MG_Enable( void* _sle ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)_sle;
+
+ if( !self->isBuilt ) {
+ Journal_Printf(self->info, "Warning: SLE has not been built, can't enable multi-grid.\n" );
+ return;
+ }
+
+ self->mgEnabled = True;
+}
+
+
+void SystemLinearEquations_MG_SelectStiffMats( void* _sle, unsigned* nSMs, StiffnessMatrix*** sms ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)_sle;
+
+ assert( self->_mgSelectStiffMats );
+ self->_mgSelectStiffMats( self, nSMs, sms );
+}
+
+
+void _SystemLinearEquations_MG_SelectStiffMats( void* _sle, unsigned* nSMs, StiffnessMatrix*** sms ) {
+ SystemLinearEquations* self = (SystemLinearEquations*)_sle;
+
+ /*
+ ** As we have nothing else to go on, attempt to apply MG to all stiffness matrices in the list.
+ */
+
+ {
+ unsigned sm_i;
+
+ *nSMs = 0;
+ for( sm_i = 0; sm_i < self->stiffnessMatrices->count; sm_i++ ) {
+ StiffnessMatrix* sm = ((StiffnessMatrix**)self->stiffnessMatrices->data)[sm_i];
+
+ /* Add this one to the list. */
+ *sms = Memory_Realloc_Array( *sms, StiffnessMatrix*, (*nSMs) + 1 );
+ (*sms)[*nSMs] = sm;
+ (*nSMs)++;
+ }
+ }
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/tests/ContextSuite.c
--- a/SLE/SystemSetup/tests/ContextSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "pcu/pcu.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-
-typedef struct {
- FiniteElementContext* context;
-} ContextSuiteData;
-
-void ContextSuite_Setup( ContextSuiteData* data ) {
- Journal_Enable_AllTypedStream( False );
-}
-
-void ContextSuite_Teardown( ContextSuiteData* data ) {
- Journal_Enable_AllTypedStream( True );
-}
-
-double ContextSuite_CalcDtFunc( FiniteElementContext* context) {
- if ( context->timeStep == 1 ) {
- return 1.0;
- }
- else {
- return context->dt * 1.5;
- }
-}
-
-void ContextSuite_TestContext( ContextSuiteData* data ) {
- /** Test Definition: */
- char expected_file[PCU_PATH_MAX];
- Stg_ComponentFactory* cf;
- Dictionary* dictionary;
- Name outputPath;
- Stream* stream;
- char xml_input[PCU_PATH_MAX];
-
- /* read in the xml input file */
- pcu_filename_input( "testContext.xml", xml_input );
-
- cf = stgMainInitFromXML( xml_input, MPI_COMM_WORLD, NULL );
- data->context = (FiniteElementContext*)LiveComponentRegister_Get( cf->LCRegister, (Name)"context" );
- stgMainBuildAndInitialise(cf );
-
- dictionary = data->context->dictionary;
- outputPath = Dictionary_GetString( dictionary, (Dictionary_Entry_Key)"outputPath" );
-
- /* Run the test ----------------------------------------------------------------------------------------------------*/
- /* This is where we'd normally construct components if it was real main.
- * instead, we'll just set the dt function so we can test it */
- EP_AppendClassHook( data->context->calcDtEP, ContextSuite_CalcDtFunc, data->context );
-
- if( data->context->rank == 0 )
- Context_PrintConcise( data->context, data->context->verbose );
-
- if ( True == Dictionary_GetBool_WithDefault( dictionary, (Dictionary_Entry_Key)"showJournalStatus", False ) ) {
- Journal_PrintConcise( );
- }
-
- /* Building phase ---------------------------------------------------------------------------------------------------*/
- Stg_Component_Build( data->context, 0 /* dummy */, False );
-
- /* Initialisaton phase ----------------------------------------------------------------------------------------------*/
- Stg_Component_Initialise( data->context, 0 /* dummy */, False );
-
- /* Run (Solve) phase ------------------------------------------------------------------------------------------------*/
- data->context->maxTimeSteps = 10;
- data->context->dtFactor = 1.0;
-
- Journal_Enable_TypedStream( InfoStream_Type, True );
- stream = Journal_Register( Info_Type, (Name)"testContext.xml" );
- data->context->info = stream; /* Redirect output to test data stream */
- Stream_RedirectFile_WithPrependedPath( stream, outputPath, "test.dat" );
-
- Journal_Printf( stream, "Running with no timestep braking, using " "dt that increases 50%% each step:\n" );
-
- Stg_Component_Execute( data->context, 0 /* dummy */, False );
- data->context->currentTime=0;
- data->context->dt = 0;
-
- Journal_Printf( stream, "\nTurning on timestep braking, at default " "level, running again:\n" );
- data->context->limitTimeStepIncreaseRate = True;
- Stg_Component_Execute( data->context, 0 /* dummy */, True );
- data->context->currentTime=0;
- data->context->dt = 0;
-
- Journal_Printf( stream, "\nTurning on timestep braking, at 80%% " "level, running again - expect same as original:\n" );
- data->context->maxTimeStepIncreasePercentage = 80;
- Stg_Component_Execute( data->context, 0 /* dummy */, True );
-
- Stream_CloseAndFreeFile( stream );
-
- /* Compare results to expected */
- pcu_filename_expected( "testContext.expected", expected_file );
- pcu_check_fileEq( "output/test.dat", expected_file );
- remove("output/test.dat");
-}
-
-void ContextSuite( pcu_suite_t* suite ) {
- pcu_suite_setData( suite, ContextSuiteData );
- pcu_suite_setFixtures( suite, ContextSuite_Setup, ContextSuite_Teardown );
- pcu_suite_addTest( suite, ContextSuite_TestContext );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/tests/ContextSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/tests/ContextSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,108 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pcu/pcu.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+
+typedef struct {
+ FiniteElementContext* context;
+} ContextSuiteData;
+
+void ContextSuite_Setup( ContextSuiteData* data ) {
+ Journal_Enable_AllTypedStream( False );
+}
+
+void ContextSuite_Teardown( ContextSuiteData* data ) {
+ Journal_Enable_AllTypedStream( True );
+}
+
+double ContextSuite_CalcDtFunc( FiniteElementContext* context) {
+ if ( context->timeStep == 1 ) {
+ return 1.0;
+ }
+ else {
+ return context->dt * 1.5;
+ }
+}
+
+void ContextSuite_TestContext( ContextSuiteData* data ) {
+ /** Test Definition: */
+ char expected_file[PCU_PATH_MAX];
+ Stg_ComponentFactory* cf;
+ Dictionary* dictionary;
+ Name outputPath;
+ Stream* stream;
+ char xml_input[PCU_PATH_MAX];
+
+ /* read in the xml input file */
+ pcu_filename_input( "testContext.xml", xml_input );
+
+ cf = stgMainInitFromXML( xml_input, MPI_COMM_WORLD, NULL );
+ data->context = (FiniteElementContext*)LiveComponentRegister_Get( cf->LCRegister, (Name)"context" );
+ stgMainBuildAndInitialise(cf );
+
+ dictionary = data->context->dictionary;
+ outputPath = Dictionary_GetString( dictionary, (Dictionary_Entry_Key)"outputPath" );
+
+ /* Run the test ----------------------------------------------------------------------------------------------------*/
+ /* This is where we'd normally construct components if it was real main.
+ * instead, we'll just set the dt function so we can test it */
+ EP_AppendClassHook( data->context->calcDtEP, ContextSuite_CalcDtFunc, data->context );
+
+ if( data->context->rank == 0 )
+ Context_PrintConcise( data->context, data->context->verbose );
+
+ if ( True == Dictionary_GetBool_WithDefault( dictionary, (Dictionary_Entry_Key)"showJournalStatus", False ) ) {
+ Journal_PrintConcise( );
+ }
+
+ /* Building phase ---------------------------------------------------------------------------------------------------*/
+ Stg_Component_Build( data->context, 0 /* dummy */, False );
+
+ /* Initialisaton phase ----------------------------------------------------------------------------------------------*/
+ Stg_Component_Initialise( data->context, 0 /* dummy */, False );
+
+ /* Run (Solve) phase ------------------------------------------------------------------------------------------------*/
+ data->context->maxTimeSteps = 10;
+ data->context->dtFactor = 1.0;
+
+ Journal_Enable_TypedStream( InfoStream_Type, True );
+ stream = Journal_Register( Info_Type, (Name)"testContext.xml" );
+ data->context->info = stream; /* Redirect output to test data stream */
+ Stream_RedirectFile_WithPrependedPath( stream, outputPath, "test.dat" );
+
+ Journal_Printf( stream, "Running with no timestep braking, using " "dt that increases 50%% each step:\n" );
+
+ Stg_Component_Execute( data->context, 0 /* dummy */, False );
+ data->context->currentTime=0;
+ data->context->dt = 0;
+
+ Journal_Printf( stream, "\nTurning on timestep braking, at default " "level, running again:\n" );
+ data->context->limitTimeStepIncreaseRate = True;
+ Stg_Component_Execute( data->context, 0 /* dummy */, True );
+ data->context->currentTime=0;
+ data->context->dt = 0;
+
+ Journal_Printf( stream, "\nTurning on timestep braking, at 80%% " "level, running again - expect same as original:\n" );
+ data->context->maxTimeStepIncreasePercentage = 80;
+ Stg_Component_Execute( data->context, 0 /* dummy */, True );
+
+ Stream_CloseAndFreeFile( stream );
+
+ /* Compare results to expected */
+ pcu_filename_expected( "testContext.expected", expected_file );
+ pcu_check_fileEq( "output/test.dat", expected_file );
+ remove("output/test.dat");
+}
+
+void ContextSuite( pcu_suite_t* suite ) {
+ pcu_suite_setData( suite, ContextSuiteData );
+ pcu_suite_setFixtures( suite, ContextSuite_Setup, ContextSuite_Teardown );
+ pcu_suite_addTest( suite, ContextSuite_TestContext );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/tests/SolutionVectorSuite.c
--- a/SLE/SystemSetup/tests/SolutionVectorSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,187 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "pcu/pcu.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-
-typedef struct {
-} SolutionVectorSuiteData;
-
-void SolutionVectorSuite_Setup( SolutionVectorSuiteData* data ) { }
-
-void SolutionVectorSuite_Teardown( SolutionVectorSuiteData* data ) {}
-
-
-FeVariable* SolutionVectorSuite_buildFeVar() {
- CartesianGenerator* gen;
- FeMesh* feMesh;
- DofLayout* dofs;
- FeEquationNumber* eqNum;
- Variable_Register* varReg;
- int maxDecomp[3] = {0, 1, 1};
- int sizes[3];
- double minCrd[3];
- double maxCrd[3];
- static int arraySize;
- static double* arrayPtrs[2];
- int nRanks;
- Variable* var;
- VariableCondition* bcs;
- ConditionFunction_Register* cfReg;
- Dictionary* dict;
- XML_IO_Handler* ioHandler;
- FieldVariable_Register* fieldReg;
- FeVariable* feVar;
- int n_i;
- char xml_input[PCU_PATH_MAX];
-
- pcu_filename_input( "testSolutionVector.xml", xml_input );
-
- MPI_Comm_size( MPI_COMM_WORLD, &nRanks );
- sizes[0] = nRanks * 2;
- sizes[1] = sizes[2] = 2;
- minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
- maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nRanks;
-
- gen = CartesianGenerator_New( "", NULL );
- CartesianGenerator_SetDimSize( gen, 2 );
- CartesianGenerator_SetTopologyParams( gen, (unsigned*)sizes, 0, NULL, (unsigned*)maxDecomp );
- CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
- CartesianGenerator_SetShadowDepth( gen, 0 );
-
- feMesh = FeMesh_New( "", NULL );
- Mesh_SetGenerator( feMesh, gen );
- FeMesh_SetElementFamily( feMesh, "linear" );
- Stg_Component_Build( feMesh, NULL, False );
-
- varReg = Variable_Register_New();
- cfReg = ConditionFunction_Register_New();
-
- arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
- arrayPtrs[0] = Memory_Alloc_Array_Unnamed( double, arraySize * 2 );
-/*
- arrayPtrs[1] = Memory_Alloc_Array_Unnamed( double, arraySize );
-*/
- var = Variable_NewVector( "velocity", NULL, Variable_DataType_Double, 2, (unsigned*)&arraySize, NULL,
- (void**)arrayPtrs, varReg,
- "vx", "vy" );
- Variable_Register_BuildAll( varReg );
-
- dofs = DofLayout_New( "", NULL, varReg, 0, feMesh );
- dofs->nBaseVariables = 2;
- dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, 2 );
- dofs->baseVariables[0] = var->components[0];
- dofs->baseVariables[1] = var->components[1];
- Stg_Component_Build( dofs, NULL, False );
- Stg_Component_Initialise( dofs, NULL, False );
-
- ioHandler = XML_IO_Handler_New();
- dict = Dictionary_New();
- IO_Handler_ReadAllFromFile( ioHandler, xml_input, dict );
- bcs = (VariableCondition*)WallVC_New( "", NULL, "wallVC", varReg, cfReg, dict, feMesh );
- Stg_Component_Build( bcs, NULL, False );
- Stg_Component_Initialise( bcs, NULL, False );
-
- eqNum = FeEquationNumber_New( "", NULL, feMesh, dofs, bcs, NULL );
- Stg_Component_Build( eqNum, NULL, False );
- Stg_Component_Initialise( eqNum, NULL, False );
-
- fieldReg = FieldVariable_Register_New();
- feVar = FeVariable_New( "velocity", NULL, feMesh, NULL, dofs, bcs, NULL, NULL, 2, True,
- False, False, fieldReg );
-
- for( n_i = 0; n_i < Mesh_GetLocalSize( feMesh, (MeshTopology_Dim)0 ); n_i++ ) {
- /*const double pi=acos(-1.0);*/
- double* pos = Mesh_GetVertex( feMesh, n_i );
-
- Variable_SetValue( var, n_i, pos );
- /*
- arrayPtrs[0][n_i] = (1.0 - pos[1]) + 0.1 * cos( pi * pos[0] ) * sin( pi * pos[1] );
- arrayPtrs[1][n_i] = (1.0 - pos[1]) + 0.1 * cos( pi * pos[0] ) * sin( pi * pos[1] );
- */
- }
-
- /* Build and initialise system */
- Stg_Component_Build( bcs, 0, False );
- Stg_Component_Build( feVar, 0, False );
- Stg_Component_Initialise( feVar, 0, False );
-
- return feVar;
-}
-
-
-void SolutionVectorSuite_TestSolutionVector( SolutionVectorSuiteData* data ) {
- FeVariable* feVar;
- FeMesh* mesh;
- int nEls, nVerts, nDims;
- const int *verts;
- double* vert;
- double val[3];
- InterpolationResult ret;
- SolutionVector* sol;
- int lSize;
- double* array;
- IArray* incArray;
- int e_i, v_i, d_i, a_i;
-
- feVar = SolutionVectorSuite_buildFeVar();
- FeVariable_SyncShadowValues( feVar );
- sol = SolutionVector_New( "velocity", NULL, MPI_COMM_WORLD, feVar );
- /* Check solution vector created */
- pcu_check_true(sol);
- Stg_Component_Build( sol, NULL, False );
-
- SolutionVector_LoadCurrentFeVariableValuesOntoVector( sol );
- VecGetLocalSize( sol->vector, &lSize );
- VecGetArray( sol->vector, &array );
-
- for( a_i = 0; a_i < lSize; a_i++ )
- array[a_i] += 1.0;
- VecRestoreArray( sol->vector, &array );
- SolutionVector_UpdateSolutionOntoNodes( sol );
-
- mesh = feVar->feMesh;
- nDims = Mesh_GetDimSize( mesh );
- nEls = Mesh_GetDomainSize( mesh, (MeshTopology_Dim)nDims );
- incArray = IArray_New();
-
- for( e_i = 0; e_i < nEls; e_i++ ) {
- Mesh_GetIncidence( mesh, (MeshTopology_Dim)nDims, e_i, (MeshTopology_Dim)0, incArray );
- nVerts = IArray_GetSize( incArray );
- verts = IArray_GetPtr( incArray );
- for( v_i = 0; v_i < nVerts; v_i++ ) {
- vert = Mesh_GetVertex( mesh, verts[v_i] );
- ret = FieldVariable_InterpolateValueAt( feVar, vert, val );
- if( ret != LOCAL && ret != SHADOW )
- continue;
- for( d_i = 0; d_i < nDims; d_i++ ) {
- if( !Num_Approx( vert[d_i] + 1.0, val[d_i] ) )
- break;
- }
- if( d_i < nDims )
- break;
- }
- if( v_i < nVerts )
- break;
- }
-
- /* Check all elements processed */
- pcu_check_true(e_i == nEls);
-
- NewClass_Delete( incArray );
-
- FreeObject( feVar );
- FreeObject( sol );
-}
-
-void SolutionVectorSuite( pcu_suite_t* suite ) {
- pcu_suite_setData( suite, SolutionVectorSuiteData );
- pcu_suite_setFixtures( suite, SolutionVectorSuite_Setup, SolutionVectorSuite_Teardown );
- pcu_suite_addTest( suite, SolutionVectorSuite_TestSolutionVector );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/tests/SolutionVectorSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/tests/SolutionVectorSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,187 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pcu/pcu.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+
+typedef struct {
+} SolutionVectorSuiteData;
+
+void SolutionVectorSuite_Setup( SolutionVectorSuiteData* data ) { }
+
+void SolutionVectorSuite_Teardown( SolutionVectorSuiteData* data ) {}
+
+
+FeVariable* SolutionVectorSuite_buildFeVar() {
+ CartesianGenerator* gen;
+ FeMesh* feMesh;
+ DofLayout* dofs;
+ FeEquationNumber* eqNum;
+ Variable_Register* varReg;
+ int maxDecomp[3] = {0, 1, 1};
+ int sizes[3];
+ double minCrd[3];
+ double maxCrd[3];
+ static int arraySize;
+ static double* arrayPtrs[2];
+ int nRanks;
+ Variable* var;
+ VariableCondition* bcs;
+ ConditionFunction_Register* cfReg;
+ Dictionary* dict;
+ XML_IO_Handler* ioHandler;
+ FieldVariable_Register* fieldReg;
+ FeVariable* feVar;
+ int n_i;
+ char xml_input[PCU_PATH_MAX];
+
+ pcu_filename_input( "testSolutionVector.xml", xml_input );
+
+ MPI_Comm_size( MPI_COMM_WORLD, &nRanks );
+ sizes[0] = nRanks * 2;
+ sizes[1] = sizes[2] = 2;
+ minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
+ maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nRanks;
+
+ gen = CartesianGenerator_New( "", NULL );
+ CartesianGenerator_SetDimSize( gen, 2 );
+ CartesianGenerator_SetTopologyParams( gen, (unsigned*)sizes, 0, NULL, (unsigned*)maxDecomp );
+ CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+ CartesianGenerator_SetShadowDepth( gen, 0 );
+
+ feMesh = FeMesh_New( "", NULL );
+ Mesh_SetGenerator( feMesh, gen );
+ FeMesh_SetElementFamily( feMesh, "linear" );
+ Stg_Component_Build( feMesh, NULL, False );
+
+ varReg = Variable_Register_New();
+ cfReg = ConditionFunction_Register_New();
+
+ arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+ arrayPtrs[0] = Memory_Alloc_Array_Unnamed( double, arraySize * 2 );
+/*
+ arrayPtrs[1] = Memory_Alloc_Array_Unnamed( double, arraySize );
+*/
+ var = Variable_NewVector( "velocity", NULL, Variable_DataType_Double, 2, (unsigned*)&arraySize, NULL,
+ (void**)arrayPtrs, varReg,
+ "vx", "vy" );
+ Variable_Register_BuildAll( varReg );
+
+ dofs = DofLayout_New( "", NULL, varReg, 0, feMesh );
+ dofs->nBaseVariables = 2;
+ dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, 2 );
+ dofs->baseVariables[0] = var->components[0];
+ dofs->baseVariables[1] = var->components[1];
+ Stg_Component_Build( dofs, NULL, False );
+ Stg_Component_Initialise( dofs, NULL, False );
+
+ ioHandler = XML_IO_Handler_New();
+ dict = Dictionary_New();
+ IO_Handler_ReadAllFromFile( ioHandler, xml_input, dict );
+ bcs = (VariableCondition*)WallVC_New( "", NULL, "wallVC", varReg, cfReg, dict, feMesh );
+ Stg_Component_Build( bcs, NULL, False );
+ Stg_Component_Initialise( bcs, NULL, False );
+
+ eqNum = FeEquationNumber_New( "", NULL, feMesh, dofs, bcs, NULL );
+ Stg_Component_Build( eqNum, NULL, False );
+ Stg_Component_Initialise( eqNum, NULL, False );
+
+ fieldReg = FieldVariable_Register_New();
+ feVar = FeVariable_New( "velocity", NULL, feMesh, NULL, dofs, bcs, NULL, NULL, 2, True,
+ False, False, fieldReg );
+
+ for( n_i = 0; n_i < Mesh_GetLocalSize( feMesh, (MeshTopology_Dim)0 ); n_i++ ) {
+ /*const double pi=acos(-1.0);*/
+ double* pos = Mesh_GetVertex( feMesh, n_i );
+
+ Variable_SetValue( var, n_i, pos );
+ /*
+ arrayPtrs[0][n_i] = (1.0 - pos[1]) + 0.1 * cos( pi * pos[0] ) * sin( pi * pos[1] );
+ arrayPtrs[1][n_i] = (1.0 - pos[1]) + 0.1 * cos( pi * pos[0] ) * sin( pi * pos[1] );
+ */
+ }
+
+ /* Build and initialise system */
+ Stg_Component_Build( bcs, 0, False );
+ Stg_Component_Build( feVar, 0, False );
+ Stg_Component_Initialise( feVar, 0, False );
+
+ return feVar;
+}
+
+
+void SolutionVectorSuite_TestSolutionVector( SolutionVectorSuiteData* data ) {
+ FeVariable* feVar;
+ FeMesh* mesh;
+ int nEls, nVerts, nDims;
+ const int *verts;
+ double* vert;
+ double val[3];
+ InterpolationResult ret;
+ SolutionVector* sol;
+ int lSize;
+ double* array;
+ IArray* incArray;
+ int e_i, v_i, d_i, a_i;
+
+ feVar = SolutionVectorSuite_buildFeVar();
+ FeVariable_SyncShadowValues( feVar );
+ sol = SolutionVector_New( "velocity", NULL, MPI_COMM_WORLD, feVar );
+ /* Check solution vector created */
+ pcu_check_true(sol);
+ Stg_Component_Build( sol, NULL, False );
+
+ SolutionVector_LoadCurrentFeVariableValuesOntoVector( sol );
+ VecGetLocalSize( sol->vector, &lSize );
+ VecGetArray( sol->vector, &array );
+
+ for( a_i = 0; a_i < lSize; a_i++ )
+ array[a_i] += 1.0;
+ VecRestoreArray( sol->vector, &array );
+ SolutionVector_UpdateSolutionOntoNodes( sol );
+
+ mesh = feVar->feMesh;
+ nDims = Mesh_GetDimSize( mesh );
+ nEls = Mesh_GetDomainSize( mesh, (MeshTopology_Dim)nDims );
+ incArray = IArray_New();
+
+ for( e_i = 0; e_i < nEls; e_i++ ) {
+ Mesh_GetIncidence( mesh, (MeshTopology_Dim)nDims, e_i, (MeshTopology_Dim)0, incArray );
+ nVerts = IArray_GetSize( incArray );
+ verts = IArray_GetPtr( incArray );
+ for( v_i = 0; v_i < nVerts; v_i++ ) {
+ vert = Mesh_GetVertex( mesh, verts[v_i] );
+ ret = FieldVariable_InterpolateValueAt( feVar, vert, val );
+ if( ret != LOCAL && ret != SHADOW )
+ continue;
+ for( d_i = 0; d_i < nDims; d_i++ ) {
+ if( !Num_Approx( vert[d_i] + 1.0, val[d_i] ) )
+ break;
+ }
+ if( d_i < nDims )
+ break;
+ }
+ if( v_i < nVerts )
+ break;
+ }
+
+ /* Check all elements processed */
+ pcu_check_true(e_i == nEls);
+
+ NewClass_Delete( incArray );
+
+ FreeObject( feVar );
+ FreeObject( sol );
+}
+
+void SolutionVectorSuite( pcu_suite_t* suite ) {
+ pcu_suite_setData( suite, SolutionVectorSuiteData );
+ pcu_suite_setFixtures( suite, SolutionVectorSuite_Setup, SolutionVectorSuite_Teardown );
+ pcu_suite_addTest( suite, SolutionVectorSuite_TestSolutionVector );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/tests/StiffnessMatrixSuite.c
--- a/SLE/SystemSetup/tests/StiffnessMatrixSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "pcu/pcu.h"
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-
-typedef struct {
-} StiffnessMatrixSuiteData;
-
-void StiffnessMatrixSuite_Setup( StiffnessMatrixSuiteData* data ) {
- Journal_Enable_AllTypedStream( False );
-}
-
-void StiffnessMatrixSuite_Teardown( StiffnessMatrixSuiteData* data ) {
- Journal_Enable_AllTypedStream( True );
-}
-
-FeVariable* buildFeVar() {
- CartesianGenerator* gen;
- FeMesh* feMesh;
- DofLayout* dofs;
- FeEquationNumber* eqNum;
- Variable_Register* varReg;
- int maxDecomp[3] = {0, 1, 1};
- int sizes[3];
- double minCrd[3];
- double maxCrd[3];
- char xml_input[PCU_PATH_MAX];
- static int arraySize;
- static double* arrayPtrs[2];
- int nRanks;
- Variable* var;
- VariableCondition* bcs;
- ConditionFunction_Register* cfReg;
- Dictionary* dict;
- XML_IO_Handler* ioHandler;
- FieldVariable_Register* fieldReg;
- FeVariable* feVar;
- int n_i;
-
- MPI_Comm_size( MPI_COMM_WORLD, &nRanks );
- sizes[0] = nRanks * 2;
- sizes[1] = sizes[2] = 2;
- minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
- maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nRanks;
-
- gen = CartesianGenerator_New( "", NULL );
- CartesianGenerator_SetDimSize( gen, 2 );
- CartesianGenerator_SetTopologyParams( gen, (unsigned*)sizes, 0, NULL, (unsigned*)maxDecomp );
- CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
- CartesianGenerator_SetShadowDepth( gen, 0 );
-
- feMesh = FeMesh_New( "", NULL );
- Mesh_SetGenerator( feMesh, gen );
- FeMesh_SetElementFamily( feMesh, "linear" );
- Stg_Component_Build( feMesh, NULL, False );
-
- varReg = Variable_Register_New();
- cfReg = ConditionFunction_Register_New();
-
- arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
- arrayPtrs[0] = Memory_Alloc_Array_Unnamed( double, arraySize * 2 );
- var = Variable_NewVector( "velocity", NULL, Variable_DataType_Double, 2, (unsigned*)&arraySize, NULL,
- (void**)arrayPtrs, varReg, "vx", "vy" );
- Variable_Register_BuildAll( varReg );
-
- dofs = DofLayout_New( "", NULL, varReg, 0, feMesh );
- dofs->nBaseVariables = 2;
- dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, 2 );
- dofs->baseVariables[0] = var->components[0];
- dofs->baseVariables[1] = var->components[1];
- Stg_Component_Build( dofs, NULL, False );
- Stg_Component_Initialise( dofs, NULL, False );
-
- ioHandler = XML_IO_Handler_New();
- dict = Dictionary_New();
- pcu_filename_input( "velWallVC.xml", xml_input );
- IO_Handler_ReadAllFromFile( ioHandler, xml_input, dict );
- bcs = (VariableCondition*)WallVC_New( "", NULL, "wallVC", varReg, cfReg, dict, feMesh );
- Stg_Component_Build( bcs, NULL, False );
- Stg_Component_Initialise( bcs, NULL, False );
-
- eqNum = FeEquationNumber_New( "", NULL, feMesh, dofs, bcs, NULL );
- Stg_Component_Build( eqNum, NULL, False );
- Stg_Component_Initialise( eqNum, NULL, False );
-
- fieldReg = FieldVariable_Register_New();
- feVar = FeVariable_New( "velocity", NULL, feMesh, NULL, dofs, bcs, NULL, NULL, 2, True,
- False, False, fieldReg );
-
- for( n_i = 0; n_i < Mesh_GetLocalSize( feMesh, (MeshTopology_Dim)0 ); n_i++ ) {
- /*const double pi=acos(-1.0);*/
- double* pos = Mesh_GetVertex( feMesh, n_i );
-
- /* assign the position vector as the nodes vector */
- Variable_SetValue( var, n_i, pos );
- }
-
- /* Build and initialise system */
- Stg_Component_Build( bcs, 0, False );
- Stg_Component_Build( feVar, 0, False );
- Stg_Component_Initialise( feVar, 0, False );
-
- return feVar;
-}
-
-
-void StiffnessMatrixSuite_TestStiffnessMatrix( StiffnessMatrixSuiteData* data ) {
- FeVariable* feVar;
- FeMesh* mesh;
- EntryPoint_Register* ep_reg;
- StiffnessMatrix* mat;
- ForceVector* vec;
- MPI_Comm comm;
-
- pcu_docstring( "This test just creates a Stiffness matrix data structure, builds, itialises, refreshes and then destroys it.\n" );
-
- /* we need an EP register here for the construction of the ForceVector and StiffnessMatrix */
- ep_reg = EntryPoint_Register_New();
-
- /* here we build a feVar with the position vector stored on the nodes */
- feVar = buildFeVar();
- mesh = feVar->feMesh;
- FeVariable_SyncShadowValues( feVar );
-
- /* create SiffnessMatrix, it requires a ForceVector */
- comm = Comm_GetMPIComm( Mesh_GetCommTopology( mesh, MT_VERTEX ) );
- vec = ForceVector_New( "testVector", NULL, feVar, 2, ep_reg, comm );
- mat = StiffnessMatrix_New( "testMatrix", feVar, feVar, vec, NULL, 2, False, False, ep_reg, comm);
-
- /* build & initialise the mat, this should build and initialise the vec */
- Stg_Component_Build( mat, NULL, False );
- Stg_Component_Initialise( mat, NULL, False );
-
- StiffnessMatrix_RefreshMatrix( mat );
-
- pcu_check_true( mat->matrix != NULL );
-
- Stg_Component_Destroy( feVar, NULL, True );
- Stg_Component_Destroy( vec, NULL, True );
- Stg_Component_Destroy( mat, NULL, True );
- _Stg_Component_Delete( feVar );
- _Stg_Component_Delete( vec );
- /*_Stg_Component_Delete( mat );*/
- Stg_Class_Delete( ep_reg );
-}
-
-void StiffnessMatrixSuite( pcu_suite_t* suite ) {
- pcu_suite_setData( suite, StiffnessMatrixSuiteData );
- pcu_suite_setFixtures( suite, StiffnessMatrixSuite_Setup, StiffnessMatrixSuite_Teardown );
- pcu_suite_addTest( suite, StiffnessMatrixSuite_TestStiffnessMatrix );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/SystemSetup/tests/StiffnessMatrixSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/SystemSetup/tests/StiffnessMatrixSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,158 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pcu/pcu.h"
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+
+typedef struct {
+} StiffnessMatrixSuiteData;
+
+void StiffnessMatrixSuite_Setup( StiffnessMatrixSuiteData* data ) {
+ Journal_Enable_AllTypedStream( False );
+}
+
+void StiffnessMatrixSuite_Teardown( StiffnessMatrixSuiteData* data ) {
+ Journal_Enable_AllTypedStream( True );
+}
+
+FeVariable* buildFeVar() {
+ CartesianGenerator* gen;
+ FeMesh* feMesh;
+ DofLayout* dofs;
+ FeEquationNumber* eqNum;
+ Variable_Register* varReg;
+ int maxDecomp[3] = {0, 1, 1};
+ int sizes[3];
+ double minCrd[3];
+ double maxCrd[3];
+ char xml_input[PCU_PATH_MAX];
+ static int arraySize;
+ static double* arrayPtrs[2];
+ int nRanks;
+ Variable* var;
+ VariableCondition* bcs;
+ ConditionFunction_Register* cfReg;
+ Dictionary* dict;
+ XML_IO_Handler* ioHandler;
+ FieldVariable_Register* fieldReg;
+ FeVariable* feVar;
+ int n_i;
+
+ MPI_Comm_size( MPI_COMM_WORLD, &nRanks );
+ sizes[0] = nRanks * 2;
+ sizes[1] = sizes[2] = 2;
+ minCrd[0] = minCrd[1] = minCrd[2] = 0.0;
+ maxCrd[0] = maxCrd[1] = maxCrd[2] = (double)nRanks;
+
+ gen = CartesianGenerator_New( "", NULL );
+ CartesianGenerator_SetDimSize( gen, 2 );
+ CartesianGenerator_SetTopologyParams( gen, (unsigned*)sizes, 0, NULL, (unsigned*)maxDecomp );
+ CartesianGenerator_SetGeometryParams( gen, minCrd, maxCrd );
+ CartesianGenerator_SetShadowDepth( gen, 0 );
+
+ feMesh = FeMesh_New( "", NULL );
+ Mesh_SetGenerator( feMesh, gen );
+ FeMesh_SetElementFamily( feMesh, "linear" );
+ Stg_Component_Build( feMesh, NULL, False );
+
+ varReg = Variable_Register_New();
+ cfReg = ConditionFunction_Register_New();
+
+ arraySize = Mesh_GetDomainSize( feMesh, MT_VERTEX );
+ arrayPtrs[0] = Memory_Alloc_Array_Unnamed( double, arraySize * 2 );
+ var = Variable_NewVector( "velocity", NULL, Variable_DataType_Double, 2, (unsigned*)&arraySize, NULL,
+ (void**)arrayPtrs, varReg, "vx", "vy" );
+ Variable_Register_BuildAll( varReg );
+
+ dofs = DofLayout_New( "", NULL, varReg, 0, feMesh );
+ dofs->nBaseVariables = 2;
+ dofs->baseVariables = Memory_Alloc_Array_Unnamed( Variable*, 2 );
+ dofs->baseVariables[0] = var->components[0];
+ dofs->baseVariables[1] = var->components[1];
+ Stg_Component_Build( dofs, NULL, False );
+ Stg_Component_Initialise( dofs, NULL, False );
+
+ ioHandler = XML_IO_Handler_New();
+ dict = Dictionary_New();
+ pcu_filename_input( "velWallVC.xml", xml_input );
+ IO_Handler_ReadAllFromFile( ioHandler, xml_input, dict );
+ bcs = (VariableCondition*)WallVC_New( "", NULL, "wallVC", varReg, cfReg, dict, feMesh );
+ Stg_Component_Build( bcs, NULL, False );
+ Stg_Component_Initialise( bcs, NULL, False );
+
+ eqNum = FeEquationNumber_New( "", NULL, feMesh, dofs, bcs, NULL );
+ Stg_Component_Build( eqNum, NULL, False );
+ Stg_Component_Initialise( eqNum, NULL, False );
+
+ fieldReg = FieldVariable_Register_New();
+ feVar = FeVariable_New( "velocity", NULL, feMesh, NULL, dofs, bcs, NULL, NULL, 2, True,
+ False, False, fieldReg );
+
+ for( n_i = 0; n_i < Mesh_GetLocalSize( feMesh, (MeshTopology_Dim)0 ); n_i++ ) {
+ /*const double pi=acos(-1.0);*/
+ double* pos = Mesh_GetVertex( feMesh, n_i );
+
+ /* assign the position vector as the nodes vector */
+ Variable_SetValue( var, n_i, pos );
+ }
+
+ /* Build and initialise system */
+ Stg_Component_Build( bcs, 0, False );
+ Stg_Component_Build( feVar, 0, False );
+ Stg_Component_Initialise( feVar, 0, False );
+
+ return feVar;
+}
+
+
+void StiffnessMatrixSuite_TestStiffnessMatrix( StiffnessMatrixSuiteData* data ) {
+ FeVariable* feVar;
+ FeMesh* mesh;
+ EntryPoint_Register* ep_reg;
+ StiffnessMatrix* mat;
+ ForceVector* vec;
+ MPI_Comm comm;
+
+ pcu_docstring( "This test just creates a Stiffness matrix data structure, builds, itialises, refreshes and then destroys it.\n" );
+
+ /* we need an EP register here for the construction of the ForceVector and StiffnessMatrix */
+ ep_reg = EntryPoint_Register_New();
+
+ /* here we build a feVar with the position vector stored on the nodes */
+ feVar = buildFeVar();
+ mesh = feVar->feMesh;
+ FeVariable_SyncShadowValues( feVar );
+
+ /* create SiffnessMatrix, it requires a ForceVector */
+ comm = Comm_GetMPIComm( Mesh_GetCommTopology( mesh, MT_VERTEX ) );
+ vec = ForceVector_New( "testVector", NULL, feVar, 2, ep_reg, comm );
+ mat = StiffnessMatrix_New( "testMatrix", feVar, feVar, vec, NULL, 2, False, False, ep_reg, comm);
+
+ /* build & initialise the mat, this should build and initialise the vec */
+ Stg_Component_Build( mat, NULL, False );
+ Stg_Component_Initialise( mat, NULL, False );
+
+ StiffnessMatrix_RefreshMatrix( mat );
+
+ pcu_check_true( mat->matrix != NULL );
+
+ Stg_Component_Destroy( feVar, NULL, True );
+ Stg_Component_Destroy( vec, NULL, True );
+ Stg_Component_Destroy( mat, NULL, True );
+ _Stg_Component_Delete( feVar );
+ _Stg_Component_Delete( vec );
+ /*_Stg_Component_Delete( mat );*/
+ Stg_Class_Delete( ep_reg );
+}
+
+void StiffnessMatrixSuite( pcu_suite_t* suite ) {
+ pcu_suite_setData( suite, StiffnessMatrixSuiteData );
+ pcu_suite_setFixtures( suite, StiffnessMatrixSuite_Setup, StiffnessMatrixSuite_Teardown );
+ pcu_suite_addTest( suite, StiffnessMatrixSuite_TestStiffnessMatrix );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/src/Finalise.c
--- a/SLE/src/Finalise.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "StgFEM/SLE/ProvidedSystems/ProvidedSystems.h"
-#include "Finalise.h"
-
-#include <stdio.h>
-
-Bool StgFEM_SLE_Finalise( void ) {
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- //StgFEM_SLE_LinearAlgebra_Finalise();
- StgFEM_SLE_SystemSetup_Finalise();
- StgFEM_SLE_ProvidedSystems_Finalise();
-
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/src/Finalise.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/src/Finalise.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,62 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "StgFEM/SLE/ProvidedSystems/ProvidedSystems.h"
+#include "Finalise.h"
+
+#include <stdio.h>
+
+Bool StgFEM_SLE_Finalise( void ) {
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ //StgFEM_SLE_LinearAlgebra_Finalise();
+ StgFEM_SLE_SystemSetup_Finalise();
+ StgFEM_SLE_ProvidedSystems_Finalise();
+
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/src/Init.c
--- a/SLE/src/Init.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
-#include "StgFEM/SLE/ProvidedSystems/ProvidedSystems.h"
-
-#include "types.h"
-#include "Init.h"
-
-#include <stdio.h>
-
-/** Initialises the Linear Algebra package, then any init for this package
-such as streams etc */
-Bool StgFEM_SLE_Init( int* argc, char** argv[] ) {
- int tmp;
-
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
- tmp = Stream_GetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ) );
- Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), 0 );
- Journal_Printf( /* DO NOT CHANGE OR REMOVE */
- Journal_Register( InfoStream_Type, (Name)"Context" ),
- "StGermain SLE Library revision %s. Copyright (C) 2003-2005 VPAC.\n", VERSION );
- Stream_Flush( Journal_Register( InfoStream_Type, (Name)"Context" ) );
- Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), tmp );
-
- //StgFEM_SLE_LinearAlgebra_Init( argc, argv );
- StgFEM_SLE_SystemSetup_Init( argc, argv );
- StgFEM_SLE_ProvidedSystems_Init( argc, argv );
-
- return True;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SLE/src/Init.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SLE/src/Init.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,75 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SystemSetup/SystemSetup.h"
+#include "StgFEM/SLE/ProvidedSystems/ProvidedSystems.h"
+
+#include "types.h"
+#include "Init.h"
+
+#include <stdio.h>
+
+/** Initialises the Linear Algebra package, then any init for this package
+such as streams etc */
+Bool StgFEM_SLE_Init( int* argc, char** argv[] ) {
+ int tmp;
+
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+ tmp = Stream_GetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ) );
+ Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), 0 );
+ Journal_Printf( /* DO NOT CHANGE OR REMOVE */
+ Journal_Register( InfoStream_Type, (Name)"Context" ),
+ "StGermain SLE Library revision %s. Copyright (C) 2003-2005 VPAC.\n", VERSION );
+ Stream_Flush( Journal_Register( InfoStream_Type, (Name)"Context" ) );
+ Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), tmp );
+
+ //StgFEM_SLE_LinearAlgebra_Init( argc, argv );
+ StgFEM_SLE_SystemSetup_Init( argc, argv );
+ StgFEM_SLE_ProvidedSystems_Init( argc, argv );
+
+ return True;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SysTest/AnalyticPlugins/AdvDiffSteadyState1D/AdvDiffSteadyState1D.c
--- a/SysTest/AnalyticPlugins/AdvDiffSteadyState1D/AdvDiffSteadyState1D.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: AdvDiffSteadyState1D.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-/* This analytic solutions is just the advection of a diffusing temperature for one time step.
- * The advection is in the direction of one of the i,j,k axis
- * */
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-#include <string.h>
-
-const Type AdvDiffSteadyState1D_Type = "AdvDiffSteadyState1D";
-
-typedef struct {
- __FieldTest
- AdvDiffResidualForceTerm* residual;
- /* Velocity in this analyticSolution is constant */
- double velocity;
- Axis velocityDirection;
- double A;
- double B;
- double c;
- FeVariable* temperatureField;
-} AdvDiffSteadyState1D;
-
-void AdvDiffSteadyState1D_TemperatureFunction( void* analyticSolution, double* coord, double* temperature ) {
- AdvDiffSteadyState1D* self = (AdvDiffSteadyState1D*)analyticSolution;
- double exponent;
- double kappa = self->residual->defaultDiffusivity;
-
- exponent = self->velocity / kappa * ( coord[ self->velocityDirection ] - self->c );
- *temperature = self->A * exp( exponent ) + self->B;
-}
-
-void AdvDiffSteadyState1D_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* temperature ){
- DomainContext* context = (DomainContext*)_context;
- AdvDiffSteadyState1D* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)AdvDiffSteadyState1D_Type, AdvDiffSteadyState1D, True, 0 /* dummy */ );
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* coord;
-
- feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- AdvDiffSteadyState1D_TemperatureFunction( self, coord, (double*)temperature );
-}
-
-
-void _AdvDiffSteadyState1D_Build( void* analyticSolution, void* data ) {
- AdvDiffSteadyState1D* self = (AdvDiffSteadyState1D*)analyticSolution;
- FeVariable* velocityField = Stg_CheckType( self->residual->velocityField, FeVariable );
- CompositeVC* velocityICs = Stg_CheckType( velocityField->ics, CompositeVC );
- Stream* errorStream = Journal_MyStream( Error_Type, self );
- AllNodesVC* allNodesVC;
- AllNodesVC_Entry* vcEntry;
-
- _FieldTest_Build( self, data );
-
- /* here we assign the memory and the func ptr for analytic sols */
- self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 1 );
- /* this order MUST be consistent with the xml file definition */
- self->_analyticSolutionList[0] = AdvDiffSteadyState1D_TemperatureFunction;
-
- /* Get AllNodes Variable Condition */
- Stg_Component_Build( velocityICs, data, False );
- Journal_Firewall( velocityICs->itemCount == 1, errorStream,
- "Velocity Field needs to have one and only one Boundary Condition.\n"
- "Currently it has %d types of VariableConditions.\n", velocityICs->itemCount );
- allNodesVC = Stg_CheckType( velocityICs->itemTbl[ 0 ], AllNodesVC );
-
- /* Get Variable Condition entry */
- Journal_Firewall( allNodesVC->_entryCount == 1, errorStream,
- "Velocity Field has more than one Boundary Condition.\n"
- "Currently it has %d VariableCondition entries.\n", allNodesVC->_entryCount );
- vcEntry = &allNodesVC->_entryTbl[0];
-
- /* Get Velocity Direction from Variable Condition */
- if ( strcmp( vcEntry->varName, "vx" ) == 0 ) {
- self->velocityDirection = I_AXIS;
- }
- else if ( strcmp( vcEntry->varName, "vy" ) == 0 ) {
- self->velocityDirection = J_AXIS;
- }
- else if ( strcmp( vcEntry->varName, "vz" ) == 0 ) {
- self->velocityDirection = K_AXIS;
- }
- else {
- Journal_Firewall( False, errorStream, "Cannot recognise Boundary Condition: %s.\n", vcEntry->varName );
- }
-}
-
-void _AdvDiffSteadyState1D_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- AdvDiffSteadyState1D* self = (AdvDiffSteadyState1D*)analyticSolution;
- ConditionFunction* condFunc;
-
- _FieldTest_AssignFromXML( self, cf, data );
-
- self->residual = Stg_ComponentFactory_ConstructByName( cf, (Name)"defaultResidualForceTerm", AdvDiffResidualForceTerm, True, data );
-
- self->velocity = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"velocity", 1.0 );
- self->A = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"A", 1.0 );
- self->B = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"B", 0.0 );
- self->c = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"c", 0.0 );
-
- condFunc = ConditionFunction_New( AdvDiffSteadyState1D_TemperatureBC, (Name)"AnalyticSolutionFunction" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
-}
-
-void* _AdvDiffSteadyState1D_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(AdvDiffSteadyState1D);
- Type type = AdvDiffSteadyState1D_Type;
- Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
- Stg_Class_PrintFunction* _print = _FieldTest_Print;
- Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _AdvDiffSteadyState1D_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _AdvDiffSteadyState1D_AssignFromXML;
- Stg_Component_BuildFunction* _build = _AdvDiffSteadyState1D_Build;
- Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
- Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_AdvDiffSteadyState1D_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, AdvDiffSteadyState1D_Type, (Name)"0", _AdvDiffSteadyState1D_DefaultNew );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SysTest/AnalyticPlugins/AdvDiffSteadyState1D/AdvDiffSteadyState1D.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SysTest/AnalyticPlugins/AdvDiffSteadyState1D/AdvDiffSteadyState1D.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,177 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: AdvDiffSteadyState1D.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+/* This analytic solutions is just the advection of a diffusing temperature for one time step.
+ * The advection is in the direction of one of the i,j,k axis
+ * */
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+#include <string.h>
+
+const Type AdvDiffSteadyState1D_Type = "AdvDiffSteadyState1D";
+
+typedef struct {
+ __FieldTest
+ AdvDiffResidualForceTerm* residual;
+ /* Velocity in this analyticSolution is constant */
+ double velocity;
+ Axis velocityDirection;
+ double A;
+ double B;
+ double c;
+ FeVariable* temperatureField;
+} AdvDiffSteadyState1D;
+
+void AdvDiffSteadyState1D_TemperatureFunction( void* analyticSolution, double* coord, double* temperature ) {
+ AdvDiffSteadyState1D* self = (AdvDiffSteadyState1D*)analyticSolution;
+ double exponent;
+ double kappa = self->residual->defaultDiffusivity;
+
+ exponent = self->velocity / kappa * ( coord[ self->velocityDirection ] - self->c );
+ *temperature = self->A * exp( exponent ) + self->B;
+}
+
+void AdvDiffSteadyState1D_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* temperature ){
+ DomainContext* context = (DomainContext*)_context;
+ AdvDiffSteadyState1D* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)AdvDiffSteadyState1D_Type, AdvDiffSteadyState1D, True, 0 /* dummy */ );
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* coord;
+
+ feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ AdvDiffSteadyState1D_TemperatureFunction( self, coord, (double*)temperature );
+}
+
+
+void _AdvDiffSteadyState1D_Build( void* analyticSolution, void* data ) {
+ AdvDiffSteadyState1D* self = (AdvDiffSteadyState1D*)analyticSolution;
+ FeVariable* velocityField = Stg_CheckType( self->residual->velocityField, FeVariable );
+ CompositeVC* velocityICs = Stg_CheckType( velocityField->ics, CompositeVC );
+ Stream* errorStream = Journal_MyStream( Error_Type, self );
+ AllNodesVC* allNodesVC;
+ AllNodesVC_Entry* vcEntry;
+
+ _FieldTest_Build( self, data );
+
+ /* here we assign the memory and the func ptr for analytic sols */
+ self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 1 );
+ /* this order MUST be consistent with the xml file definition */
+ self->_analyticSolutionList[0] = AdvDiffSteadyState1D_TemperatureFunction;
+
+ /* Get AllNodes Variable Condition */
+ Stg_Component_Build( velocityICs, data, False );
+ Journal_Firewall( velocityICs->itemCount == 1, errorStream,
+ "Velocity Field needs to have one and only one Boundary Condition.\n"
+ "Currently it has %d types of VariableConditions.\n", velocityICs->itemCount );
+ allNodesVC = Stg_CheckType( velocityICs->itemTbl[ 0 ], AllNodesVC );
+
+ /* Get Variable Condition entry */
+ Journal_Firewall( allNodesVC->_entryCount == 1, errorStream,
+ "Velocity Field has more than one Boundary Condition.\n"
+ "Currently it has %d VariableCondition entries.\n", allNodesVC->_entryCount );
+ vcEntry = &allNodesVC->_entryTbl[0];
+
+ /* Get Velocity Direction from Variable Condition */
+ if ( strcmp( vcEntry->varName, "vx" ) == 0 ) {
+ self->velocityDirection = I_AXIS;
+ }
+ else if ( strcmp( vcEntry->varName, "vy" ) == 0 ) {
+ self->velocityDirection = J_AXIS;
+ }
+ else if ( strcmp( vcEntry->varName, "vz" ) == 0 ) {
+ self->velocityDirection = K_AXIS;
+ }
+ else {
+ Journal_Firewall( False, errorStream, "Cannot recognise Boundary Condition: %s.\n", vcEntry->varName );
+ }
+}
+
+void _AdvDiffSteadyState1D_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ AdvDiffSteadyState1D* self = (AdvDiffSteadyState1D*)analyticSolution;
+ ConditionFunction* condFunc;
+
+ _FieldTest_AssignFromXML( self, cf, data );
+
+ self->residual = Stg_ComponentFactory_ConstructByName( cf, (Name)"defaultResidualForceTerm", AdvDiffResidualForceTerm, True, data );
+
+ self->velocity = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"velocity", 1.0 );
+ self->A = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"A", 1.0 );
+ self->B = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"B", 0.0 );
+ self->c = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"c", 0.0 );
+
+ condFunc = ConditionFunction_New( AdvDiffSteadyState1D_TemperatureBC, (Name)"AnalyticSolutionFunction" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+}
+
+void* _AdvDiffSteadyState1D_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(AdvDiffSteadyState1D);
+ Type type = AdvDiffSteadyState1D_Type;
+ Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
+ Stg_Class_PrintFunction* _print = _FieldTest_Print;
+ Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _AdvDiffSteadyState1D_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _AdvDiffSteadyState1D_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _AdvDiffSteadyState1D_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_AdvDiffSteadyState1D_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, AdvDiffSteadyState1D_Type, (Name)"0", _AdvDiffSteadyState1D_DefaultNew );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SysTest/AnalyticPlugins/CosineHillRotate/CosineHillRotate.c
--- a/SysTest/AnalyticPlugins/CosineHillRotate/CosineHillRotate.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: CosineHillRotate.c 968 2007-10-23 07:53:39Z JulianGiordani $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-const Type CosineHillRotate_Type = "CosineHillRotate";
-
-typedef struct {
- __FieldTest
- FeVariable* temperatureField;
- double hillHeight;
- double hillDiameter;
- Coord rotationCentre;
-} CosineHillRotate;
-
-void CosineHillRotate_TemperatureFunction( void* analyticSolution, double* coord, double* temperature ) {
- CosineHillRotate *self = (CosineHillRotate*)analyticSolution;
- double distanceFromCentre = StGermain_DistanceBetweenPoints( self->rotationCentre, coord, 2 );
-
- if (distanceFromCentre < self->hillDiameter )
- *temperature = self->hillHeight * (0.5 + 0.5 * cos( 2.0 * M_PI/self->hillDiameter * distanceFromCentre + M_PI ) );
- else
- *temperature = 0.0;
-}
-
-void CosineHillRotate_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- CosineHillRotate* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)CosineHillRotate_Type, CosineHillRotate, True, 0 );
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
-
- feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- CosineHillRotate_TemperatureFunction( self, coord, result );
-}
-
-void _CosineHillRotate_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- CosineHillRotate* self = (CosineHillRotate*)analyticSolution;
- ConditionFunction* condFunc;
-
- _FieldTest_AssignFromXML( self, cf, data );
-
- /* Read values from dictionary */
- self->hillHeight = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"CosineHillHeight" , 1.0 );
- self->hillDiameter = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"CosineHillDiameter", 1.0 );
- self->rotationCentre[ I_AXIS ] = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SolidBodyRotationCentreX" , 0.0 );
- self->rotationCentre[ J_AXIS ] = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SolidBodyRotationCentreY" , 0.0 );
- self->rotationCentre[ K_AXIS ] = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SolidBodyRotationCentreZ" , 0.0 );
-
- /* Create Condition Functions */
- condFunc = ConditionFunction_New( CosineHillRotate_TemperatureBC, (Name)"Temperature_CosineHill" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-}
-
-void _CosineHillRotate_Build( void* analyticSolution, void* data ) {
- CosineHillRotate* self = (CosineHillRotate*)analyticSolution;
-
- _FieldTest_Build( self, data );
-
- /* here we assign the memory and the func ptr for analytic sols */
- self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 1 );
- /* this order MUST be consistent with the xml file definition */
- self->_analyticSolutionList[0] = CosineHillRotate_TemperatureFunction;
-}
-
-void* _CosineHillRotate_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(CosineHillRotate);
- Type type = CosineHillRotate_Type;
- Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
- Stg_Class_PrintFunction* _print = _FieldTest_Print;
- Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _CosineHillRotate_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _CosineHillRotate_AssignFromXML;
- Stg_Component_BuildFunction* _build = _CosineHillRotate_Build;
- Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
- Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_CosineHillRotate_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, CosineHillRotate_Type, (Name)"0", _CosineHillRotate_DefaultNew );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SysTest/AnalyticPlugins/CosineHillRotate/CosineHillRotate.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SysTest/AnalyticPlugins/CosineHillRotate/CosineHillRotate.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,137 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: CosineHillRotate.c 968 2007-10-23 07:53:39Z JulianGiordani $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+const Type CosineHillRotate_Type = "CosineHillRotate";
+
+typedef struct {
+ __FieldTest
+ FeVariable* temperatureField;
+ double hillHeight;
+ double hillDiameter;
+ Coord rotationCentre;
+} CosineHillRotate;
+
+void CosineHillRotate_TemperatureFunction( void* analyticSolution, double* coord, double* temperature ) {
+ CosineHillRotate *self = (CosineHillRotate*)analyticSolution;
+ double distanceFromCentre = StGermain_DistanceBetweenPoints( self->rotationCentre, coord, 2 );
+
+ if (distanceFromCentre < self->hillDiameter )
+ *temperature = self->hillHeight * (0.5 + 0.5 * cos( 2.0 * M_PI/self->hillDiameter * distanceFromCentre + M_PI ) );
+ else
+ *temperature = 0.0;
+}
+
+void CosineHillRotate_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ CosineHillRotate* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)CosineHillRotate_Type, CosineHillRotate, True, 0 );
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+
+ feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ CosineHillRotate_TemperatureFunction( self, coord, result );
+}
+
+void _CosineHillRotate_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ CosineHillRotate* self = (CosineHillRotate*)analyticSolution;
+ ConditionFunction* condFunc;
+
+ _FieldTest_AssignFromXML( self, cf, data );
+
+ /* Read values from dictionary */
+ self->hillHeight = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"CosineHillHeight" , 1.0 );
+ self->hillDiameter = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"CosineHillDiameter", 1.0 );
+ self->rotationCentre[ I_AXIS ] = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SolidBodyRotationCentreX" , 0.0 );
+ self->rotationCentre[ J_AXIS ] = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SolidBodyRotationCentreY" , 0.0 );
+ self->rotationCentre[ K_AXIS ] = Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"SolidBodyRotationCentreZ" , 0.0 );
+
+ /* Create Condition Functions */
+ condFunc = ConditionFunction_New( CosineHillRotate_TemperatureBC, (Name)"Temperature_CosineHill" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+}
+
+void _CosineHillRotate_Build( void* analyticSolution, void* data ) {
+ CosineHillRotate* self = (CosineHillRotate*)analyticSolution;
+
+ _FieldTest_Build( self, data );
+
+ /* here we assign the memory and the func ptr for analytic sols */
+ self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 1 );
+ /* this order MUST be consistent with the xml file definition */
+ self->_analyticSolutionList[0] = CosineHillRotate_TemperatureFunction;
+}
+
+void* _CosineHillRotate_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(CosineHillRotate);
+ Type type = CosineHillRotate_Type;
+ Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
+ Stg_Class_PrintFunction* _print = _FieldTest_Print;
+ Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _CosineHillRotate_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _CosineHillRotate_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _CosineHillRotate_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_CosineHillRotate_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, CosineHillRotate_Type, (Name)"0", _CosineHillRotate_DefaultNew );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SysTest/AnalyticPlugins/HomogeneousNaturalBCs/HomogeneousNaturalBCs.c
--- a/SysTest/AnalyticPlugins/HomogeneousNaturalBCs/HomogeneousNaturalBCs.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: HomogeneousNaturalBCs.c 967 2007-10-23 05:27:09Z JulianGiordani $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-const Type HomogeneousNaturalBCs_Type = "HomogeneousNaturalBCs";
-
-typedef struct {
- __FieldTest
- double angle;
- FeVariable* temperatureField;
-} HomogeneousNaturalBCs;
-
-
-void HomogeneousNaturalBCs_Velocity_SkewToMesh( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- HomogeneousNaturalBCs* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)HomogeneousNaturalBCs_Type, HomogeneousNaturalBCs, True, 0 );
- double* result = (double*) _result;
-
- result[ I_AXIS ] = cos( self->angle );
- result[ J_AXIS ] = sin( self->angle );
-}
-
-
-void HomogeneousNaturalBCs_TemperatureFunction( void* analyticSolution, double* coord, double* temperature ) {
- HomogeneousNaturalBCs *self = (HomogeneousNaturalBCs*)analyticSolution;
-
- if ( coord[ J_AXIS ] < tan( self->angle ) * coord[ I_AXIS ] + 0.25 )
- *temperature = 1.0;
- else
- *temperature = 0.0;
-}
-
-void HomogeneousNaturalBCs_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- HomogeneousNaturalBCs* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)HomogeneousNaturalBCs_Type, HomogeneousNaturalBCs, True, 0 );
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
-
- feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- HomogeneousNaturalBCs_TemperatureFunction( self, coord, result );
-}
-
-void _HomogeneousNaturalBCs_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- HomogeneousNaturalBCs* self = (HomogeneousNaturalBCs*)analyticSolution;
- ConditionFunction* condFunc;
-
- _FieldTest_AssignFromXML( self, cf, data );
-
- self->angle = StGermain_DegreeToRadian (Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"VelocitySkewAngle", 45.0 ) );
-
- /* Create Condition Functions */
-/*
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
-*/
- condFunc = ConditionFunction_New( HomogeneousNaturalBCs_Velocity_SkewToMesh, (Name)"Velocity_SkewToMesh" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New( HomogeneousNaturalBCs_TemperatureBC, (Name)"Temperature_StepFunction" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-}
-
-void _HomogeneousNaturalBCs_Build( void* analyticSolution, void* data ) {
- HomogeneousNaturalBCs* self = (HomogeneousNaturalBCs*)analyticSolution;
-
- _FieldTest_Build( self, data );
-
- /* here we assign the memory and the func ptr for analytic sols */
- self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 1 );
- /* this order MUST be consistent with the xml file definition */
- self->_analyticSolutionList[0] = HomogeneousNaturalBCs_TemperatureFunction;
-}
-
-void* _HomogeneousNaturalBCs_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(HomogeneousNaturalBCs);
- Type type = HomogeneousNaturalBCs_Type;
- Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
- Stg_Class_PrintFunction* _print = _FieldTest_Print;
- Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _HomogeneousNaturalBCs_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _HomogeneousNaturalBCs_AssignFromXML;
- Stg_Component_BuildFunction* _build = _HomogeneousNaturalBCs_Build;
- Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
- Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_HomogeneousNaturalBCs_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, HomogeneousNaturalBCs_Type, (Name)"0", _HomogeneousNaturalBCs_DefaultNew );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SysTest/AnalyticPlugins/HomogeneousNaturalBCs/HomogeneousNaturalBCs.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SysTest/AnalyticPlugins/HomogeneousNaturalBCs/HomogeneousNaturalBCs.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,145 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: HomogeneousNaturalBCs.c 967 2007-10-23 05:27:09Z JulianGiordani $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+const Type HomogeneousNaturalBCs_Type = "HomogeneousNaturalBCs";
+
+typedef struct {
+ __FieldTest
+ double angle;
+ FeVariable* temperatureField;
+} HomogeneousNaturalBCs;
+
+
+void HomogeneousNaturalBCs_Velocity_SkewToMesh( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ HomogeneousNaturalBCs* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)HomogeneousNaturalBCs_Type, HomogeneousNaturalBCs, True, 0 );
+ double* result = (double*) _result;
+
+ result[ I_AXIS ] = cos( self->angle );
+ result[ J_AXIS ] = sin( self->angle );
+}
+
+
+void HomogeneousNaturalBCs_TemperatureFunction( void* analyticSolution, double* coord, double* temperature ) {
+ HomogeneousNaturalBCs *self = (HomogeneousNaturalBCs*)analyticSolution;
+
+ if ( coord[ J_AXIS ] < tan( self->angle ) * coord[ I_AXIS ] + 0.25 )
+ *temperature = 1.0;
+ else
+ *temperature = 0.0;
+}
+
+void HomogeneousNaturalBCs_TemperatureBC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ HomogeneousNaturalBCs* self = Stg_ComponentFactory_ConstructByName( context->CF, (Name)HomogeneousNaturalBCs_Type, HomogeneousNaturalBCs, True, 0 );
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+
+ feVariable = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ HomogeneousNaturalBCs_TemperatureFunction( self, coord, result );
+}
+
+void _HomogeneousNaturalBCs_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ HomogeneousNaturalBCs* self = (HomogeneousNaturalBCs*)analyticSolution;
+ ConditionFunction* condFunc;
+
+ _FieldTest_AssignFromXML( self, cf, data );
+
+ self->angle = StGermain_DegreeToRadian (Stg_ComponentFactory_GetRootDictDouble( cf, (Dictionary_Entry_Key)"VelocitySkewAngle", 45.0 ) );
+
+ /* Create Condition Functions */
+/*
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+*/
+ condFunc = ConditionFunction_New( HomogeneousNaturalBCs_Velocity_SkewToMesh, (Name)"Velocity_SkewToMesh" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New( HomogeneousNaturalBCs_TemperatureBC, (Name)"Temperature_StepFunction" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+}
+
+void _HomogeneousNaturalBCs_Build( void* analyticSolution, void* data ) {
+ HomogeneousNaturalBCs* self = (HomogeneousNaturalBCs*)analyticSolution;
+
+ _FieldTest_Build( self, data );
+
+ /* here we assign the memory and the func ptr for analytic sols */
+ self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 1 );
+ /* this order MUST be consistent with the xml file definition */
+ self->_analyticSolutionList[0] = HomogeneousNaturalBCs_TemperatureFunction;
+}
+
+void* _HomogeneousNaturalBCs_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(HomogeneousNaturalBCs);
+ Type type = HomogeneousNaturalBCs_Type;
+ Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
+ Stg_Class_PrintFunction* _print = _FieldTest_Print;
+ Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _HomogeneousNaturalBCs_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _HomogeneousNaturalBCs_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _HomogeneousNaturalBCs_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_HomogeneousNaturalBCs_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, HomogeneousNaturalBCs_Type, (Name)"0", _HomogeneousNaturalBCs_DefaultNew );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SysTest/AnalyticPlugins/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.c
--- a/SysTest/AnalyticPlugins/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: LidDrivenIsoviscousAnalytic.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-/* This is taken from Mirko Velic's Analytic Stokes Flow solution */
-
-const Type LidDrivenIsoviscousAnalytic_Type = "LidDrivenIsoviscousAnalytic";
-
-typedef struct {
- __FieldTest
- unsigned int wavenumber;
- double A, B, C, D;
- FeVariable* velocityField;
- FeVariable* pressureField;
-} LidDrivenIsoviscousAnalytic;
-
-
-void LidDrivenIsoviscousAnalytic_CalculateConstants( LidDrivenIsoviscousAnalytic *self ) {
- double E;
- double e_nPI;
- double e_2nPI;
- double e_4nPI;
- double n;
-
- n = (double) self->wavenumber;
-
- e_nPI = exp( n * M_PI );
- e_2nPI = e_nPI * e_nPI;
- e_4nPI = e_2nPI * e_2nPI;
-
- E = (4.0 * n * n * M_PI * M_PI + 2.0 ) * e_2nPI - e_4nPI - 1.0;
-
- self->A = ( e_2nPI - 1.0 )* e_nPI / E;
- self->B = - self->A;
-
- self->C = ( 2.0 * n * M_PI - e_2nPI + 1.0 ) * e_nPI / E;
- self->D = - ( 2.0 * n * M_PI * e_2nPI - e_2nPI + 1.0 ) * e_nPI / E;
-}
-
-void LidDrivenIsoviscousAnalytic_VelocityFunction( void* analyticSolution, double* coord, double* velocity ) {
- LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)analyticSolution;
- double x,y;
- double n;
- double A, B, C, D;
-
- /* Get local copy of constants */
- n = (double) self->wavenumber;
- A = self->A;
- B = self->B;
- C = self->C;
- D = self->D;
-
- /* get copy of coords */
- x = coord[I_AXIS];
- y = coord[J_AXIS];
-
- velocity[ I_AXIS ] = sin( n * M_PI * x ) *
- ( ( A * n * M_PI + C + C * n * M_PI * y) *exp( n * M_PI * y )
- - ( B * n * M_PI - D + D * n * M_PI * y ) * exp( - n * M_PI * y ) );
- velocity[ J_AXIS ] = - n * M_PI * cos( n * M_PI * x ) *
- ( ( A + C * y ) * exp( n * M_PI * y )
- + ( B + D * y ) * exp( - n * M_PI * y ) );
-}
-
-
-void LidDrivenIsoviscousAnalytic_PressureFunction( void* analyticSolution, double* coord, double* pressure ) {
- LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)analyticSolution;
- double x,y;
- double n;
- double A, B, C, D;
-
- /* Get local copy of constants */
- n = (double) self->wavenumber;
- A = self->A;
- B = self->B;
- C = self->C;
- D = self->D;
-
- /* get copy of coords */
- x = coord[I_AXIS];
- y = coord[J_AXIS];
-
- *pressure = - 2.0 * n * M_PI * cos( n * M_PI * x ) * ( C * exp( n * M_PI * y ) + D * exp( - n * M_PI * y ) );
-}
-
-void _LidDrivenIsoviscousAnalytic_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)analyticSolution;
-
- _FieldTest_AssignFromXML( self, cf, data );
-
- /* Set constants */
- self->wavenumber = Stg_ComponentFactory_GetRootDictUnsignedInt( cf, (Dictionary_Entry_Key)"sinusoidalLidWavenumber", 1 );
- LidDrivenIsoviscousAnalytic_CalculateConstants( self );
-}
-
-void _LidDrivenIsoviscousAnalytic_Build( void* analyticSolution, void* data ) {
- LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)analyticSolution;
-
- _FieldTest_Build( self, data );
-
- /* here we assign the memory and the func ptr for analytic sols */
- self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 2 );
- /* this order MUST be consistent with the xml file definition */
- self->_analyticSolutionList[0] = LidDrivenIsoviscousAnalytic_VelocityFunction;
- self->_analyticSolutionList[1] = LidDrivenIsoviscousAnalytic_PressureFunction;
-}
-
-void* _LidDrivenIsoviscousAnalytic_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(LidDrivenIsoviscousAnalytic);
- Type type = LidDrivenIsoviscousAnalytic_Type;
- Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
- Stg_Class_PrintFunction* _print = _FieldTest_Print;
- Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LidDrivenIsoviscousAnalytic_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _LidDrivenIsoviscousAnalytic_AssignFromXML;
- Stg_Component_BuildFunction* _build = _LidDrivenIsoviscousAnalytic_Build;
- Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
- Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_LidDrivenIsoviscousAnalytic_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, LidDrivenIsoviscousAnalytic_Type, (Name)"0", _LidDrivenIsoviscousAnalytic_DefaultNew );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SysTest/AnalyticPlugins/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SysTest/AnalyticPlugins/LidDrivenIsoviscousAnalytic/LidDrivenIsoviscousAnalytic.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,175 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: LidDrivenIsoviscousAnalytic.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+/* This is taken from Mirko Velic's Analytic Stokes Flow solution */
+
+const Type LidDrivenIsoviscousAnalytic_Type = "LidDrivenIsoviscousAnalytic";
+
+typedef struct {
+ __FieldTest
+ unsigned int wavenumber;
+ double A, B, C, D;
+ FeVariable* velocityField;
+ FeVariable* pressureField;
+} LidDrivenIsoviscousAnalytic;
+
+
+void LidDrivenIsoviscousAnalytic_CalculateConstants( LidDrivenIsoviscousAnalytic *self ) {
+ double E;
+ double e_nPI;
+ double e_2nPI;
+ double e_4nPI;
+ double n;
+
+ n = (double) self->wavenumber;
+
+ e_nPI = exp( n * M_PI );
+ e_2nPI = e_nPI * e_nPI;
+ e_4nPI = e_2nPI * e_2nPI;
+
+ E = (4.0 * n * n * M_PI * M_PI + 2.0 ) * e_2nPI - e_4nPI - 1.0;
+
+ self->A = ( e_2nPI - 1.0 )* e_nPI / E;
+ self->B = - self->A;
+
+ self->C = ( 2.0 * n * M_PI - e_2nPI + 1.0 ) * e_nPI / E;
+ self->D = - ( 2.0 * n * M_PI * e_2nPI - e_2nPI + 1.0 ) * e_nPI / E;
+}
+
+void LidDrivenIsoviscousAnalytic_VelocityFunction( void* analyticSolution, double* coord, double* velocity ) {
+ LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)analyticSolution;
+ double x,y;
+ double n;
+ double A, B, C, D;
+
+ /* Get local copy of constants */
+ n = (double) self->wavenumber;
+ A = self->A;
+ B = self->B;
+ C = self->C;
+ D = self->D;
+
+ /* get copy of coords */
+ x = coord[I_AXIS];
+ y = coord[J_AXIS];
+
+ velocity[ I_AXIS ] = sin( n * M_PI * x ) *
+ ( ( A * n * M_PI + C + C * n * M_PI * y) *exp( n * M_PI * y )
+ - ( B * n * M_PI - D + D * n * M_PI * y ) * exp( - n * M_PI * y ) );
+ velocity[ J_AXIS ] = - n * M_PI * cos( n * M_PI * x ) *
+ ( ( A + C * y ) * exp( n * M_PI * y )
+ + ( B + D * y ) * exp( - n * M_PI * y ) );
+}
+
+
+void LidDrivenIsoviscousAnalytic_PressureFunction( void* analyticSolution, double* coord, double* pressure ) {
+ LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)analyticSolution;
+ double x,y;
+ double n;
+ double A, B, C, D;
+
+ /* Get local copy of constants */
+ n = (double) self->wavenumber;
+ A = self->A;
+ B = self->B;
+ C = self->C;
+ D = self->D;
+
+ /* get copy of coords */
+ x = coord[I_AXIS];
+ y = coord[J_AXIS];
+
+ *pressure = - 2.0 * n * M_PI * cos( n * M_PI * x ) * ( C * exp( n * M_PI * y ) + D * exp( - n * M_PI * y ) );
+}
+
+void _LidDrivenIsoviscousAnalytic_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)analyticSolution;
+
+ _FieldTest_AssignFromXML( self, cf, data );
+
+ /* Set constants */
+ self->wavenumber = Stg_ComponentFactory_GetRootDictUnsignedInt( cf, (Dictionary_Entry_Key)"sinusoidalLidWavenumber", 1 );
+ LidDrivenIsoviscousAnalytic_CalculateConstants( self );
+}
+
+void _LidDrivenIsoviscousAnalytic_Build( void* analyticSolution, void* data ) {
+ LidDrivenIsoviscousAnalytic *self = (LidDrivenIsoviscousAnalytic*)analyticSolution;
+
+ _FieldTest_Build( self, data );
+
+ /* here we assign the memory and the func ptr for analytic sols */
+ self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 2 );
+ /* this order MUST be consistent with the xml file definition */
+ self->_analyticSolutionList[0] = LidDrivenIsoviscousAnalytic_VelocityFunction;
+ self->_analyticSolutionList[1] = LidDrivenIsoviscousAnalytic_PressureFunction;
+}
+
+void* _LidDrivenIsoviscousAnalytic_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(LidDrivenIsoviscousAnalytic);
+ Type type = LidDrivenIsoviscousAnalytic_Type;
+ Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
+ Stg_Class_PrintFunction* _print = _FieldTest_Print;
+ Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LidDrivenIsoviscousAnalytic_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _LidDrivenIsoviscousAnalytic_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _LidDrivenIsoviscousAnalytic_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_LidDrivenIsoviscousAnalytic_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, LidDrivenIsoviscousAnalytic_Type, (Name)"0", _LidDrivenIsoviscousAnalytic_DefaultNew );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SysTest/AnalyticPlugins/LinearTemperatureField/LinearTemperatureField.c
--- a/SysTest/AnalyticPlugins/LinearTemperatureField/LinearTemperatureField.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: LinearTemperatureField.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-/** Pretty simple.
- * One time step with the diffusion coefficiants K = 1
- * TempBCs Bottom BC = 1, top BC = 0, sides = 0
- */
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-const Type LinearTemperatureField_Type = "LinearTemperatureField";
-
-typedef struct { __FieldTest FeVariable* temperatureField; } LinearTemperatureField;
-
-void LinearTemperatureField_TemperatureFunction( void* analyticSolution, double* coord, double* value ) {
- *value = 1.0 - coord[ J_AXIS ];
-}
-
-
-void _LinearTemperatureField_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- LinearTemperatureField *self = (LinearTemperatureField*)analyticSolution;
-
- _FieldTest_AssignFromXML( self, cf, data );
-
- self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"TemperatureField", FeVariable, True, data );
-}
-
-void _LinearTemperatureField_Build( void* analyticSolution, void* data ) {
- LinearTemperatureField *self = (LinearTemperatureField*)analyticSolution;
-
- _FieldTest_Build( self, data );
-
- /* here we assign the memory and the func ptr for analytic sols */
- self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 1 );
- /* this order MUST be consistent with the xml file definition */
- self->_analyticSolutionList[0] = LinearTemperatureField_TemperatureFunction;
-}
-
-void* _LinearTemperatureField_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(LinearTemperatureField);
- Type type = LinearTemperatureField_Type;
- Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
- Stg_Class_PrintFunction* _print = _FieldTest_Print;
- Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LinearTemperatureField_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _LinearTemperatureField_AssignFromXML;
- Stg_Component_BuildFunction* _build = _LinearTemperatureField_Build;
- Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
- Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_LinearTemperatureField_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, LinearTemperatureField_Type, (Name)"0", _LinearTemperatureField_DefaultNew );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SysTest/AnalyticPlugins/LinearTemperatureField/LinearTemperatureField.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SysTest/AnalyticPlugins/LinearTemperatureField/LinearTemperatureField.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,104 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: LinearTemperatureField.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+/** Pretty simple.
+ * One time step with the diffusion coefficiants K = 1
+ * TempBCs Bottom BC = 1, top BC = 0, sides = 0
+ */
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+const Type LinearTemperatureField_Type = "LinearTemperatureField";
+
+typedef struct { __FieldTest FeVariable* temperatureField; } LinearTemperatureField;
+
+void LinearTemperatureField_TemperatureFunction( void* analyticSolution, double* coord, double* value ) {
+ *value = 1.0 - coord[ J_AXIS ];
+}
+
+
+void _LinearTemperatureField_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ LinearTemperatureField *self = (LinearTemperatureField*)analyticSolution;
+
+ _FieldTest_AssignFromXML( self, cf, data );
+
+ self->temperatureField = Stg_ComponentFactory_ConstructByName( cf, (Name)"TemperatureField", FeVariable, True, data );
+}
+
+void _LinearTemperatureField_Build( void* analyticSolution, void* data ) {
+ LinearTemperatureField *self = (LinearTemperatureField*)analyticSolution;
+
+ _FieldTest_Build( self, data );
+
+ /* here we assign the memory and the func ptr for analytic sols */
+ self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 1 );
+ /* this order MUST be consistent with the xml file definition */
+ self->_analyticSolutionList[0] = LinearTemperatureField_TemperatureFunction;
+}
+
+void* _LinearTemperatureField_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(LinearTemperatureField);
+ Type type = LinearTemperatureField_Type;
+ Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
+ Stg_Class_PrintFunction* _print = _FieldTest_Print;
+ Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LinearTemperatureField_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _LinearTemperatureField_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _LinearTemperatureField_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FieldTest_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_LinearTemperatureField_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, LinearTemperatureField_Type, (Name)"0", _LinearTemperatureField_DefaultNew );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 SysTest/AnalyticPlugins/LinearVelocityAnalytic/LinearVelocityAnalytic.c
--- a/SysTest/AnalyticPlugins/LinearVelocityAnalytic/LinearVelocityAnalytic.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,379 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: LinearVelocityAnalytic.c 1111 2008-04-23 04:12:36Z RobertTurnbull $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-#include <string.h>
-
-const Type LinearVelocityAnalytic_Type = "LinearVelocityAnalytic";
-
-typedef struct {
- __FieldTest
- FeVariable* velocityField;
- double nodeVelocity[8][3];
- double nodeCoords[8][3];
- int cornerNodeCount;
-} LinearVelocityAnalytic;
-
-Index Grid_ProjectIJK( Grid* grid, Index i, Index j, Index k ) {
- IJK ijk = {0,0,0};
-
- ijk[0] = i;
- ijk[1] = j;
- ijk[2] = k;
-
- return Grid_Project( grid, ijk );
-}
-Index Grid_ProjectIJK_MinMax( Grid* grid, Bool iIsMax, Bool jIsMax, Bool kIsMax ) {
- IJK ijk = {0,0,0};
-
- if ( iIsMax )
- ijk[0] = grid->sizes[0] - 1;
- if ( jIsMax )
- ijk[1] = grid->sizes[1] - 1;
- if ( kIsMax )
- ijk[2] = grid->sizes[2] - 1;
-
- return Grid_Project( grid, ijk );
-}
-
-void LinearVelocityAnalytic_GetCornerNodeVelocities(void* analyticSolution) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
- Grid* vertGrid;
- Node_GlobalIndex nodeMapper[8];
- FeVariable* velocityField = self->velocityField;
- FeMesh* mesh = velocityField->feMesh;
- Dimension_Index dim = velocityField->dim;
- Node_Index globalNode_I;
- Node_Index ii;
-
- vertGrid = *(Grid**)ExtensionManager_Get( mesh->info, mesh, ExtensionManager_GetHandle( mesh->info, (Name)"vertexGrid" ) );
-
- /* Find global indicies of nodes */
- self->cornerNodeCount = 4;
- nodeMapper[0] = Grid_ProjectIJK_MinMax( vertGrid, False, False, False );
- nodeMapper[1] = Grid_ProjectIJK_MinMax( vertGrid, True, False, False );
- nodeMapper[2] = Grid_ProjectIJK_MinMax( vertGrid, False, True, False );
- nodeMapper[3] = Grid_ProjectIJK_MinMax( vertGrid, True, True, False );
- if ( dim == 3 ) {
- self->cornerNodeCount = 8;
- nodeMapper[4] = Grid_ProjectIJK_MinMax( vertGrid, False, False, True );
- nodeMapper[5] = Grid_ProjectIJK_MinMax( vertGrid, True, False, True );
- nodeMapper[6] = Grid_ProjectIJK_MinMax( vertGrid, False, True, True );
- nodeMapper[7] = Grid_ProjectIJK_MinMax( vertGrid, True, True, True );
- }
-
- /* Loop over corner nodes */
- for ( ii = 0 ; ii < self->cornerNodeCount ; ii++ ) {
- globalNode_I = nodeMapper[ ii ];
- FeVariable_GetValueAtNodeGlobal( velocityField, globalNode_I, self->nodeVelocity[ii] );
- FeVariable_GetCoordAtNodeGlobal( velocityField, globalNode_I, self->nodeCoords[ii] );
- }
-}
-
-void GetLocalCoords( LinearVelocityAnalytic* self, double* coord, double* xi ) {
- FeVariable* velocityField = self->velocityField;
- XYZ min;
- XYZ max;
- Dimension_Index dim = velocityField->dim;
- Dimension_Index dim_I;
-
- _FeVariable_GetMinAndMaxGlobalCoords( velocityField, min, max );
- for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
- xi[ dim_I ] = 2.0 * (coord[ dim_I ] - min[ dim_I ])/(max[dim_I] - min[dim_I]) - 1;
- }
-}
-
-/* Do a normal linear interpolation as if the box were a FEM element */
-void LinearVelocityAnalytic_VelocityFunction( void* analyticSolution, double* coord, double* velocity ) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
- FeVariable* velocityField = self->velocityField;
- FeMesh* mesh = velocityField->feMesh;
- Dimension_Index dim = velocityField->dim;
- Dimension_Index dim_I;
- XYZ xi;
- double Ni[8];
- Node_Index ii;
- ElementType* elementType;
-
- /* Transform the coordinate into a master coordinate system */
- GetLocalCoords( self, coord, xi );
-
- /* Get Shape Functions */
- elementType = FeMesh_GetElementType( mesh, 0 );
- ElementType_EvaluateShapeFunctionsAt( elementType, xi, Ni );
-
- /* Do interpolation */
- /* Loop over corner nodes */
- memset( velocity, 0, dim*sizeof(double) );
- for ( ii = 0 ; ii < self->cornerNodeCount ; ii++ ) {
- for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
- velocity[ dim_I ] += Ni[ ii ] * self->nodeVelocity[ii][ dim_I ];
- }
- }
-}
-void LinearVelocityAnalytic_PressureFunction( void* analyticSolution, double* coord, double* pressure ) {
- *pressure = 0.0;
-}
-
-void LinearVelocityAnalytic_VelocityGradientsFunction( void* analyticSolution, double* coord, double* velocityGradients ) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
- FeVariable* velocityField = self->velocityField;
- FeMesh* mesh = velocityField->feMesh;
- ElementType* elementType;
- XYZ xi;
- double jac[3][3];
- double cof[3][3]; /* cofactors */
- double detJac;
- Node_Index node_I;
- double** GNi;
- double** GNx;
- double* nodeCoord;
- double nodeValue;
- Dimension_Index dim = velocityField->dim;
- Dimension_Index i, j, dx, dxi;
- Dimension_Index dim_I;
-
- /* Transform the coordinate into a master coordinate system */
- GetLocalCoords( self, coord, xi );
-
- GNi = Memory_Alloc_2DArray( double, dim, self->cornerNodeCount, (Name)"GNi" );
- GNx = Memory_Alloc_2DArray( double, dim, self->cornerNodeCount, (Name)"GNx" );
-
- /* Get Shape Functions */
- elementType = FeMesh_GetElementType( mesh, 0 );
- elementType->_evaluateShapeFunctionLocalDerivsAt( elementType, xi, GNi );
-
- /* build the jacobian matrix */
- /*
- jac = \sum_i d/d\xi( N_i ) x_i \sum_i d/d\xi( N_i ) y_i
- \sum_i d/d\eta( N_i ) x_i \sum_i d/d\eta( N_i ) y_i
- */
- if( dim == 2 ) {
- jac[0][0] = jac[0][1] = jac[1][0] = jac[1][1] = 0.0;
- for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
- nodeCoord = self->nodeCoords[ node_I ];
- jac[0][0] = jac[0][0] + GNi[0][node_I] * nodeCoord[0];
- jac[0][1] = jac[0][1] + GNi[0][node_I] * nodeCoord[1];
-
- jac[1][0] = jac[1][0] + GNi[1][node_I] * nodeCoord[0];
- jac[1][1] = jac[1][1] + GNi[1][node_I] * nodeCoord[1];
- }
- }
-
- if( dim == 3 ) {
- jac[0][0] = jac[0][1] = jac[0][2] = 0.0;
- jac[1][0] = jac[1][1] = jac[1][2] = 0.0;
- jac[2][0] = jac[2][1] = jac[2][2] = 0.0;
- for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
- nodeCoord = self->nodeCoords[ node_I ];
- jac[0][0] = jac[0][0] + GNi[0][node_I] * nodeCoord[0];
- jac[0][1] = jac[0][1] + GNi[0][node_I] * nodeCoord[1];
- jac[0][2] = jac[0][2] + GNi[0][node_I] * nodeCoord[2];
-
- jac[1][0] = jac[1][0] + GNi[1][node_I] * nodeCoord[0];
- jac[1][1] = jac[1][1] + GNi[1][node_I] * nodeCoord[1];
- jac[1][2] = jac[1][2] + GNi[1][node_I] * nodeCoord[2];
-
- jac[2][0] = jac[2][0] + GNi[2][node_I] * nodeCoord[0];
- jac[2][1] = jac[2][1] + GNi[2][node_I] * nodeCoord[1];
- jac[2][2] = jac[2][2] + GNi[2][node_I] * nodeCoord[2];
- }
- }
-
- /* get determinant of the jacobian matrix */
- if( dim == 2 ) {
- detJac = jac[0][0]*jac[1][1] - jac[0][1]*jac[1][0];
- }
- if( dim == 3 ) {
- detJac = jac[0][0]*( jac[1][1]*jac[2][2] - jac[1][2]*jac[2][1] )
- - jac[0][1]*( jac[1][0]*jac[2][2] - jac[1][2]*jac[2][0] )
- + jac[0][2]*( jac[1][0]*jac[2][1] - jac[1][1]*jac[2][0] );
- }
-
- /* invert the jacobian matrix A^-1 = adj(A)/det(A) */
- if( dim == 2 ) {
- double tmp = jac[0][0];
- jac[0][0] = jac[1][1]/detJac;
- jac[1][1] = tmp/detJac;
- jac[0][1] = -jac[0][1]/detJac;
- jac[1][0] = -jac[1][0]/detJac;
- }
- if( dim == 3 ) {
- /*
- 00 01 02
- 10 11 12
- 20 21 22
- */
- cof[0][0] = jac[1][1]*jac[2][2] - jac[1][2]*jac[2][1];
- cof[1][0] = -(jac[1][0]*jac[2][2] - jac[1][2]*jac[2][0]);
- cof[2][0] = jac[1][0]*jac[2][1] - jac[1][1]*jac[2][0];
-
- cof[0][1] = -(jac[0][1]*jac[2][2] - jac[0][2]*jac[2][1]);
- cof[1][1] = jac[0][0]*jac[2][2] - jac[0][2]*jac[2][0];
- cof[2][1] = -(jac[0][0]*jac[2][1] - jac[0][1]*jac[2][0]);
-
- cof[0][2] = jac[0][1]*jac[1][2] - jac[0][2]*jac[1][1];
- cof[1][2] = -(jac[0][0]*jac[1][2] - jac[0][2]*jac[1][0]);
- cof[2][2] = jac[0][0]*jac[1][1] - jac[0][1]*jac[1][0];
-
- for( i=0; i<dim; i++ ) {
- for( j=0; j<dim; j++ ) {
- jac[i][j] = cof[i][j]/detJac;
- }
- }
-
-
- }
-
- /* get global derivs Ni_x, Ni_y and Ni_z if dim == 3 */
- for( dx=0; dx<dim; dx++ ) {
- for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
- double globalSF_DerivVal = 0.0;
- for(dxi=0; dxi<dim; dxi++) {
- globalSF_DerivVal = globalSF_DerivVal + GNi[dxi][node_I] * jac[dx][dxi];
- }
-
- GNx[dx][node_I] = globalSF_DerivVal;
- }
- }
-
- /* Initialise velocity gradients */
- memset( velocityGradients, 0, sizeof( double ) * dim * dim );
-
- for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
- /* Interpolate derivative from nodes */
- for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
- nodeValue = self->nodeVelocity[ node_I ][ dim_I ];
-
- velocityGradients[dim_I*dim + 0] += GNx[0][node_I] * nodeValue;
- velocityGradients[dim_I*dim + 1] += GNx[1][node_I] * nodeValue;
- if( dim == 3 )
- velocityGradients[dim_I*dim + 2] += GNx[2][node_I] * nodeValue;
- }
- }
- Memory_Free( GNi );
- Memory_Free( GNx );
-}
-
-void LinearVelocityAnalytic_StrainRateFunction( void* analyticSolution, double* coord, double* strainRate ) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
- Dimension_Index dim = self->velocityField->dim;
- TensorArray velocityGradients;
-
- /* Get Velocity Gradients */
- LinearVelocityAnalytic_VelocityGradientsFunction( self, coord, velocityGradients );
-
- /* Get Strain Rate */
- TensorArray_GetSymmetricPart( velocityGradients, dim, strainRate );
-}
-
-void LinearVelocityAnalytic_StrainRateInvFunction( void* analyticSolution, double* coord, double* strainRateInv ) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
- Dimension_Index dim = self->velocityField->dim;
- SymmetricTensor strainRate;
-
- /* Get Strain Rate */
- LinearVelocityAnalytic_StrainRateFunction( self, coord, strainRate );
-
- /* Get Invariant */
- *strainRateInv = SymmetricTensor_2ndInvariant( strainRate, dim );
-}
-
-void _LinearVelocityAnalytic_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
-
- _FieldTest_AssignFromXML( self, cf, data );
-
- self->velocityField = Stg_ComponentFactory_ConstructByName( cf, (Name)"VelocityField", FeVariable, True, data );
-}
-
-void _LinearVelocityAnalytic_Build( void* analyticSolution, void* data ) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
-
- _FieldTest_Build( self, data );
-
- /* here we assign the memory and the func ptr for analytic sols */
- self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 4 );
- /* this order MUST be consistent with the xml file definition */
- self->_analyticSolutionList[0] = LinearVelocityAnalytic_VelocityFunction;
- self->_analyticSolutionList[1] = LinearVelocityAnalytic_PressureFunction;
- self->_analyticSolutionList[2] = LinearVelocityAnalytic_StrainRateFunction;
- self->_analyticSolutionList[3] = LinearVelocityAnalytic_StrainRateInvFunction;
-}
-
-void _LinearVelocityAnalytic_Initialise( void* analyticSolution, void* data ) {
- LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
-
- Stg_Component_Initialise( self->velocityField, data, False );
- LinearVelocityAnalytic_GetCornerNodeVelocities( self );
-
- _FieldTest_Initialise( self, data );
-}
-
-void* _LinearVelocityAnalytic_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(LinearVelocityAnalytic);
- Type type = LinearVelocityAnalytic_Type;
- Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
- Stg_Class_PrintFunction* _print = _FieldTest_Print;
- Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LinearVelocityAnalytic_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _LinearVelocityAnalytic_AssignFromXML;
- Stg_Component_BuildFunction* _build = _LinearVelocityAnalytic_Build;
- Stg_Component_InitialiseFunction* _initialise = _LinearVelocityAnalytic_Initialise;
- Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
- Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_LinearVelocityAnalytic_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, LinearVelocityAnalytic_Type, (Name)"0", _LinearVelocityAnalytic_DefaultNew );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 SysTest/AnalyticPlugins/LinearVelocityAnalytic/LinearVelocityAnalytic.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SysTest/AnalyticPlugins/LinearVelocityAnalytic/LinearVelocityAnalytic.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,379 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: LinearVelocityAnalytic.c 1111 2008-04-23 04:12:36Z RobertTurnbull $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+#include <string.h>
+
+const Type LinearVelocityAnalytic_Type = "LinearVelocityAnalytic";
+
+typedef struct {
+ __FieldTest
+ FeVariable* velocityField;
+ double nodeVelocity[8][3];
+ double nodeCoords[8][3];
+ int cornerNodeCount;
+} LinearVelocityAnalytic;
+
+Index Grid_ProjectIJK( Grid* grid, Index i, Index j, Index k ) {
+ IJK ijk = {0,0,0};
+
+ ijk[0] = i;
+ ijk[1] = j;
+ ijk[2] = k;
+
+ return Grid_Project( grid, ijk );
+}
+Index Grid_ProjectIJK_MinMax( Grid* grid, Bool iIsMax, Bool jIsMax, Bool kIsMax ) {
+ IJK ijk = {0,0,0};
+
+ if ( iIsMax )
+ ijk[0] = grid->sizes[0] - 1;
+ if ( jIsMax )
+ ijk[1] = grid->sizes[1] - 1;
+ if ( kIsMax )
+ ijk[2] = grid->sizes[2] - 1;
+
+ return Grid_Project( grid, ijk );
+}
+
+void LinearVelocityAnalytic_GetCornerNodeVelocities(void* analyticSolution) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+ Grid* vertGrid;
+ Node_GlobalIndex nodeMapper[8];
+ FeVariable* velocityField = self->velocityField;
+ FeMesh* mesh = velocityField->feMesh;
+ Dimension_Index dim = velocityField->dim;
+ Node_Index globalNode_I;
+ Node_Index ii;
+
+ vertGrid = *(Grid**)ExtensionManager_Get( mesh->info, mesh, ExtensionManager_GetHandle( mesh->info, (Name)"vertexGrid" ) );
+
+ /* Find global indicies of nodes */
+ self->cornerNodeCount = 4;
+ nodeMapper[0] = Grid_ProjectIJK_MinMax( vertGrid, False, False, False );
+ nodeMapper[1] = Grid_ProjectIJK_MinMax( vertGrid, True, False, False );
+ nodeMapper[2] = Grid_ProjectIJK_MinMax( vertGrid, False, True, False );
+ nodeMapper[3] = Grid_ProjectIJK_MinMax( vertGrid, True, True, False );
+ if ( dim == 3 ) {
+ self->cornerNodeCount = 8;
+ nodeMapper[4] = Grid_ProjectIJK_MinMax( vertGrid, False, False, True );
+ nodeMapper[5] = Grid_ProjectIJK_MinMax( vertGrid, True, False, True );
+ nodeMapper[6] = Grid_ProjectIJK_MinMax( vertGrid, False, True, True );
+ nodeMapper[7] = Grid_ProjectIJK_MinMax( vertGrid, True, True, True );
+ }
+
+ /* Loop over corner nodes */
+ for ( ii = 0 ; ii < self->cornerNodeCount ; ii++ ) {
+ globalNode_I = nodeMapper[ ii ];
+ FeVariable_GetValueAtNodeGlobal( velocityField, globalNode_I, self->nodeVelocity[ii] );
+ FeVariable_GetCoordAtNodeGlobal( velocityField, globalNode_I, self->nodeCoords[ii] );
+ }
+}
+
+void GetLocalCoords( LinearVelocityAnalytic* self, double* coord, double* xi ) {
+ FeVariable* velocityField = self->velocityField;
+ XYZ min;
+ XYZ max;
+ Dimension_Index dim = velocityField->dim;
+ Dimension_Index dim_I;
+
+ _FeVariable_GetMinAndMaxGlobalCoords( velocityField, min, max );
+ for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
+ xi[ dim_I ] = 2.0 * (coord[ dim_I ] - min[ dim_I ])/(max[dim_I] - min[dim_I]) - 1;
+ }
+}
+
+/* Do a normal linear interpolation as if the box were a FEM element */
+void LinearVelocityAnalytic_VelocityFunction( void* analyticSolution, double* coord, double* velocity ) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+ FeVariable* velocityField = self->velocityField;
+ FeMesh* mesh = velocityField->feMesh;
+ Dimension_Index dim = velocityField->dim;
+ Dimension_Index dim_I;
+ XYZ xi;
+ double Ni[8];
+ Node_Index ii;
+ ElementType* elementType;
+
+ /* Transform the coordinate into a master coordinate system */
+ GetLocalCoords( self, coord, xi );
+
+ /* Get Shape Functions */
+ elementType = FeMesh_GetElementType( mesh, 0 );
+ ElementType_EvaluateShapeFunctionsAt( elementType, xi, Ni );
+
+ /* Do interpolation */
+ /* Loop over corner nodes */
+ memset( velocity, 0, dim*sizeof(double) );
+ for ( ii = 0 ; ii < self->cornerNodeCount ; ii++ ) {
+ for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
+ velocity[ dim_I ] += Ni[ ii ] * self->nodeVelocity[ii][ dim_I ];
+ }
+ }
+}
+void LinearVelocityAnalytic_PressureFunction( void* analyticSolution, double* coord, double* pressure ) {
+ *pressure = 0.0;
+}
+
+void LinearVelocityAnalytic_VelocityGradientsFunction( void* analyticSolution, double* coord, double* velocityGradients ) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+ FeVariable* velocityField = self->velocityField;
+ FeMesh* mesh = velocityField->feMesh;
+ ElementType* elementType;
+ XYZ xi;
+ double jac[3][3];
+ double cof[3][3]; /* cofactors */
+ double detJac;
+ Node_Index node_I;
+ double** GNi;
+ double** GNx;
+ double* nodeCoord;
+ double nodeValue;
+ Dimension_Index dim = velocityField->dim;
+ Dimension_Index i, j, dx, dxi;
+ Dimension_Index dim_I;
+
+ /* Transform the coordinate into a master coordinate system */
+ GetLocalCoords( self, coord, xi );
+
+ GNi = Memory_Alloc_2DArray( double, dim, self->cornerNodeCount, (Name)"GNi" );
+ GNx = Memory_Alloc_2DArray( double, dim, self->cornerNodeCount, (Name)"GNx" );
+
+ /* Get Shape Functions */
+ elementType = FeMesh_GetElementType( mesh, 0 );
+ elementType->_evaluateShapeFunctionLocalDerivsAt( elementType, xi, GNi );
+
+ /* build the jacobian matrix */
+ /*
+ jac = \sum_i d/d\xi( N_i ) x_i \sum_i d/d\xi( N_i ) y_i
+ \sum_i d/d\eta( N_i ) x_i \sum_i d/d\eta( N_i ) y_i
+ */
+ if( dim == 2 ) {
+ jac[0][0] = jac[0][1] = jac[1][0] = jac[1][1] = 0.0;
+ for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
+ nodeCoord = self->nodeCoords[ node_I ];
+ jac[0][0] = jac[0][0] + GNi[0][node_I] * nodeCoord[0];
+ jac[0][1] = jac[0][1] + GNi[0][node_I] * nodeCoord[1];
+
+ jac[1][0] = jac[1][0] + GNi[1][node_I] * nodeCoord[0];
+ jac[1][1] = jac[1][1] + GNi[1][node_I] * nodeCoord[1];
+ }
+ }
+
+ if( dim == 3 ) {
+ jac[0][0] = jac[0][1] = jac[0][2] = 0.0;
+ jac[1][0] = jac[1][1] = jac[1][2] = 0.0;
+ jac[2][0] = jac[2][1] = jac[2][2] = 0.0;
+ for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
+ nodeCoord = self->nodeCoords[ node_I ];
+ jac[0][0] = jac[0][0] + GNi[0][node_I] * nodeCoord[0];
+ jac[0][1] = jac[0][1] + GNi[0][node_I] * nodeCoord[1];
+ jac[0][2] = jac[0][2] + GNi[0][node_I] * nodeCoord[2];
+
+ jac[1][0] = jac[1][0] + GNi[1][node_I] * nodeCoord[0];
+ jac[1][1] = jac[1][1] + GNi[1][node_I] * nodeCoord[1];
+ jac[1][2] = jac[1][2] + GNi[1][node_I] * nodeCoord[2];
+
+ jac[2][0] = jac[2][0] + GNi[2][node_I] * nodeCoord[0];
+ jac[2][1] = jac[2][1] + GNi[2][node_I] * nodeCoord[1];
+ jac[2][2] = jac[2][2] + GNi[2][node_I] * nodeCoord[2];
+ }
+ }
+
+ /* get determinant of the jacobian matrix */
+ if( dim == 2 ) {
+ detJac = jac[0][0]*jac[1][1] - jac[0][1]*jac[1][0];
+ }
+ if( dim == 3 ) {
+ detJac = jac[0][0]*( jac[1][1]*jac[2][2] - jac[1][2]*jac[2][1] )
+ - jac[0][1]*( jac[1][0]*jac[2][2] - jac[1][2]*jac[2][0] )
+ + jac[0][2]*( jac[1][0]*jac[2][1] - jac[1][1]*jac[2][0] );
+ }
+
+ /* invert the jacobian matrix A^-1 = adj(A)/det(A) */
+ if( dim == 2 ) {
+ double tmp = jac[0][0];
+ jac[0][0] = jac[1][1]/detJac;
+ jac[1][1] = tmp/detJac;
+ jac[0][1] = -jac[0][1]/detJac;
+ jac[1][0] = -jac[1][0]/detJac;
+ }
+ if( dim == 3 ) {
+ /*
+ 00 01 02
+ 10 11 12
+ 20 21 22
+ */
+ cof[0][0] = jac[1][1]*jac[2][2] - jac[1][2]*jac[2][1];
+ cof[1][0] = -(jac[1][0]*jac[2][2] - jac[1][2]*jac[2][0]);
+ cof[2][0] = jac[1][0]*jac[2][1] - jac[1][1]*jac[2][0];
+
+ cof[0][1] = -(jac[0][1]*jac[2][2] - jac[0][2]*jac[2][1]);
+ cof[1][1] = jac[0][0]*jac[2][2] - jac[0][2]*jac[2][0];
+ cof[2][1] = -(jac[0][0]*jac[2][1] - jac[0][1]*jac[2][0]);
+
+ cof[0][2] = jac[0][1]*jac[1][2] - jac[0][2]*jac[1][1];
+ cof[1][2] = -(jac[0][0]*jac[1][2] - jac[0][2]*jac[1][0]);
+ cof[2][2] = jac[0][0]*jac[1][1] - jac[0][1]*jac[1][0];
+
+ for( i=0; i<dim; i++ ) {
+ for( j=0; j<dim; j++ ) {
+ jac[i][j] = cof[i][j]/detJac;
+ }
+ }
+
+
+ }
+
+ /* get global derivs Ni_x, Ni_y and Ni_z if dim == 3 */
+ for( dx=0; dx<dim; dx++ ) {
+ for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
+ double globalSF_DerivVal = 0.0;
+ for(dxi=0; dxi<dim; dxi++) {
+ globalSF_DerivVal = globalSF_DerivVal + GNi[dxi][node_I] * jac[dx][dxi];
+ }
+
+ GNx[dx][node_I] = globalSF_DerivVal;
+ }
+ }
+
+ /* Initialise velocity gradients */
+ memset( velocityGradients, 0, sizeof( double ) * dim * dim );
+
+ for ( dim_I = 0 ; dim_I < dim ; dim_I++ ) {
+ /* Interpolate derivative from nodes */
+ for( node_I =0; node_I < self->cornerNodeCount ; node_I ++){
+ nodeValue = self->nodeVelocity[ node_I ][ dim_I ];
+
+ velocityGradients[dim_I*dim + 0] += GNx[0][node_I] * nodeValue;
+ velocityGradients[dim_I*dim + 1] += GNx[1][node_I] * nodeValue;
+ if( dim == 3 )
+ velocityGradients[dim_I*dim + 2] += GNx[2][node_I] * nodeValue;
+ }
+ }
+ Memory_Free( GNi );
+ Memory_Free( GNx );
+}
+
+void LinearVelocityAnalytic_StrainRateFunction( void* analyticSolution, double* coord, double* strainRate ) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+ Dimension_Index dim = self->velocityField->dim;
+ TensorArray velocityGradients;
+
+ /* Get Velocity Gradients */
+ LinearVelocityAnalytic_VelocityGradientsFunction( self, coord, velocityGradients );
+
+ /* Get Strain Rate */
+ TensorArray_GetSymmetricPart( velocityGradients, dim, strainRate );
+}
+
+void LinearVelocityAnalytic_StrainRateInvFunction( void* analyticSolution, double* coord, double* strainRateInv ) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+ Dimension_Index dim = self->velocityField->dim;
+ SymmetricTensor strainRate;
+
+ /* Get Strain Rate */
+ LinearVelocityAnalytic_StrainRateFunction( self, coord, strainRate );
+
+ /* Get Invariant */
+ *strainRateInv = SymmetricTensor_2ndInvariant( strainRate, dim );
+}
+
+void _LinearVelocityAnalytic_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+
+ _FieldTest_AssignFromXML( self, cf, data );
+
+ self->velocityField = Stg_ComponentFactory_ConstructByName( cf, (Name)"VelocityField", FeVariable, True, data );
+}
+
+void _LinearVelocityAnalytic_Build( void* analyticSolution, void* data ) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+
+ _FieldTest_Build( self, data );
+
+ /* here we assign the memory and the func ptr for analytic sols */
+ self->_analyticSolutionList = Memory_Alloc_Array_Unnamed( FieldTest_AnalyticSolutionFunc*, 4 );
+ /* this order MUST be consistent with the xml file definition */
+ self->_analyticSolutionList[0] = LinearVelocityAnalytic_VelocityFunction;
+ self->_analyticSolutionList[1] = LinearVelocityAnalytic_PressureFunction;
+ self->_analyticSolutionList[2] = LinearVelocityAnalytic_StrainRateFunction;
+ self->_analyticSolutionList[3] = LinearVelocityAnalytic_StrainRateInvFunction;
+}
+
+void _LinearVelocityAnalytic_Initialise( void* analyticSolution, void* data ) {
+ LinearVelocityAnalytic *self = (LinearVelocityAnalytic*)analyticSolution;
+
+ Stg_Component_Initialise( self->velocityField, data, False );
+ LinearVelocityAnalytic_GetCornerNodeVelocities( self );
+
+ _FieldTest_Initialise( self, data );
+}
+
+void* _LinearVelocityAnalytic_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(LinearVelocityAnalytic);
+ Type type = LinearVelocityAnalytic_Type;
+ Stg_Class_DeleteFunction* _delete = _FieldTest_Delete;
+ Stg_Class_PrintFunction* _print = _FieldTest_Print;
+ Stg_Class_CopyFunction* _copy = _FieldTest_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _LinearVelocityAnalytic_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _LinearVelocityAnalytic_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _LinearVelocityAnalytic_Build;
+ Stg_Component_InitialiseFunction* _initialise = _LinearVelocityAnalytic_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _FieldTest_Execute;
+ Stg_Component_DestroyFunction* _destroy = _FieldTest_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _FieldTest_New( FIELDTEST_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_LinearVelocityAnalytic_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, LinearVelocityAnalytic_Type, (Name)"0", _LinearVelocityAnalytic_DefaultNew );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 libStgFEM/Toolbox/Toolbox.c
--- a/libStgFEM/Toolbox/Toolbox.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-** Kent Humphries, Software Engineer, VPAC. (kenth at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: StandardConditionFunctions.c 532 2006-04-04 00:21:59Z PatrickSunter $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-#include "Toolbox.h"
-
-const Type StgFEM_Toolbox_Type = "StgFEM_Toolbox";
-
-void _StgFEM_Toolbox_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
-}
-
-void* _StgFEM_Toolbox_DefaultNew( Name name ) {
- return Codelet_New(
- StgFEM_Toolbox_Type,
- _StgFEM_Toolbox_DefaultNew,
- _StgFEM_Toolbox_AssignFromXML,
- _Codelet_Build,
- _Codelet_Initialise,
- _Codelet_Execute,
- _Codelet_Destroy,
- name );
-}
-
-void StgFEM_Toolbox_Initialise( PluginsManager* pluginsManager, int* argc, char*** argv ) {
- StgFEM_Init( argc, argv );
-}
-
-void StgFEM_Toolbox_Finalise( PluginsManager* pluginsManager ) {
- StgFEM_Finalise();
-
- Journal_RPrintf( Journal_Register( DebugStream_Type, (Name)StgFEM_Toolbox_Type ), "Finalised: StGermain FEM Toolbox.\n" );
-}
-
-Index StgFEM_Toolbox_Register( PluginsManager* pluginsManager ) {
- return PluginsManager_Submit( pluginsManager, StgFEM_Toolbox_Type, (Name)"0", _StgFEM_Toolbox_DefaultNew );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 libStgFEM/Toolbox/Toolbox.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libStgFEM/Toolbox/Toolbox.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,81 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+** Kent Humphries, Software Engineer, VPAC. (kenth at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: StandardConditionFunctions.c 532 2006-04-04 00:21:59Z PatrickSunter $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+#include "Toolbox.h"
+
+const Type StgFEM_Toolbox_Type = "StgFEM_Toolbox";
+
+void _StgFEM_Toolbox_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
+}
+
+void* _StgFEM_Toolbox_DefaultNew( Name name ) {
+ return Codelet_New(
+ StgFEM_Toolbox_Type,
+ _StgFEM_Toolbox_DefaultNew,
+ _StgFEM_Toolbox_AssignFromXML,
+ _Codelet_Build,
+ _Codelet_Initialise,
+ _Codelet_Execute,
+ _Codelet_Destroy,
+ name );
+}
+
+void StgFEM_Toolbox_Initialise( PluginsManager* pluginsManager, int* argc, char*** argv ) {
+ StgFEM_Init( argc, argv );
+}
+
+void StgFEM_Toolbox_Finalise( PluginsManager* pluginsManager ) {
+ StgFEM_Finalise();
+
+ Journal_RPrintf( Journal_Register( DebugStream_Type, (Name)StgFEM_Toolbox_Type ), "Finalised: StGermain FEM Toolbox.\n" );
+}
+
+Index StgFEM_Toolbox_Register( PluginsManager* pluginsManager ) {
+ return PluginsManager_Submit( pluginsManager, StgFEM_Toolbox_Type, (Name)"0", _StgFEM_Toolbox_DefaultNew );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 libStgFEM/src/Finalise.c
--- a/libStgFEM/src/Finalise.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SLE.h"
-#include "StgFEM/Assembly/Assembly.h"
-#include "Finalise.h"
-
-#include <stdio.h>
-
-Bool StgFEM_Finalise( void ) {
- if( ToolboxesManager_IsInitialised( stgToolboxesManager, "StgFEM" ) ) {
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
-
- Stream_IndentBranch( StgFEM_Debug );
- StgFEM_Discretisation_Finalise();
- StgFEM_SLE_Finalise();
- StgFEM_Assembly_Finalise();
- Stream_UnIndentBranch( StgFEM_Debug );
- return True;
- } else {
- return False;
- }
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 libStgFEM/src/Finalise.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libStgFEM/src/Finalise.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,67 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Finalise.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SLE.h"
+#include "StgFEM/Assembly/Assembly.h"
+#include "Finalise.h"
+
+#include <stdio.h>
+
+Bool StgFEM_Finalise( void ) {
+ if( ToolboxesManager_IsInitialised( stgToolboxesManager, "StgFEM" ) ) {
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+
+ Stream_IndentBranch( StgFEM_Debug );
+ StgFEM_Discretisation_Finalise();
+ StgFEM_SLE_Finalise();
+ StgFEM_Assembly_Finalise();
+ Stream_UnIndentBranch( StgFEM_Debug );
+ return True;
+ } else {
+ return False;
+ }
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 libStgFEM/src/Init.c
--- a/libStgFEM/src/Init.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "StgFEM/SLE/SLE.h"
-#include "StgFEM/Assembly/Assembly.h"
-#include "Init.h"
-
-#include <stdio.h>
-
-/** Initialises the Linear Algebra package, then any init for this package
-such as streams etc */
-Bool StgFEM_StandardConditionFunctions_Init( int * argc, char ** argv[] );
-Bool StgFEM_Init( int* argc, char** argv[] ) {
- /* This init function tells StGermain of all the component types, etc this module contributes. Because it can be linked at compile
- time or linked in by a toolbox at runtime, we need to make sure it isn't run twice (compiled in and loaded through a toolbox.*/
- if( !ToolboxesManager_IsInitialised( stgToolboxesManager, "StgFEM" ) ) {
- int tmp;
- char* directory;
-
- Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
- tmp = Stream_GetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ) );
- Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), 0 );
- Journal_Printf( /* DO NOT CHANGE OR REMOVE */
- Journal_Register( InfoStream_Type, (Name)"Context" ),
- "StGermain Finite Element Framework revision %s. Copyright (C) 2003-2005 VPAC.\n", VERSION );
- Stream_Flush( Journal_Register( InfoStream_Type, (Name)"Context" ) );
- Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), tmp );
-
- StgFEM_Discretisation_Init( argc, argv );
- StgFEM_SLE_Init( argc, argv );
- StgFEM_Assembly_Init( argc, argv );
- StgFEM_StandardConditionFunctions_Init( argc, argv );
-
- /* Add the StgFEM path to the global xml path dictionary */
- directory = Memory_Alloc_Array( char, 200, "xmlDirectory" ) ;
- sprintf(directory, "%s%s", LIB_DIR, "/StGermain" );
- XML_IO_Handler_AddDirectory("StgFEM", directory );
- Memory_Free(directory);
-
- /* Add the plugin path to the global plugin list */
- ModulesManager_AddDirectory( "StgFEM", LIB_DIR );
-
- return True;
- }
- return False;
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 libStgFEM/src/Init.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libStgFEM/src/Init.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,90 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Init.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "StgFEM/SLE/SLE.h"
+#include "StgFEM/Assembly/Assembly.h"
+#include "Init.h"
+
+#include <stdio.h>
+
+/** Initialises the Linear Algebra package, then any init for this package
+such as streams etc */
+Bool StgFEM_StandardConditionFunctions_Init( int * argc, char ** argv[] );
+Bool StgFEM_Init( int* argc, char** argv[] ) {
+ /* This init function tells StGermain of all the component types, etc this module contributes. Because it can be linked at compile
+ time or linked in by a toolbox at runtime, we need to make sure it isn't run twice (compiled in and loaded through a toolbox.*/
+ if( !ToolboxesManager_IsInitialised( stgToolboxesManager, "StgFEM" ) ) {
+ int tmp;
+ char* directory;
+
+ Journal_Printf( Journal_Register( DebugStream_Type, (Name)"Context" ), "In: %s\n", __func__ ); /* DO NOT CHANGE OR REMOVE */
+ tmp = Stream_GetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ) );
+ Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), 0 );
+ Journal_Printf( /* DO NOT CHANGE OR REMOVE */
+ Journal_Register( InfoStream_Type, (Name)"Context" ),
+ "StGermain Finite Element Framework revision %s. Copyright (C) 2003-2005 VPAC.\n", VERSION );
+ Stream_Flush( Journal_Register( InfoStream_Type, (Name)"Context" ) );
+ Stream_SetPrintingRank( Journal_Register( InfoStream_Type, (Name)"Context" ), tmp );
+
+ StgFEM_Discretisation_Init( argc, argv );
+ StgFEM_SLE_Init( argc, argv );
+ StgFEM_Assembly_Init( argc, argv );
+ StgFEM_StandardConditionFunctions_Init( argc, argv );
+
+ /* Add the StgFEM path to the global xml path dictionary */
+ directory = Memory_Alloc_Array( char, 200, "xmlDirectory" ) ;
+ sprintf(directory, "%s%s", LIB_DIR, "/StGermain" );
+ XML_IO_Handler_AddDirectory("StgFEM", directory );
+ Memory_Free(directory);
+
+ /* Add the plugin path to the global plugin list */
+ ModulesManager_AddDirectory( "StgFEM", LIB_DIR );
+
+ return True;
+ }
+ return False;
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 libStgFEM/tests/LibStgFEMSuite.c
--- a/libStgFEM/tests/LibStgFEMSuite.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-#include <mpi.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "pcu/pcu.h"
-#include <StGermain/StGermain.h>
-
-#include "StgDomain/StgDomain.h"
-#include "StgFEM/StgFEM.h"
-
-#include "LibStgFEMSuite.h"
-
-typedef struct {
-} LibStgFEMSuiteData;
-
-void LibStgFEMSuite_Setup( LibStgFEMSuiteData* data ) {
-}
-
-void LibStgFEMSuite_Teardown( LibStgFEMSuiteData* data ) {
-}
-
-void LibStgFEMSuite_DirectoryStGermain( LibStgFEMSuiteData* data ) {
- Stg_Object* testDirectoryStGermain;
- testDirectoryStGermain = (Stg_Object*)Stg_ObjectList_Get( Project_XMLSearchPaths, (Name)"StGermain" );
- pcu_check_true( testDirectoryStGermain != NULL );
-}
-
-void LibStgFEMSuite_DirectoryStgFEM( LibStgFEMSuiteData * data ) {
- Stg_Object* testDirectoryStGermain;
- Stg_Object* testDirectoryStgFEM;
-
- testDirectoryStGermain = (Stg_Object*)Stg_ObjectList_Get( Project_XMLSearchPaths, (Name)"StGermain" );
- testDirectoryStgFEM= (Stg_Object*)Stg_ObjectList_Get( Project_XMLSearchPaths, (Name)"StgFEM" );
-
- pcu_check_true( ( strcmp((char* )LIB_DIR, (char*)testDirectoryStGermain) ) || ( testDirectoryStgFEM != NULL ) );
-}
-
-void LibStgFEMSuite( pcu_suite_t* suite ) {
-
- pcu_suite_setData( suite, LibStgFEMSuiteData );
- pcu_suite_setFixtures( suite, LibStgFEMSuite_Setup, LibStgFEMSuite_Teardown);
-
- pcu_suite_addTest( suite, LibStgFEMSuite_DirectoryStGermain );
- pcu_suite_addTest( suite, LibStgFEMSuite_DirectoryStgFEM);
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 libStgFEM/tests/LibStgFEMSuite.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libStgFEM/tests/LibStgFEMSuite.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,49 @@
+#include <mpi.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pcu/pcu.h"
+#include <StGermain/StGermain.h>
+
+#include "StgDomain/StgDomain.h"
+#include "StgFEM/StgFEM.h"
+
+#include "LibStgFEMSuite.h"
+
+typedef struct {
+} LibStgFEMSuiteData;
+
+void LibStgFEMSuite_Setup( LibStgFEMSuiteData* data ) {
+}
+
+void LibStgFEMSuite_Teardown( LibStgFEMSuiteData* data ) {
+}
+
+void LibStgFEMSuite_DirectoryStGermain( LibStgFEMSuiteData* data ) {
+ Stg_Object* testDirectoryStGermain;
+ testDirectoryStGermain = (Stg_Object*)Stg_ObjectList_Get( Project_XMLSearchPaths, (Name)"StGermain" );
+ pcu_check_true( testDirectoryStGermain != NULL );
+}
+
+void LibStgFEMSuite_DirectoryStgFEM( LibStgFEMSuiteData * data ) {
+ Stg_Object* testDirectoryStGermain;
+ Stg_Object* testDirectoryStgFEM;
+
+ testDirectoryStGermain = (Stg_Object*)Stg_ObjectList_Get( Project_XMLSearchPaths, (Name)"StGermain" );
+ testDirectoryStgFEM= (Stg_Object*)Stg_ObjectList_Get( Project_XMLSearchPaths, (Name)"StgFEM" );
+
+ pcu_check_true( ( strcmp((char* )LIB_DIR, (char*)testDirectoryStGermain) ) || ( testDirectoryStgFEM != NULL ) );
+}
+
+void LibStgFEMSuite( pcu_suite_t* suite ) {
+
+ pcu_suite_setData( suite, LibStgFEMSuiteData );
+ pcu_suite_setFixtures( suite, LibStgFEMSuite_Setup, LibStgFEMSuite_Teardown);
+
+ pcu_suite_addTest( suite, LibStgFEMSuite_DirectoryStGermain );
+ pcu_suite_addTest( suite, LibStgFEMSuite_DirectoryStgFEM);
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 libStgFEM/tests/testLibStgFEM.c
--- a/libStgFEM/tests/testLibStgFEM.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: testLibStgFEM.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-int main( int argc, char* argv[] ) {
- MPI_Comm CommWorld;
- int rank;
- int numProcessors;
- int procToWatch;
-
- /* Initialise MPI, get world info */
- MPI_Init( &argc, &argv );
- MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld );
- MPI_Comm_size( CommWorld, &numProcessors );
- MPI_Comm_rank( CommWorld, &rank );
- /* Read input */
-
- if( !StGermain_Init( &argc, &argv ) || !StgDomain_Init( &argc, &argv ) ) {
- fprintf( stderr, "Error initialising StGermain, exiting.\n" );
- exit( EXIT_FAILURE );
- }
- StgFEM_Init( &argc, &argv );
- MPI_Barrier( CommWorld ); /* Ensures copyright info always come first in output */
-
- if( argc >= 2 ) {
- procToWatch = atoi( argv[1] );
- }
- else {
- procToWatch = 0;
- }
- if( rank == procToWatch ) {
- Stg_Object* testDirectory;
- printf( "Watching rank: %i\n", rank );
- /* Testing entries in xmlDictionary */
- testDirectory = Stg_ObjectList_Get( xmlSearchPaths, (Name)"StGermain" );
- if (testDirectory != NULL) {
- printf("StGermain XML library Path found.\n");
- }
- else {
- printf("StGermain XML library Path not found.\n");
- }
- /* For build in the same build directory */
- if (strcmp((char* )LIB_DIR, (char*)testDirectory)) {
- printf("StgFEM XML library Path found.\n");
- }
- /* For build in separate directories */
- else{
- testDirectory = Stg_ObjectList_Get( xmlSearchPaths, (Name)"StgFEM" );
- if (testDirectory != NULL) {
- printf("StgFEM XML library Path found.\n");
- }
- else {
- printf("StgFEM XML library Path not found.\n");
- }
- }
-
- }
-
- StgFEM_Finalise();
- StGermain_Finalise();
-
- /* Close off MPI */
- MPI_Finalize( );
-
- return 0; /* success */
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 libStgFEM/tests/testLibStgFEM.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libStgFEM/tests/testLibStgFEM.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,114 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: testLibStgFEM.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int main( int argc, char* argv[] ) {
+ MPI_Comm CommWorld;
+ int rank;
+ int numProcessors;
+ int procToWatch;
+
+ /* Initialise MPI, get world info */
+ MPI_Init( &argc, &argv );
+ MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld );
+ MPI_Comm_size( CommWorld, &numProcessors );
+ MPI_Comm_rank( CommWorld, &rank );
+ /* Read input */
+
+ if( !StGermain_Init( &argc, &argv ) || !StgDomain_Init( &argc, &argv ) ) {
+ fprintf( stderr, "Error initialising StGermain, exiting.\n" );
+ exit( EXIT_FAILURE );
+ }
+ StgFEM_Init( &argc, &argv );
+ MPI_Barrier( CommWorld ); /* Ensures copyright info always come first in output */
+
+ if( argc >= 2 ) {
+ procToWatch = atoi( argv[1] );
+ }
+ else {
+ procToWatch = 0;
+ }
+ if( rank == procToWatch ) {
+ Stg_Object* testDirectory;
+ printf( "Watching rank: %i\n", rank );
+ /* Testing entries in xmlDictionary */
+ testDirectory = Stg_ObjectList_Get( xmlSearchPaths, (Name)"StGermain" );
+ if (testDirectory != NULL) {
+ printf("StGermain XML library Path found.\n");
+ }
+ else {
+ printf("StGermain XML library Path not found.\n");
+ }
+ /* For build in the same build directory */
+ if (strcmp((char* )LIB_DIR, (char*)testDirectory)) {
+ printf("StgFEM XML library Path found.\n");
+ }
+ /* For build in separate directories */
+ else{
+ testDirectory = Stg_ObjectList_Get( xmlSearchPaths, (Name)"StgFEM" );
+ if (testDirectory != NULL) {
+ printf("StgFEM XML library Path found.\n");
+ }
+ else {
+ printf("StgFEM XML library Path not found.\n");
+ }
+ }
+
+ }
+
+ StgFEM_Finalise();
+ StGermain_Finalise();
+
+ /* Close off MPI */
+ MPI_Finalize( );
+
+ return 0; /* success */
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.c
--- a/plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,541 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-** Copyright (c) 2005, Monash Cluster Computing
-** All rights reserved.
-** Redistribution and use in source and binary forms, with or without modification,
-** are permitted provided that the following conditions are met:
-**
-** * Redistributions of source code must retain the above copyright notice,
-** this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** * Neither the name of the Monash University nor the names of its contributors
-** may be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-**
-** Contact:
-*% Louis Moresi - Louis.Moresi at sci.monash.edu.au
-*%
-** Contributors:
-*+ Mirko Velic
-*+ Julian Giordani
-*+ Robert Turnbull
-*+ Vincent Lemiale
-*+ Louis Moresi
-*+ David May
-*+ David Stegman
-*+ Patrick Sunter
-** $Id: solA.c 567 2006-05-25 02:10:57Z JulianGiordani $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-#include <string.h>
-
-const Type CompareFeVariableAgainstReferenceSolution_Type = "StgFEM_CompareFeVariableAgainstReferenceSolution";
-
-void CompareFeVariableAgainstReferenceSolution_TestAll( void* compareFeVariable, void* data );
-void CompareFeVariableAgainstReferenceSolution_TestVariable( void* compareFeVariable, FeVariable* feVarToTest, double tolerance, Bool relativeErrorMeasure );
-void _CompareFeVariableAgainstReferenceSolution_Delete( void* compareFeVariable );
-
-typedef struct {
- __Codelet
- Stg_ComponentFactory* cf;
-
- char* referencePath;
- Swarm* integrationSwarm;
-
- Stg_ObjectList* variables;
- Stg_ObjectList* tolerances;
- Stg_ObjectList* relativeErrorMeasure;
-
- Index timeStepToCompare;
-
- char* importFormatType;
- char* exportFormatType;
-
- char* referenceFeVariableSuffix;
- Bool alwaysOutputErrors;
-} CompareFeVariableAgainstReferenceSolution;
-
-
-void _CompareFeVariableAgainstReferenceSolution_AssignFromXML( void* compareFeVariable, Stg_ComponentFactory* cf, void* data ) {
- CompareFeVariableAgainstReferenceSolution* self = (CompareFeVariableAgainstReferenceSolution*) compareFeVariable;
-
- AbstractContext* context;
-
- Dictionary* dictionary;
- char* referencePath;
- char* integrationSwarmName;
-
- char* varName;
- Dictionary_Entry_Value* varList;
-
- FeVariable* feVarToTest;
- Index var_I;
- double tolerance;
- Bool relativeErrorMeasure;
-
- char* tmpName;
-
- Stream* myStream;
-
- context = (AbstractContext*)Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
- self->context = context;
- self->cf = cf;
-
- EP_AppendClassHook(
- Context_GetEntryPoint( context, AbstractContext_EP_DumpClass ),
- CompareFeVariableAgainstReferenceSolution_TestAll,
- self );
-
- self->alwaysOutputErrors = Dictionary_GetBool_WithDefault( cf->rootDict, (Dictionary_Entry_Key)"alwaysOutputErrors", False );
-
- dictionary = Dictionary_GetDictionary( cf->rootDict, self->name );
- Journal_Firewall(
- dictionary != NULL,
- Journal_MyStream( Error_Type, self ),
- "In func %s - Specify FeVariables to compare in struct %s\n", __func__, self->name );
-
- referencePath = Dictionary_GetString_WithDefault( dictionary, "referencePath", "./" );
- Journal_Printf(
- Journal_MyStream( Info_Type, self ),
- "%s: Using reference path %s\n", self->name, referencePath );
- if ( referencePath[ strlen(referencePath) ] == (int)'/' ) {
- self->referencePath = StG_Strdup( referencePath );
- }
- else {
- Stg_asprintf( &self->referencePath, "%s/", referencePath );
- }
-
- integrationSwarmName = Dictionary_GetString_WithDefault( dictionary, "integrationSwarm", "gaussSwarm" );
- Journal_Printf(
- Journal_MyStream( Info_Type, self ),
- "%s: Using integration swarm %s\n", self->name, integrationSwarmName );
- self->integrationSwarm = Stg_ComponentFactory_ConstructByName( cf, (Name)integrationSwarmName, Swarm, True, data );
-
- self->variables = Stg_ObjectList_New();
- self->tolerances = Stg_ObjectList_New();
- self->relativeErrorMeasure = Stg_ObjectList_New( );
-
- varList = Dictionary_Get( dictionary, (Dictionary_Entry_Key)"variables" );
- Journal_Firewall(
- varList != NULL && Dictionary_Entry_Value_GetCount( varList ) > 0,
- Journal_MyStream( Error_Type, self ),
- "In func %s - Specify FeVariables to compare in list \"variables\" for %s\n", __func__, self->name );
-
- for ( var_I = 0; var_I < Dictionary_Entry_Value_GetCount( varList ); ++var_I ) {
- varName = Dictionary_Entry_Value_AsString( Dictionary_Entry_Value_GetElement( varList, var_I ) );
- feVarToTest = Stg_ComponentFactory_ConstructByName( cf, (Name)varName, FeVariable, True, data );
- Journal_Printf(
- Journal_MyStream( Info_Type, self ),
- "%s: Comparing FeVariable %s\n", self->name, varName );
-
- tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"tolerance" );
- tolerance = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)tmpName, 0.005 );
-
- tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"useRelativeErrorMeasure" );
- relativeErrorMeasure = Dictionary_GetBool_WithDefault( dictionary, (Dictionary_Entry_Key)tmpName, False );
-
- Stg_ObjectList_Append( self->variables, feVarToTest );
- Stg_ObjectList_Append( self->tolerances, Stg_PrimitiveObject_New_Double( tolerance, (Name)varName ) );
- Stg_ObjectList_Append( self->relativeErrorMeasure, Stg_PrimitiveObject_New_Int( (relativeErrorMeasure)?1:0, (Name)varName ) );
- }
-
- /* Default is zero which means every time step */
- self->timeStepToCompare = Dictionary_GetUnsignedInt_WithDefault( dictionary, "timeStepToCompare", 0 );
- if ( self->timeStepToCompare == 0 ) {
- Journal_Printf(
- Journal_MyStream( Info_Type, self ),
- "%s: timeStepToCompare is 0 - All time steps will be compared\n",
- self->type );
- }
-
- self->referenceFeVariableSuffix = StG_Strdup( Dictionary_GetString_WithDefault( dictionary, "referenceFeVariableSuffix",
- "Reference" ) );
-
-
- myStream = Journal_MyStream( Info_Type, self );
- Stg_asprintf( &tmpName, "%s.dat", self->name );
- Stream_RedirectFile_WithPrependedPath( myStream, self->context->outputPath, tmpName );
- Memory_Free( tmpName );
-}
-
-
-void* _CompareFeVariableAgainstReferenceSolution_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(CompareFeVariableAgainstReferenceSolution);
- Type type = CompareFeVariableAgainstReferenceSolution_Type;
- Stg_Class_DeleteFunction* _delete = _CompareFeVariableAgainstReferenceSolution_Delete;
- Stg_Class_PrintFunction* _print = _Codelet_Print;
- Stg_Class_CopyFunction* _copy = _Codelet_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _CompareFeVariableAgainstReferenceSolution_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _CompareFeVariableAgainstReferenceSolution_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Codelet_Build;
- Stg_Component_InitialiseFunction* _initialise = _Codelet_Initialise;
- Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
- Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _Codelet_New( CODELET_PASSARGS );
-}
-
-
-Index StgFEM_CompareFeVariableAgainstReferenceSolution_Register( PluginsManager* pluginsManager ) {
- return PluginsManager_Submit( pluginsManager, CompareFeVariableAgainstReferenceSolution_Type, (Name)"0", _CompareFeVariableAgainstReferenceSolution_DefaultNew );
-}
-
-
-void CompareFeVariableAgainstReferenceSolution_TestAll( void* compareFeVariable, void* data ) {
- CompareFeVariableAgainstReferenceSolution* self = (CompareFeVariableAgainstReferenceSolution*) compareFeVariable;
-
- FeVariable* feVarToTest;
- double tolerance;
- int relativeErrorMeasure;
-
- Index var_I;
-
- /* No need to test initial conditions */
- if ( self->context->timeStep < 1 ) {
- return;
- }
-
- if ( self->timeStepToCompare != 0 && self->context->timeStep != self->timeStepToCompare ) {
- /* Only compare timesteps that has been selected iff timeStepToCompare is non-zero */
- return;
- }
-
- for ( var_I = 0; var_I < self->variables->count; ++var_I ) {
- feVarToTest = (FeVariable*)Stg_ObjectList_At( self->variables, var_I );
- tolerance = ((Stg_PrimitiveObject*)Stg_ObjectList_At( self->tolerances, var_I ))->value.asDouble;
- relativeErrorMeasure = ((Stg_PrimitiveObject*)Stg_ObjectList_At( self->relativeErrorMeasure, var_I ))->value.asInt;
- CompareFeVariableAgainstReferenceSolution_TestVariable( self, feVarToTest, tolerance, relativeErrorMeasure ? True : False );
- }
-}
-
-
-void CompareFeVariableAgainstReferenceSolution_TestVariable( void* compareFeVariable, FeVariable* feVarToTest, double tolerance, Bool relativeErrorMeasure ) {
- CompareFeVariableAgainstReferenceSolution* self = (CompareFeVariableAgainstReferenceSolution*) compareFeVariable;
- Variable_Register* variable_Register;
- Variable* referenceDataVariable;
- Variable* roundedDataVariable;
- char* referenceVariableName[9];
- char* roundedVariableName[9];
- Variable_Index variable_I;
- DofLayout* referenceDofLayout;
- DofLayout* roundedDofLayout;
- Node_DomainIndex dNode_I;
- Dof_Index dofCountAtNode;
- Dof_Index dofCountAtPrevNode = 0;
- Dof_Index dof_I;
- double* nodalValues = NULL;
-
- FeVariable* referenceFeVar;
- OperatorFeVariable* refMagnitudeField;
- FeVariable* roundedFeVar;
- OperatorFeVariable* errorField;
- OperatorFeVariable* errorMagnitudeField, *relativeErrorMagnitudeField;
- OperatorFeVariable* feVarOutput;
-
- char* tmpName;
- char* tmpName2;
- char* filename;
- Bool scalar;
- Dof_Index componentsCount;
- /* TODO: hardcode for now - should be read in constructor, or read from the reference */
- /* feVar type, or file reader or something */
- unsigned int numSigFigsInReferenceFeVar = 15;
- char* refName = NULL;
- double result;
-
- variable_Register = self->context->variable_Register;
-
- componentsCount = feVarToTest->fieldComponentCount;
- scalar = (componentsCount == 1) ? True : False;
-
- /* Ok:- here, we know that the reference, or benchmark, FeVariable that we are
- comparing against may have been rounded off already, and we don't want to give
- a spurious error result just because the solution just calculated has accuracy
- beyond what the rounded benchmark is giving. Thus, we truncate the result to the
- level of the reference FeVariable */
-
- /* Create a DataVariable for the Reference. This serves as the memory object is is linked to */
- /* Likewise, for the rounded-off version of the "live" FeVar we are testing */
- assert( Class_IsSuper( feVarToTest->feMesh->topo, IGraph ) );
- tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"Reference-DataVariable" );
- tmpName2 = Stg_Object_AppendSuffix( feVarToTest, (Name)"Rounded-DataVariable" );
- if ( scalar == 1 ) {
- referenceDataVariable = Variable_NewScalar( tmpName, self->context, Variable_DataType_Double, (Index*)&((IGraph*)feVarToTest->feMesh->topo)->remotes[MT_VERTEX]->nDomains, NULL, (void**)NULL, variable_Register );
- roundedDataVariable = Variable_NewScalar( tmpName2, self->context, Variable_DataType_Double, (Index*)&((IGraph*)feVarToTest->feMesh->topo)->remotes[MT_VERTEX]->nDomains, NULL, (void**)NULL, variable_Register );
- }
- else {
- Journal_Firewall(
- componentsCount <= 9,
- Journal_MyStream( Error_Type, self ),
- "In func %s - Cannot create a variable with more than 9 components (%s)\n",
- __func__,
- feVarToTest->name );
- for ( variable_I = 0 ; variable_I < componentsCount; variable_I++ ) {
- Stg_asprintf(
- &referenceVariableName[ variable_I ],
- "%s-Reference-ComponentVariable%d",
- feVarToTest->name,
- variable_I );
- Stg_asprintf(
- &roundedVariableName[ variable_I ],
- "%s-Rounded-ComponentVariable%d",
- feVarToTest->name,
- variable_I );
- }
- referenceDataVariable = Variable_NewVector(
- tmpName,
- self->context,
- Variable_DataType_Double,
- componentsCount,
- (Index*)(&((IGraph*)feVarToTest->feMesh->topo)->remotes[MT_VERTEX]->nDomains),
- NULL,
- (void**)NULL,
- variable_Register,
- referenceVariableName[0],
- referenceVariableName[1],
- referenceVariableName[2],
- referenceVariableName[3],
- referenceVariableName[4],
- referenceVariableName[5],
- referenceVariableName[6],
- referenceVariableName[7],
- referenceVariableName[8] );
-
- roundedDataVariable = Variable_NewVector(
- tmpName2,
- self->context,
- Variable_DataType_Double,
- componentsCount,
- (Index*)(&((IGraph*)feVarToTest->feMesh->topo)->remotes[MT_VERTEX]->nDomains),
- NULL,
- (void**)NULL,
- variable_Register,
- roundedVariableName[0],
- roundedVariableName[1],
- roundedVariableName[2],
- roundedVariableName[3],
- roundedVariableName[4],
- roundedVariableName[5],
- roundedVariableName[6],
- roundedVariableName[7],
- roundedVariableName[8] );
- }
- Memory_Free( tmpName );
- Memory_Free( tmpName2 );
-
- referenceDataVariable->allocateSelf = True;
- roundedDataVariable->allocateSelf = True;
-
- Stg_Component_Build( referenceDataVariable, NULL, False );
- Stg_Component_Initialise( referenceDataVariable, NULL, False );
- Stg_Component_Build( roundedDataVariable, NULL, False );
- Stg_Component_Initialise( roundedDataVariable, NULL, False );
-
- /* Create Dof layout for this variable based on its own DataVariable */
- tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"Reference-DofLayout" );
- tmpName2 = Stg_Object_AppendSuffix( feVarToTest, (Name)"Rounded-DofLayout" );
- referenceDofLayout = DofLayout_New( tmpName, (DomainContext*)self->context, variable_Register, Mesh_GetDomainSize( feVarToTest->feMesh, MT_VERTEX ), NULL );
- roundedDofLayout = DofLayout_New( tmpName2, (DomainContext*)self->context, variable_Register, Mesh_GetDomainSize( feVarToTest->feMesh, MT_VERTEX ), NULL );
-
- if ( scalar ) {
- DofLayout_AddAllFromVariableArray( referenceDofLayout, 1, &referenceDataVariable );
- DofLayout_AddAllFromVariableArray( roundedDofLayout, 1, &roundedDataVariable );
- }
- else {
- for ( variable_I = 0 ; variable_I < componentsCount ; variable_I++ ) {
- /* Assign variable to each node */
- for( dNode_I = 0; dNode_I < Mesh_GetDomainSize( feVarToTest->feMesh, MT_VERTEX ); dNode_I++ ) {
- DofLayout_AddDof_ByVarName( referenceDofLayout, referenceVariableName[variable_I], dNode_I );
- DofLayout_AddDof_ByVarName( roundedDofLayout, roundedVariableName[variable_I], dNode_I );
- }
- /* Free Name */
- Memory_Free( referenceVariableName[ variable_I ] );
- Memory_Free( roundedVariableName[ variable_I ] );
- }
- }
- Memory_Free( tmpName );
- Memory_Free( tmpName2 );
-
- Stg_Component_Build( referenceDofLayout, NULL, False );
- Stg_Component_Initialise( referenceDofLayout, NULL, False );
- Stg_Component_Build( roundedDofLayout, NULL, False );
- Stg_Component_Initialise( roundedDofLayout, NULL, False );
-
- if ( strlen( self->referenceFeVariableSuffix ) > 0 ) {
- refName = Stg_Object_AppendSuffix( feVarToTest, (Name)self->referenceFeVariableSuffix );
- }
- else {
- /* refName = Stg_Object_AppendSuffix( feVarToTest, (Name)"Reference" ); */
- /* We actually need the referenceFeVar initially to be called the same as feVarToTest,
- * so it reads the correct values - PatrickSunter, 9 Jun 2007 */
- refName = StG_Strdup( feVarToTest->name );
- }
-
- referenceFeVar = FeVariable_New_FromTemplate(
- refName,
- (DomainContext*)self->context,
- feVarToTest,
- referenceDofLayout,
- NULL,
- True, /* isReference = True */
- False, /* Don't set the "test every timestep var", since we re-create this guy each timestep anyway*/
- feVarToTest->fieldVariable_Register );
-
- tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"Rounded" );
- roundedFeVar = FeVariable_New_FromTemplate(
- tmpName,
- (DomainContext*)self->context,
- feVarToTest,
- roundedDofLayout,
- NULL,
- False,
- False,
- feVarToTest->fieldVariable_Register );
-
- Memory_Free( tmpName );
-
- Stg_Component_Build( referenceFeVar, self->context, False );
- Stg_Component_Build( roundedFeVar, self->context, False );
- /* Note we _don't_ pass in the context to the vars below to disable checkpoint-restart,
- * since we want manual control over loading these 2 */
- Stg_Component_Initialise( referenceFeVar, NULL, False );
- Stg_Component_Initialise( roundedFeVar, NULL, False );
-
- filename = Memory_Alloc_Array_Unnamed( char, strlen(self->referencePath) + strlen(self->name) + 1 + 5 + 1 + 3 + 1 );
-#ifdef READ_HDF5
- sprintf( filename, "%s/%s.%.5u.h5", self->referencePath, self->name, self->context->timeStep );
-#else
- sprintf( filename, "%s/%s.%.5u.h5", self->referencePath, self->name, self->context->timeStep );
-#endif
- FeVariable_ReadFromFile( referenceFeVar, filename );
-
- /* Note this is a bit inelegant, but kind of necessary unless we rewrite the FeVariable
- * checkpointing-reading code again to be more general - see my comment above when
- * refName is allocated */
- if ( 0 == strcmp( feVarToTest->name, referenceFeVar->name ) ) {
- Memory_Free( referenceFeVar->name );
- referenceFeVar->name = Stg_Object_AppendSuffix( feVarToTest, (Name)"Reference" );
- }
- tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"MagnitudeField" );
- refMagnitudeField = OperatorFeVariable_NewUnary( tmpName, (DomainContext*)self->context, referenceFeVar, "Magnitude" );
- Memory_Free( tmpName );
-
- /* now we need to round off the feVar we are testing, and copy the result to the roundedFeVar */
- for( dNode_I = 0; dNode_I < Mesh_GetDomainSize( feVarToTest->feMesh, MT_VERTEX ); dNode_I++ ) {
- dofCountAtNode = feVarToTest->dofLayout->dofCounts[dNode_I];
-
- if ( dofCountAtNode != dofCountAtPrevNode ) {
- nodalValues = Memory_Realloc_Array( nodalValues, double, dofCountAtNode );
- }
- FeVariable_GetValueAtNode( feVarToTest, dNode_I, nodalValues );
-
- for ( dof_I=0; dof_I < dofCountAtNode; dof_I++ ) {
- nodalValues[dof_I] = StG_RoundDoubleToNSigFigs( nodalValues[dof_I], numSigFigsInReferenceFeVar );
- }
- FeVariable_SetValueAtNode( roundedFeVar, dNode_I, nodalValues );
- dofCountAtPrevNode = dofCountAtNode;
- }
- Memory_Free( nodalValues );
-
- tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"ErrorField" );
- errorField = OperatorFeVariable_NewBinary( tmpName, (DomainContext*)self->context, roundedFeVar, referenceFeVar, "Subtraction" );
- Memory_Free( tmpName );
-
- tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"ErrorMagnitudeField" );
- errorMagnitudeField = OperatorFeVariable_NewUnary( tmpName, (DomainContext*)self->context, errorField, "Magnitude" );
- Memory_Free( tmpName );
-
- tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"RelativeErrorMagnitudeField" );
- relativeErrorMagnitudeField = OperatorFeVariable_NewBinary( tmpName, (DomainContext*)self->context, errorMagnitudeField, refMagnitudeField, "ScalarDivision" );
- Memory_Free( tmpName );
-
- /* Build and Initialise the newly-created OperatorFeVariables - else we can't use them */
- Stg_Component_Build( errorField, self->context, False );
- Stg_Component_Build( errorMagnitudeField, self->context, False );
- Stg_Component_Build( refMagnitudeField, self->context, False );
- Stg_Component_Build( relativeErrorMagnitudeField, self->context, False );
- Stg_Component_Initialise( errorField, self->context, False );
- Stg_Component_Initialise( errorMagnitudeField, self->context, False );
- Stg_Component_Initialise( refMagnitudeField, self->context, False );
- Stg_Component_Initialise( relativeErrorMagnitudeField, self->context, False );
-
- /* If the relativeErrorMeasure flag was used, then change the calculations and output to be relative */
- if( relativeErrorMeasure )
- feVarOutput = relativeErrorMagnitudeField;
- else
- feVarOutput = errorMagnitudeField;
-
- result = FeVariable_Integrate( feVarOutput, self->integrationSwarm );
-
- Journal_Printf(
- Journal_MyStream( Info_Type, self ),
- "Timestep %u: Total integrated value of '%s' is %s a tolerance %.5g.\n",
- self->context->timeStep,
- feVarOutput->name,
- result <= tolerance ? "within" : "outside",
- tolerance );
-
- if ( ( result > tolerance ) || (True == self->alwaysOutputErrors) ) {
- if( relativeErrorMeasure ) {
- Journal_Printf(
- Journal_MyStream( Info_Type, self ),
- "\t(Integrated total relative error was %g)\n",
- result );
- }
- else {
- Journal_Printf(
- Journal_MyStream( Info_Type, self ),
- "\t(Integrated total absolute error was %g)\n",
- result );
- }
- }
-
- /* TODO: The lines below were commented out. Why? This is actually a bad memory leak! PatrickSunter, 9 Jul 2007 */
- /*
- Stg_Class_Delete( referenceDataVariable );
- Stg_Class_Delete( referenceDofLayout );
- Stg_Class_Delete( referenceFeVar );
- Stg_Class_Delete( roundedDataVariable );
- Stg_Class_Delete( roundedDofLayout );
- Stg_Class_Delete( roundedFeVar );
- Stg_Class_Delete( errorField );
- Stg_Class_Delete( errorMagnitudeField );
- Stg_Class_Delete( relativeErrorMagnitudeField );
- */
-
- Memory_Free( refName );
-}
-
-void _CompareFeVariableAgainstReferenceSolution_Delete( void* compareFeVariable ) {
- CompareFeVariableAgainstReferenceSolution* self = (CompareFeVariableAgainstReferenceSolution*) compareFeVariable;
-
- Memory_Free( self->referencePath );
- Memory_Free( self->referenceFeVariableSuffix );
- Memory_Free( self->importFormatType );
- Memory_Free( self->exportFormatType );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/CompareFeVariableAgainstReferenceSolution/CompareFeVariableAgainstReferenceSolution.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,541 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+** Copyright (c) 2005, Monash Cluster Computing
+** All rights reserved.
+** Redistribution and use in source and binary forms, with or without modification,
+** are permitted provided that the following conditions are met:
+**
+** * Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of the Monash University nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+**
+** Contact:
+*% Louis Moresi - Louis.Moresi at sci.monash.edu.au
+*%
+** Contributors:
+*+ Mirko Velic
+*+ Julian Giordani
+*+ Robert Turnbull
+*+ Vincent Lemiale
+*+ Louis Moresi
+*+ David May
+*+ David Stegman
+*+ Patrick Sunter
+** $Id: solA.c 567 2006-05-25 02:10:57Z JulianGiordani $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+#include <string.h>
+
+const Type CompareFeVariableAgainstReferenceSolution_Type = "StgFEM_CompareFeVariableAgainstReferenceSolution";
+
+void CompareFeVariableAgainstReferenceSolution_TestAll( void* compareFeVariable, void* data );
+void CompareFeVariableAgainstReferenceSolution_TestVariable( void* compareFeVariable, FeVariable* feVarToTest, double tolerance, Bool relativeErrorMeasure );
+void _CompareFeVariableAgainstReferenceSolution_Delete( void* compareFeVariable );
+
+typedef struct {
+ __Codelet
+ Stg_ComponentFactory* cf;
+
+ char* referencePath;
+ Swarm* integrationSwarm;
+
+ Stg_ObjectList* variables;
+ Stg_ObjectList* tolerances;
+ Stg_ObjectList* relativeErrorMeasure;
+
+ Index timeStepToCompare;
+
+ char* importFormatType;
+ char* exportFormatType;
+
+ char* referenceFeVariableSuffix;
+ Bool alwaysOutputErrors;
+} CompareFeVariableAgainstReferenceSolution;
+
+
+void _CompareFeVariableAgainstReferenceSolution_AssignFromXML( void* compareFeVariable, Stg_ComponentFactory* cf, void* data ) {
+ CompareFeVariableAgainstReferenceSolution* self = (CompareFeVariableAgainstReferenceSolution*) compareFeVariable;
+
+ AbstractContext* context;
+
+ Dictionary* dictionary;
+ char* referencePath;
+ char* integrationSwarmName;
+
+ char* varName;
+ Dictionary_Entry_Value* varList;
+
+ FeVariable* feVarToTest;
+ Index var_I;
+ double tolerance;
+ Bool relativeErrorMeasure;
+
+ char* tmpName;
+
+ Stream* myStream;
+
+ context = (AbstractContext*)Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+ self->context = context;
+ self->cf = cf;
+
+ EP_AppendClassHook(
+ Context_GetEntryPoint( context, AbstractContext_EP_DumpClass ),
+ CompareFeVariableAgainstReferenceSolution_TestAll,
+ self );
+
+ self->alwaysOutputErrors = Dictionary_GetBool_WithDefault( cf->rootDict, (Dictionary_Entry_Key)"alwaysOutputErrors", False );
+
+ dictionary = Dictionary_GetDictionary( cf->rootDict, self->name );
+ Journal_Firewall(
+ dictionary != NULL,
+ Journal_MyStream( Error_Type, self ),
+ "In func %s - Specify FeVariables to compare in struct %s\n", __func__, self->name );
+
+ referencePath = Dictionary_GetString_WithDefault( dictionary, "referencePath", "./" );
+ Journal_Printf(
+ Journal_MyStream( Info_Type, self ),
+ "%s: Using reference path %s\n", self->name, referencePath );
+ if ( referencePath[ strlen(referencePath) ] == (int)'/' ) {
+ self->referencePath = StG_Strdup( referencePath );
+ }
+ else {
+ Stg_asprintf( &self->referencePath, "%s/", referencePath );
+ }
+
+ integrationSwarmName = Dictionary_GetString_WithDefault( dictionary, "integrationSwarm", "gaussSwarm" );
+ Journal_Printf(
+ Journal_MyStream( Info_Type, self ),
+ "%s: Using integration swarm %s\n", self->name, integrationSwarmName );
+ self->integrationSwarm = Stg_ComponentFactory_ConstructByName( cf, (Name)integrationSwarmName, Swarm, True, data );
+
+ self->variables = Stg_ObjectList_New();
+ self->tolerances = Stg_ObjectList_New();
+ self->relativeErrorMeasure = Stg_ObjectList_New( );
+
+ varList = Dictionary_Get( dictionary, (Dictionary_Entry_Key)"variables" );
+ Journal_Firewall(
+ varList != NULL && Dictionary_Entry_Value_GetCount( varList ) > 0,
+ Journal_MyStream( Error_Type, self ),
+ "In func %s - Specify FeVariables to compare in list \"variables\" for %s\n", __func__, self->name );
+
+ for ( var_I = 0; var_I < Dictionary_Entry_Value_GetCount( varList ); ++var_I ) {
+ varName = Dictionary_Entry_Value_AsString( Dictionary_Entry_Value_GetElement( varList, var_I ) );
+ feVarToTest = Stg_ComponentFactory_ConstructByName( cf, (Name)varName, FeVariable, True, data );
+ Journal_Printf(
+ Journal_MyStream( Info_Type, self ),
+ "%s: Comparing FeVariable %s\n", self->name, varName );
+
+ tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"tolerance" );
+ tolerance = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)tmpName, 0.005 );
+
+ tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"useRelativeErrorMeasure" );
+ relativeErrorMeasure = Dictionary_GetBool_WithDefault( dictionary, (Dictionary_Entry_Key)tmpName, False );
+
+ Stg_ObjectList_Append( self->variables, feVarToTest );
+ Stg_ObjectList_Append( self->tolerances, Stg_PrimitiveObject_New_Double( tolerance, (Name)varName ) );
+ Stg_ObjectList_Append( self->relativeErrorMeasure, Stg_PrimitiveObject_New_Int( (relativeErrorMeasure)?1:0, (Name)varName ) );
+ }
+
+ /* Default is zero which means every time step */
+ self->timeStepToCompare = Dictionary_GetUnsignedInt_WithDefault( dictionary, "timeStepToCompare", 0 );
+ if ( self->timeStepToCompare == 0 ) {
+ Journal_Printf(
+ Journal_MyStream( Info_Type, self ),
+ "%s: timeStepToCompare is 0 - All time steps will be compared\n",
+ self->type );
+ }
+
+ self->referenceFeVariableSuffix = StG_Strdup( Dictionary_GetString_WithDefault( dictionary, "referenceFeVariableSuffix",
+ "Reference" ) );
+
+
+ myStream = Journal_MyStream( Info_Type, self );
+ Stg_asprintf( &tmpName, "%s.dat", self->name );
+ Stream_RedirectFile_WithPrependedPath( myStream, self->context->outputPath, tmpName );
+ Memory_Free( tmpName );
+}
+
+
+void* _CompareFeVariableAgainstReferenceSolution_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(CompareFeVariableAgainstReferenceSolution);
+ Type type = CompareFeVariableAgainstReferenceSolution_Type;
+ Stg_Class_DeleteFunction* _delete = _CompareFeVariableAgainstReferenceSolution_Delete;
+ Stg_Class_PrintFunction* _print = _Codelet_Print;
+ Stg_Class_CopyFunction* _copy = _Codelet_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _CompareFeVariableAgainstReferenceSolution_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _CompareFeVariableAgainstReferenceSolution_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Codelet_Build;
+ Stg_Component_InitialiseFunction* _initialise = _Codelet_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
+ Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _Codelet_New( CODELET_PASSARGS );
+}
+
+
+Index StgFEM_CompareFeVariableAgainstReferenceSolution_Register( PluginsManager* pluginsManager ) {
+ return PluginsManager_Submit( pluginsManager, CompareFeVariableAgainstReferenceSolution_Type, (Name)"0", _CompareFeVariableAgainstReferenceSolution_DefaultNew );
+}
+
+
+void CompareFeVariableAgainstReferenceSolution_TestAll( void* compareFeVariable, void* data ) {
+ CompareFeVariableAgainstReferenceSolution* self = (CompareFeVariableAgainstReferenceSolution*) compareFeVariable;
+
+ FeVariable* feVarToTest;
+ double tolerance;
+ int relativeErrorMeasure;
+
+ Index var_I;
+
+ /* No need to test initial conditions */
+ if ( self->context->timeStep < 1 ) {
+ return;
+ }
+
+ if ( self->timeStepToCompare != 0 && self->context->timeStep != self->timeStepToCompare ) {
+ /* Only compare timesteps that has been selected iff timeStepToCompare is non-zero */
+ return;
+ }
+
+ for ( var_I = 0; var_I < self->variables->count; ++var_I ) {
+ feVarToTest = (FeVariable*)Stg_ObjectList_At( self->variables, var_I );
+ tolerance = ((Stg_PrimitiveObject*)Stg_ObjectList_At( self->tolerances, var_I ))->value.asDouble;
+ relativeErrorMeasure = ((Stg_PrimitiveObject*)Stg_ObjectList_At( self->relativeErrorMeasure, var_I ))->value.asInt;
+ CompareFeVariableAgainstReferenceSolution_TestVariable( self, feVarToTest, tolerance, relativeErrorMeasure ? True : False );
+ }
+}
+
+
+void CompareFeVariableAgainstReferenceSolution_TestVariable( void* compareFeVariable, FeVariable* feVarToTest, double tolerance, Bool relativeErrorMeasure ) {
+ CompareFeVariableAgainstReferenceSolution* self = (CompareFeVariableAgainstReferenceSolution*) compareFeVariable;
+ Variable_Register* variable_Register;
+ Variable* referenceDataVariable;
+ Variable* roundedDataVariable;
+ char* referenceVariableName[9];
+ char* roundedVariableName[9];
+ Variable_Index variable_I;
+ DofLayout* referenceDofLayout;
+ DofLayout* roundedDofLayout;
+ Node_DomainIndex dNode_I;
+ Dof_Index dofCountAtNode;
+ Dof_Index dofCountAtPrevNode = 0;
+ Dof_Index dof_I;
+ double* nodalValues = NULL;
+
+ FeVariable* referenceFeVar;
+ OperatorFeVariable* refMagnitudeField;
+ FeVariable* roundedFeVar;
+ OperatorFeVariable* errorField;
+ OperatorFeVariable* errorMagnitudeField, *relativeErrorMagnitudeField;
+ OperatorFeVariable* feVarOutput;
+
+ char* tmpName;
+ char* tmpName2;
+ char* filename;
+ Bool scalar;
+ Dof_Index componentsCount;
+ /* TODO: hardcode for now - should be read in constructor, or read from the reference */
+ /* feVar type, or file reader or something */
+ unsigned int numSigFigsInReferenceFeVar = 15;
+ char* refName = NULL;
+ double result;
+
+ variable_Register = self->context->variable_Register;
+
+ componentsCount = feVarToTest->fieldComponentCount;
+ scalar = (componentsCount == 1) ? True : False;
+
+ /* Ok:- here, we know that the reference, or benchmark, FeVariable that we are
+ comparing against may have been rounded off already, and we don't want to give
+ a spurious error result just because the solution just calculated has accuracy
+ beyond what the rounded benchmark is giving. Thus, we truncate the result to the
+ level of the reference FeVariable */
+
+ /* Create a DataVariable for the Reference. This serves as the memory object is is linked to */
+ /* Likewise, for the rounded-off version of the "live" FeVar we are testing */
+ assert( Class_IsSuper( feVarToTest->feMesh->topo, IGraph ) );
+ tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"Reference-DataVariable" );
+ tmpName2 = Stg_Object_AppendSuffix( feVarToTest, (Name)"Rounded-DataVariable" );
+ if ( scalar == 1 ) {
+ referenceDataVariable = Variable_NewScalar( tmpName, self->context, Variable_DataType_Double, (Index*)&((IGraph*)feVarToTest->feMesh->topo)->remotes[MT_VERTEX]->nDomains, NULL, (void**)NULL, variable_Register );
+ roundedDataVariable = Variable_NewScalar( tmpName2, self->context, Variable_DataType_Double, (Index*)&((IGraph*)feVarToTest->feMesh->topo)->remotes[MT_VERTEX]->nDomains, NULL, (void**)NULL, variable_Register );
+ }
+ else {
+ Journal_Firewall(
+ componentsCount <= 9,
+ Journal_MyStream( Error_Type, self ),
+ "In func %s - Cannot create a variable with more than 9 components (%s)\n",
+ __func__,
+ feVarToTest->name );
+ for ( variable_I = 0 ; variable_I < componentsCount; variable_I++ ) {
+ Stg_asprintf(
+ &referenceVariableName[ variable_I ],
+ "%s-Reference-ComponentVariable%d",
+ feVarToTest->name,
+ variable_I );
+ Stg_asprintf(
+ &roundedVariableName[ variable_I ],
+ "%s-Rounded-ComponentVariable%d",
+ feVarToTest->name,
+ variable_I );
+ }
+ referenceDataVariable = Variable_NewVector(
+ tmpName,
+ self->context,
+ Variable_DataType_Double,
+ componentsCount,
+ (Index*)(&((IGraph*)feVarToTest->feMesh->topo)->remotes[MT_VERTEX]->nDomains),
+ NULL,
+ (void**)NULL,
+ variable_Register,
+ referenceVariableName[0],
+ referenceVariableName[1],
+ referenceVariableName[2],
+ referenceVariableName[3],
+ referenceVariableName[4],
+ referenceVariableName[5],
+ referenceVariableName[6],
+ referenceVariableName[7],
+ referenceVariableName[8] );
+
+ roundedDataVariable = Variable_NewVector(
+ tmpName2,
+ self->context,
+ Variable_DataType_Double,
+ componentsCount,
+ (Index*)(&((IGraph*)feVarToTest->feMesh->topo)->remotes[MT_VERTEX]->nDomains),
+ NULL,
+ (void**)NULL,
+ variable_Register,
+ roundedVariableName[0],
+ roundedVariableName[1],
+ roundedVariableName[2],
+ roundedVariableName[3],
+ roundedVariableName[4],
+ roundedVariableName[5],
+ roundedVariableName[6],
+ roundedVariableName[7],
+ roundedVariableName[8] );
+ }
+ Memory_Free( tmpName );
+ Memory_Free( tmpName2 );
+
+ referenceDataVariable->allocateSelf = True;
+ roundedDataVariable->allocateSelf = True;
+
+ Stg_Component_Build( referenceDataVariable, NULL, False );
+ Stg_Component_Initialise( referenceDataVariable, NULL, False );
+ Stg_Component_Build( roundedDataVariable, NULL, False );
+ Stg_Component_Initialise( roundedDataVariable, NULL, False );
+
+ /* Create Dof layout for this variable based on its own DataVariable */
+ tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"Reference-DofLayout" );
+ tmpName2 = Stg_Object_AppendSuffix( feVarToTest, (Name)"Rounded-DofLayout" );
+ referenceDofLayout = DofLayout_New( tmpName, (DomainContext*)self->context, variable_Register, Mesh_GetDomainSize( feVarToTest->feMesh, MT_VERTEX ), NULL );
+ roundedDofLayout = DofLayout_New( tmpName2, (DomainContext*)self->context, variable_Register, Mesh_GetDomainSize( feVarToTest->feMesh, MT_VERTEX ), NULL );
+
+ if ( scalar ) {
+ DofLayout_AddAllFromVariableArray( referenceDofLayout, 1, &referenceDataVariable );
+ DofLayout_AddAllFromVariableArray( roundedDofLayout, 1, &roundedDataVariable );
+ }
+ else {
+ for ( variable_I = 0 ; variable_I < componentsCount ; variable_I++ ) {
+ /* Assign variable to each node */
+ for( dNode_I = 0; dNode_I < Mesh_GetDomainSize( feVarToTest->feMesh, MT_VERTEX ); dNode_I++ ) {
+ DofLayout_AddDof_ByVarName( referenceDofLayout, referenceVariableName[variable_I], dNode_I );
+ DofLayout_AddDof_ByVarName( roundedDofLayout, roundedVariableName[variable_I], dNode_I );
+ }
+ /* Free Name */
+ Memory_Free( referenceVariableName[ variable_I ] );
+ Memory_Free( roundedVariableName[ variable_I ] );
+ }
+ }
+ Memory_Free( tmpName );
+ Memory_Free( tmpName2 );
+
+ Stg_Component_Build( referenceDofLayout, NULL, False );
+ Stg_Component_Initialise( referenceDofLayout, NULL, False );
+ Stg_Component_Build( roundedDofLayout, NULL, False );
+ Stg_Component_Initialise( roundedDofLayout, NULL, False );
+
+ if ( strlen( self->referenceFeVariableSuffix ) > 0 ) {
+ refName = Stg_Object_AppendSuffix( feVarToTest, (Name)self->referenceFeVariableSuffix );
+ }
+ else {
+ /* refName = Stg_Object_AppendSuffix( feVarToTest, (Name)"Reference" ); */
+ /* We actually need the referenceFeVar initially to be called the same as feVarToTest,
+ * so it reads the correct values - PatrickSunter, 9 Jun 2007 */
+ refName = StG_Strdup( feVarToTest->name );
+ }
+
+ referenceFeVar = FeVariable_New_FromTemplate(
+ refName,
+ (DomainContext*)self->context,
+ feVarToTest,
+ referenceDofLayout,
+ NULL,
+ True, /* isReference = True */
+ False, /* Don't set the "test every timestep var", since we re-create this guy each timestep anyway*/
+ feVarToTest->fieldVariable_Register );
+
+ tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"Rounded" );
+ roundedFeVar = FeVariable_New_FromTemplate(
+ tmpName,
+ (DomainContext*)self->context,
+ feVarToTest,
+ roundedDofLayout,
+ NULL,
+ False,
+ False,
+ feVarToTest->fieldVariable_Register );
+
+ Memory_Free( tmpName );
+
+ Stg_Component_Build( referenceFeVar, self->context, False );
+ Stg_Component_Build( roundedFeVar, self->context, False );
+ /* Note we _don't_ pass in the context to the vars below to disable checkpoint-restart,
+ * since we want manual control over loading these 2 */
+ Stg_Component_Initialise( referenceFeVar, NULL, False );
+ Stg_Component_Initialise( roundedFeVar, NULL, False );
+
+ filename = Memory_Alloc_Array_Unnamed( char, strlen(self->referencePath) + strlen(self->name) + 1 + 5 + 1 + 3 + 1 );
+#ifdef READ_HDF5
+ sprintf( filename, "%s/%s.%.5u.h5", self->referencePath, self->name, self->context->timeStep );
+#else
+ sprintf( filename, "%s/%s.%.5u.h5", self->referencePath, self->name, self->context->timeStep );
+#endif
+ FeVariable_ReadFromFile( referenceFeVar, filename );
+
+ /* Note this is a bit inelegant, but kind of necessary unless we rewrite the FeVariable
+ * checkpointing-reading code again to be more general - see my comment above when
+ * refName is allocated */
+ if ( 0 == strcmp( feVarToTest->name, referenceFeVar->name ) ) {
+ Memory_Free( referenceFeVar->name );
+ referenceFeVar->name = Stg_Object_AppendSuffix( feVarToTest, (Name)"Reference" );
+ }
+ tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"MagnitudeField" );
+ refMagnitudeField = OperatorFeVariable_NewUnary( tmpName, (DomainContext*)self->context, referenceFeVar, "Magnitude" );
+ Memory_Free( tmpName );
+
+ /* now we need to round off the feVar we are testing, and copy the result to the roundedFeVar */
+ for( dNode_I = 0; dNode_I < Mesh_GetDomainSize( feVarToTest->feMesh, MT_VERTEX ); dNode_I++ ) {
+ dofCountAtNode = feVarToTest->dofLayout->dofCounts[dNode_I];
+
+ if ( dofCountAtNode != dofCountAtPrevNode ) {
+ nodalValues = Memory_Realloc_Array( nodalValues, double, dofCountAtNode );
+ }
+ FeVariable_GetValueAtNode( feVarToTest, dNode_I, nodalValues );
+
+ for ( dof_I=0; dof_I < dofCountAtNode; dof_I++ ) {
+ nodalValues[dof_I] = StG_RoundDoubleToNSigFigs( nodalValues[dof_I], numSigFigsInReferenceFeVar );
+ }
+ FeVariable_SetValueAtNode( roundedFeVar, dNode_I, nodalValues );
+ dofCountAtPrevNode = dofCountAtNode;
+ }
+ Memory_Free( nodalValues );
+
+ tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"ErrorField" );
+ errorField = OperatorFeVariable_NewBinary( tmpName, (DomainContext*)self->context, roundedFeVar, referenceFeVar, "Subtraction" );
+ Memory_Free( tmpName );
+
+ tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"ErrorMagnitudeField" );
+ errorMagnitudeField = OperatorFeVariable_NewUnary( tmpName, (DomainContext*)self->context, errorField, "Magnitude" );
+ Memory_Free( tmpName );
+
+ tmpName = Stg_Object_AppendSuffix( feVarToTest, (Name)"RelativeErrorMagnitudeField" );
+ relativeErrorMagnitudeField = OperatorFeVariable_NewBinary( tmpName, (DomainContext*)self->context, errorMagnitudeField, refMagnitudeField, "ScalarDivision" );
+ Memory_Free( tmpName );
+
+ /* Build and Initialise the newly-created OperatorFeVariables - else we can't use them */
+ Stg_Component_Build( errorField, self->context, False );
+ Stg_Component_Build( errorMagnitudeField, self->context, False );
+ Stg_Component_Build( refMagnitudeField, self->context, False );
+ Stg_Component_Build( relativeErrorMagnitudeField, self->context, False );
+ Stg_Component_Initialise( errorField, self->context, False );
+ Stg_Component_Initialise( errorMagnitudeField, self->context, False );
+ Stg_Component_Initialise( refMagnitudeField, self->context, False );
+ Stg_Component_Initialise( relativeErrorMagnitudeField, self->context, False );
+
+ /* If the relativeErrorMeasure flag was used, then change the calculations and output to be relative */
+ if( relativeErrorMeasure )
+ feVarOutput = relativeErrorMagnitudeField;
+ else
+ feVarOutput = errorMagnitudeField;
+
+ result = FeVariable_Integrate( feVarOutput, self->integrationSwarm );
+
+ Journal_Printf(
+ Journal_MyStream( Info_Type, self ),
+ "Timestep %u: Total integrated value of '%s' is %s a tolerance %.5g.\n",
+ self->context->timeStep,
+ feVarOutput->name,
+ result <= tolerance ? "within" : "outside",
+ tolerance );
+
+ if ( ( result > tolerance ) || (True == self->alwaysOutputErrors) ) {
+ if( relativeErrorMeasure ) {
+ Journal_Printf(
+ Journal_MyStream( Info_Type, self ),
+ "\t(Integrated total relative error was %g)\n",
+ result );
+ }
+ else {
+ Journal_Printf(
+ Journal_MyStream( Info_Type, self ),
+ "\t(Integrated total absolute error was %g)\n",
+ result );
+ }
+ }
+
+ /* TODO: The lines below were commented out. Why? This is actually a bad memory leak! PatrickSunter, 9 Jul 2007 */
+ /*
+ Stg_Class_Delete( referenceDataVariable );
+ Stg_Class_Delete( referenceDofLayout );
+ Stg_Class_Delete( referenceFeVar );
+ Stg_Class_Delete( roundedDataVariable );
+ Stg_Class_Delete( roundedDofLayout );
+ Stg_Class_Delete( roundedFeVar );
+ Stg_Class_Delete( errorField );
+ Stg_Class_Delete( errorMagnitudeField );
+ Stg_Class_Delete( relativeErrorMagnitudeField );
+ */
+
+ Memory_Free( refName );
+}
+
+void _CompareFeVariableAgainstReferenceSolution_Delete( void* compareFeVariable ) {
+ CompareFeVariableAgainstReferenceSolution* self = (CompareFeVariableAgainstReferenceSolution*) compareFeVariable;
+
+ Memory_Free( self->referencePath );
+ Memory_Free( self->referenceFeVariableSuffix );
+ Memory_Free( self->importFormatType );
+ Memory_Free( self->exportFormatType );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/FeVariableImportExporters/FeVariable_ImportExport_ABAQUS/FeVariable_ImportExport_ABAQUS.c
--- a/plugins/FeVariableImportExporters/FeVariable_ImportExport_ABAQUS/FeVariable_ImportExport_ABAQUS.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,246 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: FeVariable_ImportExport_ABAQUS.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-#include <string.h>
-
-const Type StgFEM_FeVariable_ImportExport_ABAQUS_Type = "StgFEM_FeVariable_ImportExport_ABAQUS";
-Name ABAQUS_ImportExportType = "ABAQUS";
-
-
-void FeVariable_ReadNodalValuesFromFile_ABAQUS( void* _feVariable, Name prefixStr, unsigned int timeStep ) {
- FeVariable* feVariable = (FeVariable*)_feVariable;
- char* filename;
- Node_LocalIndex lNode_I = 0;
- Node_GlobalIndex gNode_I = 0;
- Node_GlobalIndex gNodeCount_I = 0;
- Dof_Index dof_I;
- Dof_Index dofAtEachNodeCount;
- FILE* inputFile;
- double variableVal;
- char lineString[1000];
- const unsigned int MAX_LINE_LENGTH = 1000;
- Processor_Index proc_I=0;
- Dimension_Index dim_I=0;
- char* matchString;
- Index currentFileLine = 0;
- Coord localGeometryMin;
- Coord localGeometryMax;
- Stream* debugStream = Journal_Register( Debug_Type, (Name)StgFEM_FeVariable_ImportExport_ABAQUS_Type );
- FeMesh* mesh = feVariable->feMesh;
- MPI_Comm comm;
- unsigned rank, nProcs;
- double min[3], max[3];
- unsigned nDims;
-
- Journal_DPrintf( debugStream, "In %s(): for FeVariable \"%s\"\n", __func__, feVariable->name );
- Stream_Indent( debugStream );
-
- nDims = Mesh_GetDimSize( mesh );
- comm = Comm_GetMPIComm( Mesh_GetCommTopology( mesh, MT_VERTEX ) );
- MPI_Comm_rank( comm, (int*)&rank );
- MPI_Comm_size( comm, (int*)&nProcs );
-
- /* prefix feVariable->name . 00000 . dat \0 */
- filename = Memory_Alloc_Array_Unnamed( char, strlen(prefixStr) + strlen(feVariable->name) + 1 + 5 + 1 + 3 + 1 );
- sprintf( filename, "%s%s.%.5u.rpt", prefixStr, feVariable->name, timeStep );
-
- /* TODO May need/want to change to MPI file stuff */
-
- /* This loop used to stop 2 processors trying to open the file at the same time, which
- * seems to cause problems */
- for ( proc_I = 0; proc_I < nProcs; proc_I++ ) {
- MPI_Barrier( comm );
- if ( proc_I == rank ) {
- inputFile = fopen( filename, "r" );
- }
- }
-
- if ( NULL==inputFile ) {
- Stream* errorStr = Journal_Register( Error_Type, (Name)feVariable->type );
- Journal_Printf( errorStr, "Error- in %s(), for feVariable \"%s\": Couldn't find checkpoint file with "
- "prefix \"%s\", timestep %d - thus full filename \"%s\" - aborting.\n", __func__, feVariable->name,
- prefixStr, timeStep, filename );
- exit(EXIT_FAILURE);
- }
-
- /* This is where we skip over the ABAQUS header stuff */
- while ( !feof(inputFile) ) {
- currentFileLine++;
- fgets( lineString, MAX_LINE_LENGTH, inputFile );
- matchString = strstr( lineString, " Node" );
- if ( matchString != NULL ) {
- /* Grab the "Label" and the "----" lines */
- fgets( lineString, MAX_LINE_LENGTH, inputFile );
- fgets( lineString, MAX_LINE_LENGTH, inputFile );
- currentFileLine += 2;
- /* Ok, now we're ready to start reading the actual field values */
- break;
- }
- }
- Journal_DPrintf( debugStream, "Skipped %u lines of ABAQUS header info...\n", currentFileLine );
-
- dofAtEachNodeCount = feVariable->fieldComponentCount;
-
- /* Need to re-set the geometry here, in case we're loading from a checkpoint that had compression/squashing BCs,
- and hence ended up with a smaller mesh than the original */
- for ( dim_I = 0; dim_I < 3; dim_I++ ) {
- localGeometryMin[dim_I] = HUGE_VAL;
- localGeometryMax[dim_I] = -HUGE_VAL;
- }
-
- Journal_DPrintf( debugStream, "Processing Nodal Data...\n", currentFileLine );
- Stream_Indent( debugStream );
- /* Note: in ABAQUS, the number of lines of nodal values from hereon is always == the number of global nodes */
- for ( gNodeCount_I = 0; gNodeCount_I < Mesh_GetGlobalSize( mesh, MT_VERTEX ); gNodeCount_I++ ) {
- fscanf( inputFile, "%u ", &gNode_I );
- /* Note: ABAQUS has same layout of global node indices as StgFEM, except it indexes starting from 1 - thus we
- * need to subtract 1 here */
- gNode_I -= 1;
-
- if ( Mesh_GlobalToDomain( feVariable->feMesh, MT_VERTEX, gNode_I, &lNode_I ) ) {
- Journal_DPrintfL( debugStream, 3, "Found info for global node %u, local node %u:\n", gNode_I, lNode_I );
- Stream_Indent( debugStream );
-
- /* Note: until we have proper mesh geometry, topology etc checkpointing, we re-load the
- node co-ords from the feVariable file - and also update the geometry */
- fscanf( inputFile, "%lg %lg ", Mesh_GetVertex( mesh, lNode_I ),
- Mesh_GetVertex( mesh, lNode_I ) + 1 );
- if ( feVariable->fieldComponentCount == 3 ) {
- fscanf( inputFile, "%lg", Mesh_GetVertex( mesh, lNode_I ) + 2 );
- }
-
- Journal_DPrintfL( debugStream, 3, "read coord (%.3f, %.3f, %.3f)\n",
- Mesh_GetVertex( mesh, lNode_I )[0],
- Mesh_GetVertex( mesh, lNode_I )[1],
- (nDims == 3) ? Mesh_GetVertex( mesh, lNode_I )[2] : 0.0 );
-
- for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
- fscanf( inputFile, "%lg ", &variableVal );
- DofLayout_SetValueDouble( feVariable->dofLayout, lNode_I, dof_I, variableVal );
- Journal_DPrintfL( debugStream, 3, "read dof %u: %g\n", dof_I, variableVal );
- /* TODO: Hack for now - ABAQUS only uses initial coords, so assume this is displacement and add */
- Mesh_GetVertex( mesh, lNode_I )[dof_I] += variableVal;
- Journal_DPrintfL( debugStream, 3, "TODO: using HACK assumption of disp.:- updating nodeCoord[%u] to %.3f\n",
- dof_I, Mesh_GetVertex( mesh, lNode_I )[dof_I] );
- }
-
- for ( dim_I = 0; dim_I < 3; dim_I++ ) {
- if ( Mesh_GetVertex( mesh, lNode_I )[dim_I] < localGeometryMin[dim_I] ) {
- localGeometryMin[dim_I] = Mesh_GetVertex( mesh, lNode_I )[dim_I];
- }
- else if ( Mesh_GetVertex( mesh, lNode_I )[dim_I] > localGeometryMax[dim_I] ) {
- localGeometryMax[dim_I] = Mesh_GetVertex( mesh, lNode_I )[dim_I];
- }
- }
-
- }
- else {
- Journal_DPrintfL( debugStream, 3, "not on current proc -> skipping\n" );
- fgets( lineString, MAX_LINE_LENGTH, inputFile );
- }
- Stream_UnIndent( debugStream );
- currentFileLine++;
- }
- fclose( inputFile );
- Stream_UnIndent( debugStream );
-
- /* Resync the mesh and update deformation members. */
- Mesh_Sync( mesh );
- Mesh_DeformationUpdate( mesh );
-
- Mesh_GetGlobalCoordRange( mesh, min, max );
- Journal_DPrintf( debugStream, "Recalculated global field min coord as (%.3f, %.3f, %.3f)\n",
- min[0], min[1], (nDims == 3) ? min[2] : 0.0 );
- Journal_DPrintf( debugStream, "Recalculated global field max coord as (%.3f, %.3f, %.3f)\n",
- max[0], max[1], (nDims == 3) ? max[2] : 0.0 );
-
- Stream_UnIndent( debugStream );
-}
-
-
-void FeVariable_SaveNodalValuesToFile_ABAQUS( void* _feVariable, Name prefixStr, unsigned int timeStep ) {
- FeVariable* feVariable = (FeVariable*)_feVariable;
- Stream* errorStream = Journal_Register( Error_Type, (Name)StgFEM_FeVariable_ImportExport_ABAQUS_Type );
-
- Journal_Firewall( 0, errorStream, "Error - in %s(), for FeVariable \"%s\": function not implemented yet.\n",
- __func__, feVariable->name );
-}
-
-
-void _StgFEM_FeVariable_ImportExport_ABAQUS_AssignFromXML( void* componment, Stg_ComponentFactory* cf, void* data ) {
- AbstractContext* context;
-
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
-
-}
-
-void* _StgFEM_FeVariable_ImportExport_ABAQUS_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof( Codelet );
- Type type = StgFEM_FeVariable_ImportExport_ABAQUS_Type;
- Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
- Stg_Class_PrintFunction* _print = _Codelet_Print;
- Stg_Class_CopyFunction* _copy = _Codelet_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_FeVariable_ImportExport_ABAQUS_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _StgFEM_FeVariable_ImportExport_ABAQUS_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Codelet_Build;
- Stg_Component_InitialiseFunction* _initialise = _Codelet_Initialise;
- Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
- Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _Codelet_New( CODELET_PASSARGS );
-}
-
-Index StgFEM_FeVariable_ImportExport_ABAQUS_Register( PluginsManager* pluginsManager ) {
- return PluginsManager_Submit( pluginsManager, StgFEM_FeVariable_ImportExport_ABAQUS_Type, (Name)"0", _StgFEM_FeVariable_ImportExport_ABAQUS_DefaultNew );
-}
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/FeVariableImportExporters/FeVariable_ImportExport_ABAQUS/FeVariable_ImportExport_ABAQUS.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/FeVariableImportExporters/FeVariable_ImportExport_ABAQUS/FeVariable_ImportExport_ABAQUS.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,246 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: FeVariable_ImportExport_ABAQUS.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+#include <string.h>
+
+const Type StgFEM_FeVariable_ImportExport_ABAQUS_Type = "StgFEM_FeVariable_ImportExport_ABAQUS";
+Name ABAQUS_ImportExportType = "ABAQUS";
+
+
+void FeVariable_ReadNodalValuesFromFile_ABAQUS( void* _feVariable, Name prefixStr, unsigned int timeStep ) {
+ FeVariable* feVariable = (FeVariable*)_feVariable;
+ char* filename;
+ Node_LocalIndex lNode_I = 0;
+ Node_GlobalIndex gNode_I = 0;
+ Node_GlobalIndex gNodeCount_I = 0;
+ Dof_Index dof_I;
+ Dof_Index dofAtEachNodeCount;
+ FILE* inputFile;
+ double variableVal;
+ char lineString[1000];
+ const unsigned int MAX_LINE_LENGTH = 1000;
+ Processor_Index proc_I=0;
+ Dimension_Index dim_I=0;
+ char* matchString;
+ Index currentFileLine = 0;
+ Coord localGeometryMin;
+ Coord localGeometryMax;
+ Stream* debugStream = Journal_Register( Debug_Type, (Name)StgFEM_FeVariable_ImportExport_ABAQUS_Type );
+ FeMesh* mesh = feVariable->feMesh;
+ MPI_Comm comm;
+ unsigned rank, nProcs;
+ double min[3], max[3];
+ unsigned nDims;
+
+ Journal_DPrintf( debugStream, "In %s(): for FeVariable \"%s\"\n", __func__, feVariable->name );
+ Stream_Indent( debugStream );
+
+ nDims = Mesh_GetDimSize( mesh );
+ comm = Comm_GetMPIComm( Mesh_GetCommTopology( mesh, MT_VERTEX ) );
+ MPI_Comm_rank( comm, (int*)&rank );
+ MPI_Comm_size( comm, (int*)&nProcs );
+
+ /* prefix feVariable->name . 00000 . dat \0 */
+ filename = Memory_Alloc_Array_Unnamed( char, strlen(prefixStr) + strlen(feVariable->name) + 1 + 5 + 1 + 3 + 1 );
+ sprintf( filename, "%s%s.%.5u.rpt", prefixStr, feVariable->name, timeStep );
+
+ /* TODO May need/want to change to MPI file stuff */
+
+ /* This loop used to stop 2 processors trying to open the file at the same time, which
+ * seems to cause problems */
+ for ( proc_I = 0; proc_I < nProcs; proc_I++ ) {
+ MPI_Barrier( comm );
+ if ( proc_I == rank ) {
+ inputFile = fopen( filename, "r" );
+ }
+ }
+
+ if ( NULL==inputFile ) {
+ Stream* errorStr = Journal_Register( Error_Type, (Name)feVariable->type );
+ Journal_Printf( errorStr, "Error- in %s(), for feVariable \"%s\": Couldn't find checkpoint file with "
+ "prefix \"%s\", timestep %d - thus full filename \"%s\" - aborting.\n", __func__, feVariable->name,
+ prefixStr, timeStep, filename );
+ exit(EXIT_FAILURE);
+ }
+
+ /* This is where we skip over the ABAQUS header stuff */
+ while ( !feof(inputFile) ) {
+ currentFileLine++;
+ fgets( lineString, MAX_LINE_LENGTH, inputFile );
+ matchString = strstr( lineString, " Node" );
+ if ( matchString != NULL ) {
+ /* Grab the "Label" and the "----" lines */
+ fgets( lineString, MAX_LINE_LENGTH, inputFile );
+ fgets( lineString, MAX_LINE_LENGTH, inputFile );
+ currentFileLine += 2;
+ /* Ok, now we're ready to start reading the actual field values */
+ break;
+ }
+ }
+ Journal_DPrintf( debugStream, "Skipped %u lines of ABAQUS header info...\n", currentFileLine );
+
+ dofAtEachNodeCount = feVariable->fieldComponentCount;
+
+ /* Need to re-set the geometry here, in case we're loading from a checkpoint that had compression/squashing BCs,
+ and hence ended up with a smaller mesh than the original */
+ for ( dim_I = 0; dim_I < 3; dim_I++ ) {
+ localGeometryMin[dim_I] = HUGE_VAL;
+ localGeometryMax[dim_I] = -HUGE_VAL;
+ }
+
+ Journal_DPrintf( debugStream, "Processing Nodal Data...\n", currentFileLine );
+ Stream_Indent( debugStream );
+ /* Note: in ABAQUS, the number of lines of nodal values from hereon is always == the number of global nodes */
+ for ( gNodeCount_I = 0; gNodeCount_I < Mesh_GetGlobalSize( mesh, MT_VERTEX ); gNodeCount_I++ ) {
+ fscanf( inputFile, "%u ", &gNode_I );
+ /* Note: ABAQUS has same layout of global node indices as StgFEM, except it indexes starting from 1 - thus we
+ * need to subtract 1 here */
+ gNode_I -= 1;
+
+ if ( Mesh_GlobalToDomain( feVariable->feMesh, MT_VERTEX, gNode_I, &lNode_I ) ) {
+ Journal_DPrintfL( debugStream, 3, "Found info for global node %u, local node %u:\n", gNode_I, lNode_I );
+ Stream_Indent( debugStream );
+
+ /* Note: until we have proper mesh geometry, topology etc checkpointing, we re-load the
+ node co-ords from the feVariable file - and also update the geometry */
+ fscanf( inputFile, "%lg %lg ", Mesh_GetVertex( mesh, lNode_I ),
+ Mesh_GetVertex( mesh, lNode_I ) + 1 );
+ if ( feVariable->fieldComponentCount == 3 ) {
+ fscanf( inputFile, "%lg", Mesh_GetVertex( mesh, lNode_I ) + 2 );
+ }
+
+ Journal_DPrintfL( debugStream, 3, "read coord (%.3f, %.3f, %.3f)\n",
+ Mesh_GetVertex( mesh, lNode_I )[0],
+ Mesh_GetVertex( mesh, lNode_I )[1],
+ (nDims == 3) ? Mesh_GetVertex( mesh, lNode_I )[2] : 0.0 );
+
+ for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
+ fscanf( inputFile, "%lg ", &variableVal );
+ DofLayout_SetValueDouble( feVariable->dofLayout, lNode_I, dof_I, variableVal );
+ Journal_DPrintfL( debugStream, 3, "read dof %u: %g\n", dof_I, variableVal );
+ /* TODO: Hack for now - ABAQUS only uses initial coords, so assume this is displacement and add */
+ Mesh_GetVertex( mesh, lNode_I )[dof_I] += variableVal;
+ Journal_DPrintfL( debugStream, 3, "TODO: using HACK assumption of disp.:- updating nodeCoord[%u] to %.3f\n",
+ dof_I, Mesh_GetVertex( mesh, lNode_I )[dof_I] );
+ }
+
+ for ( dim_I = 0; dim_I < 3; dim_I++ ) {
+ if ( Mesh_GetVertex( mesh, lNode_I )[dim_I] < localGeometryMin[dim_I] ) {
+ localGeometryMin[dim_I] = Mesh_GetVertex( mesh, lNode_I )[dim_I];
+ }
+ else if ( Mesh_GetVertex( mesh, lNode_I )[dim_I] > localGeometryMax[dim_I] ) {
+ localGeometryMax[dim_I] = Mesh_GetVertex( mesh, lNode_I )[dim_I];
+ }
+ }
+
+ }
+ else {
+ Journal_DPrintfL( debugStream, 3, "not on current proc -> skipping\n" );
+ fgets( lineString, MAX_LINE_LENGTH, inputFile );
+ }
+ Stream_UnIndent( debugStream );
+ currentFileLine++;
+ }
+ fclose( inputFile );
+ Stream_UnIndent( debugStream );
+
+ /* Resync the mesh and update deformation members. */
+ Mesh_Sync( mesh );
+ Mesh_DeformationUpdate( mesh );
+
+ Mesh_GetGlobalCoordRange( mesh, min, max );
+ Journal_DPrintf( debugStream, "Recalculated global field min coord as (%.3f, %.3f, %.3f)\n",
+ min[0], min[1], (nDims == 3) ? min[2] : 0.0 );
+ Journal_DPrintf( debugStream, "Recalculated global field max coord as (%.3f, %.3f, %.3f)\n",
+ max[0], max[1], (nDims == 3) ? max[2] : 0.0 );
+
+ Stream_UnIndent( debugStream );
+}
+
+
+void FeVariable_SaveNodalValuesToFile_ABAQUS( void* _feVariable, Name prefixStr, unsigned int timeStep ) {
+ FeVariable* feVariable = (FeVariable*)_feVariable;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)StgFEM_FeVariable_ImportExport_ABAQUS_Type );
+
+ Journal_Firewall( 0, errorStream, "Error - in %s(), for FeVariable \"%s\": function not implemented yet.\n",
+ __func__, feVariable->name );
+}
+
+
+void _StgFEM_FeVariable_ImportExport_ABAQUS_AssignFromXML( void* componment, Stg_ComponentFactory* cf, void* data ) {
+ AbstractContext* context;
+
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+
+}
+
+void* _StgFEM_FeVariable_ImportExport_ABAQUS_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof( Codelet );
+ Type type = StgFEM_FeVariable_ImportExport_ABAQUS_Type;
+ Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
+ Stg_Class_PrintFunction* _print = _Codelet_Print;
+ Stg_Class_CopyFunction* _copy = _Codelet_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_FeVariable_ImportExport_ABAQUS_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _StgFEM_FeVariable_ImportExport_ABAQUS_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Codelet_Build;
+ Stg_Component_InitialiseFunction* _initialise = _Codelet_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
+ Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _Codelet_New( CODELET_PASSARGS );
+}
+
+Index StgFEM_FeVariable_ImportExport_ABAQUS_Register( PluginsManager* pluginsManager ) {
+ return PluginsManager_Submit( pluginsManager, StgFEM_FeVariable_ImportExport_ABAQUS_Type, (Name)"0", _StgFEM_FeVariable_ImportExport_ABAQUS_DefaultNew );
+}
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/FeVariableImportExporters/FeVariable_ImportExport_SpecRidge2D/FeVariable_ImportExport_SpecRidge2D.c
--- a/plugins/FeVariableImportExporters/FeVariable_ImportExport_SpecRidge2D/FeVariable_ImportExport_SpecRidge2D.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,249 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: FeVariable_ImportExport_SpecRidge2D.c 835 2007-05-16 02:54:29Z DaveLee $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-#include <string.h>
-
-const Type StgFEM_FeVariable_ImportExport_SpecRidge2D_Type = "StgFEM_FeVariable_ImportExport_SpecRidge2D";
-Name SpecRidge2D_ImportExportType = "SpecRidge2D";
-
-
-void FeVariable_ReadNodalValuesFromFile_SpecRidge2D( void* _feVariable, Name prefixStr, unsigned int timeStep ) {
- FeVariable* feVariable = (FeVariable*)_feVariable;
- char* filename;
- Node_LocalIndex lNode_I = 0;
- Node_GlobalIndex gNode_I = 0;
- Dof_Index dof_I;
- Dof_Index dofAtEachNodeCount;
- FILE* inputFile;
- double variableVal;
- char lineString[1000];
- const unsigned int MAX_LINE_LENGTH = 1000;
- Processor_Index proc_I=0;
- Dimension_Index dim_I=0;
- /* char* matchString; */
- Index currentFileLine = 0;
- Coord localGeometryMin;
- Coord localGeometryMax;
- Stream* debugStream = Journal_Register( Debug_Type, (Name)StgFEM_FeVariable_ImportExport_SpecRidge2D_Type );
- FeMesh* mesh = feVariable->feMesh;
- MPI_Comm comm;
- unsigned rank, nProcs;
- double min[3], max[3];
- unsigned nDims;
-
- Journal_DPrintf( debugStream, "In %s(): for FeVariable \"%s\"\n", __func__, feVariable->name );
- Stream_Indent( debugStream );
-
- nDims = Mesh_GetDimSize( mesh );
- comm = Comm_GetMPIComm( Mesh_GetCommTopology( mesh, MT_VERTEX ) );
- MPI_Comm_rank( comm, (int*)&rank );
- MPI_Comm_size( comm, (int*)&nProcs );
-
- /* prefix feVariable->name . 00000 . dat \0 */
- filename = Memory_Alloc_Array_Unnamed( char, strlen(prefixStr) + strlen(feVariable->name) + 1 + 5 + 1 + 3 + 1 );
- sprintf( filename, "%s%s.%.5u.rpt", prefixStr, feVariable->name, timeStep );
-
- /* TODO May need/want to change to MPI file stuff */
-
- /* This loop used to stop 2 processors trying to open the file at the same time, which
- * seems to cause problems */
- for ( proc_I = 0; proc_I < nProcs; proc_I++ ) {
- MPI_Barrier( comm );
- if ( proc_I == rank ) {
- inputFile = fopen( filename, "r" );
- }
- }
-
- if ( NULL == inputFile ) {
- Stream* errorStr = Journal_Register( Error_Type, (Name)feVariable->type );
- Journal_Printf( errorStr, "Error- in %s(), for feVariable \"%s\": Couldn't find checkpoint file with "
- "prefix \"%s\", timestep %d - thus full filename \"%s\" - aborting.\n", __func__, feVariable->name,
- prefixStr, timeStep, filename );
- exit(EXIT_FAILURE);
- }
-
- /* This is where we skip over the file header stuff */
- /*while ( !feof(inputFile) ) {
- currentFileLine++;
- fgets( lineString, MAX_LINE_LENGTH, inputFile );
- matchString = strstr( lineString, " Node" );
- if ( matchString != NULL ) {*/
- /* Grab the "Label" and the "----" lines */
- /*fgets( lineString, MAX_LINE_LENGTH, inputFile );
- fgets( lineString, MAX_LINE_LENGTH, inputFile );
- currentFileLine += 2;*/
- /* Ok, now we're ready to start reading the actual field values */
- /*break;
- }
- }
- Journal_DPrintf( debugStream, "Skipped %u lines of SpecRidge2D header info...\n", currentFileLine );
-*/
- dofAtEachNodeCount = feVariable->fieldComponentCount;
-
- /* Need to re-set the geometry here, in case we're loading from a checkpoint that had compression/squashing BCs,
- and hence ended up with a smaller mesh than the original */
- for ( dim_I = 0; dim_I < 3; dim_I++ ) {
- localGeometryMin[dim_I] = HUGE_VAL;
- localGeometryMax[dim_I] = -HUGE_VAL;
- }
-
- Journal_DPrintf( debugStream, "Processing Nodal Data...\n", currentFileLine );
- Stream_Indent( debugStream );
- /* TODO: add error checking to make sure number of lines in file == number of global nodes */
- /* Note: in ABAQUS, the number of lines of nodal values from hereon is always == the number of global nodes */
- for ( gNode_I = 0; gNode_I < Mesh_GetGlobalSize( mesh, MT_VERTEX ); gNode_I++ ) {
- /*fscanf( inputFile, "%u ", &gNode_I );*/
- /* Note: ABAQUS has same layout of global node indices as StgFEM, except it indexes starting from 1 - thus we
- * need to subtract 1 here */
- /*gNode_I -= 1;*/
-
- if ( Mesh_GlobalToDomain( feVariable->feMesh, MT_VERTEX, gNode_I, &lNode_I ) ) {
- Journal_DPrintfL( debugStream, 3, "Found info for global node %u, local node %u:\n", gNode_I, lNode_I );
- Stream_Indent( debugStream );
-
- fscanf( inputFile, "%lg %lg ", Mesh_GetVertex( mesh, lNode_I ),
- Mesh_GetVertex( mesh, lNode_I ) + 1 );
- if ( feVariable->fieldComponentCount == 3 ) {
- fscanf( inputFile, "%lg", Mesh_GetVertex( mesh, lNode_I ) + 2 );
- }
-
- Journal_DPrintfL( debugStream, 3, "read coord (%.3f, %.3f, %.3f)\n",
- Mesh_GetVertex( mesh, lNode_I )[0],
- Mesh_GetVertex( mesh, lNode_I )[1],
- (nDims == 3) ? Mesh_GetVertex( mesh, lNode_I )[2] : 0.0 );
-
- for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
- fscanf( inputFile, " %lg ", &variableVal );
-
- DofLayout_SetValueDouble( feVariable->dofLayout, lNode_I, dof_I, variableVal );
- Journal_DPrintfL( debugStream, 3, "read dof %u: %g\n", dof_I, variableVal );
- /* TODO: Hack for now - ABAQUS only uses initial coords, so assume this is displacement and add */
- /*Mesh_GetVertex( mesh, lNode_I )[dof_I] += variableVal;*/
- /*Journal_DPrintfL( debugStream, 3, "TODO: using HACK assumption of disp.:- updating nodeCoord[%u] to %.3f\n",
- dof_I, Mesh_GetVertex( mesh, lNode_I )[dof_I] );*/
- /*printf("value %d: %f ", dof_I, variableVal);*/
-
- }
-
- for ( dim_I = 0; dim_I < 3; dim_I++ ) {
- if ( Mesh_GetVertex( mesh, lNode_I )[dim_I] < localGeometryMin[dim_I] ) {
- localGeometryMin[dim_I] = Mesh_GetVertex( mesh, lNode_I )[dim_I];
- }
- else if ( Mesh_GetVertex( mesh, lNode_I )[dim_I] > localGeometryMax[dim_I] ) {
- localGeometryMax[dim_I] = Mesh_GetVertex( mesh, lNode_I )[dim_I];
- }
- }
-
- }
- else {
- Journal_DPrintfL( debugStream, 3, "not on current proc -> skipping\n" );
- fgets( lineString, MAX_LINE_LENGTH, inputFile );
- }
- Stream_UnIndent( debugStream );
- currentFileLine++;
- }
- fclose( inputFile );
- Stream_UnIndent( debugStream );
-
- /* Resync the mesh and update deformation members. */
- Mesh_Sync( mesh );
- Mesh_DeformationUpdate( mesh );
-
- Mesh_GetGlobalCoordRange( mesh, min, max );
- Journal_DPrintf( debugStream, "Recalculated global field min coord as (%.3f, %.3f, %.3f)\n",
- min[0], min[1], (nDims == 3) ? min[2] : 0.0 );
- Journal_DPrintf( debugStream, "Recalculated global field max coord as (%.3f, %.3f, %.3f)\n",
- max[0], max[1], (nDims == 3) ? max[2] : 0.0 );
-
- Stream_UnIndent( debugStream );
-
-
-}
-
-
-void FeVariable_SaveNodalValuesToFile_SpecRidge2D( void* _feVariable, Name prefixStr, unsigned int timeStep ) {
- FeVariable* feVariable = (FeVariable*)_feVariable;
- Stream* errorStream = Journal_Register( Error_Type, (Name)StgFEM_FeVariable_ImportExport_SpecRidge2D_Type );
-
- Journal_Firewall( 0, errorStream, "Error - in %s(), for FeVariable \"%s\": function not implemented yet.\n",
- __func__, feVariable->name );
-}
-
-
-void _StgFEM_FeVariable_ImportExport_SpecRidge2D_AssignFromXML( void* componment, Stg_ComponentFactory* cf, void* data ) {
- AbstractContext* context;
-
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
-
-}
-
-void* _StgFEM_FeVariable_ImportExport_SpecRidge2D_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof( Codelet );
- Type type = StgFEM_FeVariable_ImportExport_SpecRidge2D_Type;
- Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
- Stg_Class_PrintFunction* _print = _Codelet_Print;
- Stg_Class_CopyFunction* _copy = _Codelet_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_FeVariable_ImportExport_SpecRidge2D_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _StgFEM_FeVariable_ImportExport_SpecRidge2D_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Codelet_Build;
- Stg_Component_InitialiseFunction* _initialise = _Codelet_Initialise;
- Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
- Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _Codelet_New( CODELET_PASSARGS );
-}
-
-Index StgFEM_FeVariable_ImportExport_SpecRidge2D_Register( PluginsManager* pluginsManager ) {
- return PluginsManager_Submit( pluginsManager, StgFEM_FeVariable_ImportExport_SpecRidge2D_Type, (Name)"0", _StgFEM_FeVariable_ImportExport_SpecRidge2D_DefaultNew );
-}
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/FeVariableImportExporters/FeVariable_ImportExport_SpecRidge2D/FeVariable_ImportExport_SpecRidge2D.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/FeVariableImportExporters/FeVariable_ImportExport_SpecRidge2D/FeVariable_ImportExport_SpecRidge2D.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,249 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: FeVariable_ImportExport_SpecRidge2D.c 835 2007-05-16 02:54:29Z DaveLee $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+#include <string.h>
+
+const Type StgFEM_FeVariable_ImportExport_SpecRidge2D_Type = "StgFEM_FeVariable_ImportExport_SpecRidge2D";
+Name SpecRidge2D_ImportExportType = "SpecRidge2D";
+
+
+void FeVariable_ReadNodalValuesFromFile_SpecRidge2D( void* _feVariable, Name prefixStr, unsigned int timeStep ) {
+ FeVariable* feVariable = (FeVariable*)_feVariable;
+ char* filename;
+ Node_LocalIndex lNode_I = 0;
+ Node_GlobalIndex gNode_I = 0;
+ Dof_Index dof_I;
+ Dof_Index dofAtEachNodeCount;
+ FILE* inputFile;
+ double variableVal;
+ char lineString[1000];
+ const unsigned int MAX_LINE_LENGTH = 1000;
+ Processor_Index proc_I=0;
+ Dimension_Index dim_I=0;
+ /* char* matchString; */
+ Index currentFileLine = 0;
+ Coord localGeometryMin;
+ Coord localGeometryMax;
+ Stream* debugStream = Journal_Register( Debug_Type, (Name)StgFEM_FeVariable_ImportExport_SpecRidge2D_Type );
+ FeMesh* mesh = feVariable->feMesh;
+ MPI_Comm comm;
+ unsigned rank, nProcs;
+ double min[3], max[3];
+ unsigned nDims;
+
+ Journal_DPrintf( debugStream, "In %s(): for FeVariable \"%s\"\n", __func__, feVariable->name );
+ Stream_Indent( debugStream );
+
+ nDims = Mesh_GetDimSize( mesh );
+ comm = Comm_GetMPIComm( Mesh_GetCommTopology( mesh, MT_VERTEX ) );
+ MPI_Comm_rank( comm, (int*)&rank );
+ MPI_Comm_size( comm, (int*)&nProcs );
+
+ /* prefix feVariable->name . 00000 . dat \0 */
+ filename = Memory_Alloc_Array_Unnamed( char, strlen(prefixStr) + strlen(feVariable->name) + 1 + 5 + 1 + 3 + 1 );
+ sprintf( filename, "%s%s.%.5u.rpt", prefixStr, feVariable->name, timeStep );
+
+ /* TODO May need/want to change to MPI file stuff */
+
+ /* This loop used to stop 2 processors trying to open the file at the same time, which
+ * seems to cause problems */
+ for ( proc_I = 0; proc_I < nProcs; proc_I++ ) {
+ MPI_Barrier( comm );
+ if ( proc_I == rank ) {
+ inputFile = fopen( filename, "r" );
+ }
+ }
+
+ if ( NULL == inputFile ) {
+ Stream* errorStr = Journal_Register( Error_Type, (Name)feVariable->type );
+ Journal_Printf( errorStr, "Error- in %s(), for feVariable \"%s\": Couldn't find checkpoint file with "
+ "prefix \"%s\", timestep %d - thus full filename \"%s\" - aborting.\n", __func__, feVariable->name,
+ prefixStr, timeStep, filename );
+ exit(EXIT_FAILURE);
+ }
+
+ /* This is where we skip over the file header stuff */
+ /*while ( !feof(inputFile) ) {
+ currentFileLine++;
+ fgets( lineString, MAX_LINE_LENGTH, inputFile );
+ matchString = strstr( lineString, " Node" );
+ if ( matchString != NULL ) {*/
+ /* Grab the "Label" and the "----" lines */
+ /*fgets( lineString, MAX_LINE_LENGTH, inputFile );
+ fgets( lineString, MAX_LINE_LENGTH, inputFile );
+ currentFileLine += 2;*/
+ /* Ok, now we're ready to start reading the actual field values */
+ /*break;
+ }
+ }
+ Journal_DPrintf( debugStream, "Skipped %u lines of SpecRidge2D header info...\n", currentFileLine );
+*/
+ dofAtEachNodeCount = feVariable->fieldComponentCount;
+
+ /* Need to re-set the geometry here, in case we're loading from a checkpoint that had compression/squashing BCs,
+ and hence ended up with a smaller mesh than the original */
+ for ( dim_I = 0; dim_I < 3; dim_I++ ) {
+ localGeometryMin[dim_I] = HUGE_VAL;
+ localGeometryMax[dim_I] = -HUGE_VAL;
+ }
+
+ Journal_DPrintf( debugStream, "Processing Nodal Data...\n", currentFileLine );
+ Stream_Indent( debugStream );
+ /* TODO: add error checking to make sure number of lines in file == number of global nodes */
+ /* Note: in ABAQUS, the number of lines of nodal values from hereon is always == the number of global nodes */
+ for ( gNode_I = 0; gNode_I < Mesh_GetGlobalSize( mesh, MT_VERTEX ); gNode_I++ ) {
+ /*fscanf( inputFile, "%u ", &gNode_I );*/
+ /* Note: ABAQUS has same layout of global node indices as StgFEM, except it indexes starting from 1 - thus we
+ * need to subtract 1 here */
+ /*gNode_I -= 1;*/
+
+ if ( Mesh_GlobalToDomain( feVariable->feMesh, MT_VERTEX, gNode_I, &lNode_I ) ) {
+ Journal_DPrintfL( debugStream, 3, "Found info for global node %u, local node %u:\n", gNode_I, lNode_I );
+ Stream_Indent( debugStream );
+
+ fscanf( inputFile, "%lg %lg ", Mesh_GetVertex( mesh, lNode_I ),
+ Mesh_GetVertex( mesh, lNode_I ) + 1 );
+ if ( feVariable->fieldComponentCount == 3 ) {
+ fscanf( inputFile, "%lg", Mesh_GetVertex( mesh, lNode_I ) + 2 );
+ }
+
+ Journal_DPrintfL( debugStream, 3, "read coord (%.3f, %.3f, %.3f)\n",
+ Mesh_GetVertex( mesh, lNode_I )[0],
+ Mesh_GetVertex( mesh, lNode_I )[1],
+ (nDims == 3) ? Mesh_GetVertex( mesh, lNode_I )[2] : 0.0 );
+
+ for ( dof_I = 0; dof_I < dofAtEachNodeCount; dof_I++ ) {
+ fscanf( inputFile, " %lg ", &variableVal );
+
+ DofLayout_SetValueDouble( feVariable->dofLayout, lNode_I, dof_I, variableVal );
+ Journal_DPrintfL( debugStream, 3, "read dof %u: %g\n", dof_I, variableVal );
+ /* TODO: Hack for now - ABAQUS only uses initial coords, so assume this is displacement and add */
+ /*Mesh_GetVertex( mesh, lNode_I )[dof_I] += variableVal;*/
+ /*Journal_DPrintfL( debugStream, 3, "TODO: using HACK assumption of disp.:- updating nodeCoord[%u] to %.3f\n",
+ dof_I, Mesh_GetVertex( mesh, lNode_I )[dof_I] );*/
+ /*printf("value %d: %f ", dof_I, variableVal);*/
+
+ }
+
+ for ( dim_I = 0; dim_I < 3; dim_I++ ) {
+ if ( Mesh_GetVertex( mesh, lNode_I )[dim_I] < localGeometryMin[dim_I] ) {
+ localGeometryMin[dim_I] = Mesh_GetVertex( mesh, lNode_I )[dim_I];
+ }
+ else if ( Mesh_GetVertex( mesh, lNode_I )[dim_I] > localGeometryMax[dim_I] ) {
+ localGeometryMax[dim_I] = Mesh_GetVertex( mesh, lNode_I )[dim_I];
+ }
+ }
+
+ }
+ else {
+ Journal_DPrintfL( debugStream, 3, "not on current proc -> skipping\n" );
+ fgets( lineString, MAX_LINE_LENGTH, inputFile );
+ }
+ Stream_UnIndent( debugStream );
+ currentFileLine++;
+ }
+ fclose( inputFile );
+ Stream_UnIndent( debugStream );
+
+ /* Resync the mesh and update deformation members. */
+ Mesh_Sync( mesh );
+ Mesh_DeformationUpdate( mesh );
+
+ Mesh_GetGlobalCoordRange( mesh, min, max );
+ Journal_DPrintf( debugStream, "Recalculated global field min coord as (%.3f, %.3f, %.3f)\n",
+ min[0], min[1], (nDims == 3) ? min[2] : 0.0 );
+ Journal_DPrintf( debugStream, "Recalculated global field max coord as (%.3f, %.3f, %.3f)\n",
+ max[0], max[1], (nDims == 3) ? max[2] : 0.0 );
+
+ Stream_UnIndent( debugStream );
+
+
+}
+
+
+void FeVariable_SaveNodalValuesToFile_SpecRidge2D( void* _feVariable, Name prefixStr, unsigned int timeStep ) {
+ FeVariable* feVariable = (FeVariable*)_feVariable;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)StgFEM_FeVariable_ImportExport_SpecRidge2D_Type );
+
+ Journal_Firewall( 0, errorStream, "Error - in %s(), for FeVariable \"%s\": function not implemented yet.\n",
+ __func__, feVariable->name );
+}
+
+
+void _StgFEM_FeVariable_ImportExport_SpecRidge2D_AssignFromXML( void* componment, Stg_ComponentFactory* cf, void* data ) {
+ AbstractContext* context;
+
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+
+}
+
+void* _StgFEM_FeVariable_ImportExport_SpecRidge2D_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof( Codelet );
+ Type type = StgFEM_FeVariable_ImportExport_SpecRidge2D_Type;
+ Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
+ Stg_Class_PrintFunction* _print = _Codelet_Print;
+ Stg_Class_CopyFunction* _copy = _Codelet_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_FeVariable_ImportExport_SpecRidge2D_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _StgFEM_FeVariable_ImportExport_SpecRidge2D_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Codelet_Build;
+ Stg_Component_InitialiseFunction* _initialise = _Codelet_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
+ Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _Codelet_New( CODELET_PASSARGS );
+}
+
+Index StgFEM_FeVariable_ImportExport_SpecRidge2D_Register( PluginsManager* pluginsManager ) {
+ return PluginsManager_Submit( pluginsManager, StgFEM_FeVariable_ImportExport_SpecRidge2D_Type, (Name)"0", _StgFEM_FeVariable_ImportExport_SpecRidge2D_DefaultNew );
+}
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/FileAnalyticSolution/FileAnalyticSolution.c
--- a/plugins/FileAnalyticSolution/FileAnalyticSolution.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: FileAnalyticSolution.c 989 2007-12-18 13:57:56Z JulianGiordani $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-/* This is taken from Mirko Velic's Analytic Stokes Flow solution */
-
-const Type FileAnalyticSolution_Type = "FileAnalyticSolution";
-
-typedef struct {
- __AnalyticSolution
- char* referencePath;
-} FileAnalyticSolution;
-
-void FileAnalyticSolution_DummyFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* value ) {
- abort();
-}
-
-
-
-void _FileAnalyticSolution_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
- FileAnalyticSolution * self = (FileAnalyticSolution*)analyticSolution;
- Dictionary_Entry_Value* varList;
- Index var_I;
- char* varName;
- FeVariable* feVarToTest;
-
- _AnalyticSolution_AssignFromXML( self, cf, data );
- varList = Dictionary_Get( cf->rootDict, (Dictionary_Entry_Key)self->name );
- Journal_Firewall( varList != NULL, Journal_Register( Error_Type, (Name)self->type ),
- "Error- in %s(): Can't find list in XML '%s'\n", __func__, self->name );
-
- for ( var_I = 0; var_I < Dictionary_Entry_Value_GetCount( varList ); ++var_I ) {
- varName = Dictionary_Entry_Value_AsString( Dictionary_Entry_Value_GetElement( varList, var_I ) );
- feVarToTest = Stg_ComponentFactory_ConstructByName( cf, (Name)varName, FeVariable, True, data );
-
- AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, feVarToTest, FileAnalyticSolution_DummyFunction );
- }
-
-
- /* Get reference path */
- self->referencePath = Dictionary_GetString_WithDefault( cf->rootDict, "referencePath", "./expected/" );
-}
-
-void _FileAnalyticSolution_Initialise( void* analyticSolution, void* data ) {
- FileAnalyticSolution *self = (FileAnalyticSolution*)analyticSolution;
- FeVariable* analyticFeVariable;
- Index analyticFeVariableCount = Stg_ObjectList_Count( self->analyticFeVariableList );
- Index analyticFeVariable_I;
-
-
- assert( analyticFeVariableCount == Stg_ObjectList_Count( self->analyticFeVariableFuncList ) );
-
- /* Assign values to all analytic fields */
- for ( analyticFeVariable_I = 0 ; analyticFeVariable_I < analyticFeVariableCount ; analyticFeVariable_I++ ) {
- Stg_Component_Initialise( Stg_ObjectList_At( self->feVariableList, analyticFeVariable_I ), data, False ) ;
- Stg_Component_Initialise( Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I ), data, False ) ;
- Stg_Component_Initialise( Stg_ObjectList_At( self->errorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
- Stg_Component_Initialise( Stg_ObjectList_At( self->relativeErrorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
-
- /* Initialise values from file */
- analyticFeVariable = (FeVariable*) Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I );
- FeVariable_ReadFromFile( analyticFeVariable, self->referencePath, 0 );
- }
-}
-
-void* _FileAnalyticSolution_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(FileAnalyticSolution);
- Type type = FileAnalyticSolution_Type;
- Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
- Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
- Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _FileAnalyticSolution_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _FileAnalyticSolution_AssignFromXML;
- Stg_Component_BuildFunction* _build = _AnalyticSolution_Build;
- Stg_Component_InitialiseFunction* _initialise = _FileAnalyticSolution_Initialise;
- Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
- Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
-}
-
-/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
-Index StgFEM_FileAnalyticSolution_Register( PluginsManager* pluginsManager ) {
- /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
- return PluginsManager_Submit( pluginsManager, FileAnalyticSolution_Type, (Name)"0", _FileAnalyticSolution_DefaultNew );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/FileAnalyticSolution/FileAnalyticSolution.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/FileAnalyticSolution/FileAnalyticSolution.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,133 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: FileAnalyticSolution.c 989 2007-12-18 13:57:56Z JulianGiordani $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+/* This is taken from Mirko Velic's Analytic Stokes Flow solution */
+
+const Type FileAnalyticSolution_Type = "FileAnalyticSolution";
+
+typedef struct {
+ __AnalyticSolution
+ char* referencePath;
+} FileAnalyticSolution;
+
+void FileAnalyticSolution_DummyFunction( void* analyticSolution, FeVariable* analyticFeVariable, double* coord, double* value ) {
+ abort();
+}
+
+
+
+void _FileAnalyticSolution_AssignFromXML( void* analyticSolution, Stg_ComponentFactory* cf, void* data ) {
+ FileAnalyticSolution * self = (FileAnalyticSolution*)analyticSolution;
+ Dictionary_Entry_Value* varList;
+ Index var_I;
+ char* varName;
+ FeVariable* feVarToTest;
+
+ _AnalyticSolution_AssignFromXML( self, cf, data );
+ varList = Dictionary_Get( cf->rootDict, (Dictionary_Entry_Key)self->name );
+ Journal_Firewall( varList != NULL, Journal_Register( Error_Type, (Name)self->type ),
+ "Error- in %s(): Can't find list in XML '%s'\n", __func__, self->name );
+
+ for ( var_I = 0; var_I < Dictionary_Entry_Value_GetCount( varList ); ++var_I ) {
+ varName = Dictionary_Entry_Value_AsString( Dictionary_Entry_Value_GetElement( varList, var_I ) );
+ feVarToTest = Stg_ComponentFactory_ConstructByName( cf, (Name)varName, FeVariable, True, data );
+
+ AnalyticSolution_RegisterFeVariableWithAnalyticFunction( self, feVarToTest, FileAnalyticSolution_DummyFunction );
+ }
+
+
+ /* Get reference path */
+ self->referencePath = Dictionary_GetString_WithDefault( cf->rootDict, "referencePath", "./expected/" );
+}
+
+void _FileAnalyticSolution_Initialise( void* analyticSolution, void* data ) {
+ FileAnalyticSolution *self = (FileAnalyticSolution*)analyticSolution;
+ FeVariable* analyticFeVariable;
+ Index analyticFeVariableCount = Stg_ObjectList_Count( self->analyticFeVariableList );
+ Index analyticFeVariable_I;
+
+
+ assert( analyticFeVariableCount == Stg_ObjectList_Count( self->analyticFeVariableFuncList ) );
+
+ /* Assign values to all analytic fields */
+ for ( analyticFeVariable_I = 0 ; analyticFeVariable_I < analyticFeVariableCount ; analyticFeVariable_I++ ) {
+ Stg_Component_Initialise( Stg_ObjectList_At( self->feVariableList, analyticFeVariable_I ), data, False ) ;
+ Stg_Component_Initialise( Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I ), data, False ) ;
+ Stg_Component_Initialise( Stg_ObjectList_At( self->errorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
+ Stg_Component_Initialise( Stg_ObjectList_At( self->relativeErrorMagnitudeFieldList, analyticFeVariable_I ), data, False ) ;
+
+ /* Initialise values from file */
+ analyticFeVariable = (FeVariable*) Stg_ObjectList_At( self->analyticFeVariableList, analyticFeVariable_I );
+ FeVariable_ReadFromFile( analyticFeVariable, self->referencePath, 0 );
+ }
+}
+
+void* _FileAnalyticSolution_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(FileAnalyticSolution);
+ Type type = FileAnalyticSolution_Type;
+ Stg_Class_DeleteFunction* _delete = _AnalyticSolution_Delete;
+ Stg_Class_PrintFunction* _print = _AnalyticSolution_Print;
+ Stg_Class_CopyFunction* _copy = _AnalyticSolution_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _FileAnalyticSolution_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _FileAnalyticSolution_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _AnalyticSolution_Build;
+ Stg_Component_InitialiseFunction* _initialise = _FileAnalyticSolution_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _AnalyticSolution_Execute;
+ Stg_Component_DestroyFunction* _destroy = _AnalyticSolution_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return (void*) _AnalyticSolution_New( ANALYTICSOLUTION_PASSARGS );
+}
+
+/* This function is automatically run by StGermain when this plugin is loaded. The name must be "<plugin-name>_Register". */
+Index StgFEM_FileAnalyticSolution_Register( PluginsManager* pluginsManager ) {
+ /* A plugin is only properly registered once it returns the handle provided when submitting a codelet to StGermain. */
+ return PluginsManager_Submit( pluginsManager, FileAnalyticSolution_Type, (Name)"0", _FileAnalyticSolution_DefaultNew );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Multigrid/Multigrid.c
--- a/plugins/Multigrid/Multigrid.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd,
-** 110 Victoria Street, Melbourne, 3053, Australia.
-**
-** Authors:
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Multigrid.c 2192 2004-10-15 02:45:38Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <mpi.h>
-#include <petsc.h>
-#include <petscvec.h>
-#include <petscmat.h>
-#include <petscksp.h>
-#include <petscsnes.h>
-
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-
-#include "Multigrid.h"
-
-
-const Type StgFEM_Multigrid_Type = "StgFEM_Multigrid";
-StgFEM_Multigrid* StgFEM_Multigrid_selfPointer = NULL;
-
-
-void StgFEM_Multigrid_SolverSetup( void* _solver, void* _stokesSLE ) {
- StgFEM_Multigrid* self = StgFEM_Multigrid_selfPointer;
- Stokes_SLE_UzawaSolver* solver = (Stokes_SLE_UzawaSolver*)_solver;
- Stokes_SLE* sle = (Stokes_SLE*)_stokesSLE;
-
- Journal_DPrintf( solver->debug, "In %s:\n", __func__ );
- Stream_IndentBranch( StgFEM_Debug );
-
- Journal_DPrintfL( solver->debug, 1, "Setting up MatrixSolver for the velocity eqn.\n" );
- self->mgSolver->mgData->matrixChanged = True;
- //MatrixSolver_SetMatrix( self->velSolver, sle->kStiffMat->matrix );
- //KSPSetOperators( self->velSolver, ((PETScMatrix*)sle->kStiffMat->matrix)->petscMat,
- // ((PETScMatrix*)sle->kStiffMat->matrix)->petscMat, DIFFERENT_NONZERO_PATTERN );
-
- self->mgSolver->mgData->matrix = sle->kStiffMat->matrix;
- PETScMGSolver_Setup( self->mgSolver, NULL, NULL );
- solver->velSolver = self->mgSolver->mgData->ksp;
- KSPSetOperators( solver->velSolver, sle->kStiffMat->matrix, sle->kStiffMat->matrix, DIFFERENT_NONZERO_PATTERN );
-/*
- KSPSetOperators( solver->velSolver, sle->kStiffMat->matrix, sle->kStiffMat->matrix, DIFFERENT_NONZERO_PATTERN );
- KSPSetFromOptions( solver->velSolver );
-*/
-
- if( solver->pcSolver ) {
- Journal_DPrintfL( solver->debug, 1, "Setting up MatrixSolver for the Preconditioner.\n" );
- //MatrixSolver_SetMatrix( self->pcSolver, self->preconditioner->matrix );
- //KSPSetOperators( self->pcSolver, ((PETScMatrix*)self->preconditioner->matrix)->petscMat,
- // ((PETScMatrix*)self->preconditioner->matrix)->petscMat, DIFFERENT_NONZERO_PATTERN );
- KSPSetOperators( solver->pcSolver, solver->preconditioner->matrix, solver->preconditioner->matrix, DIFFERENT_NONZERO_PATTERN );
- KSPSetFromOptions( solver->pcSolver );
- }
-
- Stream_UnIndentBranch( StgFEM_Debug );
-}
-
-
-void StgFEM_Multigrid_AssignFromXML( void* _self, Stg_ComponentFactory* cf, void* data ) {
- StgFEM_Multigrid* self = (StgFEM_Multigrid*)_self;
-
- StgFEM_Multigrid_selfPointer = self;
-
- self->sle = Stg_ComponentFactory_ConstructByName( cf, (Name)"stokesEqn", Stokes_SLE, True, data );
- self->mgSolver = Stg_ComponentFactory_ConstructByName( cf, (Name)"mgSolver", PETScMGSolver, True, data );
-
- /* Replace the setup routine... hacky. */
- self->sle->solver->_solverSetup = StgFEM_Multigrid_SolverSetup;
-
-}
-
-void StgFEM_Multigrid_Build( void* _self, void* data ) {
- StgFEM_Multigrid* self = (StgFEM_Multigrid*)_self;
-
- Stg_Component_Build( self->mgSolver, data, False );
- Stg_Component_Build( self->sle, data, False );
-}
-
-void StgFEM_Multigrid_Initialise( void* _self, void* data ) {
- StgFEM_Multigrid* self = (StgFEM_Multigrid*)_self;
-
- Stg_Component_Initialise( self->mgSolver, data, False );
- Stg_Component_Initialise( self->sle, data, False );
-
- /* Setup the MG solver. */
- PETScMGSolver_SetComm( self->mgSolver, MPI_COMM_WORLD );
-}
-
-void* StgFEM_Multigrid_New( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(StgFEM_Multigrid);
- Type type = StgFEM_Multigrid_Type;
- Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
- Stg_Class_PrintFunction* _print = _Codelet_Print;
- Stg_Class_CopyFunction* _copy = _Codelet_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = StgFEM_Multigrid_New;
- Stg_Component_ConstructFunction* _construct = StgFEM_Multigrid_AssignFromXML;
- Stg_Component_BuildFunction* _build = StgFEM_Multigrid_Build;
- Stg_Component_InitialiseFunction* _initialise = StgFEM_Multigrid_Initialise;
- Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
- Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _Codelet_New( CODELET_PASSARGS );
-}
-
-Index StgFEM_Multigrid_Register( PluginsManager* mgr ) {
- return PluginsManager_Submit( mgr, StgFEM_Multigrid_Type, (Name)"0", StgFEM_Multigrid_New );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Multigrid/Multigrid.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/Multigrid/Multigrid.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,143 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003, Victorian Partnership for Advanced Computing (VPAC) Ltd,
+** 110 Victoria Street, Melbourne, 3053, Australia.
+**
+** Authors:
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Siew-Ching Tan, Software Engineer, VPAC. (siew at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Multigrid.c 2192 2004-10-15 02:45:38Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <mpi.h>
+#include <petsc.h>
+#include <petscvec.h>
+#include <petscmat.h>
+#include <petscksp.h>
+#include <petscsnes.h>
+
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+
+#include "Multigrid.h"
+
+
+const Type StgFEM_Multigrid_Type = "StgFEM_Multigrid";
+StgFEM_Multigrid* StgFEM_Multigrid_selfPointer = NULL;
+
+
+void StgFEM_Multigrid_SolverSetup( void* _solver, void* _stokesSLE ) {
+ StgFEM_Multigrid* self = StgFEM_Multigrid_selfPointer;
+ Stokes_SLE_UzawaSolver* solver = (Stokes_SLE_UzawaSolver*)_solver;
+ Stokes_SLE* sle = (Stokes_SLE*)_stokesSLE;
+
+ Journal_DPrintf( solver->debug, "In %s:\n", __func__ );
+ Stream_IndentBranch( StgFEM_Debug );
+
+ Journal_DPrintfL( solver->debug, 1, "Setting up MatrixSolver for the velocity eqn.\n" );
+ self->mgSolver->mgData->matrixChanged = True;
+ //MatrixSolver_SetMatrix( self->velSolver, sle->kStiffMat->matrix );
+ //KSPSetOperators( self->velSolver, ((PETScMatrix*)sle->kStiffMat->matrix)->petscMat,
+ // ((PETScMatrix*)sle->kStiffMat->matrix)->petscMat, DIFFERENT_NONZERO_PATTERN );
+
+ self->mgSolver->mgData->matrix = sle->kStiffMat->matrix;
+ PETScMGSolver_Setup( self->mgSolver, NULL, NULL );
+ solver->velSolver = self->mgSolver->mgData->ksp;
+ KSPSetOperators( solver->velSolver, sle->kStiffMat->matrix, sle->kStiffMat->matrix, DIFFERENT_NONZERO_PATTERN );
+/*
+ KSPSetOperators( solver->velSolver, sle->kStiffMat->matrix, sle->kStiffMat->matrix, DIFFERENT_NONZERO_PATTERN );
+ KSPSetFromOptions( solver->velSolver );
+*/
+
+ if( solver->pcSolver ) {
+ Journal_DPrintfL( solver->debug, 1, "Setting up MatrixSolver for the Preconditioner.\n" );
+ //MatrixSolver_SetMatrix( self->pcSolver, self->preconditioner->matrix );
+ //KSPSetOperators( self->pcSolver, ((PETScMatrix*)self->preconditioner->matrix)->petscMat,
+ // ((PETScMatrix*)self->preconditioner->matrix)->petscMat, DIFFERENT_NONZERO_PATTERN );
+ KSPSetOperators( solver->pcSolver, solver->preconditioner->matrix, solver->preconditioner->matrix, DIFFERENT_NONZERO_PATTERN );
+ KSPSetFromOptions( solver->pcSolver );
+ }
+
+ Stream_UnIndentBranch( StgFEM_Debug );
+}
+
+
+void StgFEM_Multigrid_AssignFromXML( void* _self, Stg_ComponentFactory* cf, void* data ) {
+ StgFEM_Multigrid* self = (StgFEM_Multigrid*)_self;
+
+ StgFEM_Multigrid_selfPointer = self;
+
+ self->sle = Stg_ComponentFactory_ConstructByName( cf, (Name)"stokesEqn", Stokes_SLE, True, data );
+ self->mgSolver = Stg_ComponentFactory_ConstructByName( cf, (Name)"mgSolver", PETScMGSolver, True, data );
+
+ /* Replace the setup routine... hacky. */
+ self->sle->solver->_solverSetup = StgFEM_Multigrid_SolverSetup;
+
+}
+
+void StgFEM_Multigrid_Build( void* _self, void* data ) {
+ StgFEM_Multigrid* self = (StgFEM_Multigrid*)_self;
+
+ Stg_Component_Build( self->mgSolver, data, False );
+ Stg_Component_Build( self->sle, data, False );
+}
+
+void StgFEM_Multigrid_Initialise( void* _self, void* data ) {
+ StgFEM_Multigrid* self = (StgFEM_Multigrid*)_self;
+
+ Stg_Component_Initialise( self->mgSolver, data, False );
+ Stg_Component_Initialise( self->sle, data, False );
+
+ /* Setup the MG solver. */
+ PETScMGSolver_SetComm( self->mgSolver, MPI_COMM_WORLD );
+}
+
+void* StgFEM_Multigrid_New( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(StgFEM_Multigrid);
+ Type type = StgFEM_Multigrid_Type;
+ Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
+ Stg_Class_PrintFunction* _print = _Codelet_Print;
+ Stg_Class_CopyFunction* _copy = _Codelet_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = StgFEM_Multigrid_New;
+ Stg_Component_ConstructFunction* _construct = StgFEM_Multigrid_AssignFromXML;
+ Stg_Component_BuildFunction* _build = StgFEM_Multigrid_Build;
+ Stg_Component_InitialiseFunction* _initialise = StgFEM_Multigrid_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
+ Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _Codelet_New( CODELET_PASSARGS );
+}
+
+Index StgFEM_Multigrid_Register( PluginsManager* mgr ) {
+ return PluginsManager_Submit( mgr, StgFEM_Multigrid_Type, (Name)"0", StgFEM_Multigrid_New );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/CPUTime/CPUTime.c
--- a/plugins/Output/CPUTime/CPUTime.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: CPUTime.c 1107 2008-04-16 01:54:15Z BelindaMay $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/FrequentOutput/FrequentOutput.h>
-
-#include "CPUTime.h"
-
-const Type StgFEM_CPUTime_Type = "StgFEM_CPUTime";
-
-void StgFEM_CPUTime_PrintTimeInfo( AbstractContext* context ) {
- StgFEM_CPUTime* self = (StgFEM_CPUTime*)LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_CPUTime_Type );
-
- /* Print Current Time Taken */
- StgFEM_FrequentOutput_PrintValue( context, MPI_Wtime() - self->initialTime );
-}
-
-void _StgFEM_CPUTime_AssignFromXML( void* componment, Stg_ComponentFactory* cf, void* data ) {
- StgFEM_CPUTime* self = (StgFEM_CPUTime*)componment;
- Dictionary* pluginDict = Codelet_GetPluginDictionary( self, cf->rootDict );
-
- self->context = Stg_ComponentFactory_ConstructByName( cf, Dictionary_GetString( pluginDict, (Dictionary_Entry_Key)"Context" ), AbstractContext, True, data );
- if( !self->context )
- self->context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
-
- /* Initialise Timer */
- self->initialTime = MPI_Wtime( );
-
- /* Print Header to file */
- StgFEM_FrequentOutput_PrintString( self->context, "CPU_Time" );
-
- ContextEP_Append( self->context, AbstractContext_EP_FrequentOutput ,StgFEM_CPUTime_PrintTimeInfo );
-}
-
-void* _StgFEM_CPUTime_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof( StgFEM_CPUTime );
- Type type = StgFEM_CPUTime_Type;
- Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
- Stg_Class_PrintFunction* _print = _Codelet_Print;
- Stg_Class_CopyFunction* _copy = _Codelet_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_CPUTime_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _StgFEM_CPUTime_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Codelet_Build;
- Stg_Component_InitialiseFunction* _initialise = _Codelet_Initialise;
- Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
- Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _Codelet_New( CODELET_PASSARGS );
-}
-
-Index StgFEM_CPUTime_Register( PluginsManager* pluginsManager ) {
- return PluginsManager_Submit( pluginsManager, StgFEM_CPUTime_Type, (Name)"0", _StgFEM_CPUTime_DefaultNew );
-}
-
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/CPUTime/CPUTime.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/Output/CPUTime/CPUTime.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,101 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: CPUTime.c 1107 2008-04-16 01:54:15Z BelindaMay $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/FrequentOutput/FrequentOutput.h>
+
+#include "CPUTime.h"
+
+const Type StgFEM_CPUTime_Type = "StgFEM_CPUTime";
+
+void StgFEM_CPUTime_PrintTimeInfo( AbstractContext* context ) {
+ StgFEM_CPUTime* self = (StgFEM_CPUTime*)LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_CPUTime_Type );
+
+ /* Print Current Time Taken */
+ StgFEM_FrequentOutput_PrintValue( context, MPI_Wtime() - self->initialTime );
+}
+
+void _StgFEM_CPUTime_AssignFromXML( void* componment, Stg_ComponentFactory* cf, void* data ) {
+ StgFEM_CPUTime* self = (StgFEM_CPUTime*)componment;
+ Dictionary* pluginDict = Codelet_GetPluginDictionary( self, cf->rootDict );
+
+ self->context = Stg_ComponentFactory_ConstructByName( cf, Dictionary_GetString( pluginDict, (Dictionary_Entry_Key)"Context" ), AbstractContext, True, data );
+ if( !self->context )
+ self->context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+
+ /* Initialise Timer */
+ self->initialTime = MPI_Wtime( );
+
+ /* Print Header to file */
+ StgFEM_FrequentOutput_PrintString( self->context, "CPU_Time" );
+
+ ContextEP_Append( self->context, AbstractContext_EP_FrequentOutput ,StgFEM_CPUTime_PrintTimeInfo );
+}
+
+void* _StgFEM_CPUTime_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof( StgFEM_CPUTime );
+ Type type = StgFEM_CPUTime_Type;
+ Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
+ Stg_Class_PrintFunction* _print = _Codelet_Print;
+ Stg_Class_CopyFunction* _copy = _Codelet_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_CPUTime_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _StgFEM_CPUTime_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Codelet_Build;
+ Stg_Component_InitialiseFunction* _initialise = _Codelet_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
+ Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _Codelet_New( CODELET_PASSARGS );
+}
+
+Index StgFEM_CPUTime_Register( PluginsManager* pluginsManager ) {
+ return PluginsManager_Submit( pluginsManager, StgFEM_CPUTime_Type, (Name)"0", _StgFEM_CPUTime_DefaultNew );
+}
+
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/CPUTimeAndNumberOfIterationsForInnerAndOuterSolve/CPUTimeAndNumberOfIterationsForInnerAndOuterSolve.c
--- a/plugins/Output/CPUTimeAndNumberOfIterationsForInnerAndOuterSolve/CPUTimeAndNumberOfIterationsForInnerAndOuterSolve.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: CPUTimeAndNumberOfIterationsForInnerAndOuterSolve.c 1107 2008-04-16 01:54:15Z BelindaMay $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/FrequentOutput/FrequentOutput.h>
-#include "CPUTimeAndNumberOfIterationsForInnerAndOuterSolve.h"
-#include "StgFEM/Discretisation/Discretisation.h"
-#include "../../../SLE/SystemSetup/src/SystemSetup.h"
-#include "../../../SLE/ProvidedSystems/StokesFlow/src/StokesFlow.h"
-//#include "../../../SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_UzawaSolve.h"
-
-
-const Type StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Type = "StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve";
-
-void StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_PrintTimeInfo( AbstractContext* context ) {
- StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve* self;
- Stokes_SLE* sle = (Stokes_SLE*) LiveComponentRegister_Get( context->CF->LCRegister, (Name)"stokesEqn");
- SLE_Solver* solver = (SLE_Solver* ) LiveComponentRegister_Get( context->CF->LCRegister, (Name)"uzawa");
-
- self = (StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve* )LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Type );
-
- /* Print Current Average InnerIteration Time Taken */
- StgFEM_FrequentOutput_PrintValue( context, solver->avgtimeinnerits);
- /* Print Current Average OuterIteration Time Taken */
- StgFEM_FrequentOutput_PrintValue( context, solver->avgtimeouterits);
- /* Print Current Average NonLinearIteration Time Taken */
- if(sle->isNonLinear == True){
- StgFEM_FrequentOutput_PrintValue( context, solver->avgtimenonlinearits);
- }
- /* Print Average Number of Inner Iterations*/
- StgFEM_FrequentOutput_PrintValue( context, solver->avgnuminnerits);
- /* Print Number of Outer Iterations */
- StgFEM_FrequentOutput_PrintValue( context, solver->avgnumouterits);
- /* Print Number of NonLinear Iterations*/
- if(sle->isNonLinear == True){
- StgFEM_FrequentOutput_PrintValue( context, solver->totalnumnonlinearits);
- }
-}
-
-void _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
- StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve* self = (StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve*)component;
- AbstractContext* context;
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
- self->context = context;
-
- ContextEP_Append( context, AbstractContext_EP_FrequentOutput ,StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_PrintTimeInfo );
-}
-
-void _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Initialise( void* component, void* data ) {
- StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve* self = (StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve*)component;
- Stokes_SLE* sle = (Stokes_SLE*) LiveComponentRegister_Get( self->context->CF->LCRegister, (Name)"stokesEqn" );
-
- /*this isn't set to true before the initialise phase*/
-
- /* Print Header to file */
- StgFEM_FrequentOutput_PrintString( self->context, "AvgCPUInner" );
- StgFEM_FrequentOutput_PrintString( self->context, "AvgCPUOuter" );
- if(sle->isNonLinear == True){
- StgFEM_FrequentOutput_PrintString( self->context, "AvgCPUNonLin" );
- }
- StgFEM_FrequentOutput_PrintString( self->context, "AvgInIts" );
- StgFEM_FrequentOutput_PrintString( self->context, "AvgOutIts" );
- if(sle->isNonLinear == True){
- StgFEM_FrequentOutput_PrintString( self->context, "NonLinIts" );
- }
-}
-
-void* _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_DefaultNew( Name name ) {
- SizeT _sizeOfSelf = sizeof( StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve );
- Type type = StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Type;
- Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
- Stg_Class_PrintFunction* _print = _Codelet_Print;
- Stg_Class_CopyFunction* _copy = _Codelet_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Codelet_Build;
- Stg_Component_InitialiseFunction* _initialise = _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Initialise;
- Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
- Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _Codelet_New( CODELET_PASSARGS );
-}
-
-Index StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Register( PluginsManager* pluginsManager ) {
- return PluginsManager_Submit( pluginsManager, StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Type, (Name)"0", _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_DefaultNew );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/CPUTimeAndNumberOfIterationsForInnerAndOuterSolve/CPUTimeAndNumberOfIterationsForInnerAndOuterSolve.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/Output/CPUTimeAndNumberOfIterationsForInnerAndOuterSolve/CPUTimeAndNumberOfIterationsForInnerAndOuterSolve.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,129 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: CPUTimeAndNumberOfIterationsForInnerAndOuterSolve.c 1107 2008-04-16 01:54:15Z BelindaMay $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/FrequentOutput/FrequentOutput.h>
+#include "CPUTimeAndNumberOfIterationsForInnerAndOuterSolve.h"
+#include "StgFEM/Discretisation/Discretisation.h"
+#include "../../../SLE/SystemSetup/src/SystemSetup.h"
+#include "../../../SLE/ProvidedSystems/StokesFlow/src/StokesFlow.h"
+//#include "../../../SLE/ProvidedSystems/StokesFlow/src/Stokes_SLE_UzawaSolve.h"
+
+
+const Type StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Type = "StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve";
+
+void StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_PrintTimeInfo( AbstractContext* context ) {
+ StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve* self;
+ Stokes_SLE* sle = (Stokes_SLE*) LiveComponentRegister_Get( context->CF->LCRegister, (Name)"stokesEqn");
+ SLE_Solver* solver = (SLE_Solver* ) LiveComponentRegister_Get( context->CF->LCRegister, (Name)"uzawa");
+
+ self = (StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve* )LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Type );
+
+ /* Print Current Average InnerIteration Time Taken */
+ StgFEM_FrequentOutput_PrintValue( context, solver->avgtimeinnerits);
+ /* Print Current Average OuterIteration Time Taken */
+ StgFEM_FrequentOutput_PrintValue( context, solver->avgtimeouterits);
+ /* Print Current Average NonLinearIteration Time Taken */
+ if(sle->isNonLinear == True){
+ StgFEM_FrequentOutput_PrintValue( context, solver->avgtimenonlinearits);
+ }
+ /* Print Average Number of Inner Iterations*/
+ StgFEM_FrequentOutput_PrintValue( context, solver->avgnuminnerits);
+ /* Print Number of Outer Iterations */
+ StgFEM_FrequentOutput_PrintValue( context, solver->avgnumouterits);
+ /* Print Number of NonLinear Iterations*/
+ if(sle->isNonLinear == True){
+ StgFEM_FrequentOutput_PrintValue( context, solver->totalnumnonlinearits);
+ }
+}
+
+void _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
+ StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve* self = (StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve*)component;
+ AbstractContext* context;
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+ self->context = context;
+
+ ContextEP_Append( context, AbstractContext_EP_FrequentOutput ,StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_PrintTimeInfo );
+}
+
+void _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Initialise( void* component, void* data ) {
+ StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve* self = (StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve*)component;
+ Stokes_SLE* sle = (Stokes_SLE*) LiveComponentRegister_Get( self->context->CF->LCRegister, (Name)"stokesEqn" );
+
+ /*this isn't set to true before the initialise phase*/
+
+ /* Print Header to file */
+ StgFEM_FrequentOutput_PrintString( self->context, "AvgCPUInner" );
+ StgFEM_FrequentOutput_PrintString( self->context, "AvgCPUOuter" );
+ if(sle->isNonLinear == True){
+ StgFEM_FrequentOutput_PrintString( self->context, "AvgCPUNonLin" );
+ }
+ StgFEM_FrequentOutput_PrintString( self->context, "AvgInIts" );
+ StgFEM_FrequentOutput_PrintString( self->context, "AvgOutIts" );
+ if(sle->isNonLinear == True){
+ StgFEM_FrequentOutput_PrintString( self->context, "NonLinIts" );
+ }
+}
+
+void* _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_DefaultNew( Name name ) {
+ SizeT _sizeOfSelf = sizeof( StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve );
+ Type type = StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Type;
+ Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
+ Stg_Class_PrintFunction* _print = _Codelet_Print;
+ Stg_Class_CopyFunction* _copy = _Codelet_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Codelet_Build;
+ Stg_Component_InitialiseFunction* _initialise = _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
+ Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _Codelet_New( CODELET_PASSARGS );
+}
+
+Index StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Register( PluginsManager* pluginsManager ) {
+ return PluginsManager_Submit( pluginsManager, StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_Type, (Name)"0", _StgFEM_CPUTimeAndNumberOfIterationsForInnerAndOuterSolve_DefaultNew );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/FeVariableList/FeVariableList.c
--- a/plugins/Output/FeVariableList/FeVariableList.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-#include <string.h>
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "FeVariableList.h"
-
-#ifndef MASTER
- #define MASTER 0
-#endif
-
-const Type StgFEM_FeVariableList_Type = "StgFEM_FeVariableList";
-
-void _StgFEM_FeVariableList_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
- StgFEM_FeVariableList* self = (StgFEM_FeVariableList*) component;
- AbstractContext* context;
- Dictionary* dictionary;
- Stream* stream;
- Name fevariableListFilename;
- Bool fileOpened;
- Bool PrintToFile;
-
- self->context = context = (AbstractContext*)Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
- dictionary = context->dictionary;
-
- /* Create Stream */
- stream = self->stream = Journal_Register( InfoStream_Type, (Name)"FeVariableList" );
-
- /* Set auto flush on stream */
- Stream_SetAutoFlush( stream, True );
-
- /* Print to screen or to file? */
- PrintToFile = Dictionary_GetBool_WithDefault( dictionary, (Dictionary_Entry_Key)"FeVariableListPrintToFile", True );
- if(PrintToFile ){
- /* Get name of fevariable list file */
- fevariableListFilename = Dictionary_GetString_WithDefault( dictionary, "FeVariableListFilename", "FeVariables.list" );
- /* Open New File */
- if ( context->rank == MASTER ) {
- Stream* errorStream = Journal_Register( Error_Type, (Name)CURR_MODULE_NAME );
- fileOpened = Stream_RedirectFile_WithPrependedPath( stream, context->outputPath, fevariableListFilename );
- Journal_Firewall( fileOpened, errorStream,
- "Could not open file %s/%s. Possibly directory %s does not exist or is not writable.\n"
- "Check 'outputPath' in input file.\n", context->outputPath, fevariableListFilename, context->outputPath );
- }
- /* Set it so only master processor can print to stream */
- Stream_SetPrintingRank( stream, MASTER );
- }
-}
-
-void* _StgFEM_FeVariableList_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(StgFEM_FeVariableList);
- Type type = StgFEM_FeVariableList_Type;
- Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
- Stg_Class_PrintFunction* _print = _Codelet_Print;
- Stg_Class_CopyFunction* _copy = _Codelet_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_FeVariableList_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _StgFEM_FeVariableList_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Codelet_Build;
- Stg_Component_InitialiseFunction* _initialise = StgFEM_FeVariableList_PrintVariables;
- Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
- Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _Codelet_New( CODELET_PASSARGS );
-}
-
-Index StgFEM_FeVariableList_Register( PluginsManager* pluginsManager ) {
- return PluginsManager_Submit( pluginsManager, StgFEM_FeVariableList_Type, (Name)"0", _StgFEM_FeVariableList_DefaultNew );
-}
-
-void StgFEM_FeVariableList_PrintVariables( void* _self, void* data ){
- StgFEM_FeVariableList* self = (StgFEM_FeVariableList*) _self;
- DomainContext* context = (DomainContext*)self->context;
- Stream* stream = self->stream;;
- FieldVariable_Register* fV_Register;
- Index variablecount;
- Index countindex;
- Index columnWidth1 = 70;
- Index columnWidth2 = 30;
-
- /* Get FeVariable Register*/
- fV_Register = context->fieldVariable_Register;
- variablecount = (Index) fV_Register->objects->count;
-
- /* Print header material */
- Journal_Printf( stream, "\n");
- Journal_PrintString_WithLength( stream, "FeVariable", columnWidth1 );
- Journal_PrintString_WithLength( stream, "FeVariableType", columnWidth2 );
- Journal_Printf( stream, "\n");
- Journal_PrintString_WithLength( stream, "------------------------", columnWidth1 );
- Journal_PrintString_WithLength( stream, "------------------------", columnWidth2 );
- Journal_Printf( stream, "\n");
-
- /* Print Variables */
- for(countindex = 1; countindex <= variablecount; ++countindex){
- Journal_PrintString_WithLength( stream, fV_Register->objects->data[ countindex - 1 ]->name, columnWidth1 );
- Journal_PrintString_WithLength( stream, fV_Register->objects->data[ countindex - 1 ]->type, columnWidth2 );
- Journal_Printf( stream, "\n");
- }
- Journal_Printf( stream, "\n");
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/FeVariableList/FeVariableList.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/Output/FeVariableList/FeVariableList.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,145 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+#include <string.h>
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "FeVariableList.h"
+
+#ifndef MASTER
+ #define MASTER 0
+#endif
+
+const Type StgFEM_FeVariableList_Type = "StgFEM_FeVariableList";
+
+void _StgFEM_FeVariableList_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
+ StgFEM_FeVariableList* self = (StgFEM_FeVariableList*) component;
+ AbstractContext* context;
+ Dictionary* dictionary;
+ Stream* stream;
+ Name fevariableListFilename;
+ Bool fileOpened;
+ Bool PrintToFile;
+
+ self->context = context = (AbstractContext*)Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+ dictionary = context->dictionary;
+
+ /* Create Stream */
+ stream = self->stream = Journal_Register( InfoStream_Type, (Name)"FeVariableList" );
+
+ /* Set auto flush on stream */
+ Stream_SetAutoFlush( stream, True );
+
+ /* Print to screen or to file? */
+ PrintToFile = Dictionary_GetBool_WithDefault( dictionary, (Dictionary_Entry_Key)"FeVariableListPrintToFile", True );
+ if(PrintToFile ){
+ /* Get name of fevariable list file */
+ fevariableListFilename = Dictionary_GetString_WithDefault( dictionary, "FeVariableListFilename", "FeVariables.list" );
+ /* Open New File */
+ if ( context->rank == MASTER ) {
+ Stream* errorStream = Journal_Register( Error_Type, (Name)CURR_MODULE_NAME );
+ fileOpened = Stream_RedirectFile_WithPrependedPath( stream, context->outputPath, fevariableListFilename );
+ Journal_Firewall( fileOpened, errorStream,
+ "Could not open file %s/%s. Possibly directory %s does not exist or is not writable.\n"
+ "Check 'outputPath' in input file.\n", context->outputPath, fevariableListFilename, context->outputPath );
+ }
+ /* Set it so only master processor can print to stream */
+ Stream_SetPrintingRank( stream, MASTER );
+ }
+}
+
+void* _StgFEM_FeVariableList_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(StgFEM_FeVariableList);
+ Type type = StgFEM_FeVariableList_Type;
+ Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
+ Stg_Class_PrintFunction* _print = _Codelet_Print;
+ Stg_Class_CopyFunction* _copy = _Codelet_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_FeVariableList_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _StgFEM_FeVariableList_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Codelet_Build;
+ Stg_Component_InitialiseFunction* _initialise = StgFEM_FeVariableList_PrintVariables;
+ Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
+ Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _Codelet_New( CODELET_PASSARGS );
+}
+
+Index StgFEM_FeVariableList_Register( PluginsManager* pluginsManager ) {
+ return PluginsManager_Submit( pluginsManager, StgFEM_FeVariableList_Type, (Name)"0", _StgFEM_FeVariableList_DefaultNew );
+}
+
+void StgFEM_FeVariableList_PrintVariables( void* _self, void* data ){
+ StgFEM_FeVariableList* self = (StgFEM_FeVariableList*) _self;
+ DomainContext* context = (DomainContext*)self->context;
+ Stream* stream = self->stream;;
+ FieldVariable_Register* fV_Register;
+ Index variablecount;
+ Index countindex;
+ Index columnWidth1 = 70;
+ Index columnWidth2 = 30;
+
+ /* Get FeVariable Register*/
+ fV_Register = context->fieldVariable_Register;
+ variablecount = (Index) fV_Register->objects->count;
+
+ /* Print header material */
+ Journal_Printf( stream, "\n");
+ Journal_PrintString_WithLength( stream, "FeVariable", columnWidth1 );
+ Journal_PrintString_WithLength( stream, "FeVariableType", columnWidth2 );
+ Journal_Printf( stream, "\n");
+ Journal_PrintString_WithLength( stream, "------------------------", columnWidth1 );
+ Journal_PrintString_WithLength( stream, "------------------------", columnWidth2 );
+ Journal_Printf( stream, "\n");
+
+ /* Print Variables */
+ for(countindex = 1; countindex <= variablecount; ++countindex){
+ Journal_PrintString_WithLength( stream, fV_Register->objects->data[ countindex - 1 ]->name, columnWidth1 );
+ Journal_PrintString_WithLength( stream, fV_Register->objects->data[ countindex - 1 ]->type, columnWidth2 );
+ Journal_Printf( stream, "\n");
+ }
+ Journal_Printf( stream, "\n");
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/FrequentOutput/FrequentOutput.c
--- a/plugins/Output/FrequentOutput/FrequentOutput.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,201 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: FrequentOutput.c 1219 2008-09-04 23:09:02Z JohnMansour $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-#include <string.h>
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "FrequentOutput.h"
-
-#ifndef MASTER
- #define MASTER 0
-#endif
-
-const Type StgFEM_FrequentOutput_Type = "StgFEM_FrequentOutput";
-
-void _StgFEM_FrequentOutput_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
- StgFEM_FrequentOutput* self = (StgFEM_FrequentOutput*) component;
- AbstractContext* context;
- Dictionary* dictionary;
- Stream* stream;
- Name frequentOutputFilename;
- Bool fileOpened;
- Stream* errorStream = Journal_Register( Error_Type, (Name)CURR_MODULE_NAME );
- Dictionary* pluginDict = Codelet_GetPluginDictionary( self, cf->rootDict );
-
- context = Stg_ComponentFactory_ConstructByName( cf, Dictionary_GetString( pluginDict, (Dictionary_Entry_Key)"Context" ), AbstractContext, True, data );
- self->context = context;
- dictionary = context->dictionary;
-
- ContextEP_Append( context, AbstractContext_EP_Initialise, StgFEM_FrequentOutput_PrintNewLine );
- ContextEP_Prepend_AlwaysFirst( context, AbstractContext_EP_FrequentOutput, StgFEM_FrequentOutput_PrintTime );
- ContextEP_Append_AlwaysLast( context, AbstractContext_EP_FrequentOutput, StgFEM_FrequentOutput_PrintNewLine );
-
- /* Create Stream */
- stream = self->stream = Journal_Register( InfoStream_Type, (Name)"FrequentOutputFile" );
-
- /* Set auto flush on stream */
- Stream_SetAutoFlush( stream, True );
-
- /* Get name of frequent output file */
- frequentOutputFilename = Dictionary_GetString_WithDefault( dictionary, "FrequentOutputFilename", "FrequentOutput.dat" );
-
- /* Open File */
- if ( context->rank == MASTER ) {
- if ( (context->loadFromCheckPoint == False) && (Dictionary_GetBool_WithDefault( context->dictionary, (Dictionary_Entry_Key)"visualOnly", False ) == False ) ) {
- /* Always overwrite the file if starting a new run */
- fileOpened = Stream_RedirectFile_WithPrependedPath( stream, context->outputPath, frequentOutputFilename );
- }
- else {
- /* Just append to the file if doing a restart from checkpoint */
- fileOpened = Stream_AppendFile_WithPrependedPath( stream, context->outputPath, frequentOutputFilename );
- }
- Journal_Firewall( fileOpened, errorStream,
- "Could not open file %s/%s. Possibly directory %s does not exist or is not writable.\n"
- "Check 'outputPath' in input file.\n", context->outputPath, frequentOutputFilename, context->outputPath );
- }
-
- /* Set it so only master processor can print to stream */
- Stream_SetPrintingRank( stream, MASTER );
-
- /* Read in values from dictionary */
- self->columnWidth = Dictionary_GetUnsignedInt_WithDefault( dictionary, "FrequentOutputColumnWidth", 12 );
- self->decimalLength = Dictionary_GetUnsignedInt_WithDefault( dictionary, "FrequentOutputDecimalLength", 6 );
- self->borderString = Dictionary_GetString_WithDefault( dictionary, "FrequentOutputBorderString", " " );
-
- StgFEM_FrequentOutput_PrintHeader( context );
-}
-
-void* _StgFEM_FrequentOutput_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(StgFEM_FrequentOutput);
- Type type = StgFEM_FrequentOutput_Type;
- Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
- Stg_Class_PrintFunction* _print = _Codelet_Print;
- Stg_Class_CopyFunction* _copy = _Codelet_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_FrequentOutput_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _StgFEM_FrequentOutput_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Codelet_Build;
- Stg_Component_InitialiseFunction* _initialise = _Codelet_Initialise;
- Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
- Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _Codelet_New( CODELET_PASSARGS );
-}
-
-Index StgFEM_FrequentOutput_Register( PluginsManager* pluginsManager ) {
- return PluginsManager_Submit( pluginsManager, StgFEM_FrequentOutput_Type, (Name)"0", _StgFEM_FrequentOutput_DefaultNew );
-}
-
-void StgFEM_FrequentOutput_PrintString( void* _context, char* string ) {
- AbstractContext* context = (AbstractContext*) _context;
- Stream* stream;
-
- StgFEM_FrequentOutput* self = (StgFEM_FrequentOutput*)LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_FrequentOutput_Type );
- stream = self->stream;
-
- /* Print some empty space at start */
- Journal_Printf( stream, self->borderString );
-
- /* Print String - Truncated if nessesary */
- Journal_PrintString_WithLength( stream, string, self->columnWidth );
-}
-
-void StgFEM_FrequentOutput_PrintDouble( void* _context, double value ) {
- AbstractContext* context = (AbstractContext*) _context;
- char* formatString;
- Stream* stream;
-
- StgFEM_FrequentOutput* self = (StgFEM_FrequentOutput*)LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_FrequentOutput_Type );
-
- stream = self->stream;
-
- /* Create format String */
- Stg_asprintf( &formatString, "%%%d.%dg", self->columnWidth, self->decimalLength );
-
- Journal_Printf( self->stream, self->borderString );
- Journal_Printf( self->stream, formatString, value );
-
- Memory_Free( formatString );
-}
-
-void StgFEM_FrequentOutput_PrintHeader( void* _context ) {
- AbstractContext* context = (AbstractContext*) _context;
- char* firstBorderString;
- Stream* stream;
-
- StgFEM_FrequentOutput* self = (StgFEM_FrequentOutput*)LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_FrequentOutput_Type );
-
- stream = self->stream;
-
- /* Print First Boarder with '#' in the front */
- firstBorderString = StG_Strdup( self->borderString );
- firstBorderString[0] = '#';
- Journal_Printf( stream, firstBorderString );
- Memory_Free( firstBorderString );
-
- Journal_PrintString_WithLength( stream, "Timestep", self->columnWidth );
-
- StgFEM_FrequentOutput_PrintString( context, "Time" );
-}
-
-void StgFEM_FrequentOutput_PrintTime( void* _context ) {
- AbstractContext* context = (AbstractContext*) _context;
-
- StgFEM_FrequentOutput_PrintValue( context, context->timeStep );
- StgFEM_FrequentOutput_PrintValue( context, context->currentTime );
-}
-
-void StgFEM_FrequentOutput_PrintNewLine( void* _context ) {
- AbstractContext* context = (AbstractContext*) _context;
- Stream* stream;
-
- StgFEM_FrequentOutput* self = (StgFEM_FrequentOutput*)LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_FrequentOutput_Type );
-
- stream = self->stream;
-
- Journal_Printf( stream, "\n" );
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/FrequentOutput/FrequentOutput.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/Output/FrequentOutput/FrequentOutput.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,201 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: FrequentOutput.c 1219 2008-09-04 23:09:02Z JohnMansour $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+#include <string.h>
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "FrequentOutput.h"
+
+#ifndef MASTER
+ #define MASTER 0
+#endif
+
+const Type StgFEM_FrequentOutput_Type = "StgFEM_FrequentOutput";
+
+void _StgFEM_FrequentOutput_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
+ StgFEM_FrequentOutput* self = (StgFEM_FrequentOutput*) component;
+ AbstractContext* context;
+ Dictionary* dictionary;
+ Stream* stream;
+ Name frequentOutputFilename;
+ Bool fileOpened;
+ Stream* errorStream = Journal_Register( Error_Type, (Name)CURR_MODULE_NAME );
+ Dictionary* pluginDict = Codelet_GetPluginDictionary( self, cf->rootDict );
+
+ context = Stg_ComponentFactory_ConstructByName( cf, Dictionary_GetString( pluginDict, (Dictionary_Entry_Key)"Context" ), AbstractContext, True, data );
+ self->context = context;
+ dictionary = context->dictionary;
+
+ ContextEP_Append( context, AbstractContext_EP_Initialise, StgFEM_FrequentOutput_PrintNewLine );
+ ContextEP_Prepend_AlwaysFirst( context, AbstractContext_EP_FrequentOutput, StgFEM_FrequentOutput_PrintTime );
+ ContextEP_Append_AlwaysLast( context, AbstractContext_EP_FrequentOutput, StgFEM_FrequentOutput_PrintNewLine );
+
+ /* Create Stream */
+ stream = self->stream = Journal_Register( InfoStream_Type, (Name)"FrequentOutputFile" );
+
+ /* Set auto flush on stream */
+ Stream_SetAutoFlush( stream, True );
+
+ /* Get name of frequent output file */
+ frequentOutputFilename = Dictionary_GetString_WithDefault( dictionary, "FrequentOutputFilename", "FrequentOutput.dat" );
+
+ /* Open File */
+ if ( context->rank == MASTER ) {
+ if ( (context->loadFromCheckPoint == False) && (Dictionary_GetBool_WithDefault( context->dictionary, (Dictionary_Entry_Key)"visualOnly", False ) == False ) ) {
+ /* Always overwrite the file if starting a new run */
+ fileOpened = Stream_RedirectFile_WithPrependedPath( stream, context->outputPath, frequentOutputFilename );
+ }
+ else {
+ /* Just append to the file if doing a restart from checkpoint */
+ fileOpened = Stream_AppendFile_WithPrependedPath( stream, context->outputPath, frequentOutputFilename );
+ }
+ Journal_Firewall( fileOpened, errorStream,
+ "Could not open file %s/%s. Possibly directory %s does not exist or is not writable.\n"
+ "Check 'outputPath' in input file.\n", context->outputPath, frequentOutputFilename, context->outputPath );
+ }
+
+ /* Set it so only master processor can print to stream */
+ Stream_SetPrintingRank( stream, MASTER );
+
+ /* Read in values from dictionary */
+ self->columnWidth = Dictionary_GetUnsignedInt_WithDefault( dictionary, "FrequentOutputColumnWidth", 12 );
+ self->decimalLength = Dictionary_GetUnsignedInt_WithDefault( dictionary, "FrequentOutputDecimalLength", 6 );
+ self->borderString = Dictionary_GetString_WithDefault( dictionary, "FrequentOutputBorderString", " " );
+
+ StgFEM_FrequentOutput_PrintHeader( context );
+}
+
+void* _StgFEM_FrequentOutput_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(StgFEM_FrequentOutput);
+ Type type = StgFEM_FrequentOutput_Type;
+ Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
+ Stg_Class_PrintFunction* _print = _Codelet_Print;
+ Stg_Class_CopyFunction* _copy = _Codelet_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_FrequentOutput_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _StgFEM_FrequentOutput_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Codelet_Build;
+ Stg_Component_InitialiseFunction* _initialise = _Codelet_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
+ Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _Codelet_New( CODELET_PASSARGS );
+}
+
+Index StgFEM_FrequentOutput_Register( PluginsManager* pluginsManager ) {
+ return PluginsManager_Submit( pluginsManager, StgFEM_FrequentOutput_Type, (Name)"0", _StgFEM_FrequentOutput_DefaultNew );
+}
+
+void StgFEM_FrequentOutput_PrintString( void* _context, char* string ) {
+ AbstractContext* context = (AbstractContext*) _context;
+ Stream* stream;
+
+ StgFEM_FrequentOutput* self = (StgFEM_FrequentOutput*)LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_FrequentOutput_Type );
+ stream = self->stream;
+
+ /* Print some empty space at start */
+ Journal_Printf( stream, self->borderString );
+
+ /* Print String - Truncated if nessesary */
+ Journal_PrintString_WithLength( stream, string, self->columnWidth );
+}
+
+void StgFEM_FrequentOutput_PrintDouble( void* _context, double value ) {
+ AbstractContext* context = (AbstractContext*) _context;
+ char* formatString;
+ Stream* stream;
+
+ StgFEM_FrequentOutput* self = (StgFEM_FrequentOutput*)LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_FrequentOutput_Type );
+
+ stream = self->stream;
+
+ /* Create format String */
+ Stg_asprintf( &formatString, "%%%d.%dg", self->columnWidth, self->decimalLength );
+
+ Journal_Printf( self->stream, self->borderString );
+ Journal_Printf( self->stream, formatString, value );
+
+ Memory_Free( formatString );
+}
+
+void StgFEM_FrequentOutput_PrintHeader( void* _context ) {
+ AbstractContext* context = (AbstractContext*) _context;
+ char* firstBorderString;
+ Stream* stream;
+
+ StgFEM_FrequentOutput* self = (StgFEM_FrequentOutput*)LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_FrequentOutput_Type );
+
+ stream = self->stream;
+
+ /* Print First Boarder with '#' in the front */
+ firstBorderString = StG_Strdup( self->borderString );
+ firstBorderString[0] = '#';
+ Journal_Printf( stream, firstBorderString );
+ Memory_Free( firstBorderString );
+
+ Journal_PrintString_WithLength( stream, "Timestep", self->columnWidth );
+
+ StgFEM_FrequentOutput_PrintString( context, "Time" );
+}
+
+void StgFEM_FrequentOutput_PrintTime( void* _context ) {
+ AbstractContext* context = (AbstractContext*) _context;
+
+ StgFEM_FrequentOutput_PrintValue( context, context->timeStep );
+ StgFEM_FrequentOutput_PrintValue( context, context->currentTime );
+}
+
+void StgFEM_FrequentOutput_PrintNewLine( void* _context ) {
+ AbstractContext* context = (AbstractContext*) _context;
+ Stream* stream;
+
+ StgFEM_FrequentOutput* self = (StgFEM_FrequentOutput*)LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_FrequentOutput_Type );
+
+ stream = self->stream;
+
+ Journal_Printf( stream, "\n" );
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/PeakMemory/PeakMemory.c
--- a/plugins/Output/PeakMemory/PeakMemory.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/Discretisation/Discretisation.h>
-#include <StgFEM/FrequentOutput/FrequentOutput.h>
-
-#include "PeakMemory.h"
-
-const Type StgFEM_PeakMemory_Type = "StgFEM_PeakMemory";
-
-void StgFEM_PeakMemory_PrintMemoryInfo( AbstractContext* context ) {
- PetscLogDouble stgPeak, totalMem, petscMem, ave;
-
- stgPeak = (PetscLogDouble)stgMemory->stgPeakMemory;
- MPI_Allreduce( &stgPeak, &ave, 1, MPI_DOUBLE, MPI_SUM, context->communicator );
- ave /= 1024 * 1024;
- StgFEM_FrequentOutput_PrintValue( context, ave );
-
- PetscMallocGetMaximumUsage( &petscMem );
- MPI_Allreduce( &petscMem, &ave, 1, MPI_DOUBLE, MPI_SUM, context->communicator );
- ave /= 1024 * 1024;
- StgFEM_FrequentOutput_PrintValue( context, ave );
-
- PetscMemoryGetMaximumUsage( &totalMem );
- MPI_Allreduce( &totalMem, &ave, 1, MPI_DOUBLE, MPI_SUM, context->communicator );
- ave /= 1024 * 1024;
- StgFEM_FrequentOutput_PrintValue( context, ave );
-}
-
-void _StgFEM_PeakMemory_AssignFromXML( void* componment, Stg_ComponentFactory* cf, void* data ) {
- AbstractContext* context;
-
- /* Turn on the magical petsc logging */
- PetscMemorySetGetMaximumUsage();
-
- context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
- StgFEM_FrequentOutput* self = (StgFEM_FrequentOutput* )LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_FrequentOutput_Type );
-
- /* set the stupid stream column width so I don't get "..." behaviour */
- self->columnWidth = 15;
-
- /* Print Header to file */
- StgFEM_FrequentOutput_PrintString( context, "StgPeakMem(Mb)" );
- StgFEM_FrequentOutput_PrintString( context, "PetscMem(Mb)" );
- StgFEM_FrequentOutput_PrintString( context, "ProgMem(Mb)" );
-
- ContextEP_Append( context, AbstractContext_EP_FrequentOutput ,StgFEM_PeakMemory_PrintMemoryInfo );
-}
-
-void* _StgFEM_PeakMemory_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof( Codelet );
- Type type = StgFEM_PeakMemory_Type;
- Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
- Stg_Class_PrintFunction* _print = _Codelet_Print;
- Stg_Class_CopyFunction* _copy = _Codelet_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_PeakMemory_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _StgFEM_PeakMemory_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Codelet_Build;
- Stg_Component_InitialiseFunction* _initialise = _Codelet_Initialise;
- Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
- Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _Codelet_New( CODELET_PASSARGS );
-}
-
-Index StgFEM_PeakMemory_Register( PluginsManager* pluginsManager ) {
- return PluginsManager_Submit( pluginsManager, StgFEM_PeakMemory_Type, (Name)"0", _StgFEM_PeakMemory_DefaultNew );
-}
-
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/PeakMemory/PeakMemory.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/Output/PeakMemory/PeakMemory.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,116 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/Discretisation/Discretisation.h>
+#include <StgFEM/FrequentOutput/FrequentOutput.h>
+
+#include "PeakMemory.h"
+
+const Type StgFEM_PeakMemory_Type = "StgFEM_PeakMemory";
+
+void StgFEM_PeakMemory_PrintMemoryInfo( AbstractContext* context ) {
+ PetscLogDouble stgPeak, totalMem, petscMem, ave;
+
+ stgPeak = (PetscLogDouble)stgMemory->stgPeakMemory;
+ MPI_Allreduce( &stgPeak, &ave, 1, MPI_DOUBLE, MPI_SUM, context->communicator );
+ ave /= 1024 * 1024;
+ StgFEM_FrequentOutput_PrintValue( context, ave );
+
+ PetscMallocGetMaximumUsage( &petscMem );
+ MPI_Allreduce( &petscMem, &ave, 1, MPI_DOUBLE, MPI_SUM, context->communicator );
+ ave /= 1024 * 1024;
+ StgFEM_FrequentOutput_PrintValue( context, ave );
+
+ PetscMemoryGetMaximumUsage( &totalMem );
+ MPI_Allreduce( &totalMem, &ave, 1, MPI_DOUBLE, MPI_SUM, context->communicator );
+ ave /= 1024 * 1024;
+ StgFEM_FrequentOutput_PrintValue( context, ave );
+}
+
+void _StgFEM_PeakMemory_AssignFromXML( void* componment, Stg_ComponentFactory* cf, void* data ) {
+ AbstractContext* context;
+
+ /* Turn on the magical petsc logging */
+ PetscMemorySetGetMaximumUsage();
+
+ context = Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+ StgFEM_FrequentOutput* self = (StgFEM_FrequentOutput* )LiveComponentRegister_Get( context->CF->LCRegister, (Name)StgFEM_FrequentOutput_Type );
+
+ /* set the stupid stream column width so I don't get "..." behaviour */
+ self->columnWidth = 15;
+
+ /* Print Header to file */
+ StgFEM_FrequentOutput_PrintString( context, "StgPeakMem(Mb)" );
+ StgFEM_FrequentOutput_PrintString( context, "PetscMem(Mb)" );
+ StgFEM_FrequentOutput_PrintString( context, "ProgMem(Mb)" );
+
+ ContextEP_Append( context, AbstractContext_EP_FrequentOutput ,StgFEM_PeakMemory_PrintMemoryInfo );
+}
+
+void* _StgFEM_PeakMemory_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof( Codelet );
+ Type type = StgFEM_PeakMemory_Type;
+ Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
+ Stg_Class_PrintFunction* _print = _Codelet_Print;
+ Stg_Class_CopyFunction* _copy = _Codelet_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_PeakMemory_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _StgFEM_PeakMemory_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Codelet_Build;
+ Stg_Component_InitialiseFunction* _initialise = _Codelet_Initialise;
+ Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
+ Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _Codelet_New( CODELET_PASSARGS );
+}
+
+Index StgFEM_PeakMemory_Register( PluginsManager* pluginsManager ) {
+ return PluginsManager_Submit( pluginsManager, StgFEM_PeakMemory_Type, (Name)"0", _StgFEM_PeakMemory_DefaultNew );
+}
+
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/PrintFeVariableDiscreteValues/Plugin.c
--- a/plugins/Output/PrintFeVariableDiscreteValues/Plugin.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Plugin.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-#include "Plugin.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-const Type StgFEM_PrintFeVariableDiscreteValues_Type = "StgFEM_PrintFeVariableDiscreteValues";
-
-Name PRINT_FE_VARIABLE_DISCRETE_VALUES_TAG = "PrintFeVariableDiscreteValues";
-
-void _StgFEM_PrintFeVariableDiscreteValues_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
- FiniteElementContext* context;
-
- context = (FiniteElementContext*)Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
-
- ContextEP_Append( context, AbstractContext_EP_Dump, PrintFeVariableDiscreteValues );
-}
-
-void* _StgFEM_PrintFeVariableDiscreteValues_DefaultNew( Name name ) {
- return Codelet_New(
- StgFEM_PrintFeVariableDiscreteValues_Type,
- _StgFEM_PrintFeVariableDiscreteValues_DefaultNew,
- _StgFEM_PrintFeVariableDiscreteValues_AssignFromXML,
- _Codelet_Build,
- _Codelet_Initialise,
- _Codelet_Execute,
- _Codelet_Destroy,
- name );
-}
-
-Index StgFEM_PrintFeVariableDiscreteValues_Register( PluginsManager* pluginsManager ) {
- Journal_DPrintf( StgFEM_Debug, "In: %s( void* )\n", __func__ );
-
- return PluginsManager_Submit( pluginsManager, StgFEM_PrintFeVariableDiscreteValues_Type, (Name)"0", _StgFEM_PrintFeVariableDiscreteValues_DefaultNew );
-}
-
-
-void PrintFeVariableDiscreteValues( void* _context ) {
- FiniteElementContext* context = (FiniteElementContext* )_context;
- FeVariable* currFeVar;
- Stream* stream;
- Name currFeVarName;
- Dictionary_Entry_Value* feVarList=NULL;
- Dictionary_Entry_Value* currFvParam=NULL;
- Index feVar_I=0;
- Index numFeVarsToPrint=0;
- Stream* warningStr = Journal_Register( Error_Type, (Name)CURR_MODULE_NAME );
-
- stream = Journal_Register( Info_Type, (Name)CURR_MODULE_NAME );
-
- feVarList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)(char*)PRINT_FE_VARIABLE_DISCRETE_VALUES_TAG );
- if ( NULL == feVarList ) {
- Journal_Printf( warningStr, "Warning - in %s: Plugin \"%s\" loaded, but no \"%s\" tag found "
- "in dictionary. Not printing any FE vars.\n", __func__, CURR_MODULE_NAME, PRINT_FE_VARIABLE_DISCRETE_VALUES_TAG );
- return;
- }
-
- numFeVarsToPrint = Dictionary_Entry_Value_GetCount( feVarList );
- if ( 0 == numFeVarsToPrint ) {
- Journal_Printf( warningStr, "Warning - in %s: Plugin \"%s\" loaded, \"%s\" list found, "
- "but list has 0 entries.\n",
- __func__, CURR_MODULE_NAME, PRINT_FE_VARIABLE_DISCRETE_VALUES_TAG );
- return;
- }
-
-
- for ( feVar_I=0; feVar_I < numFeVarsToPrint; feVar_I++ ) {
- currFvParam = Dictionary_Entry_Value_GetElement( feVarList, feVar_I );
- currFeVarName = Dictionary_Entry_Value_AsString( currFvParam );
- currFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, currFeVarName );
- if ( NULL == currFeVar ) {
- Journal_Printf( warningStr, "Warning - in %s: You requested printing the values of feVariable "
- "\"%s\", but it doesn't exist in the context's field variable register. Skipping.\n",
- __func__, currFeVarName );
- Journal_Printf( warningStr, "(Field Vars currently registered are: " );
- Stg_ObjectList_PrintAllEntryNames( context->fieldVariable_Register->objects, warningStr );
- Journal_Printf( warningStr, ")\n" );
- continue;
- }
- Journal_Printf( stream, "%s Values (at end of timestep %d):\n", currFeVarName, context->timeStep );
- FeVariable_PrintLocalDiscreteValues( currFeVar, stream );
- Journal_Printf( stream, "\n" );
- }
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/PrintFeVariableDiscreteValues/Plugin.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/Output/PrintFeVariableDiscreteValues/Plugin.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,130 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Plugin.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+#include "Plugin.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+const Type StgFEM_PrintFeVariableDiscreteValues_Type = "StgFEM_PrintFeVariableDiscreteValues";
+
+Name PRINT_FE_VARIABLE_DISCRETE_VALUES_TAG = "PrintFeVariableDiscreteValues";
+
+void _StgFEM_PrintFeVariableDiscreteValues_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
+ FiniteElementContext* context;
+
+ context = (FiniteElementContext*)Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
+
+ ContextEP_Append( context, AbstractContext_EP_Dump, PrintFeVariableDiscreteValues );
+}
+
+void* _StgFEM_PrintFeVariableDiscreteValues_DefaultNew( Name name ) {
+ return Codelet_New(
+ StgFEM_PrintFeVariableDiscreteValues_Type,
+ _StgFEM_PrintFeVariableDiscreteValues_DefaultNew,
+ _StgFEM_PrintFeVariableDiscreteValues_AssignFromXML,
+ _Codelet_Build,
+ _Codelet_Initialise,
+ _Codelet_Execute,
+ _Codelet_Destroy,
+ name );
+}
+
+Index StgFEM_PrintFeVariableDiscreteValues_Register( PluginsManager* pluginsManager ) {
+ Journal_DPrintf( StgFEM_Debug, "In: %s( void* )\n", __func__ );
+
+ return PluginsManager_Submit( pluginsManager, StgFEM_PrintFeVariableDiscreteValues_Type, (Name)"0", _StgFEM_PrintFeVariableDiscreteValues_DefaultNew );
+}
+
+
+void PrintFeVariableDiscreteValues( void* _context ) {
+ FiniteElementContext* context = (FiniteElementContext* )_context;
+ FeVariable* currFeVar;
+ Stream* stream;
+ Name currFeVarName;
+ Dictionary_Entry_Value* feVarList=NULL;
+ Dictionary_Entry_Value* currFvParam=NULL;
+ Index feVar_I=0;
+ Index numFeVarsToPrint=0;
+ Stream* warningStr = Journal_Register( Error_Type, (Name)CURR_MODULE_NAME );
+
+ stream = Journal_Register( Info_Type, (Name)CURR_MODULE_NAME );
+
+ feVarList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)(char*)PRINT_FE_VARIABLE_DISCRETE_VALUES_TAG );
+ if ( NULL == feVarList ) {
+ Journal_Printf( warningStr, "Warning - in %s: Plugin \"%s\" loaded, but no \"%s\" tag found "
+ "in dictionary. Not printing any FE vars.\n", __func__, CURR_MODULE_NAME, PRINT_FE_VARIABLE_DISCRETE_VALUES_TAG );
+ return;
+ }
+
+ numFeVarsToPrint = Dictionary_Entry_Value_GetCount( feVarList );
+ if ( 0 == numFeVarsToPrint ) {
+ Journal_Printf( warningStr, "Warning - in %s: Plugin \"%s\" loaded, \"%s\" list found, "
+ "but list has 0 entries.\n",
+ __func__, CURR_MODULE_NAME, PRINT_FE_VARIABLE_DISCRETE_VALUES_TAG );
+ return;
+ }
+
+
+ for ( feVar_I=0; feVar_I < numFeVarsToPrint; feVar_I++ ) {
+ currFvParam = Dictionary_Entry_Value_GetElement( feVarList, feVar_I );
+ currFeVarName = Dictionary_Entry_Value_AsString( currFvParam );
+ currFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, currFeVarName );
+ if ( NULL == currFeVar ) {
+ Journal_Printf( warningStr, "Warning - in %s: You requested printing the values of feVariable "
+ "\"%s\", but it doesn't exist in the context's field variable register. Skipping.\n",
+ __func__, currFeVarName );
+ Journal_Printf( warningStr, "(Field Vars currently registered are: " );
+ Stg_ObjectList_PrintAllEntryNames( context->fieldVariable_Register->objects, warningStr );
+ Journal_Printf( warningStr, ")\n" );
+ continue;
+ }
+ Journal_Printf( stream, "%s Values (at end of timestep %d):\n", currFeVarName, context->timeStep );
+ FeVariable_PrintLocalDiscreteValues( currFeVar, stream );
+ Journal_Printf( stream, "\n" );
+ }
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/PrintFeVariableDiscreteValues_2dBox/Plugin.c
--- a/plugins/Output/PrintFeVariableDiscreteValues_2dBox/Plugin.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: Plugin.c 964 2007-10-11 08:03:06Z SteveQuenette $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-#include "Plugin.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-const Type StgFEM_PrintFeVariableDiscreteValues_2dBox_Type = "StgFEM_PrintFeVariableDiscreteValues_2dBox";
-
-Name PRINT_FE_VARIABLE_DISCRETE_VALUES_2D_BOX_TAG = "PrintFeVariableDiscreteValues_2dBox";
-
-void _StgFEM_PrintFeVariableDiscreteValues_2dBox_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
- FiniteElementContext* context;
-
- context = (FiniteElementContext*)Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
- /* Add extensions to nodes, elements and the context */
-
- /* Add extensions to functionality (entry points) */
- ContextEP_Append( context, AbstractContext_EP_Dump, PrintFeVariableDiscreteValues_2dBox );
-}
-
-void* _StgFEM_PrintFeVariableDiscreteValues_2dBox_DefaultNew( Name name ) {
- return Codelet_New(
- StgFEM_PrintFeVariableDiscreteValues_2dBox_Type,
- _StgFEM_PrintFeVariableDiscreteValues_2dBox_DefaultNew,
- _StgFEM_PrintFeVariableDiscreteValues_2dBox_AssignFromXML,
- _Codelet_Build,
- _Codelet_Initialise,
- _Codelet_Execute,
- _Codelet_Destroy,
- name );
-}
-
-Index StgFEM_PrintFeVariableDiscreteValues_2dBox_Register( PluginsManager* pluginsManager ) {
- Journal_DPrintf( StgFEM_Debug, "In: %s( void* )\n", __func__ );
-
- return PluginsManager_Submit( pluginsManager, StgFEM_PrintFeVariableDiscreteValues_2dBox_Type, (Name)"0", _StgFEM_PrintFeVariableDiscreteValues_2dBox_DefaultNew );
-}
-
-
-void PrintFeVariableDiscreteValues_2dBox( void* _context ) {
- FiniteElementContext* context = (FiniteElementContext* )_context;
- FeVariable* currFeVar;
- Stream* stream;
- Name currFeVarName;
- Dictionary_Entry_Value* feVarList=NULL;
- Dictionary_Entry_Value* currFvParam=NULL;
- Index feVar_I=0;
- Index numFeVarsToPrint=0;
- Stream* warningStr = Journal_Register( Error_Type, (Name)CURR_MODULE_NAME );
-
- stream = Journal_Register( Info_Type, (Name)CURR_MODULE_NAME );
-
- feVarList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)(char*)PRINT_FE_VARIABLE_DISCRETE_VALUES_2D_BOX_TAG );
- if ( NULL == feVarList ) {
- Journal_Printf( warningStr, "Warning - in %s: Plugin \"%s\" loaded, but no \"%s\" tag found "
- "in dictionary. Not printing any FE vars.\n", __func__, CURR_MODULE_NAME, PRINT_FE_VARIABLE_DISCRETE_VALUES_2D_BOX_TAG );
- return;
- }
-
- numFeVarsToPrint = Dictionary_Entry_Value_GetCount( feVarList );
- if ( 0 == numFeVarsToPrint ) {
- Journal_Printf( warningStr, "Warning - in %s: Plugin \"%s\" loaded, \"%s\" list found, "
- "but list has 0 entries.\n",
- __func__, CURR_MODULE_NAME, PRINT_FE_VARIABLE_DISCRETE_VALUES_2D_BOX_TAG );
- return;
- }
-
-
- for ( feVar_I=0; feVar_I < numFeVarsToPrint; feVar_I++ ) {
- currFvParam = Dictionary_Entry_Value_GetElement( feVarList, feVar_I );
- currFeVarName = Dictionary_Entry_Value_AsString( currFvParam );
- currFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, currFeVarName );
- if ( NULL == currFeVar ) {
- Journal_Printf( warningStr, "Warning - in %s: You requested printing the values of feVariable "
- "\"%s\", but it doesn't exist in the context's field variable register. Skipping.\n",
- __func__, currFeVarName );
- Journal_Printf( warningStr, "(Field Vars currently registered are: " );
- Stg_ObjectList_PrintAllEntryNames( context->fieldVariable_Register->objects, warningStr );
- Journal_Printf( warningStr, ")\n" );
- continue;
- }
- Journal_Printf( stream, "%s Values (at end of timestep %d):\n", currFeVarName, context->timeStep );
- FeVariable_PrintLocalDiscreteValues_2dBox( currFeVar, stream );
- Journal_Printf( stream, "\n" );
- }
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/PrintFeVariableDiscreteValues_2dBox/Plugin.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/Output/PrintFeVariableDiscreteValues_2dBox/Plugin.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,132 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: Plugin.c 964 2007-10-11 08:03:06Z SteveQuenette $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+#include "Plugin.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+const Type StgFEM_PrintFeVariableDiscreteValues_2dBox_Type = "StgFEM_PrintFeVariableDiscreteValues_2dBox";
+
+Name PRINT_FE_VARIABLE_DISCRETE_VALUES_2D_BOX_TAG = "PrintFeVariableDiscreteValues_2dBox";
+
+void _StgFEM_PrintFeVariableDiscreteValues_2dBox_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
+ FiniteElementContext* context;
+
+ context = (FiniteElementContext*)Stg_ComponentFactory_ConstructByName( cf, (Name)"context", FiniteElementContext, True, data );
+ /* Add extensions to nodes, elements and the context */
+
+ /* Add extensions to functionality (entry points) */
+ ContextEP_Append( context, AbstractContext_EP_Dump, PrintFeVariableDiscreteValues_2dBox );
+}
+
+void* _StgFEM_PrintFeVariableDiscreteValues_2dBox_DefaultNew( Name name ) {
+ return Codelet_New(
+ StgFEM_PrintFeVariableDiscreteValues_2dBox_Type,
+ _StgFEM_PrintFeVariableDiscreteValues_2dBox_DefaultNew,
+ _StgFEM_PrintFeVariableDiscreteValues_2dBox_AssignFromXML,
+ _Codelet_Build,
+ _Codelet_Initialise,
+ _Codelet_Execute,
+ _Codelet_Destroy,
+ name );
+}
+
+Index StgFEM_PrintFeVariableDiscreteValues_2dBox_Register( PluginsManager* pluginsManager ) {
+ Journal_DPrintf( StgFEM_Debug, "In: %s( void* )\n", __func__ );
+
+ return PluginsManager_Submit( pluginsManager, StgFEM_PrintFeVariableDiscreteValues_2dBox_Type, (Name)"0", _StgFEM_PrintFeVariableDiscreteValues_2dBox_DefaultNew );
+}
+
+
+void PrintFeVariableDiscreteValues_2dBox( void* _context ) {
+ FiniteElementContext* context = (FiniteElementContext* )_context;
+ FeVariable* currFeVar;
+ Stream* stream;
+ Name currFeVarName;
+ Dictionary_Entry_Value* feVarList=NULL;
+ Dictionary_Entry_Value* currFvParam=NULL;
+ Index feVar_I=0;
+ Index numFeVarsToPrint=0;
+ Stream* warningStr = Journal_Register( Error_Type, (Name)CURR_MODULE_NAME );
+
+ stream = Journal_Register( Info_Type, (Name)CURR_MODULE_NAME );
+
+ feVarList = Dictionary_Get( context->dictionary, (Dictionary_Entry_Key)(char*)PRINT_FE_VARIABLE_DISCRETE_VALUES_2D_BOX_TAG );
+ if ( NULL == feVarList ) {
+ Journal_Printf( warningStr, "Warning - in %s: Plugin \"%s\" loaded, but no \"%s\" tag found "
+ "in dictionary. Not printing any FE vars.\n", __func__, CURR_MODULE_NAME, PRINT_FE_VARIABLE_DISCRETE_VALUES_2D_BOX_TAG );
+ return;
+ }
+
+ numFeVarsToPrint = Dictionary_Entry_Value_GetCount( feVarList );
+ if ( 0 == numFeVarsToPrint ) {
+ Journal_Printf( warningStr, "Warning - in %s: Plugin \"%s\" loaded, \"%s\" list found, "
+ "but list has 0 entries.\n",
+ __func__, CURR_MODULE_NAME, PRINT_FE_VARIABLE_DISCRETE_VALUES_2D_BOX_TAG );
+ return;
+ }
+
+
+ for ( feVar_I=0; feVar_I < numFeVarsToPrint; feVar_I++ ) {
+ currFvParam = Dictionary_Entry_Value_GetElement( feVarList, feVar_I );
+ currFeVarName = Dictionary_Entry_Value_AsString( currFvParam );
+ currFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, currFeVarName );
+ if ( NULL == currFeVar ) {
+ Journal_Printf( warningStr, "Warning - in %s: You requested printing the values of feVariable "
+ "\"%s\", but it doesn't exist in the context's field variable register. Skipping.\n",
+ __func__, currFeVarName );
+ Journal_Printf( warningStr, "(Field Vars currently registered are: " );
+ Stg_ObjectList_PrintAllEntryNames( context->fieldVariable_Register->objects, warningStr );
+ Journal_Printf( warningStr, ")\n" );
+ continue;
+ }
+ Journal_Printf( stream, "%s Values (at end of timestep %d):\n", currFeVarName, context->timeStep );
+ FeVariable_PrintLocalDiscreteValues_2dBox( currFeVar, stream );
+ Journal_Printf( stream, "\n" );
+ }
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/SwarmVariableList/SwarmVariableList.c
--- a/plugins/Output/SwarmVariableList/SwarmVariableList.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,152 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <string.h>
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-
-#include "SwarmVariableList.h"
-
-#ifndef MASTER
- #define MASTER 0
-#endif
-
-const Type StgFEM_SwarmVariableList_Type = "StgFEM_SwarmVariableList";
-
-void _StgFEM_SwarmVariableList_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
- StgFEM_SwarmVariableList* self = (StgFEM_SwarmVariableList*) component;
- AbstractContext* context;
- Dictionary* dictionary;
- Stream* stream;
- Name swarmVariableListFilename;
- Bool fileOpened;
- Bool PrintToFile;
-
- self->context = context = (AbstractContext*)Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
- dictionary = context->dictionary;
- self->swarmRegister = Swarm_Register_GetSwarm_Register( );
-
- /** create stream **/
- stream = self->stream = Journal_Register( InfoStream_Type, (Name)"SwarmVariableList" );
-
- /** set auto flush on stream **/
- Stream_SetAutoFlush( stream, True );
-
- /** print to screen or to file? **/
- PrintToFile = Dictionary_GetBool_WithDefault( dictionary, (Dictionary_Entry_Key)"SwarmVariableListPrintToFile", True );
- if(PrintToFile ){
- /** get name of SwarmVariable list file **/
- swarmVariableListFilename = Dictionary_GetString_WithDefault( dictionary, "SwarmVariableListFilename", "SwarmVariables.list" );
- /** open new file **/
- if ( context->rank == MASTER ) {
- Stream* errorStream = Journal_Register( Error_Type, (Name)CURR_MODULE_NAME );
- fileOpened = Stream_RedirectFile_WithPrependedPath( stream, context->outputPath, swarmVariableListFilename );
- Journal_Firewall( fileOpened, errorStream,
- "Could not open file %s/%s. Possibly directory %s does not exist or is not writable.\n"
- "Check 'outputPath' in input file.\n", context->outputPath, swarmVariableListFilename, context->outputPath );
- }
- /** set it so only master processor can print to stream **/
- Stream_SetPrintingRank( stream, MASTER );
- }
-}
-
-void* _StgFEM_SwarmVariableList_DefaultNew( Name name ) {
- /* Variables set in this function */
- SizeT _sizeOfSelf = sizeof(StgFEM_SwarmVariableList);
- Type type = StgFEM_SwarmVariableList_Type;
- Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
- Stg_Class_PrintFunction* _print = _Codelet_Print;
- Stg_Class_CopyFunction* _copy = _Codelet_Copy;
- Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_SwarmVariableList_DefaultNew;
- Stg_Component_ConstructFunction* _construct = _StgFEM_SwarmVariableList_AssignFromXML;
- Stg_Component_BuildFunction* _build = _Codelet_Build;
- Stg_Component_InitialiseFunction* _initialise = StgFEM_SwarmVariableList_PrintVariables;
- Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
- Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
-
- /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
- AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
-
- return _Codelet_New( CODELET_PASSARGS );
-}
-
-Index StgFEM_SwarmVariableList_Register( PluginsManager* pluginsManager ) {
- return PluginsManager_Submit( pluginsManager, StgFEM_SwarmVariableList_Type, (Name)"0", _StgFEM_SwarmVariableList_DefaultNew );
-}
-
-void StgFEM_SwarmVariableList_PrintVariables( void* _self, void* data ){
- StgFEM_SwarmVariableList* self = (StgFEM_SwarmVariableList*)_self;
- AbstractContext* context = self->context;
- Stream* stream = self->stream;;
- Index swarmCount;
- Index variablecount;
- Index countindex;
- Index swarmcountindex;
- Index columnWidth = 40;
- Swarm* currentSwarm;
-
- /** print header material **/
- Journal_Printf( stream, "\n");
- Journal_PrintString_WithLength( stream, "SwarmVariable", columnWidth );
- Journal_PrintString_WithLength( stream, "Swarm", columnWidth );
- Journal_Printf( stream, "\n");
- Journal_PrintString_WithLength( stream, "------------------------", columnWidth );
- Journal_PrintString_WithLength( stream, "------------------------", columnWidth );
- Journal_Printf( stream, "\n");
-
- /** get total number of different swarms **/
- swarmCount = self->swarmRegister->swarmList->count;
-
- /** print swarm variables **/
- for(swarmcountindex = 0; swarmcountindex < swarmCount; ++swarmcountindex){
- currentSwarm = (Swarm*)Stg_ComponentFactory_ConstructByName( context->CF, (Name)self->swarmRegister->swarmList->data[swarmcountindex]->name, Swarm, True, NULL );
- variablecount = currentSwarm->swarmVariable_Register->objects->count;
- for(countindex = 0; countindex < variablecount; ++countindex ){
- Journal_PrintString_WithLength( stream, currentSwarm->swarmVariable_Register->objects->data[ countindex ]->name, columnWidth );
- Journal_PrintString_WithLength( stream, self->swarmRegister->swarmList->data[swarmcountindex]->name, columnWidth );
- Journal_Printf( stream, "\n");
- }
- }
- Journal_Printf( stream, "\n");
-}
-
-
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/Output/SwarmVariableList/SwarmVariableList.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/Output/SwarmVariableList/SwarmVariableList.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,152 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <string.h>
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+
+#include "SwarmVariableList.h"
+
+#ifndef MASTER
+ #define MASTER 0
+#endif
+
+const Type StgFEM_SwarmVariableList_Type = "StgFEM_SwarmVariableList";
+
+void _StgFEM_SwarmVariableList_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
+ StgFEM_SwarmVariableList* self = (StgFEM_SwarmVariableList*) component;
+ AbstractContext* context;
+ Dictionary* dictionary;
+ Stream* stream;
+ Name swarmVariableListFilename;
+ Bool fileOpened;
+ Bool PrintToFile;
+
+ self->context = context = (AbstractContext*)Stg_ComponentFactory_ConstructByName( cf, (Name)"context", AbstractContext, True, data );
+ dictionary = context->dictionary;
+ self->swarmRegister = Swarm_Register_GetSwarm_Register( );
+
+ /** create stream **/
+ stream = self->stream = Journal_Register( InfoStream_Type, (Name)"SwarmVariableList" );
+
+ /** set auto flush on stream **/
+ Stream_SetAutoFlush( stream, True );
+
+ /** print to screen or to file? **/
+ PrintToFile = Dictionary_GetBool_WithDefault( dictionary, (Dictionary_Entry_Key)"SwarmVariableListPrintToFile", True );
+ if(PrintToFile ){
+ /** get name of SwarmVariable list file **/
+ swarmVariableListFilename = Dictionary_GetString_WithDefault( dictionary, "SwarmVariableListFilename", "SwarmVariables.list" );
+ /** open new file **/
+ if ( context->rank == MASTER ) {
+ Stream* errorStream = Journal_Register( Error_Type, (Name)CURR_MODULE_NAME );
+ fileOpened = Stream_RedirectFile_WithPrependedPath( stream, context->outputPath, swarmVariableListFilename );
+ Journal_Firewall( fileOpened, errorStream,
+ "Could not open file %s/%s. Possibly directory %s does not exist or is not writable.\n"
+ "Check 'outputPath' in input file.\n", context->outputPath, swarmVariableListFilename, context->outputPath );
+ }
+ /** set it so only master processor can print to stream **/
+ Stream_SetPrintingRank( stream, MASTER );
+ }
+}
+
+void* _StgFEM_SwarmVariableList_DefaultNew( Name name ) {
+ /* Variables set in this function */
+ SizeT _sizeOfSelf = sizeof(StgFEM_SwarmVariableList);
+ Type type = StgFEM_SwarmVariableList_Type;
+ Stg_Class_DeleteFunction* _delete = _Codelet_Delete;
+ Stg_Class_PrintFunction* _print = _Codelet_Print;
+ Stg_Class_CopyFunction* _copy = _Codelet_Copy;
+ Stg_Component_DefaultConstructorFunction* _defaultConstructor = _StgFEM_SwarmVariableList_DefaultNew;
+ Stg_Component_ConstructFunction* _construct = _StgFEM_SwarmVariableList_AssignFromXML;
+ Stg_Component_BuildFunction* _build = _Codelet_Build;
+ Stg_Component_InitialiseFunction* _initialise = StgFEM_SwarmVariableList_PrintVariables;
+ Stg_Component_ExecuteFunction* _execute = _Codelet_Execute;
+ Stg_Component_DestroyFunction* _destroy = _Codelet_Destroy;
+
+ /* Variables that are set to ZERO are variables that will be set either by the current _New function or another parent _New function further up the hierachy */
+ AllocationType nameAllocationType = NON_GLOBAL /* default value NON_GLOBAL */;
+
+ return _Codelet_New( CODELET_PASSARGS );
+}
+
+Index StgFEM_SwarmVariableList_Register( PluginsManager* pluginsManager ) {
+ return PluginsManager_Submit( pluginsManager, StgFEM_SwarmVariableList_Type, (Name)"0", _StgFEM_SwarmVariableList_DefaultNew );
+}
+
+void StgFEM_SwarmVariableList_PrintVariables( void* _self, void* data ){
+ StgFEM_SwarmVariableList* self = (StgFEM_SwarmVariableList*)_self;
+ AbstractContext* context = self->context;
+ Stream* stream = self->stream;;
+ Index swarmCount;
+ Index variablecount;
+ Index countindex;
+ Index swarmcountindex;
+ Index columnWidth = 40;
+ Swarm* currentSwarm;
+
+ /** print header material **/
+ Journal_Printf( stream, "\n");
+ Journal_PrintString_WithLength( stream, "SwarmVariable", columnWidth );
+ Journal_PrintString_WithLength( stream, "Swarm", columnWidth );
+ Journal_Printf( stream, "\n");
+ Journal_PrintString_WithLength( stream, "------------------------", columnWidth );
+ Journal_PrintString_WithLength( stream, "------------------------", columnWidth );
+ Journal_Printf( stream, "\n");
+
+ /** get total number of different swarms **/
+ swarmCount = self->swarmRegister->swarmList->count;
+
+ /** print swarm variables **/
+ for(swarmcountindex = 0; swarmcountindex < swarmCount; ++swarmcountindex){
+ currentSwarm = (Swarm*)Stg_ComponentFactory_ConstructByName( context->CF, (Name)self->swarmRegister->swarmList->data[swarmcountindex]->name, Swarm, True, NULL );
+ variablecount = currentSwarm->swarmVariable_Register->objects->count;
+ for(countindex = 0; countindex < variablecount; ++countindex ){
+ Journal_PrintString_WithLength( stream, currentSwarm->swarmVariable_Register->objects->data[ countindex ]->name, columnWidth );
+ Journal_PrintString_WithLength( stream, self->swarmRegister->swarmList->data[swarmcountindex]->name, columnWidth );
+ Journal_Printf( stream, "\n");
+ }
+ }
+ Journal_Printf( stream, "\n");
+}
+
+
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/StandardConditionFunctions/StandardConditionFunctions.c
--- a/plugins/StandardConditionFunctions/StandardConditionFunctions.c Wed May 11 14:43:33 2011 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2841 +0,0 @@
-/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-**
-** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
-** Melbourne, 3053, Australia.
-**
-** Primary Contributing Organisations:
-** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
-** Australian Computational Earth Systems Simulator - http://www.access.edu.au
-** Monash Cluster Computing - http://www.mcc.monash.edu.au
-** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
-**
-** Contributors:
-** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
-** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
-** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
-** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
-** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
-** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
-** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
-** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
-** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
-** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
-**
-** This library is free software; you can redistribute it and/or
-** modify it under the terms of the GNU Lesser General Public
-** License as published by the Free Software Foundation; either
-** version 2.1 of the License, or (at your option) any later version.
-**
-** This library is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** Lesser General Public License for more details.
-**
-** You should have received a copy of the GNU Lesser General Public
-** License along with this library; if not, write to the Free Software
-** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-**
-** $Id: StandardConditionFunctions.c 1196 2008-08-04 16:29:30Z LukeHodkinson $
-**
-**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-#include <string.h>
-#include <mpi.h>
-#include <StGermain/StGermain.h>
-#include <StgDomain/StgDomain.h>
-#include <StgFEM/StgFEM.h>
-#include <assert.h>
-#include "StandardConditionFunctions.h"
-#include "muParser.h"
-
-const Type StgFEM_StandardConditionFunctions_Type = "StgFEM_StandardConditionFunctions";
-
-void _StgFEM_StandardConditionFunctions_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
- Codelet* self = (Codelet*)component;
- AbstractContext* context;
- ConditionFunction* condFunc;
- Dictionary* pluginDict = Codelet_GetPluginDictionary( component, cf->rootDict );
-
- context = (AbstractContext*)Stg_ComponentFactory_ConstructByName( cf, Dictionary_GetString( pluginDict, (Dictionary_Entry_Key)"Context" ), AbstractContext, True, data );
- self->context = context;
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SolidBodyRotation, "Velocity_SolidBodyRotation" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_PartialRotationX, "Velocity_PartialRotationX" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_PartialRotationY, "Velocity_PartialRotationY" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_TaperedRotationX, "TaperedRotationX" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_TaperedRotationY, "TaperedRotationY" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SimpleShear, "Velocity_SimpleShear" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SimpleShearInverted, "Velocity_SimpleShearInverted" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_ShearZ, "ShearZ" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_Extension, "Velocity_Extension" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_PartialLid_TopLayer, "Velocity_PartialLid_TopLayer" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_Trigonometry, "Temperature_Trigonometry" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_LinearInterpolationLid, "Velocity_LinearInterpolationLid" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_Lid_RampWithCentralMax, "Velocity_Lid_RampWithCentralMax" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_LinearVelocityLeftWall, "LinearVelocityLeftWall" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_LinearVelocityRightWall, "LinearVelocityRightWall" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SinusoidalLid, "Velocity_SinusoidalLid" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_CornerOnly, "Velocity_Lid_CornerOnly" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_TemperatureCosineHill, "Temperature_CosineHill" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_ConvectionBenchmark, "Temperature_ConvectionBenchmark" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_LinearWithSinusoidalPerturbation, "LinearWithSinusoidalPerturbation" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_EdgeDriveConvectionIC, "EdgeDriveConvectionIC" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_ThermalEdgeDriveConvectionIC, "ThermalEdgeDriveConvectionIC" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_AnalyticalTemperatureIC, "AnalyticalTemperatureIC" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New( Stg_FEM_VelicTemperatureIC, "VelicTemperatureIC" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New( Stg_FEM_VelicTemperatureIC_SolB, "VelicTemperatureIC_SolB" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SinusoidalExtension, "SinusoidalExtension" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_StepFunction, "StepFunction" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StG_FEM_StandardConditionFunctions_StepFunctionProduct1, "StepFunctionProduct1");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StG_FEM_StandardConditionFunctions_StepFunctionProduct2, "StepFunctionProduct2");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StG_FEM_StandardConditionFunctions_StepFunctionProduct3, "StepFunctionProduct3");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StG_FEM_StandardConditionFunctions_StepFunctionProduct4, "StepFunctionProduct4");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_TemperatureProfile, "TemperatureProfile");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StG_FEM_StandardConditionFunctions_Gaussian, "Gaussian");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_ERF,
- (char*)"ERF");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_ERFC,
- (char*)"ERFC");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_RubberSheet,
- (char*)"RubberSheet");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_MovingStepFunction, "MovingStepFunction");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SpecRidge3D, "SpecRidge3D" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SpectralBCX, "SpectralBCX" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SpectralBCY, "SpectralBCY" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SpectralBCZ, "SpectralBCZ" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SpectralPressureBCX, "SpectralPressureBCX" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SpectralPressureBCY, "SpectralPressureBCY" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_ErrorFunc, "ErrorFunc" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_ConstantVector, "ConstantVector" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_GaussianDistribution, "GaussianDistribution" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_1DGaussianDistribution, "1DGaussianDistribution" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_HalfContainer, "HalfContainer" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_ConstantValue, "ConstantValue" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_DiagonalLine, "DiagonalLine" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_DeltaFunction, "DeltaFunction" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_InflowBottom, "InflowBottom" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_GaussianTube, "GaussianTube" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_GravitationalPotential, "GravitationalPotential" );
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_WarsTemperature,
- "WarsTemperature");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_Quadratic,
- "Quadratic");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
-
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File1,
- "File1");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File2,
- "File2");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File3,
- "File3");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File4,
- "File4");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File5,
- "File5");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File6,
- "File6");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File7,
- "File7");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File8,
- "File8");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File9,
- "File9");
- ConditionFunction_Register_Add( condFunc_Register, condFunc );
- condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File10,
- "File10");
- ConditionFunction_Register_Add(condFunc_Register,condFunc);
- condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation1,
- "Equation1");
- ConditionFunction_Register_Add(condFunc_Register,condFunc);
- condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation2,
- "Equation2");
- ConditionFunction_Register_Add(condFunc_Register,condFunc);
- condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation3,
- "Equation3");
- ConditionFunction_Register_Add(condFunc_Register,condFunc);
- condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation4,
- "Equation4");
- ConditionFunction_Register_Add(condFunc_Register,condFunc);
- condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation5,
- "Equation5");
- ConditionFunction_Register_Add(condFunc_Register,condFunc);
- condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation6,
- "Equation6");
- ConditionFunction_Register_Add(condFunc_Register,condFunc);
- condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation7,
- "Equation7");
- ConditionFunction_Register_Add(condFunc_Register,condFunc);
- condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation8,
- "Equation8");
- ConditionFunction_Register_Add(condFunc_Register,condFunc);
- condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation9,
- "Equation9");
- ConditionFunction_Register_Add(condFunc_Register,condFunc);
- condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation10,
- "Equation10");
- ConditionFunction_Register_Add(condFunc_Register,condFunc);
-}
-
-void _StgFEM_StandardConditionFunctions_Destroy( void* _self, void* data ) {
- /* This function will totally clean the condFunc_Register
- *
- * This could be trouble some if other code adds or deletes condition functions on this register
- */
-
- unsigned *refCount = &(condFunc_Register->count);
-
- /* first check if there are things still on the condFunc_Register, if so .... */
- if( *refCount != 0 ) {
- while( *refCount != 0 ) {
-
- _ConditionFunction_Delete( condFunc_Register->_cf[ *refCount-1 ] );
- condFunc_Register->_cf[ *refCount-1 ] = NULL;
-
- *refCount = *refCount - 1;
- }
- }
- _Codelet_Destroy( _self, data );
-}
-void* _StgFEM_StandardConditionFunctions_DefaultNew( Name name ) {
- return Codelet_New(
- StgFEM_StandardConditionFunctions_Type,
- _StgFEM_StandardConditionFunctions_DefaultNew,
- _StgFEM_StandardConditionFunctions_AssignFromXML,
- _Codelet_Build,
- _Codelet_Initialise,
- _Codelet_Execute,
- _StgFEM_StandardConditionFunctions_Destroy,
- name );
-}
-
-Index StgFEM_StandardConditionFunctions_Register( PluginsManager* pluginsManager ) {
- Journal_DPrintf( StgFEM_Debug, "In: %s( void* )\n", __func__ );
-
- return PluginsManager_Submit( pluginsManager, StgFEM_StandardConditionFunctions_Type, (Name)"0", _StgFEM_StandardConditionFunctions_DefaultNew );
-}
-
-Bool StgFEM_StandardConditionFunctions_Init( int* argc, char** argv[] ) {
- Stg_ComponentRegister* componentsRegister = Stg_ComponentRegister_Get_ComponentRegister();
- Stg_ComponentRegister_Add(componentsRegister,
- StgFEM_StandardConditionFunctions_Type, (Name)"0",
- _StgFEM_StandardConditionFunctions_DefaultNew );
- RegisterParent( StgFEM_StandardConditionFunctions_Type, Stg_Component_Type );
- return True;
-}
-
-#ifdef NO_ERF
-
-/* Copied from the OpenBSD iplementation of erf.c
- (src/lib/libm/src/erf.c and src/lib/libm/src/math_private.h).
- Modified to only work on 32 bit little endian machines.
- This is just a hack for Windows machines. */
-
-/* @(#)s_erf.c 5.1 93/09/24 */
-/*
- * ====================================================
- * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
- *
- * Developed at SunPro, a Sun Microsystems, Inc. business.
- * Permission to use, copy, modify, and distribute this
- * software is freely granted, provided that this notice
- * is preserved.
- * ====================================================
- */
-
-/* double erf(double x)
- * double erfc(double x)
- * x
- * 2 |\
- * erf(x) = --------- | exp(-t*t)dt
- * sqrt(pi) \|
- * 0
- *
- * erfc(x) = 1-erf(x)
- * Note that
- * erf(-x) = -erf(x)
- * erfc(-x) = 2 - erfc(x)
- *
- * Method:
- * 1. For |x| in [0, 0.84375]
- * erf(x) = x + x*R(x^2)
- * erfc(x) = 1 - erf(x) if x in [-.84375,0.25]
- * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375]
- * where R = P/Q where P is an odd poly of degree 8 and
- * Q is an odd poly of degree 10.
- * -57.90
- * | R - (erf(x)-x)/x | <= 2
- *
- *
- * Remark. The formula is derived by noting
- * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
- * and that
- * 2/sqrt(pi) = 1.128379167095512573896158903121545171688
- * is close to one. The interval is chosen because the fix
- * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
- * near 0.6174), and by some experiment, 0.84375 is chosen to
- * guarantee the error is less than one ulp for erf.
- *
- * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and
- * c = 0.84506291151 rounded to single (24 bits)
- * erf(x) = sign(x) * (c + P1(s)/Q1(s))
- * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0
- * 1+(c+P1(s)/Q1(s)) if x < 0
- * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06
- * Remark: here we use the taylor series expansion at x=1.
- * erf(1+s) = erf(1) + s*Poly(s)
- * = 0.845.. + P1(s)/Q1(s)
- * That is, we use rational approximation to approximate
- * erf(1+s) - (c = (single)0.84506291151)
- * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
- * where
- * P1(s) = degree 6 poly in s
- * Q1(s) = degree 6 poly in s
- *
- * 3. For x in [1.25,1/0.35(~2.857143)],
- * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1)
- * erf(x) = 1 - erfc(x)
- * where
- * R1(z) = degree 7 poly in z, (z=1/x^2)
- * S1(z) = degree 8 poly in z
- *
- * 4. For x in [1/0.35,28]
- * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
- * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0
- * = 2.0 - tiny (if x <= -6)
- * erf(x) = sign(x)*(1.0 - erfc(x)) if x < 6, else
- * erf(x) = sign(x)*(1.0 - tiny)
- * where
- * R2(z) = degree 6 poly in z, (z=1/x^2)
- * S2(z) = degree 7 poly in z
- *
- * Note1:
- * To compute exp(-x*x-0.5625+R/S), let s be a single
- * precision number and s := x; then
- * -x*x = -s*s + (s-x)*(s+x)
- * exp(-x*x-0.5626+R/S) =
- * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
- * Note2:
- * Here 4 and 5 make use of the asymptotic series
- * exp(-x*x)
- * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
- * x*sqrt(pi)
- * We use rational approximation to approximate
- * g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625
- * Here is the error bound for R1/S1 and R2/S2
- * |R1/S1 - f(x)| < 2**(-62.57)
- * |R2/S2 - f(x)| < 2**(-61.52)
- *
- * 5. For inf > x >= 28
- * erf(x) = sign(x) *(1 - tiny) (raise inexact)
- * erfc(x) = tiny*tiny (raise underflow) if x > 0
- * = 2 - tiny if x<0
- *
- * 7. Special case:
- * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
- * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
- * erfc/erf(NaN) is NaN
- */
-
-/* Assume little endian, 32 bit machines */
-
-typedef int int32_t;
-typedef unsigned int u_int32_t;
-
-typedef union
-{
- double value;
- struct
- {
- u_int32_t lsw;
- u_int32_t msw;
- } parts;
-} ieee_double_shape_type;
-
-/* Get the more significant 32 bit int from a double. */
-
-#define GET_HIGH_WORD(i,d) \
-do { \
- ieee_double_shape_type gh_u; \
- gh_u.value = (d); \
- (i) = gh_u.parts.msw; \
-} while (0)
-
-/* Set the less significant 32 bits of a double from an int. */
-
-#define SET_LOW_WORD(d,v) \
-do { \
- ieee_double_shape_type sl_u; \
- sl_u.value = (d); \
- sl_u.parts.lsw = (v); \
- (d) = sl_u.value; \
-} while (0)
-
-
-static const double
-tiny = 1e-300,
-half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
-one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
-two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
- /* c = (float)0.84506291151 */
-erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */
-/*
- * Coefficients for approximation to erf on [0,0.84375]
- */
-efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */
-efx8= 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */
-pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */
-pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */
-pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */
-pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */
-pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */
-qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */
-qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */
-qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */
-qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */
-qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */
-/*
- * Coefficients for approximation to erf in [0.84375,1.25]
- */
-pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */
-pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */
-pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */
-pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */
-pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */
-pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */
-pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */
-qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */
-qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */
-qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */
-qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */
-qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */
-qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */
-/*
- * Coefficients for approximation to erfc in [1.25,1/0.35]
- */
-ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */
-ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */
-ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */
-ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */
-ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */
-ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */
-ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */
-ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */
-sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */
-sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */
-sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */
-sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */
-sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */
-sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */
-sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */
-sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */
-/*
- * Coefficients for approximation to erfc in [1/.35,28]
- */
-rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */
-rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */
-rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */
-rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */
-rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */
-rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */
-rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */
-sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */
-sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */
-sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */
-sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */
-sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */
-sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */
-sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */
-
-double
-erf(double x)
-{
- int32_t hx,ix,i;
- double R,S,P,Q,s,y,z,r;
- GET_HIGH_WORD(hx,x);
- ix = hx&0x7fffffff;
- if(ix>=0x7ff00000) { /* erf(nan)=nan */
- i = ((u_int32_t)hx>>31)<<1;
- return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */
- }
-
- if(ix < 0x3feb0000) { /* |x|<0.84375 */
- if(ix < 0x3e300000) { /* |x|<2**-28 */
- if (ix < 0x00800000)
- return 0.125*(8.0*x+efx8*x); /*avoid underflow */
- return x + efx*x;
- }
- z = x*x;
- r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
- s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
- y = r/s;
- return x + x*y;
- }
- if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */
- s = fabs(x)-one;
- P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
- Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
- if(hx>=0) return erx + P/Q; else return -erx - P/Q;
- }
- if (ix >= 0x40180000) { /* inf>|x|>=6 */
- if(hx>=0) return one-tiny; else return tiny-one;
- }
- x = fabs(x);
- s = one/(x*x);
- if(ix< 0x4006DB6E) { /* |x| < 1/0.35 */
- R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
- ra5+s*(ra6+s*ra7))))));
- S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
- sa5+s*(sa6+s*(sa7+s*sa8)))))));
- } else { /* |x| >= 1/0.35 */
- R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
- rb5+s*rb6)))));
- S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
- sb5+s*(sb6+s*sb7))))));
- }
- z = x;
- SET_LOW_WORD(z,0);
- r = exp(-z*z-0.5625)*exp((z-x)*(z+x)+R/S);
- if(hx>=0) return one-r/x; else return r/x-one;
-}
-
-double
-erfc(double x)
-{
- int32_t hx,ix;
- double R,S,P,Q,s,y,z,r;
- GET_HIGH_WORD(hx,x);
- ix = hx&0x7fffffff;
- if(ix>=0x7ff00000) { /* erfc(nan)=nan */
- /* erfc(+-inf)=0,2 */
- return (double)(((u_int32_t)hx>>31)<<1)+one/x;
- }
-
- if(ix < 0x3feb0000) { /* |x|<0.84375 */
- if(ix < 0x3c700000) /* |x|<2**-56 */
- return one-x;
- z = x*x;
- r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
- s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
- y = r/s;
- if(hx < 0x3fd00000) { /* x<1/4 */
- return one-(x+x*y);
- } else {
- r = x*y;
- r += (x-half);
- return half - r ;
- }
- }
- if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */
- s = fabs(x)-one;
- P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
- Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
- if(hx>=0) {
- z = one-erx; return z - P/Q;
- } else {
- z = erx+P/Q; return one+z;
- }
- }
- if (ix < 0x403c0000) { /* |x|<28 */
- x = fabs(x);
- s = one/(x*x);
- if(ix< 0x4006DB6D) { /* |x| < 1/.35 ~ 2.857143*/
- R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
- ra5+s*(ra6+s*ra7))))));
- S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
- sa5+s*(sa6+s*(sa7+s*sa8)))))));
- } else { /* |x| >= 1/.35 ~ 2.857143 */
- if(hx<0&&ix>=0x40180000) return two-tiny;/* x < -6 */
- R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
- rb5+s*rb6)))));
- S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
- sb5+s*(sb6+s*sb7))))));
- }
- z = x;
- SET_LOW_WORD(z,0);
- r = exp(-z*z-0.5625)*
- exp((z-x)*(z+x)+R/S);
- if(hx>0) return r/x; else return two-r/x;
- } else {
- if(hx>0) return tiny*tiny; else return two-tiny;
- }
-}
-
-#endif
-
-
-void StgFEM_StandardConditionFunctions_SolidBodyRotation( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
- Coord centre;
- Coord vector;
- double omega;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
-
- /* Find Centre of Solid Body Rotation */
- centre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreX", 0.0 );
- centre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreY", 0.0 );
- centre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreZ", 0.0 );
- omega = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationOmega", 1.0 );
-
- /* Find coordinate of node */
- coord = Mesh_GetVertex( mesh, node_lI );
-
- /* Find vector from centre to node */
- StGermain_VectorSubtraction( vector, coord, centre, 2 );
-
- result[ I_AXIS ] = -omega * vector[ J_AXIS ];
- result[ J_AXIS ] = omega * vector[ I_AXIS ];
-}
-
-
-void StgFEM_StandardConditionFunctions_PartialRotationX( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
- Coord centre;
- Coord vector;
- double omega;
- double size;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
-
- /* Find Centre of Solid Body Rotation */
- centre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreX", 0.0 );
- centre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreY", 0.0 );
- centre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreZ", 0.0 );
- size = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"RadiusCylinder", 0.0 );
- omega = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationOmega", 1.0 );
-
- /* Find coordinate of node */
- coord = Mesh_GetVertex( mesh, node_lI );
-
- /* Find vector from centre to node */
- StGermain_VectorSubtraction( vector, coord, centre, 2 );
-
- /*if (context->currentTime > 1.33e-6)
- omega=0.0;*/
-
- if ((vector[ I_AXIS ]*vector[ I_AXIS ]+vector[ J_AXIS ]*vector[ J_AXIS ])<=size*size)
- *result = -omega * vector[ J_AXIS ];
- else
- *result = 0.0;
-}
-
-void StgFEM_StandardConditionFunctions_PartialRotationY( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
- Coord centre;
- Coord vector;
- double omega;
- double size;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
-
- /* Find Centre of Solid Body Rotation */
- centre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreX", 0.0 );
- centre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreY", 0.0 );
- centre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreZ", 0.0 );
- size = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"RadiusCylinder", 0.0 );
- omega = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationOmega", 1.0 );
-
- /* Find coordinate of node */
- coord = Mesh_GetVertex( mesh, node_lI );
-
- /* Find vector from centre to node */
- StGermain_VectorSubtraction( vector, coord, centre, 2 );
-
- if ((vector[ I_AXIS ]*vector[ I_AXIS ]+vector[ J_AXIS ]*vector[ J_AXIS ])<=size*size)
- *result = omega * vector[ I_AXIS ];
- else
- *result = 0.0;
-}
-
-
-void StgFEM_StandardConditionFunctions_TaperedRotationX( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
- Coord centre;
- Coord vector;
- double omega;
- double size, r, taper;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
-
- /* Find Centre of Solid Body Rotation */
- centre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationCentreX", 0.0 );
- centre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationCentreY", 0.0 );
- centre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationCentreZ", 0.0 );
- size = Dictionary_GetDouble_WithDefault( dictionary, "RadiusCylinder", 0.0 );
- omega = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationOmega", 1.0 );
-
- taper = Dictionary_GetDouble_WithDefault( dictionary, "TaperedRadius", 0.0 );
-
- /* Find coordinate of node */
- coord = Mesh_GetVertex( mesh, node_lI );
-
- /* Find vector from centre to node */
- StGermain_VectorSubtraction( vector, coord, centre, 2 );
-
- r=sqrt(vector[ I_AXIS ]*vector[ I_AXIS ]
- +vector[ J_AXIS ]*vector[ J_AXIS ]);
- if (r<=size)
- *result = -omega * vector[ J_AXIS ];
- else if(r<=taper)
- *result = -omega * vector[ J_AXIS ]*(taper-r)/(taper-size);
- else
- *result = 0;
-}
-
-void StgFEM_StandardConditionFunctions_TaperedRotationY( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
- Coord centre;
- Coord vector;
- double omega;
- double size, r, taper;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
-
- /* Find Centre of Solid Body Rotation */
- centre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationCentreX", 0.0 );
- centre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationCentreY", 0.0 );
- centre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationCentreZ", 0.0 );
- size = Dictionary_GetDouble_WithDefault( dictionary, "RadiusCylinder", 0.0 );
- omega = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationOmega", 1.0 );
-
- taper = Dictionary_GetDouble_WithDefault( dictionary, "TaperedRadius", 0.0 );
-
- /* Find coordinate of node */
- coord = Mesh_GetVertex( mesh, node_lI );
-
- /* Find vector from centre to node */
- StGermain_VectorSubtraction( vector, coord, centre, 2 );
-
-
- r=sqrt(vector[ I_AXIS ]*vector[ I_AXIS ]
- +vector[ J_AXIS ]*vector[ J_AXIS ]);
- if (r<=size)
- *result = omega * vector[ I_AXIS ];
- else if(r<=taper)
- *result = omega * vector[ I_AXIS ]*(taper-r)/(taper-size);
- else
- *result = 0;
-}
-
-
-
-
-void StgFEM_StandardConditionFunctions_SimpleShear( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
- double centre;
- double factor;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
-
- /* Find Centre of Solid Body Rotation */
- centre = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SimpleShearCentreY", 0.0 );
- factor = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SimpleShearFactor", 1.0 );
-
- /* Find coordinate of node */
- coord = Mesh_GetVertex( mesh, node_lI );
-
- *result = factor * (coord[ J_AXIS ] - centre);
-}
-
-void StgFEM_StandardConditionFunctions_ShearZ( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
- double centre;
- double factor;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
-
- /* Find Centre of Solid Body Rotation */
- centre = Dictionary_GetDouble_WithDefault( dictionary, "ShearZCentre", 0.0 );
- factor = Dictionary_GetDouble_WithDefault( dictionary, "ShearZFactor", 1.0 );
-
- /* Find coordinate of node */
- coord = Mesh_GetVertex( mesh, node_lI );
-
- *result = factor * (coord[ K_AXIS ] - centre);
-}
-
-void StgFEM_StandardConditionFunctions_SimpleShearInverted( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
- double centre;
- double factor;
- double yAxisInvert;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
-
- /* Find Centre of Solid Body Rotation */
- centre = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SimpleShearCentreY", 0.0 );
- factor = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SimpleShearFactor", 1.0 );
-
- /* Find coordinate of node */
- coord = Mesh_GetVertex( mesh, node_lI );
-
- yAxisInvert = coord[ J_AXIS ] * -1.0 - 1.0;
-
- *result = factor * ( 1.0 - coord[ J_AXIS ] ) ;
-}
-
-
-void StgFEM_StandardConditionFunctions_Extension( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
- double centre;
- double factor;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
-
- /* Find Centre of Solid Body Rotation */
- centre = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ExtensionCentreX", 0.0 );
- factor = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ExtensionFactor", 1.0 );
-
- /* Find coordinate of node */
- coord = Mesh_GetVertex( mesh, node_lI );
-
- *result = factor * (coord[ I_AXIS ] - centre);
-}
-
-
-void StgFEM_StandardConditionFunctions_PartialLid_TopLayer( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
- DomainContext* context = (DomainContext*)_context;
- FeVariable* velVar = NULL;
- FeMesh* mesh = NULL;
- double* velResult = (double*)result;
- double margin = 0;
- double min[3], max[3];
-
- velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = velVar->feMesh;
-
- Mesh_GetMinimumSeparation( mesh, &margin, NULL );
- Mesh_GetGlobalCoordRange( mesh, min, max );
- margin *= 1.1;
- if( (Mesh_GetVertex( mesh, node_lI )[I_AXIS] < (max[I_AXIS] - margin )) &&
- (Mesh_GetVertex( mesh, node_lI )[I_AXIS] > (min[I_AXIS] + margin )))
- {
- (*velResult) = 1;
- }
- else {
- (*velResult) = 0;
- }
-}
-
-void StgFEM_StandardConditionFunctions_LinearInterpolationLid( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
- DomainContext* context = (DomainContext*)_context;
- FeVariable* velVar = NULL;
- FeMesh* mesh = NULL;
- double* velResult = (double*)result;
- double boxLength = 0;
- double leftHandSideValue = 0;
- double rightHandSideValue = 0;
- double gradient = 0;
- double min[3], max[3];
-
- velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = velVar->feMesh;
-
- Mesh_GetGlobalCoordRange( mesh, min, max );
- boxLength = max[I_AXIS] - min[I_AXIS];
- leftHandSideValue = Dictionary_GetDouble_WithDefault( context->dictionary, (Dictionary_Entry_Key)"bcLeftHandSideValue", 0.0 );
- rightHandSideValue = Dictionary_GetDouble_WithDefault( context->dictionary, (Dictionary_Entry_Key)"bcRightHandSideValue", 1.0 );
- gradient = (rightHandSideValue - leftHandSideValue) / boxLength;
- (*velResult ) = leftHandSideValue + gradient * (Mesh_GetVertex( mesh, node_lI )[I_AXIS] - min[I_AXIS] );
-}
-
-
-void StgFEM_StandardConditionFunctions_Lid_RampWithCentralMax( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
- DomainContext* context = (DomainContext*)_context;
- FeVariable* velVar = NULL;
- FeMesh* mesh = NULL;
- double* velResult = (double*)result;
- double boxLength = 0;
- double xPosRelativeToTopLeft = 0;
- double min[3], max[3];
-
- velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = velVar->feMesh;
-
- Mesh_GetGlobalCoordRange( mesh, min, max );
- xPosRelativeToTopLeft = Mesh_GetVertex( mesh, node_lI )[I_AXIS] - min[I_AXIS];
- boxLength = max[I_AXIS] - min[I_AXIS];
- if ( xPosRelativeToTopLeft < boxLength / 2 ) {
- (*velResult) = 2 * xPosRelativeToTopLeft / boxLength;
- }
- else {
- (*velResult) = 1 - 2 * ( xPosRelativeToTopLeft - (boxLength/2) );
- }
-}
-void StgFEM_StandardConditionFunctions_LinearVelocityLeftWall( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
- DomainContext* context = (DomainContext*)_context;
- FeVariable* velVar = NULL;
- FeMesh* mesh = NULL;
- double* velResult = (double*)result;
- Dictionary* dictionary = context->dictionary;
- double min[3], max[3];
- double gradient, maxvel;
- velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = velVar->feMesh;
-
- maxvel = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"MaximumVelocity_Left", 0.0 );
- Mesh_GetGlobalCoordRange( mesh, min, max );
- gradient = maxvel/(min[1] - max[1]);
-
- (*velResult) = gradient*Mesh_GetVertex( mesh, node_lI )[J_AXIS];
- //printf("Left velResult is %g\n",(*velResult));
-
-}
-void StgFEM_StandardConditionFunctions_LinearVelocityRightWall( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
- DomainContext* context = (DomainContext*)_context;
- FeVariable* velVar = NULL;
- FeMesh* mesh = NULL;
- double* velResult = (double*)result;
- Dictionary* dictionary = context->dictionary;
- double min[3], max[3];
- double gradient, maxvel;
- velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = velVar->feMesh;
-
- maxvel = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"MaximumVelocity_Right", 0.0 );
- Mesh_GetGlobalCoordRange( mesh, min, max );
- gradient = maxvel/(max[1] - min[1]);
-
- (*velResult) = maxvel - gradient*Mesh_GetVertex( mesh, node_lI )[J_AXIS];
- //printf("Right velResult is %g\n",(*velResult));
-}
-
-
-void StgFEM_StandardConditionFunctions_SinusoidalLid( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
- DomainContext* context = (DomainContext*)_context;
- FeVariable* velVar = NULL;
- FeMesh* mesh = NULL;
- double* velResult = (double*)result;
- double boxLength = 0;
- double linearInterp = 0;
- double wavenumber;
- double min[3], max[3];
-
- wavenumber = Dictionary_GetDouble_WithDefault( context->dictionary, (Dictionary_Entry_Key)"sinusoidalLidWavenumber", 1 );
-
- velVar = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = velVar->feMesh;
-
- Mesh_GetGlobalCoordRange( mesh, min, max );
- boxLength = max[I_AXIS] - min[I_AXIS];
- linearInterp = (Mesh_GetVertex( mesh, node_lI )[I_AXIS] - min[I_AXIS] ) / boxLength;
- (*velResult) = sin( linearInterp * M_PI * wavenumber );
-}
-
-
-void StgFEM_StandardConditionFunctions_CornerOnly( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
- DomainContext* context = (DomainContext*)_context;
- FeVariable* velVar = NULL;
- FeMesh* feMesh = NULL;
- double* velResult = (double*)result;
- Node_GlobalIndex node_gI = 0;
- unsigned inds[3];
- Grid* elGrid;
-
- velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- feMesh = velVar->feMesh;
- elGrid = *(Grid**)ExtensionManager_Get( feMesh->info, feMesh,
- ExtensionManager_GetHandle( feMesh->info, (Name)"elGrid" ) );
-
- node_gI = Mesh_DomainToGlobal( feMesh, MT_VERTEX, node_lI );
- RegularMeshUtils_Node_1DTo3D( feMesh, node_gI, inds );
-
- if ( inds[0] == elGrid->sizes[I_AXIS] ) {
- (*velResult) = 1;
- }
- else {
- (*velResult) = 0;
- }
-}
-
-double StGermain_CosineHillValue( double* centre, double* position, double height, double diameterAtBase, Dimension_Index dim ) {
- double distanceFromCentre = StGermain_DistanceBetweenPoints( centre, position, dim );
-
- if (distanceFromCentre < diameterAtBase * 0.5 )
- return height * (0.5 + 0.5 * cos( 2.0 * M_PI/diameterAtBase * distanceFromCentre ) );
- else
- return 0.0;
-}
-
-void StgFEM_StandardConditionFunctions_TemperatureCosineHill( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* feMesh = NULL;
- double* result = (double*) _result;
- Coord centre;
- Coord rotationCentre;
- double omega;
- double hillHeight;
- double hillDiameter;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- feMesh = feVariable->feMesh;
-
- /* Read values from dictionary */
- hillHeight = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"CosineHillHeight" , 1.0 );
- hillDiameter = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"CosineHillDiameter", 1.0 );
- centre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"CosineHillCentreX" , 0.0 );
- centre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"CosineHillCentreY" , 0.0 );
- centre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"CosineHillCentreZ" , 0.0 );
-
- if ( Dictionary_GetBool( dictionary, "RotateCosineHill" ) ) {
- /* Assume solid body rotation */
- rotationCentre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreX", 0.0 );
- rotationCentre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreY", 0.0 );
- rotationCentre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreZ", 0.0 );
- omega = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationOmega", 1.0 );
-
- StGermain_VectorSubtraction( centre, rotationCentre, centre, context->dim );
- StGermain_RotateCoordinateAxis( centre, centre, K_AXIS, omega * context->currentTime );
- StGermain_VectorAddition( centre, centre, rotationCentre, context->dim );
- }
-
- *result = StGermain_CosineHillValue( centre, Mesh_GetVertex( feMesh, node_lI ), hillHeight, hillDiameter, context->dim );
-}
-
-
-void StgFEM_StandardConditionFunctions_LinearWithSinusoidalPerturbation( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* feMesh = NULL;
- unsigned nDims;
- double* result = (double*) _result;
- double topLayerBC;
- double bottomLayerBC;
- double perturbationAmplitude;
- double horizontalWaveNumber;
- double verticalWaveNumber;
- double scaleFactor;
- double* coord;
- Coord relScaledCoord;
- double min[3], max[3], topLayerCoord, bottomLayerCoord;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- feMesh = feVariable->feMesh;
-
- nDims = Mesh_GetDimSize( feMesh );
- Mesh_GetGlobalCoordRange( feMesh, min, max );
-
- topLayerCoord = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_TopLayerCoord", max[J_AXIS] );
- bottomLayerCoord = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_BottomLayerCoord", min[J_AXIS] );
-
- topLayerBC = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_TopLayerBC", 0.0 );
- bottomLayerBC = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_BottomLayerBC", 1.0 );
- scaleFactor = bottomLayerBC - topLayerBC;
- perturbationAmplitude = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_PerturbationAmplitude", 0.1 );
- /* Note: these are both multiplied by pi, so wavenumber = 1 means the perturbation goes from 0 to pi, which is
- * half a full sin or cos cycle. Wavenumber = 3 means the range is 0 -> 3pi, or 1 and a half full cycles. */
- horizontalWaveNumber = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_HorizontalWaveNumber", 1.0 );
- verticalWaveNumber = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_VerticalWaveNumber", 1.0 );
-
- coord = Mesh_GetVertex( feMesh, node_lI );
-
- /* if node is outside IC shape set to 0 temperature */
- if( coord[J_AXIS] > topLayerCoord || coord[J_AXIS] < bottomLayerCoord ) {
- *result = 0; return ;
- }
-
- /* make coord relative to box bottom left corner, then scale from 0 to 1 between box min & max */
- relScaledCoord[I_AXIS] = (coord[0] - min[0]) / (max[0] - min[0]);
- relScaledCoord[J_AXIS] = (coord[1] - bottomLayerCoord) / (topLayerCoord - bottomLayerCoord);
-
-
- /* Note: ok to use the 1.0 below since we've already scaled the coord to somewhere between 0 to 1 */
- *result = topLayerBC + scaleFactor * ( 1.0 - relScaledCoord[ J_AXIS ] )
- + perturbationAmplitude * ( cos( horizontalWaveNumber * M_PI * coord[ I_AXIS ] )
- * sin( verticalWaveNumber * M_PI * relScaledCoord[ J_AXIS ] ) );
-}
-
-void StgFEM_StandardConditionFunctions_Trigonometry( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* feMesh = NULL;
- double* result = (double*) _result;
- double* coord;
- double height, width;
- double min[3], max[3];
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- feMesh = feVariable->feMesh;
-
- Mesh_GetGlobalCoordRange( feMesh, min, max );
- coord = Mesh_GetVertex( feMesh, node_lI );
-
- /* Get Aspect Ratio */
- height = max[ J_AXIS ] - min[ J_AXIS ];
- width = max[ I_AXIS ] - min[ I_AXIS ];
-
- *result = 1.0 - 0.5 * M_PI * coord[ J_AXIS ] * sin( M_PI * coord[ I_AXIS ]/width );
-}
-
-#define SMALL 1.0e-5
-void Stg_FEM_VelicTemperatureIC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- FeVariable* temperatureField = (FeVariable*) FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- FeMesh* feMesh = temperatureField->feMesh;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double x;
- double y;
- double kx;
- double ky;
- int wavenumberX;
- double wavenumberY;
- double sigma;
- double Lx;
- double min[3], max[3];
-
- /* Find coordinate of node */
- coord = Mesh_GetVertex( feMesh, node_lI );
- Mesh_GetGlobalCoordRange( feMesh, min, max );
-
- /* Make sure that the box has right dimensions */
- assert( ( max[ J_AXIS ] - min[ J_AXIS ] - 1.0 ) < SMALL );
- Lx = max[ I_AXIS ] - min[ I_AXIS ];
-
- x = coord[ I_AXIS ] - min[ I_AXIS ];
- y = coord[ J_AXIS ] - min[ J_AXIS ];
-
- wavenumberX = Dictionary_GetInt_WithDefault( dictionary, (Dictionary_Entry_Key)"wavenumberX", 1 );
- wavenumberY = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"wavenumberY", 1.0 );
- sigma = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"sigma", 1.0 );
-
- assert( sigma > 0.0 );
- assert( wavenumberY > 0.0 );
- assert( wavenumberX > 0.0 );
-
- kx = (double)wavenumberX * M_PI / Lx;
- ky = (double)wavenumberY * M_PI;
-
- *result = sigma * sin( ky * y ) * cos( kx * x );
-}
-
-/* IC from Mirko Velic. This is the IC temperature for his solB, from his Analytic Suite. Added 22-May-2006 */
-void Stg_FEM_VelicTemperatureIC_SolB( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- FeVariable* temperatureField = (FeVariable*) FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- FeMesh* feMesh = temperatureField->feMesh;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double x;
- double y;
- double km; /* for y-direction */
- double kn; /* for x-direction */
- double wavenumberX;
- double wavenumberY;
- double L;
- double sigma;
- double min[3], max[3];
-
- /* Find coordinate of node */
- coord = Mesh_GetVertex( feMesh, node_lI );
- Mesh_GetGlobalCoordRange( feMesh, min, max );
-
- /* Make sure that the box has right dimensions */
- assert( (max[ J_AXIS ] - min[ J_AXIS ] - 1.0 ) < SMALL );
- L = max[ I_AXIS ] - min[ I_AXIS ];
-
- x = coord[ I_AXIS ] - min[ I_AXIS ];
- y = coord[ J_AXIS ] - min[ J_AXIS ];
-
- wavenumberX = Dictionary_GetInt_WithDefault( dictionary, (Dictionary_Entry_Key)"wavenumberX", 1 );
- wavenumberY = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"wavenumberY", 2.0 );
- assert( wavenumberX != wavenumberY );
- sigma = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"sigma", 1.0 );
-
- kn = wavenumberX * M_PI / L;
-/* TODO: Re-write Mirko's code and/or Documentation so the input parameters for these ICs are less confusing */
- km = wavenumberY / L;
-
- *result = sigma * sinh( km * y ) * cos( kn * x );
-}
-
-
-/* Initial Condition derived from Boundary Layer theory -
- taken from P. E. van Keken, S. D. King, U. R. Schmeling, U. R. Christensen, D. Neumeister, and M.-P. Doin. A comparison of methods for the modeling of thermochemical convection. Journal of Geophysical Research, 102(B10):22477-22496, october 1997. */
-void StgFEM_StandardConditionFunctions_AnalyticalTemperatureIC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* feMesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double u0, v0, Q;
- double x, y;
- double RaT;
- double lambda, height, width;
- double Tu, Tl, Tr, Ts;
- double min[3], max[3];
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- feMesh = feVariable->feMesh;
-
- coord = Mesh_GetVertex( feMesh, node_lI );
- Mesh_GetGlobalCoordRange( feMesh, min, max );
-
- /* Get Aspect Ratio */
- height = max[ J_AXIS ] - min[ J_AXIS ];
- width = max[ I_AXIS ] - min[ I_AXIS ];
- lambda = width/height;
-
- x = coord[ I_AXIS ] - min[ I_AXIS ];
- y = coord[ J_AXIS ] - min[ J_AXIS ];
-
- /* Get thermal Rayleigh Number from Dictionary */
- RaT = Dictionary_GetDouble( dictionary, "RaT" );
-
- /* Horizontal fluid velocity at upper boundary & lower boundary - Equation A3 */
- u0 = pow( lambda , 7.0/3.0 )/ pow(1 + lambda*lambda*lambda*lambda, 2.0/3.0) * pow(0.5*RaT/sqrt(M_PI) , 2.0/3.0);
-
- /* Vertical velocity of the upwelling and downwellings - Modified from Van Keken to match Turcotte and Shubert */
- v0 = u0; /*lambda; */
-
- /* Total rate of heat flow out of the top of the cell per unit distance along the axis of the roll - Equation A3 */
- Q = 2.0 * sqrt(M_1_PI * lambda/u0);
- Tu = 0.5 * erf( 0.5 * ( 1 - y ) * sqrt(u0/x) ); /* Equation A2a */
- Tl = 1.0 - 0.5 * erf(0.5 * y * sqrt(u0/(lambda-x))); /* Equation A2b */
- Tr = 0.5 + 0.5*Q/sqrt(M_PI) * sqrt(v0/(y+1)) * exp( -x*x*v0/(4*y+4) ); /* Equation A2c */
- Ts = 0.5 - 0.5*Q/sqrt(M_PI) * sqrt(v0/(2-y)) * exp( -(lambda - x) * (lambda - x) * v0 / (8 - 4*y) ); /* Equation A2d */
-
- /* Equation A1 */
- *result = Tu + Tl + Tr + Ts - 1.5;
-
- /* Crop result */
- if ( *result > 1.0 )
- *result = 1.0;
- else if ( *result < 0.0 )
- *result = 0.0;
-
-}
-
-void StgFEM_StandardConditionFunctions_EdgeDriveConvectionIC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double perturbationAmplitude;
- double thermalAnomalyOffset;
- double* coord;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- mesh = feVariable->feMesh;
- perturbationAmplitude = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_PerturbationAmplitude", 0.1 );
- thermalAnomalyOffset = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"thermalAnomalyOffset", 0.0 );
- coord = Mesh_GetVertex( mesh, node_lI );
-
- /* eqn 1 from S.D.King & D.L. Anderson, "Edge-drive convection", EPSL 160 (1998) 289-296 */
-
- *result = 1.0 + perturbationAmplitude * sin( M_PI * coord[ J_AXIS ] ) * cos( 0.5 * M_PI * ( coord[ I_AXIS ] + thermalAnomalyOffset ) );
-}
-
-void StgFEM_StandardConditionFunctions_ThermalEdgeDriveConvectionIC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double* coord;
- int dim;
- double contStartX, contEndX;
- double contStartY, contEndY;
- double contStartZ, contEndZ;
- double minY, maxY, interiorTemp;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- dim = Dictionary_GetInt_WithDefault( dictionary, (Dictionary_Entry_Key)"dim", 0.0 );
- contStartX = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"contStartX", 0.0 );
- contEndX = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"contEndX", 0.0 );
- contStartY = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"contStartY", 0.0 );
- contEndY = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"contEndY", 0.0 );
- minY = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"minY", 0.0 );
- maxY = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"maxY", 0.0 );
- interiorTemp = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"interiorTemp", 1.0 );
- if ( dim == 3 ) {
- contStartZ = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"contStartZ", 0.0 );
- contEndZ = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"contEndZ", 0.0 );
- }
-
- if(( coord[I_AXIS] >= contStartX && coord[ I_AXIS ] <= contEndX ) && ( coord[J_AXIS] >= contStartY && coord[ J_AXIS ] <= contEndY )) {
- if ( dim == 3 ) {
- if ( coord[K_AXIS] >= contStartZ && coord[ K_AXIS ] <= contEndZ )
- *result = 0.0;
- else
- *result = interiorTemp;
- }
- }
- else
- *result = interiorTemp;
-}
-
-void StgFEM_StandardConditionFunctions_SinusoidalExtension( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double frequency;
- double vel0;
- double amplitude;
- double phaseShift;
-
- frequency = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalExtensionFrequency", 1.0 );
- vel0 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalExtensionVelocity", 0.0 );
- amplitude = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalExtensionAmplitude", 0.0 );
- phaseShift = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalExtensionPhaseShift", 0.0 );
-
-
- *result = vel0 + amplitude * cos( 2.0 * M_PI * frequency * (context->currentTime + context->dt - phaseShift ) );
-}
-
-
-void StgFEM_StandardConditionFunctions_StepFunction( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* feMesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double lower_offset, upper_offset;
- double value, lower_value, upper_value;
- unsigned dim;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- feMesh = feVariable->feMesh;
- coord = Mesh_GetVertex( feMesh, node_lI );
-
- lower_offset = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionLowerOffset", 0.0 );
- upper_offset = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionUpperOffset", lower_offset );
- value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionValue", 0.0 );
- dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "StepFunctionDim", 0 );
-
- lower_value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionLowerValue", 0.0 );
- upper_value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionUpperValue", value );
-
- if(dim==3)
- {
- dim=0;
- coord=&(context->currentTime);
- }
-
- if(coord[dim] < lower_offset) {
- *result=lower_value;
- } else if(coord[dim] < upper_offset) {
- *result=lower_value +
- (upper_value-lower_value)
- *(coord[dim] - lower_offset)/(upper_offset-lower_offset);
- } else {
- *result=upper_value;
- }
-}
-
-
-void StG_FEM_StandardConditionFunctions_StepFunctionProduct1( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double start, end;
- double value;
- unsigned dim;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- start = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct1Start", 0.0 );
- end = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct1End", 0.0 );
- value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct1Value", 0.0 );
- dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "StepFunctionProduct1Dim", 0 );
-
- if( coord[dim] > start && coord[dim] < end ) {
- *result = value;
- }
- else {
- *result = 0;
- }
-}
-
-void StG_FEM_StandardConditionFunctions_StepFunctionProduct2( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double start, end;
- double value;
- unsigned dim;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- start = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct2Start", 0.0 );
- end = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct2End", 0.0 );
- value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct2Value", 0.0 );
- dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "StepFunctionProduct2Dim", 0 );
-
- if( coord[dim] > start && coord[dim] < end ) {
- *result = value;
- }
- else {
- *result = 0;
- }
-}
-
-
-void StG_FEM_StandardConditionFunctions_StepFunctionProduct3( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double start, end;
- double value;
- unsigned dim;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- start = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct3Start", 0.0 );
- end = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct3End", 0.0 );
- value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct3Value", 0.0 );
- dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "StepFunctionProduct3Dim", 1 );
-
- if( coord[dim] > start && coord[dim] < end ) {
- *result = value;
- }
- else {
- *result = 0;
- }
-}
-
-void StG_FEM_StandardConditionFunctions_StepFunctionProduct4( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double start, end;
- double value;
- unsigned dim;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- start = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct4Start", 0.0 );
- end = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct4End", 0.0 );
- value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct4Value", 0.0 );
- dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "StepFunctionProduct4Dim", 1 );
-
- if( coord[dim] > start && coord[dim] < end ) {
- *result = value;
- }
- else {
- *result = 0;
- }
-}
-
-/* A Gaussian GaussianHeight*exp(-((GaussianCenter-x)/GaussianWidth)^2) */
-
-void StG_FEM_StandardConditionFunctions_Gaussian
-( Node_LocalIndex node_lI, Variable_Index var_I, void* _context,
- void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double center, width, height;
- unsigned dim;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- center = Dictionary_GetDouble_WithDefault( dictionary,
- "GaussianCenter", 0.0 );
- width = Dictionary_GetDouble_WithDefault( dictionary,
- "GaussianWidth", 1.0 );
- height = Dictionary_GetDouble_WithDefault( dictionary,
- "GaussianHeight", 1.0 );
- dim = Dictionary_GetUnsignedInt_WithDefault( dictionary,
- "GaussianDim", 0 );
-
- *result=height*exp(-(center-coord[dim])*(center-coord[dim])
- /(width*width));
-}
-
-void StgFEM_StandardConditionFunctions_MovingStepFunction( Node_LocalIndex nodeInd, Variable_Index varInd, void* _ctx, void* _result ) {
- FiniteElementContext* ctx = (FiniteElementContext*)_ctx;
- FeVariable* velField;
- FeMesh* mesh;
- Dictionary* dict = ctx->dictionary;
- double* result = (double*)_result;
- double* coord, offsetLower, offsetUpper, left, right;
- double *wallCrd, pos;
- int dim, wallDepth;
- unsigned ijk[3];
- char* movingWall;
- Grid* grid;
-
- /*
- ** Get the velocity field. */
- velField = (FeVariable*)FieldVariable_Register_GetByName(
- ctx->fieldVariable_Register, "VelocityField" );
-
- /*
- ** Get the mesh and the coordinate of the node. */
- mesh = velField->feMesh;
- coord = Mesh_GetVertex( mesh, nodeInd );
-
- /*
- ** Extract all the parameters we need from the dictionary. */
- offsetLower = Dictionary_GetDouble_WithDefault( dict, (Dictionary_Entry_Key)"MovingStepFunctionOffsetLower", 0.0 );
- offsetUpper = Dictionary_GetDouble_WithDefault( dict, (Dictionary_Entry_Key)"MovingStepFunctionOffsetUpper", 0.0 );
- dim = Dictionary_GetUnsignedInt_WithDefault( dict, "MovingStepFunctionDim", 0 );
- left = Dictionary_GetDouble_WithDefault( dict, (Dictionary_Entry_Key)"MovingStepFunctionLeftSide", 0.0 );
- right = Dictionary_GetDouble_WithDefault( dict, (Dictionary_Entry_Key)"MovingStepFunctionRightSide", 0.0 );
- movingWall = Dictionary_GetString_WithDefault( dict, "MovingStepFunctionMovingWall", "lower" );
- wallDepth = Dictionary_GetInt_WithDefault( dict, (Dictionary_Entry_Key)"MovingStepFunctionWallDepth", 0 );
-
- /*
- ** Because we're dealing with a moving step function, we need to calculate
- ** from where the offset should be applied. */
- grid = *(Grid**)Mesh_GetExtension( mesh, Grid**, "vertexGrid" );
- assert( grid );
- memset( ijk, 0, 3 * sizeof(unsigned) );
- if( !strcmp( movingWall, "lower" ) ) {
- ijk[dim] = wallDepth;
- wallCrd = Mesh_GetVertex( mesh, Grid_Project( grid, ijk ) );
- offsetLower += wallCrd[dim];
- offsetUpper += wallCrd[dim];
- }
- else {
- ijk[dim] = grid->sizes[dim] - wallDepth - 1;
- wallCrd = Mesh_GetVertex( mesh, Grid_Project( grid, ijk ) );
- offsetLower += wallCrd[dim];
- offsetUpper += wallCrd[dim];
- }
-
- /*
- ** Apply the set of parameters to this node. */
- pos = coord[dim];
- if( pos <= offsetLower )
- *result = left;
- else if( pos >= offsetUpper )
- *result = right;
- else {
- *result = left + ((pos - offsetLower) / (offsetUpper - offsetLower)) * (right - left);
- }
-}
-
-void StgFEM_StandardConditionFunctions_ConvectionBenchmark( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- /* This IC is for the 2D ConvectionBenchmark defined in
- * http://www.mcc.monash.edu.au/twiki/view/Research/ConvectionBenchmarks
- */
-
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* mesh;
- double* result = (double*) _result;
- double min[3], max[3];
- double* coord;
- double x,y;
- double Lx, Ly;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- mesh = (FeMesh*)feVariable->feMesh;
-
- Mesh_GetGlobalCoordRange( mesh, min, max );
-
- Lx = max[ I_AXIS ] - min[ I_AXIS ];
- Ly = max[ J_AXIS ] - min[ J_AXIS ];
-
- coord = Mesh_GetVertex( mesh, node_lI );
-
- x = ( coord[0] - min[ I_AXIS ] ) / Lx;
- y = ( coord[1] - min[ J_AXIS ] ) / Ly;
-
-
- *result = ( 1 - y ) + ( cos( M_PI * x ) * sin( M_PI * y ) ) / 100 ;
-}
-
-void StgFEM_StandardConditionFunctions_ConstantVector( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
-
- result[0] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ConstantValueX", 0.0 );
- result[1] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ConstantValueY", 0.0 );
- if (context->dim == 3 )
- result[2] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ConstantValueZ", 0.0 );
-}
-
-/* 3D spec ridge top BC (for milestone 1 of magma project )
- * to be applied to the top x-z plane of the domain */
-void StgFEM_StandardConditionFunctions_SpecRidge3D( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* feMesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
-
- double leftVal;
- double rightVal;
- double xOffset1;
- double xOffset2;
- double yOffset1, yOffset2;
- double xBegin, xEnd;
- double zBegin, zEnd;
-
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- feMesh = feVariable->feMesh;
- coord = Mesh_GetVertex( feMesh, node_lI );
-
- leftVal = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DLeftSide", 0.0 );
- rightVal = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DRightSide", 0.0 );
- xOffset1 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DXOffset1", 0.0 );
- xOffset2 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DXOffset2", 0.0 );
- yOffset1 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DZOffset1", 0.0 );
- yOffset2 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DZOffset2", 0.0 );
- xBegin = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DXBegin", 0.0 );
- xEnd = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DXEnd", 0.0 );
- zBegin = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DZBegin", 0.0 );
- zEnd = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DZEnd", 0.0 );
-
- if( coord[0] < xBegin || coord[0] > xEnd ||
- coord[2] < zBegin || coord[2] > zEnd )
- {
- *result = 0.0;
- }
- else if( coord[0] < xOffset1 )
- *result = leftVal;
- else if( coord[0] < xOffset2 && coord[2] > yOffset1 && coord[2] < yOffset2 )
- *result = leftVal;
- else
- *result = rightVal;
-}
-
-void StgFEM_StandardConditionFunctions_TemperatureProfile( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double T_0, H_0, dH, H, H_m, A, B, C, x_min, x_max, y_max, T_m, xc, dum;
- /* G.Ito 10/08 added variables x_min, x_max, T_m, Xc, to do variation in x
- and limit maximum T */
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- T_0 = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileTop", 0.0 );
- T_m = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileMax", 10000.0 );
- H_0 = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileH0", -1.0 );
- H_m = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileHm", 1.0e+8 );
- dH = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfiledH", 0.0 );
- A = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileLinearCoefficient", 0.0 );
- B = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileExponentialCoefficient1", 0.0 );
- C = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileExponentialCoefficient2", 0.0 );
- y_max = Dictionary_GetDouble_WithDefault( dictionary, "maxY", 0.0 );
- x_max = Dictionary_GetDouble_WithDefault( dictionary, "maxX", 0.0 );
- x_min = Dictionary_GetDouble_WithDefault( dictionary, "minX", 0.0 );
- xc = Dictionary_GetDouble_WithDefault( dictionary, "ExtensionCentreX", 0.0 );
-
- if (H_0<0.0)
- {
- if(coord[1]>y_max)
- {
- *result=T_0;
- }
- else
- {
- *result=T_0 + A*(y_max-coord[1]) + B*(1-exp(-C*(y_max-coord[1])));
- }
- }
- else
- {
- if(coord[1]>=y_max)
- {
- *result=T_0;
- }
- else
- {
- H=H_0 + 2*fabs(coord[0]-xc)/(x_max-x_min)*dH;
- if (H>H_m) H=H_m;
-
- dum=T_0 + ((T_m-T_0)/H)*(y_max-coord[1])
- + B*(1-exp(-C*(y_max-coord[1])));
- if (dum>T_m) dum=T_m;
- *result=dum;
- }
- }
-
-}
-
-void StgFEM_StandardConditionFunctions_ERF( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* feMesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double width, scale, dilate, offset, constant;
- unsigned dim;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- feMesh = feVariable->feMesh;
- coord = Mesh_GetVertex( feMesh, node_lI );
-
- width = Dictionary_GetDouble_WithDefault( dictionary, "ERFWidth", 0.0 );
- offset= Dictionary_GetDouble_WithDefault(dictionary, "ERFOffset",0.0 );
- constant=Dictionary_GetDouble_WithDefault(dictionary,"ERFConstant",0.0);
- scale = Dictionary_GetDouble_WithDefault( dictionary, "ERFScale", 1.0 );
- dilate = Dictionary_GetDouble_WithDefault( dictionary,"ERFDilate",1.0 );
- dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "ERFDim", 0 );
-
- if(dim==3)
- {
- dim=0;
- coord=&(context->currentTime);
- }
-
- if(coord[dim]+offset < -width && width!=0)
- *result=constant-scale;
- else if(coord[dim]+offset > width && width!=0)
- *result=constant+scale;
- else
- *result=constant+scale*erf((coord[dim]+offset)/dilate);
-}
-
-void StgFEM_StandardConditionFunctions_ERFC(Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* feMesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double width, scale, dilate, offset, constant;
- unsigned dim;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName
- ( context->fieldVariable_Register, "VelocityField" );
- feMesh = feVariable->feMesh;
- coord = Mesh_GetVertex( feMesh, node_lI );
-
- width = Dictionary_GetDouble_WithDefault(dictionary, "ERFCWidth", 0.0 );
- offset= Dictionary_GetDouble_WithDefault(dictionary, "ERFCOffset",0.0 );
- constant=Dictionary_GetDouble_WithDefault(dictionary,"ERFCConstant",0.0);
- scale = Dictionary_GetDouble_WithDefault(dictionary, "ERFCScale", 1.0 );
- dilate = Dictionary_GetDouble_WithDefault(dictionary,"ERFCDilate",1.0 );
- dim = Dictionary_GetUnsignedInt_WithDefault(dictionary, "ERFCDim", 0 );
-
- if(dim==3)
- {
- dim=0;
- coord=&(context->currentTime);
- }
-
- if(coord[dim]+offset < -width && width!=0)
- *result=constant-scale;
- else if(coord[dim]+offset > width && width!=0)
- *result=constant+scale;
- else
- *result=constant+scale*erfc((coord[dim]+offset)/dilate);
-}
-
-void StgFEM_StandardConditionFunctions_RubberSheet( Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context,
- void* _result )
-{
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* feMesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double lower_offset, upper_offset;
- double lower_value, upper_value, time;
- unsigned dim;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- feMesh = feVariable->feMesh;
- coord = Mesh_GetVertex( feMesh, node_lI );
-
- lower_offset = Dictionary_GetDouble_WithDefault( dictionary,
- "RubberSheetLowerOffset",
- 0.0 );
- upper_offset = Dictionary_GetDouble_WithDefault( dictionary,
- "RubberSheetUpperOffset",
- lower_offset );
- dim = Dictionary_GetUnsignedInt_WithDefault( dictionary,
- "RubberSheetDim", 0 );
-
- lower_value = Dictionary_GetDouble_WithDefault( dictionary,
- "RubberSheetLowerValue",
- 0.0 );
- upper_value = Dictionary_GetDouble_WithDefault( dictionary,
- "RubberSheetUpperValue",
- 0.0 );
-
- time=context->currentTime;
-
- if(coord[dim] < lower_offset + lower_value*time)
- {
- *result=lower_value;
- }
- else if(coord[dim] < upper_offset + upper_value*time)
- {
- double min[3], max[3];
- Mesh_GetGlobalCoordRange( feMesh, min, max );
- *result=lower_value +
- (upper_value-lower_value)
- *(coord[dim] - min[dim])/(max[dim]-min[dim]);
- }
- else
- {
- *result=upper_value;
- }
-}
-
-/* get the BC's from the analytic solution as stored on the relevant FeVariable */
-void StgFEM_StandardConditionFunctions_SpectralBCX( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* analyticFeVarX = NULL;
- FeVariable* numericFeVar = NULL;
- double* result = (double*) _result;
- /*FeMesh* feMesh = NULL;
- double* coord;
- Node_LocalIndex analyticNodeI;
- Element_DomainIndex analyticElement_I;
- double analyticLocalElementCoord[3];
- FeMesh* analyticFeMesh;
- */
- analyticFeVarX = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "SpectralVelocityXField" );
- numericFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- //feMesh = numericFeVar->feMesh;
- //coord = Mesh_GetVertex( feMesh, node_lI );
-
- //analyticFeMesh = analyticFeVarX->feMesh;
- //if( Mesh_SearchElements( analyticFeMesh, coord, &analyticElement_I ) ) {
- // FeMesh_CoordGlobalToLocal( analyticFeMesh, analyticElement_I, coord, analyticLocalElementCoord );
- // FeVariable_InterpolateWithinElement( analyticFeVarX, analyticElement_I, analyticLocalElementCoord, result );
- //}
- //else { /* numerical solution node outside analytic mesh - just find closest point & use that */
- // analyticNodeI = Mesh_NearestVertex( analyticFeMesh, coord );
- // FeVariable_GetValueAtNode( analyticFeVarX, analyticNodeI, result );
- //}
-
- FeVariable_GetValueAtNode( analyticFeVarX, node_lI, result );
-}
-
-void StgFEM_StandardConditionFunctions_SpectralBCY( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* analyticFeVarY = NULL;
- FeVariable* numericFeVar = NULL;
- double* result = (double*) _result;
- /*FeMesh* feMesh = NULL;
- double* coord;
- Node_LocalIndex analyticNodeI;
- Element_DomainIndex analyticElement_I;
- double analyticLocalElementCoord[3];
- FeMesh* analyticFeMesh;
- */
- analyticFeVarY = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "SpectralVelocityYField" );
- numericFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- //feMesh = numericFeVar->feMesh;
- //coord = Mesh_GetVertex( feMesh, node_lI );
-
- //analyticFeMesh = analyticFeVarY->feMesh;
- //if( Mesh_SearchElements( analyticFeMesh, coord, &analyticElement_I ) ) {
- // FeMesh_CoordGlobalToLocal( analyticFeMesh, analyticElement_I, coord, analyticLocalElementCoord );
- // FeVariable_InterpolateWithinElement( analyticFeVarY, analyticElement_I, analyticLocalElementCoord, result );
- //}
- //else {
- // analyticNodeI = Mesh_NearestVertex( analyticFeMesh, coord );
- // FeVariable_GetValueAtNode( analyticFeVarY, analyticNodeI, result );
- //}
-
- FeVariable_GetValueAtNode( analyticFeVarY, node_lI, result );
-}
-
-void StgFEM_StandardConditionFunctions_SpectralBCZ( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* analyticFeVarZ = NULL;
- FeVariable* numericFeVar = NULL;
- double* result = (double*) _result;
- /*
- FeMesh* feMesh = NULL;
- double* coord;
- Node_LocalIndex analyticNodeI;
- Element_DomainIndex analyticElement_I;
- double analyticLocalElementCoord[3];
- FeMesh* analyticFeMesh;
- */
- analyticFeVarZ = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "SpectralVelocityZField" );
- numericFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- //feMesh = numericFeVar->feMesh;
- //coord = Mesh_GetVertex( feMesh, node_lI );
-
- //analyticFeMesh = analyticFeVarZ->feMesh;
- //if( Mesh_SearchElements( analyticFeMesh, coord, &analyticElement_I ) ) {
- // FeMesh_CoordGlobalToLocal( analyticFeMesh, analyticElement_I, coord, analyticLocalElementCoord );
- // FeVariable_InterpolateWithinElement( analyticFeVarZ, analyticElement_I, analyticLocalElementCoord, result );
- //}
- //else {
- // analyticNodeI = Mesh_NearestVertex( analyticFeMesh, coord );
- // FeVariable_GetValueAtNode( analyticFeVarZ, analyticNodeI, result );
- //}
-
- FeVariable_GetValueAtNode( analyticFeVarZ, node_lI, result );
-}
-
-void StgFEM_StandardConditionFunctions_SpectralPressureBCX( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* analyticFeVarX = NULL;
- FeVariable* numericFeVar = NULL;
- FeMesh* feMesh = NULL;
- double* result = (double*) _result;
- double* coord;
-
- analyticFeVarX = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "SpectralPressureField" );
- numericFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "PressureField" );
- feMesh = numericFeVar->feMesh;
- coord = Mesh_GetVertex( feMesh, node_lI );
-
- FeVariable_GetValueAtNode( analyticFeVarX, node_lI, result );
-}
-
-void StgFEM_StandardConditionFunctions_SpectralPressureBCY( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* analyticFeVarY = NULL;
- FeVariable* numericFeVar = NULL;
- FeMesh* feMesh = NULL;
- double* result = (double*) _result;
- double* coord;
-
- analyticFeVarY = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "SpectralPressureField" );
- numericFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "PressureField" );
- feMesh = numericFeVar->feMesh;
- coord = Mesh_GetVertex( feMesh, node_lI );
-
- FeVariable_GetValueAtNode( analyticFeVarY, node_lI, result );
-}
-
-/* error function for use in 3D spec ridge top BC */
-double errorFunction( double z, int n ) {
- double pi = 3.1415926535;
- double a;
- double erf = 0.0;
- int denom;
- int i, j;
-
- a = 2.0/sqrt( pi );
-
- for( i=0 ; i<n ; i++ ) {
- denom = 1;
- for( j=1 ; j<=2*i+1 ; j+=2 )
- denom *= j;
-
- erf += pow( 2, i )*pow( z, 2*i+1 )/denom;
- }
-
- return erf *= a*exp( -1.0*z*z );
-}
-
-
-
-void StgFEM_StandardConditionFunctions_ErrorFunc( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* feMesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double dilate;
- double width;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- feMesh = feVariable->feMesh;
- coord = Mesh_GetVertex( feMesh, node_lI );
-
- dilate = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ErrorFuncDilate", 0.0 );
- width = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ErrorFuncWidth", 0.0 );
-
- if( coord[0] < -1.0*width ) {
- *result = -1.0;
- }
- else if( coord[0] > width ) {
- *result = 1.0;
- }
- else {
- *result = errorFunction( coord[0]/dilate, 5 );
- }
-}
-
-void StgFEM_StandardConditionFunctions_GaussianDistribution( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- Name variableName;
- double* coord;
- unsigned nDims = context->dim;
- unsigned dim_I;
- double orig[3];
- double sigma = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"sigma", 1.0 );
- double gaussianScale = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianScale", 1.0 );
- double background = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"backgroundValue", 1.0 );
- double distsq = 0.0;
-
- variableName = Dictionary_GetString_WithDefault( dictionary, "FieldVariable", "" );
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, variableName );
- coord = Mesh_GetVertex( feVariable->feMesh, node_lI );
-
- orig[0] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"x0", 0.0 );
- orig[1] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"y0", 0.0 );
- orig[2] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"z0", 0.0 );
-
- for( dim_I = 0; dim_I < nDims; dim_I++ )
- distsq += ( coord[dim_I] - orig[dim_I] ) * ( coord[dim_I] - orig[dim_I] );
-
- *result = gaussianScale * exp( -distsq / ( 2.0 * sigma * sigma ) ) + background;
-}
-
-void StgFEM_StandardConditionFunctions_GravitationalPotential( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- Name variableName;
- double* coord;
-
- variableName = Dictionary_GetString_WithDefault( dictionary, "FieldVariable", "" );
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, variableName );
- coord = Mesh_GetVertex( feVariable->feMesh, node_lI );
-
- *result = -1.0 * coord[J_AXIS];
-}
-
-void StgFEM_StandardConditionFunctions_1DGaussianDistribution( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- Name variableName;
- double* coord;
- double orig[3];
- double sigma = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"sigma", 1.0 );
- double gaussianScale = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianScale", 1.0 );
- double background = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"backgroundValue", 1.0 );
- double distsq = 0.0;
-
- variableName = Dictionary_GetString_WithDefault( dictionary, "FieldVariable", "" );
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, variableName );
- coord = Mesh_GetVertex( feVariable->feMesh, node_lI );
-
- orig[0] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"x0", 0.0 );
- orig[1] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"y0", 0.0 );
- orig[2] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"z0", 0.0 );
-
- distsq = ( coord[J_AXIS] - orig[J_AXIS] ) * ( coord[J_AXIS] - orig[J_AXIS] );
-
- *result = gaussianScale * exp( -distsq / ( 2.0 * sigma * sigma ) ) + background;
-}
-
-void StgFEM_StandardConditionFunctions_HalfContainer( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- Name variableName;
- double* coord;
- double halfPoint = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"halfPoint", 0.0 );
-
- variableName = Dictionary_GetString_WithDefault( dictionary, "FieldVariable", "" );
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, variableName );
- coord = Mesh_GetVertex( feVariable->feMesh, node_lI );
-
- if( coord[1] < halfPoint )
- *result = 1;
- else
- *result = 0;
-}
-
-void StgFEM_StandardConditionFunctions_ConstantValue( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double value = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"constantValue", 1.0 );
-
- *result = value;
-}
-
-void StgFEM_StandardConditionFunctions_DiagonalLine( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double width = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"lineWidth", 1.0 );
- double* coord;
- Name variableName;
- FeVariable* feVariable = NULL;
-
- variableName = Dictionary_GetString_WithDefault( dictionary, "FieldVariable", "" );
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, variableName );
- coord = Mesh_GetVertex( feVariable->feMesh, node_lI );
-
- if( fabs( coord[0] - coord[1] ) < width )
- *result = 1.0;
- else
- *result = 0.0;
-}
-
-void StgFEM_StandardConditionFunctions_DeltaFunction( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- FiniteElementContext * context = (FiniteElementContext*)_context;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double epsilon = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"deltaFunctionEpsilon", 0.001 );
- unsigned dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "deltaFunctionDim", 0 );
- double centre = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"deltaFunctionCentre", 0.5 );
- double value = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"deltaFunctionValue", 1.0 );
- double* coord;
- Name variableName = Dictionary_GetString_WithDefault( dictionary, "DeltaFunctionFeVariable", "" );
- FeVariable* feVariable = (FeVariable*) FieldVariable_Register_GetByName( context->fieldVariable_Register, variableName );
-
- coord = Mesh_GetVertex( feVariable->feMesh, node_lI );
-
- *result = (fabs( coord[dim] - centre ) < epsilon) ? value : 0.0;
-}
-
-void StgFEM_StandardConditionFunctions_InflowBottom( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
- DomainContext* context = (DomainContext*)_context;
- FeVariable* feVariable;
- Dictionary* dictionary = context->dictionary;
- FeMesh* mesh = NULL;
- double* result = (double*) _result;
- double sideLength, wallLength, sideV;
- double min[3], max[3];
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
- Mesh_GetGlobalCoordRange( mesh, min, max );
- sideLength = max[1] - min[1];
- wallLength = max[0] - min[0];
- sideV = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"InflowSideVelocity", 1.0 );
-
- *result = 2.0 * sideV * sideLength / wallLength;
-}
-
-void StgFEM_StandardConditionFunctions_GaussianTube( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- DomainContext* context = (DomainContext*)_context;
- Dictionary* dictionary = context->dictionary;
- FeVariable* feVariable = NULL;
- FeMesh* feMesh = NULL;
- unsigned nDims;
- double* result = (double*) _result;
- double a1,b1,c1, a2,b2,c2, x,y,z,r_y,r_yz;
- double* coord;
- double min[3], max[3];
- double y_shift, z_shift;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
- feMesh = feVariable->feMesh;
-
- nDims = Mesh_GetDimSize( feMesh );
- Mesh_GetGlobalCoordRange( feMesh, min, max );
-
- a1 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_a1", 1.0 ); /* Scales the magnitude of the perturbation. */
- c1 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_c1", 0.1 ); /* Controls the smoothing length. Smaller values produce less smoothing. */
-
- a2 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_a2", 0.05 ); /* Controls ampltude of oscillations */
- b2 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_b2", 6.28318530718 ); /* Controls frequency of oscillations */
- c2 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_c2", 1.570796326795 ); /* Shifts oscillations */
-
- y_shift = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_y_origin", 0.0 );
- z_shift = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_z_origin", 0.0 );
-
- coord = Mesh_GetVertex( feMesh, node_lI );
-
- x = coord[ I_AXIS ];
- y = coord[ J_AXIS ];
-
- y = y - y_shift;
- if (nDims==2) {
- b1 = a2 * sin( b2*x - c2 );
- r_y = sqrt( (y-b1)*(y-b1) );
- *result = a1 * exp( -(r_y * r_y) / (2.0*c1*c1) );
- }
- if (nDims==3) {
- z = coord[ K_AXIS ];
- z = z - z_shift;
-
- b1 = a2 * sin( b2*x - c2 );
- r_yz = sqrt( (y-b1)*(y-b1) + z*z );
- *result = a1 * exp( -(r_yz * r_yz) / (2.0*c1*c1) );
- }
-
-
-}
-
-
-void StgFEM_StandardConditionFunctions_WarsTemperature( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- double EAEnd, WarsStart, WarsHeight, WarsTTop,
- WarsTBottom, h, maxY;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- EAEnd = Dictionary_GetDouble( dictionary, "EAEnd");
- WarsStart = Dictionary_GetDouble( dictionary, "WarsStart");
- WarsHeight = Dictionary_GetDouble( dictionary, "WarsHeight");
- WarsTTop = Dictionary_GetDouble( dictionary, "WarsTTop");
- WarsTBottom = Dictionary_GetDouble( dictionary, "WarsTBottom");
- maxY=Dictionary_GetDouble( dictionary, "maxY");
-
-
- h=WarsHeight*(coord[0]-EAEnd)/(WarsStart-EAEnd);
- if(coord[0]<EAEnd)
- h=0;
- if(coord[0]>WarsStart)
- h=WarsHeight;
- *result=WarsTBottom + ((coord[1]-h)/(maxY-h))*(WarsTTop-WarsTBottom);
-}
-
-void StgFEM_StandardConditionFunctions_Quadratic( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- int dim;
- double a, b, c;
-
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- dim = Dictionary_GetInt( dictionary, "Quadratic_Dim");
- a = Dictionary_GetDouble( dictionary, "Quadratic_Constant");
- b = Dictionary_GetDouble( dictionary, "Quadratic_Linear");
- c = Dictionary_GetDouble( dictionary, "Quadratic_Quadratic");
-
- *result= a + coord[dim]*(b + c*coord[dim]);
-}
-
-int Binary_Search(double *data, int s, int e, double value);
-
-void StgFEM_StandardConditionFunctions_FileN( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result, int file_num, double **coords, double **data);
-
-void StgFEM_StandardConditionFunctions_File1( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- static double *coords=NULL;
- static double *data=NULL;
- StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,1,
- &coords,&data);
-}
-
-void StgFEM_StandardConditionFunctions_File2( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- static double *coords=NULL;
- static double *data=NULL;
- StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,2,
- &coords,&data);
-}
-
-void StgFEM_StandardConditionFunctions_File3( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- static double *coords=NULL;
- static double *data=NULL;
- StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,3,
- &coords,&data);
-}
-
-void StgFEM_StandardConditionFunctions_File4( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- static double *coords=NULL;
- static double *data=NULL;
- StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,4,
- &coords,&data);
-}
-
-void StgFEM_StandardConditionFunctions_File5( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- static double *coords=NULL;
- static double *data=NULL;
- StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,5,
- &coords,&data);
-}
-
-void StgFEM_StandardConditionFunctions_File6( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- static double *coords=NULL;
- static double *data=NULL;
- StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,6,
- &coords,&data);
-}
-
-void StgFEM_StandardConditionFunctions_File7( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- static double *coords=NULL;
- static double *data=NULL;
- StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,7,
- &coords,&data);
-}
-
-void StgFEM_StandardConditionFunctions_File8( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- static double *coords=NULL;
- static double *data=NULL;
- StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,8,
- &coords,&data);
-}
-
-void StgFEM_StandardConditionFunctions_File9( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- static double *coords=NULL;
- static double *data=NULL;
- StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,9,
- &coords,&data);
-}
-
-void StgFEM_StandardConditionFunctions_File10( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
-{
- static double *coords=NULL;
- static double *data=NULL;
- StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,10,
- &coords,&data);
-}
-
-void StgFEM_StandardConditionFunctions_FileN( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result, int file_num, double **coords, double **data)
-{
- FiniteElementContext * context = (FiniteElementContext*)_context;
- FeVariable* feVariable = NULL;
- FeMesh* mesh = NULL;
- Dictionary* dictionary = context->dictionary;
- double* result = (double*) _result;
- double* coord;
- int dim, dim2, dim3, i, j, k;
- char *filename;
- int N, N2, N3, ndims;
- int result_index, result_index2, result_index3;
- double factor, factor2, factor3;
- feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
- mesh = feVariable->feMesh;
- coord = Mesh_GetVertex( mesh, node_lI );
-
- char fileN_number[10], fileN_dim[15], fileN_dim2[15], fileN_dim3[15],
- fileN_name[128], fileN_N[15], fileN_N2[15], fileN_N3[15];
- sprintf(fileN_number,"File%d",file_num);
- sprintf(fileN_dim,"File%d_Dim",file_num);
- sprintf(fileN_dim2,"File%d_Dim2",file_num);
- sprintf(fileN_dim3,"File%d_Dim3",file_num);
- sprintf(fileN_name,"File%d_Name",file_num);
- sprintf(fileN_N,"File%d_N",file_num);
- sprintf(fileN_N2,"File%d_N2",file_num);
- sprintf(fileN_N3,"File%d_N3",file_num);
-
- filename = Dictionary_GetString( dictionary, fileN_name);
- N = Dictionary_GetInt( dictionary, fileN_N);
- dim = Dictionary_GetInt( dictionary, fileN_dim);
- N2 = Dictionary_GetInt_WithDefault( dictionary, fileN_N2,-1);
- N3 = Dictionary_GetInt_WithDefault( dictionary, fileN_N3,-1);
-
- if(N2==-1)
- ndims=1;
- else if(N3==-1)
- ndims=2;
- else
- ndims=3;
-
- if(ndims>1)
- {
- dim2 = Dictionary_GetInt( dictionary, fileN_dim2);
- if(ndims>2)
- dim3 = Dictionary_GetInt( dictionary, fileN_dim3);
- }
-
- Journal_Firewall(dim>=0 && dim<3,
- Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
- "%s must be either 0, 1, or 2, but was set to %d\n",
- fileN_dim,dim);
- Journal_Firewall(N>0,
- Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
- "%s must be greater than zero, but was set to %d.\n",
- fileN_N,N);
- if(*data==NULL)
- {
- FILE *fp=fopen(filename,"r");
- Journal_Firewall(fp!=NULL,
- Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
- "Bad filename for %s. Could not open %s\n",
- fileN_name,filename);
-
- /* In 1D, data and coords are simple 1D arrays. In 2D, data is
- a 2D arrays, and coord is still a 1D array, with the first N
- elements being the coordinates in the Dim direction, and the
- next N2 elements being the coordinates in the Dim2
- dirction. Similarly in 3D. */
- if(ndims==1)
- {
- *data=(double *)malloc(N*sizeof(double));
- *coords=(double *)malloc(N*sizeof(double));
- }
- else if(ndims==2)
- {
- *data=(double *)malloc(N*N2*sizeof(double));
- *coords=(double *)malloc((N+N2)*sizeof(double));
- }
- else
- {
- *data=(double *)malloc(N*N2*N3*sizeof(double));
- *coords=(double *)malloc((N+N2+N3)*sizeof(double));
- }
-
- Journal_Firewall(*data!=NULL && *coords!=NULL,
- Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
- "Could not allocate enough memory for %s\n",file_num);
- if(ndims==1)
- {
- for(i=0;i<N;++i)
- fscanf(fp,"%lf %lf",*coords+i,*data+i);
- }
- else if(ndims==2)
- {
- for(i=0;i<N;++i)
- for(j=0;j<N2;++j)
- {
- fscanf(fp,"%lf %lf %lf",*coords+i,*coords+N+j,*data+i+N*j);
- }
- }
- else if(ndims==3)
- {
- for(i=0;i<N;++i)
- for(j=0;j<N2;++j)
- for(k=0;k<N3;++k)
- fscanf(fp,"%lf %lf %lf %lf",*coords+i,*coords+N+j,*coords+N+N2+k,
- *data+i+N*(j+N2*k));
- }
- fclose(fp);
- }
-
- Journal_Firewall(!(coord[dim]<(*coords)[0] || coord[dim]>(*coords)[N-1]),
- Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
- "The range in the file '%s' does not cover this value %g\nIt only covers %g to %g in the %d direction.\n",
- filename,coord[dim],(*coords)[0],(*coords)[N-1],dim);
- if(ndims>1)
- Journal_Firewall(!(coord[dim2]<(*coords)[N] || coord[dim2]>(*coords)[N+N2-1]),
- Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
- "The range in the file '%s' does not cover this value %g\nIt only covers %g to %g in the %d direction.\n",
- filename,coord[dim2],(*coords)[N],(*coords)[N+N2-1],dim2);
- if(ndims>2)
- Journal_Firewall(!(coord[dim3]<(*coords)[N+N2] || coord[dim3]>(*coords)[N+N2+N3-1]),
- Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
- "The range in the file '%s' does not cover this value %g\nIt only covers %g to %g in the %d direction.\n",
- filename,coord[dim3],(*coords)[N+N2],(*coords)[N+N2+N3-1],dim2);
-
- i=Binary_Search(*coords,0,N-1,coord[dim]);
- factor=((*coords)[i+1]-coord[dim])/((*coords)[i+1]-(*coords)[i]);
-
- if(ndims>1)
- {
- j=Binary_Search(*coords,N,N+N2-1,coord[dim2]);
- factor2=((*coords)[j+1]-coord[dim2])/((*coords)[j+1]-(*coords)[j]);
- j=j-N;
- if(ndims>2)
- {
- k=Binary_Search(*coords,N,N+N2+N3-1,coord[dim3]);
- factor3=((*coords)[k+1]-coord[dim3])/((*coords)[k+1]-(*coords)[k]);
- k=k-N-N2;
- }
- }
-
- switch(ndims)
- {
- case 1:
- *result=(*data)[i]*factor + (*data)[i+1]*(1-factor);
- break;
- case 2:
- *result=factor*(factor2*(*data)[i+N*j] + (1-factor2)*(*data)[i+N*(j+1)])
- + (1-factor)*(factor2*(*data)[i+1+N*j] + (1-factor2)*(*data)[i+1+N*(j+1)]);
- break;
- case 3:
- *result=factor*(factor2*(factor3*(*data)[i+N*(j+N2*k)]
- + (1-factor3)*(*data)[i+N*(j+N2*(k+1))])
- + (1-factor2)*(factor3*(*data)[i+N*((j+1)+N2*k)]
- + (1-factor3)*(*data)[i+N*((j+1)+N2*(k+1))]))
- + (1-factor)*(factor2*(factor3*(*data)[i+1+N*(j+N2*k)]
- + (1-factor3)*(*data)[i+1+N*(j+N2*(k+1))])
- + (1-factor2)*(factor3*(*data)[i+1+N*((j+1)+N2*k)]
- + (1-factor3)*(*data)[i+1+N*((j+1)+N2*(k+1))]));
- break;
- }
-}
-
-
-int Binary_Search(double *data, int s, int e, const double value)
-{
- int start, end, midpoint;
-
- start=s;
- end=e;
- midpoint=(end-start)/2 + start;
- while(start!=midpoint)
- {
- if(data[midpoint]>=value)
- end=midpoint;
- else
- start=midpoint;
- midpoint=(end-start)/2 + start;
- }
- return start;
-}
-
-void StgFEM_StandardConditionFunctions_EquationN(Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context,
- void* _result,
- std::string equation_string,
- const int equation_number);
-
-void StgFEM_StandardConditionFunctions_Equation1(Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context,
- void* _result)
-{
- static std::string equation_string;
- StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
- equation_string,1);
-}
-
-void StgFEM_StandardConditionFunctions_Equation2(Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context,
- void* _result)
-{
- static std::string equation_string;
- StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
- equation_string,2);
-}
-
-void StgFEM_StandardConditionFunctions_Equation3(Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context,
- void* _result)
-{
- static std::string equation_string;
- StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
- equation_string,3);
-}
-
-void StgFEM_StandardConditionFunctions_Equation4(Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context,
- void* _result)
-{
- static std::string equation_string;
- StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
- equation_string,4);
-}
-
-void StgFEM_StandardConditionFunctions_Equation5(Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context,
- void* _result)
-{
- static std::string equation_string;
- StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
- equation_string,5);
-}
-
-void StgFEM_StandardConditionFunctions_Equation6(Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context,
- void* _result)
-{
- static std::string equation_string;
- StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
- equation_string,6);
-}
-
-void StgFEM_StandardConditionFunctions_Equation7(Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context,
- void* _result)
-{
- static std::string equation_string;
- StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
- equation_string,7);
-}
-
-void StgFEM_StandardConditionFunctions_Equation8(Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context,
- void* _result)
-{
- static std::string equation_string;
- StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
- equation_string,8);
-}
-
-void StgFEM_StandardConditionFunctions_Equation9(Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context,
- void* _result)
-{
- static std::string equation_string;
- StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
- equation_string,9);
-}
-
-void StgFEM_StandardConditionFunctions_Equation10(Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context,
- void* _result)
-{
- static std::string equation_string;
- StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
- equation_string,10);
-}
-
-void StgFEM_StandardConditionFunctions_EquationN(Node_LocalIndex node_lI,
- Variable_Index var_I,
- void* _context,
- void* _result,
- std::string equation_string,
- const int equation_number)
-{
- FiniteElementContext *context=(FiniteElementContext*)_context;
- FeVariable *feVariable=(FeVariable*)FieldVariable_Register_GetByName
- (context->fieldVariable_Register, "VelocityField");
- FeMesh *mesh(feVariable->feMesh);
- Dictionary *dictionary=context->dictionary;
- double *coord=Mesh_GetVertex(mesh,node_lI);
- double *result=(double*)_result;
-
- if(equation_string.empty())
- {
- std::stringstream ss;
- ss << "Equation" << equation_number;
- equation_string=std::string(Dictionary_GetString(dictionary,
- ss.str().c_str()));
- Journal_Firewall(!equation_string.empty(),
- Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_EquationN"),
- "The equation given for %s is empty.",
- ss.str().c_str());
- }
- try
- {
- mu::Parser p;
- p.DefineVar("x", coord);
- p.DefineVar("y", coord+1);
- p.DefineVar("z", coord+2);
- p.DefineVar("t", &(context->currentTime));
- p.SetExpr(equation_string);
-
- *result=p.Eval();
- }
- catch (mu::Parser::exception_type &e)
- {
- Journal_Firewall(false,
- Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_Equation"),
- "Error when parsing equation: %s\n",e.GetMsg().c_str());
- }
-}
diff -r bd633e2a3a35 -r 46408d74ad35 plugins/StandardConditionFunctions/StandardConditionFunctions.cxx
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/StandardConditionFunctions/StandardConditionFunctions.cxx Thu May 12 11:19:05 2011 -0700
@@ -0,0 +1,2841 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+**
+** Copyright (C), 2003-2006, Victorian Partnership for Advanced Computing (VPAC) Ltd, 110 Victoria Street,
+** Melbourne, 3053, Australia.
+**
+** Primary Contributing Organisations:
+** Victorian Partnership for Advanced Computing Ltd, Computational Software Development - http://csd.vpac.org
+** Australian Computational Earth Systems Simulator - http://www.access.edu.au
+** Monash Cluster Computing - http://www.mcc.monash.edu.au
+** Computational Infrastructure for Geodynamics - http://www.geodynamics.org
+**
+** Contributors:
+** Patrick D. Sunter, Software Engineer, VPAC. (pds at vpac.org)
+** Robert Turnbull, Research Assistant, Monash University. (robert.turnbull at sci.monash.edu.au)
+** Stevan M. Quenette, Senior Software Engineer, VPAC. (steve at vpac.org)
+** David May, PhD Student, Monash University (david.may at sci.monash.edu.au)
+** Louis Moresi, Associate Professor, Monash University. (louis.moresi at sci.monash.edu.au)
+** Luke J. Hodkinson, Computational Engineer, VPAC. (lhodkins at vpac.org)
+** Alan H. Lo, Computational Engineer, VPAC. (alan at vpac.org)
+** Raquibul Hassan, Computational Engineer, VPAC. (raq at vpac.org)
+** Julian Giordani, Research Assistant, Monash University. (julian.giordani at sci.monash.edu.au)
+** Vincent Lemiale, Postdoctoral Fellow, Monash University. (vincent.lemiale at sci.monash.edu.au)
+**
+** This library is free software; you can redistribute it and/or
+** modify it under the terms of the GNU Lesser General Public
+** License as published by the Free Software Foundation; either
+** version 2.1 of the License, or (at your option) any later version.
+**
+** This library is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+** Lesser General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with this library; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+**
+** $Id: StandardConditionFunctions.c 1196 2008-08-04 16:29:30Z LukeHodkinson $
+**
+**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+#include <string.h>
+#include <mpi.h>
+#include <StGermain/StGermain.h>
+#include <StgDomain/StgDomain.h>
+#include <StgFEM/StgFEM.h>
+#include <assert.h>
+#include "StandardConditionFunctions.h"
+#include "muParser.h"
+
+const Type StgFEM_StandardConditionFunctions_Type = "StgFEM_StandardConditionFunctions";
+
+void _StgFEM_StandardConditionFunctions_AssignFromXML( void* component, Stg_ComponentFactory* cf, void* data ) {
+ Codelet* self = (Codelet*)component;
+ AbstractContext* context;
+ ConditionFunction* condFunc;
+ Dictionary* pluginDict = Codelet_GetPluginDictionary( component, cf->rootDict );
+
+ context = (AbstractContext*)Stg_ComponentFactory_ConstructByName( cf, Dictionary_GetString( pluginDict, (Dictionary_Entry_Key)"Context" ), AbstractContext, True, data );
+ self->context = context;
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SolidBodyRotation, "Velocity_SolidBodyRotation" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_PartialRotationX, "Velocity_PartialRotationX" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_PartialRotationY, "Velocity_PartialRotationY" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_TaperedRotationX, "TaperedRotationX" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_TaperedRotationY, "TaperedRotationY" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SimpleShear, "Velocity_SimpleShear" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SimpleShearInverted, "Velocity_SimpleShearInverted" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_ShearZ, "ShearZ" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_Extension, "Velocity_Extension" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_PartialLid_TopLayer, "Velocity_PartialLid_TopLayer" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_Trigonometry, "Temperature_Trigonometry" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_LinearInterpolationLid, "Velocity_LinearInterpolationLid" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_Lid_RampWithCentralMax, "Velocity_Lid_RampWithCentralMax" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_LinearVelocityLeftWall, "LinearVelocityLeftWall" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_LinearVelocityRightWall, "LinearVelocityRightWall" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SinusoidalLid, "Velocity_SinusoidalLid" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_CornerOnly, "Velocity_Lid_CornerOnly" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_TemperatureCosineHill, "Temperature_CosineHill" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_ConvectionBenchmark, "Temperature_ConvectionBenchmark" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_LinearWithSinusoidalPerturbation, "LinearWithSinusoidalPerturbation" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_EdgeDriveConvectionIC, "EdgeDriveConvectionIC" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_ThermalEdgeDriveConvectionIC, "ThermalEdgeDriveConvectionIC" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_AnalyticalTemperatureIC, "AnalyticalTemperatureIC" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New( Stg_FEM_VelicTemperatureIC, "VelicTemperatureIC" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New( Stg_FEM_VelicTemperatureIC_SolB, "VelicTemperatureIC_SolB" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SinusoidalExtension, "SinusoidalExtension" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_StepFunction, "StepFunction" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StG_FEM_StandardConditionFunctions_StepFunctionProduct1, "StepFunctionProduct1");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StG_FEM_StandardConditionFunctions_StepFunctionProduct2, "StepFunctionProduct2");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StG_FEM_StandardConditionFunctions_StepFunctionProduct3, "StepFunctionProduct3");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StG_FEM_StandardConditionFunctions_StepFunctionProduct4, "StepFunctionProduct4");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_TemperatureProfile, "TemperatureProfile");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StG_FEM_StandardConditionFunctions_Gaussian, "Gaussian");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_ERF,
+ (char*)"ERF");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_ERFC,
+ (char*)"ERFC");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_RubberSheet,
+ (char*)"RubberSheet");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_MovingStepFunction, "MovingStepFunction");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SpecRidge3D, "SpecRidge3D" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SpectralBCX, "SpectralBCX" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SpectralBCY, "SpectralBCY" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SpectralBCZ, "SpectralBCZ" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SpectralPressureBCX, "SpectralPressureBCX" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_SpectralPressureBCY, "SpectralPressureBCY" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_ErrorFunc, "ErrorFunc" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_ConstantVector, "ConstantVector" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_GaussianDistribution, "GaussianDistribution" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_1DGaussianDistribution, "1DGaussianDistribution" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_HalfContainer, "HalfContainer" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_ConstantValue, "ConstantValue" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_DiagonalLine, "DiagonalLine" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_DeltaFunction, "DeltaFunction" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_InflowBottom, "InflowBottom" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_GaussianTube, "GaussianTube" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New( StgFEM_StandardConditionFunctions_GravitationalPotential, "GravitationalPotential" );
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_WarsTemperature,
+ "WarsTemperature");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_Quadratic,
+ "Quadratic");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File1,
+ "File1");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File2,
+ "File2");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File3,
+ "File3");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File4,
+ "File4");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File5,
+ "File5");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File6,
+ "File6");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File7,
+ "File7");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File8,
+ "File8");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File9,
+ "File9");
+ ConditionFunction_Register_Add( condFunc_Register, condFunc );
+ condFunc = ConditionFunction_New(StgFEM_StandardConditionFunctions_File10,
+ "File10");
+ ConditionFunction_Register_Add(condFunc_Register,condFunc);
+ condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation1,
+ "Equation1");
+ ConditionFunction_Register_Add(condFunc_Register,condFunc);
+ condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation2,
+ "Equation2");
+ ConditionFunction_Register_Add(condFunc_Register,condFunc);
+ condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation3,
+ "Equation3");
+ ConditionFunction_Register_Add(condFunc_Register,condFunc);
+ condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation4,
+ "Equation4");
+ ConditionFunction_Register_Add(condFunc_Register,condFunc);
+ condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation5,
+ "Equation5");
+ ConditionFunction_Register_Add(condFunc_Register,condFunc);
+ condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation6,
+ "Equation6");
+ ConditionFunction_Register_Add(condFunc_Register,condFunc);
+ condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation7,
+ "Equation7");
+ ConditionFunction_Register_Add(condFunc_Register,condFunc);
+ condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation8,
+ "Equation8");
+ ConditionFunction_Register_Add(condFunc_Register,condFunc);
+ condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation9,
+ "Equation9");
+ ConditionFunction_Register_Add(condFunc_Register,condFunc);
+ condFunc=ConditionFunction_New(StgFEM_StandardConditionFunctions_Equation10,
+ "Equation10");
+ ConditionFunction_Register_Add(condFunc_Register,condFunc);
+}
+
+void _StgFEM_StandardConditionFunctions_Destroy( void* _self, void* data ) {
+ /* This function will totally clean the condFunc_Register
+ *
+ * This could be trouble some if other code adds or deletes condition functions on this register
+ */
+
+ unsigned *refCount = &(condFunc_Register->count);
+
+ /* first check if there are things still on the condFunc_Register, if so .... */
+ if( *refCount != 0 ) {
+ while( *refCount != 0 ) {
+
+ _ConditionFunction_Delete( condFunc_Register->_cf[ *refCount-1 ] );
+ condFunc_Register->_cf[ *refCount-1 ] = NULL;
+
+ *refCount = *refCount - 1;
+ }
+ }
+ _Codelet_Destroy( _self, data );
+}
+void* _StgFEM_StandardConditionFunctions_DefaultNew( Name name ) {
+ return Codelet_New(
+ StgFEM_StandardConditionFunctions_Type,
+ _StgFEM_StandardConditionFunctions_DefaultNew,
+ _StgFEM_StandardConditionFunctions_AssignFromXML,
+ _Codelet_Build,
+ _Codelet_Initialise,
+ _Codelet_Execute,
+ _StgFEM_StandardConditionFunctions_Destroy,
+ name );
+}
+
+Index StgFEM_StandardConditionFunctions_Register( PluginsManager* pluginsManager ) {
+ Journal_DPrintf( StgFEM_Debug, "In: %s( void* )\n", __func__ );
+
+ return PluginsManager_Submit( pluginsManager, StgFEM_StandardConditionFunctions_Type, (Name)"0", _StgFEM_StandardConditionFunctions_DefaultNew );
+}
+
+Bool StgFEM_StandardConditionFunctions_Init( int* argc, char** argv[] ) {
+ Stg_ComponentRegister* componentsRegister = Stg_ComponentRegister_Get_ComponentRegister();
+ Stg_ComponentRegister_Add(componentsRegister,
+ StgFEM_StandardConditionFunctions_Type, (Name)"0",
+ _StgFEM_StandardConditionFunctions_DefaultNew );
+ RegisterParent( StgFEM_StandardConditionFunctions_Type, Stg_Component_Type );
+ return True;
+}
+
+#ifdef NO_ERF
+
+/* Copied from the OpenBSD iplementation of erf.c
+ (src/lib/libm/src/erf.c and src/lib/libm/src/math_private.h).
+ Modified to only work on 32 bit little endian machines.
+ This is just a hack for Windows machines. */
+
+/* @(#)s_erf.c 5.1 93/09/24 */
+/*
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+/* double erf(double x)
+ * double erfc(double x)
+ * x
+ * 2 |\
+ * erf(x) = --------- | exp(-t*t)dt
+ * sqrt(pi) \|
+ * 0
+ *
+ * erfc(x) = 1-erf(x)
+ * Note that
+ * erf(-x) = -erf(x)
+ * erfc(-x) = 2 - erfc(x)
+ *
+ * Method:
+ * 1. For |x| in [0, 0.84375]
+ * erf(x) = x + x*R(x^2)
+ * erfc(x) = 1 - erf(x) if x in [-.84375,0.25]
+ * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375]
+ * where R = P/Q where P is an odd poly of degree 8 and
+ * Q is an odd poly of degree 10.
+ * -57.90
+ * | R - (erf(x)-x)/x | <= 2
+ *
+ *
+ * Remark. The formula is derived by noting
+ * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
+ * and that
+ * 2/sqrt(pi) = 1.128379167095512573896158903121545171688
+ * is close to one. The interval is chosen because the fix
+ * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
+ * near 0.6174), and by some experiment, 0.84375 is chosen to
+ * guarantee the error is less than one ulp for erf.
+ *
+ * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and
+ * c = 0.84506291151 rounded to single (24 bits)
+ * erf(x) = sign(x) * (c + P1(s)/Q1(s))
+ * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0
+ * 1+(c+P1(s)/Q1(s)) if x < 0
+ * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06
+ * Remark: here we use the taylor series expansion at x=1.
+ * erf(1+s) = erf(1) + s*Poly(s)
+ * = 0.845.. + P1(s)/Q1(s)
+ * That is, we use rational approximation to approximate
+ * erf(1+s) - (c = (single)0.84506291151)
+ * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
+ * where
+ * P1(s) = degree 6 poly in s
+ * Q1(s) = degree 6 poly in s
+ *
+ * 3. For x in [1.25,1/0.35(~2.857143)],
+ * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1)
+ * erf(x) = 1 - erfc(x)
+ * where
+ * R1(z) = degree 7 poly in z, (z=1/x^2)
+ * S1(z) = degree 8 poly in z
+ *
+ * 4. For x in [1/0.35,28]
+ * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
+ * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0
+ * = 2.0 - tiny (if x <= -6)
+ * erf(x) = sign(x)*(1.0 - erfc(x)) if x < 6, else
+ * erf(x) = sign(x)*(1.0 - tiny)
+ * where
+ * R2(z) = degree 6 poly in z, (z=1/x^2)
+ * S2(z) = degree 7 poly in z
+ *
+ * Note1:
+ * To compute exp(-x*x-0.5625+R/S), let s be a single
+ * precision number and s := x; then
+ * -x*x = -s*s + (s-x)*(s+x)
+ * exp(-x*x-0.5626+R/S) =
+ * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
+ * Note2:
+ * Here 4 and 5 make use of the asymptotic series
+ * exp(-x*x)
+ * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
+ * x*sqrt(pi)
+ * We use rational approximation to approximate
+ * g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625
+ * Here is the error bound for R1/S1 and R2/S2
+ * |R1/S1 - f(x)| < 2**(-62.57)
+ * |R2/S2 - f(x)| < 2**(-61.52)
+ *
+ * 5. For inf > x >= 28
+ * erf(x) = sign(x) *(1 - tiny) (raise inexact)
+ * erfc(x) = tiny*tiny (raise underflow) if x > 0
+ * = 2 - tiny if x<0
+ *
+ * 7. Special case:
+ * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
+ * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
+ * erfc/erf(NaN) is NaN
+ */
+
+/* Assume little endian, 32 bit machines */
+
+typedef int int32_t;
+typedef unsigned int u_int32_t;
+
+typedef union
+{
+ double value;
+ struct
+ {
+ u_int32_t lsw;
+ u_int32_t msw;
+ } parts;
+} ieee_double_shape_type;
+
+/* Get the more significant 32 bit int from a double. */
+
+#define GET_HIGH_WORD(i,d) \
+do { \
+ ieee_double_shape_type gh_u; \
+ gh_u.value = (d); \
+ (i) = gh_u.parts.msw; \
+} while (0)
+
+/* Set the less significant 32 bits of a double from an int. */
+
+#define SET_LOW_WORD(d,v) \
+do { \
+ ieee_double_shape_type sl_u; \
+ sl_u.value = (d); \
+ sl_u.parts.lsw = (v); \
+ (d) = sl_u.value; \
+} while (0)
+
+
+static const double
+tiny = 1e-300,
+half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
+one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
+two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */
+ /* c = (float)0.84506291151 */
+erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */
+/*
+ * Coefficients for approximation to erf on [0,0.84375]
+ */
+efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */
+efx8= 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */
+pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */
+pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */
+pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */
+pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */
+pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */
+qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */
+qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */
+qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */
+qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */
+qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */
+/*
+ * Coefficients for approximation to erf in [0.84375,1.25]
+ */
+pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */
+pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */
+pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */
+pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */
+pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */
+pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */
+pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */
+qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */
+qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */
+qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */
+qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */
+qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */
+qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */
+/*
+ * Coefficients for approximation to erfc in [1.25,1/0.35]
+ */
+ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */
+ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */
+ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */
+ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */
+ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */
+ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */
+ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */
+ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */
+sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */
+sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */
+sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */
+sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */
+sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */
+sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */
+sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */
+sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */
+/*
+ * Coefficients for approximation to erfc in [1/.35,28]
+ */
+rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */
+rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */
+rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */
+rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */
+rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */
+rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */
+rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */
+sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */
+sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */
+sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */
+sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */
+sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */
+sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */
+sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */
+
+double
+erf(double x)
+{
+ int32_t hx,ix,i;
+ double R,S,P,Q,s,y,z,r;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) { /* erf(nan)=nan */
+ i = ((u_int32_t)hx>>31)<<1;
+ return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */
+ }
+
+ if(ix < 0x3feb0000) { /* |x|<0.84375 */
+ if(ix < 0x3e300000) { /* |x|<2**-28 */
+ if (ix < 0x00800000)
+ return 0.125*(8.0*x+efx8*x); /*avoid underflow */
+ return x + efx*x;
+ }
+ z = x*x;
+ r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+ s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+ y = r/s;
+ return x + x*y;
+ }
+ if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */
+ s = fabs(x)-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+ if(hx>=0) return erx + P/Q; else return -erx - P/Q;
+ }
+ if (ix >= 0x40180000) { /* inf>|x|>=6 */
+ if(hx>=0) return one-tiny; else return tiny-one;
+ }
+ x = fabs(x);
+ s = one/(x*x);
+ if(ix< 0x4006DB6E) { /* |x| < 1/0.35 */
+ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+ ra5+s*(ra6+s*ra7))))));
+ S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+ sa5+s*(sa6+s*(sa7+s*sa8)))))));
+ } else { /* |x| >= 1/0.35 */
+ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+ rb5+s*rb6)))));
+ S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+ sb5+s*(sb6+s*sb7))))));
+ }
+ z = x;
+ SET_LOW_WORD(z,0);
+ r = exp(-z*z-0.5625)*exp((z-x)*(z+x)+R/S);
+ if(hx>=0) return one-r/x; else return r/x-one;
+}
+
+double
+erfc(double x)
+{
+ int32_t hx,ix;
+ double R,S,P,Q,s,y,z,r;
+ GET_HIGH_WORD(hx,x);
+ ix = hx&0x7fffffff;
+ if(ix>=0x7ff00000) { /* erfc(nan)=nan */
+ /* erfc(+-inf)=0,2 */
+ return (double)(((u_int32_t)hx>>31)<<1)+one/x;
+ }
+
+ if(ix < 0x3feb0000) { /* |x|<0.84375 */
+ if(ix < 0x3c700000) /* |x|<2**-56 */
+ return one-x;
+ z = x*x;
+ r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
+ s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+ y = r/s;
+ if(hx < 0x3fd00000) { /* x<1/4 */
+ return one-(x+x*y);
+ } else {
+ r = x*y;
+ r += (x-half);
+ return half - r ;
+ }
+ }
+ if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */
+ s = fabs(x)-one;
+ P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
+ Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
+ if(hx>=0) {
+ z = one-erx; return z - P/Q;
+ } else {
+ z = erx+P/Q; return one+z;
+ }
+ }
+ if (ix < 0x403c0000) { /* |x|<28 */
+ x = fabs(x);
+ s = one/(x*x);
+ if(ix< 0x4006DB6D) { /* |x| < 1/.35 ~ 2.857143*/
+ R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
+ ra5+s*(ra6+s*ra7))))));
+ S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
+ sa5+s*(sa6+s*(sa7+s*sa8)))))));
+ } else { /* |x| >= 1/.35 ~ 2.857143 */
+ if(hx<0&&ix>=0x40180000) return two-tiny;/* x < -6 */
+ R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
+ rb5+s*rb6)))));
+ S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
+ sb5+s*(sb6+s*sb7))))));
+ }
+ z = x;
+ SET_LOW_WORD(z,0);
+ r = exp(-z*z-0.5625)*
+ exp((z-x)*(z+x)+R/S);
+ if(hx>0) return r/x; else return two-r/x;
+ } else {
+ if(hx>0) return tiny*tiny; else return two-tiny;
+ }
+}
+
+#endif
+
+
+void StgFEM_StandardConditionFunctions_SolidBodyRotation( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+ Coord centre;
+ Coord vector;
+ double omega;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+
+ /* Find Centre of Solid Body Rotation */
+ centre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreX", 0.0 );
+ centre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreY", 0.0 );
+ centre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreZ", 0.0 );
+ omega = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationOmega", 1.0 );
+
+ /* Find coordinate of node */
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ /* Find vector from centre to node */
+ StGermain_VectorSubtraction( vector, coord, centre, 2 );
+
+ result[ I_AXIS ] = -omega * vector[ J_AXIS ];
+ result[ J_AXIS ] = omega * vector[ I_AXIS ];
+}
+
+
+void StgFEM_StandardConditionFunctions_PartialRotationX( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+ Coord centre;
+ Coord vector;
+ double omega;
+ double size;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+
+ /* Find Centre of Solid Body Rotation */
+ centre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreX", 0.0 );
+ centre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreY", 0.0 );
+ centre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreZ", 0.0 );
+ size = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"RadiusCylinder", 0.0 );
+ omega = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationOmega", 1.0 );
+
+ /* Find coordinate of node */
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ /* Find vector from centre to node */
+ StGermain_VectorSubtraction( vector, coord, centre, 2 );
+
+ /*if (context->currentTime > 1.33e-6)
+ omega=0.0;*/
+
+ if ((vector[ I_AXIS ]*vector[ I_AXIS ]+vector[ J_AXIS ]*vector[ J_AXIS ])<=size*size)
+ *result = -omega * vector[ J_AXIS ];
+ else
+ *result = 0.0;
+}
+
+void StgFEM_StandardConditionFunctions_PartialRotationY( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+ Coord centre;
+ Coord vector;
+ double omega;
+ double size;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+
+ /* Find Centre of Solid Body Rotation */
+ centre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreX", 0.0 );
+ centre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreY", 0.0 );
+ centre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreZ", 0.0 );
+ size = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"RadiusCylinder", 0.0 );
+ omega = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationOmega", 1.0 );
+
+ /* Find coordinate of node */
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ /* Find vector from centre to node */
+ StGermain_VectorSubtraction( vector, coord, centre, 2 );
+
+ if ((vector[ I_AXIS ]*vector[ I_AXIS ]+vector[ J_AXIS ]*vector[ J_AXIS ])<=size*size)
+ *result = omega * vector[ I_AXIS ];
+ else
+ *result = 0.0;
+}
+
+
+void StgFEM_StandardConditionFunctions_TaperedRotationX( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+ Coord centre;
+ Coord vector;
+ double omega;
+ double size, r, taper;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+
+ /* Find Centre of Solid Body Rotation */
+ centre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationCentreX", 0.0 );
+ centre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationCentreY", 0.0 );
+ centre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationCentreZ", 0.0 );
+ size = Dictionary_GetDouble_WithDefault( dictionary, "RadiusCylinder", 0.0 );
+ omega = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationOmega", 1.0 );
+
+ taper = Dictionary_GetDouble_WithDefault( dictionary, "TaperedRadius", 0.0 );
+
+ /* Find coordinate of node */
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ /* Find vector from centre to node */
+ StGermain_VectorSubtraction( vector, coord, centre, 2 );
+
+ r=sqrt(vector[ I_AXIS ]*vector[ I_AXIS ]
+ +vector[ J_AXIS ]*vector[ J_AXIS ]);
+ if (r<=size)
+ *result = -omega * vector[ J_AXIS ];
+ else if(r<=taper)
+ *result = -omega * vector[ J_AXIS ]*(taper-r)/(taper-size);
+ else
+ *result = 0;
+}
+
+void StgFEM_StandardConditionFunctions_TaperedRotationY( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+ Coord centre;
+ Coord vector;
+ double omega;
+ double size, r, taper;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+
+ /* Find Centre of Solid Body Rotation */
+ centre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationCentreX", 0.0 );
+ centre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationCentreY", 0.0 );
+ centre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationCentreZ", 0.0 );
+ size = Dictionary_GetDouble_WithDefault( dictionary, "RadiusCylinder", 0.0 );
+ omega = Dictionary_GetDouble_WithDefault( dictionary, "SolidBodyRotationOmega", 1.0 );
+
+ taper = Dictionary_GetDouble_WithDefault( dictionary, "TaperedRadius", 0.0 );
+
+ /* Find coordinate of node */
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ /* Find vector from centre to node */
+ StGermain_VectorSubtraction( vector, coord, centre, 2 );
+
+
+ r=sqrt(vector[ I_AXIS ]*vector[ I_AXIS ]
+ +vector[ J_AXIS ]*vector[ J_AXIS ]);
+ if (r<=size)
+ *result = omega * vector[ I_AXIS ];
+ else if(r<=taper)
+ *result = omega * vector[ I_AXIS ]*(taper-r)/(taper-size);
+ else
+ *result = 0;
+}
+
+
+
+
+void StgFEM_StandardConditionFunctions_SimpleShear( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+ double centre;
+ double factor;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+
+ /* Find Centre of Solid Body Rotation */
+ centre = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SimpleShearCentreY", 0.0 );
+ factor = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SimpleShearFactor", 1.0 );
+
+ /* Find coordinate of node */
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ *result = factor * (coord[ J_AXIS ] - centre);
+}
+
+void StgFEM_StandardConditionFunctions_ShearZ( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+ double centre;
+ double factor;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+
+ /* Find Centre of Solid Body Rotation */
+ centre = Dictionary_GetDouble_WithDefault( dictionary, "ShearZCentre", 0.0 );
+ factor = Dictionary_GetDouble_WithDefault( dictionary, "ShearZFactor", 1.0 );
+
+ /* Find coordinate of node */
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ *result = factor * (coord[ K_AXIS ] - centre);
+}
+
+void StgFEM_StandardConditionFunctions_SimpleShearInverted( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+ double centre;
+ double factor;
+ double yAxisInvert;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+
+ /* Find Centre of Solid Body Rotation */
+ centre = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SimpleShearCentreY", 0.0 );
+ factor = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SimpleShearFactor", 1.0 );
+
+ /* Find coordinate of node */
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ yAxisInvert = coord[ J_AXIS ] * -1.0 - 1.0;
+
+ *result = factor * ( 1.0 - coord[ J_AXIS ] ) ;
+}
+
+
+void StgFEM_StandardConditionFunctions_Extension( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+ double centre;
+ double factor;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+
+ /* Find Centre of Solid Body Rotation */
+ centre = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ExtensionCentreX", 0.0 );
+ factor = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ExtensionFactor", 1.0 );
+
+ /* Find coordinate of node */
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ *result = factor * (coord[ I_AXIS ] - centre);
+}
+
+
+void StgFEM_StandardConditionFunctions_PartialLid_TopLayer( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
+ DomainContext* context = (DomainContext*)_context;
+ FeVariable* velVar = NULL;
+ FeMesh* mesh = NULL;
+ double* velResult = (double*)result;
+ double margin = 0;
+ double min[3], max[3];
+
+ velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = velVar->feMesh;
+
+ Mesh_GetMinimumSeparation( mesh, &margin, NULL );
+ Mesh_GetGlobalCoordRange( mesh, min, max );
+ margin *= 1.1;
+ if( (Mesh_GetVertex( mesh, node_lI )[I_AXIS] < (max[I_AXIS] - margin )) &&
+ (Mesh_GetVertex( mesh, node_lI )[I_AXIS] > (min[I_AXIS] + margin )))
+ {
+ (*velResult) = 1;
+ }
+ else {
+ (*velResult) = 0;
+ }
+}
+
+void StgFEM_StandardConditionFunctions_LinearInterpolationLid( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
+ DomainContext* context = (DomainContext*)_context;
+ FeVariable* velVar = NULL;
+ FeMesh* mesh = NULL;
+ double* velResult = (double*)result;
+ double boxLength = 0;
+ double leftHandSideValue = 0;
+ double rightHandSideValue = 0;
+ double gradient = 0;
+ double min[3], max[3];
+
+ velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = velVar->feMesh;
+
+ Mesh_GetGlobalCoordRange( mesh, min, max );
+ boxLength = max[I_AXIS] - min[I_AXIS];
+ leftHandSideValue = Dictionary_GetDouble_WithDefault( context->dictionary, (Dictionary_Entry_Key)"bcLeftHandSideValue", 0.0 );
+ rightHandSideValue = Dictionary_GetDouble_WithDefault( context->dictionary, (Dictionary_Entry_Key)"bcRightHandSideValue", 1.0 );
+ gradient = (rightHandSideValue - leftHandSideValue) / boxLength;
+ (*velResult ) = leftHandSideValue + gradient * (Mesh_GetVertex( mesh, node_lI )[I_AXIS] - min[I_AXIS] );
+}
+
+
+void StgFEM_StandardConditionFunctions_Lid_RampWithCentralMax( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
+ DomainContext* context = (DomainContext*)_context;
+ FeVariable* velVar = NULL;
+ FeMesh* mesh = NULL;
+ double* velResult = (double*)result;
+ double boxLength = 0;
+ double xPosRelativeToTopLeft = 0;
+ double min[3], max[3];
+
+ velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = velVar->feMesh;
+
+ Mesh_GetGlobalCoordRange( mesh, min, max );
+ xPosRelativeToTopLeft = Mesh_GetVertex( mesh, node_lI )[I_AXIS] - min[I_AXIS];
+ boxLength = max[I_AXIS] - min[I_AXIS];
+ if ( xPosRelativeToTopLeft < boxLength / 2 ) {
+ (*velResult) = 2 * xPosRelativeToTopLeft / boxLength;
+ }
+ else {
+ (*velResult) = 1 - 2 * ( xPosRelativeToTopLeft - (boxLength/2) );
+ }
+}
+void StgFEM_StandardConditionFunctions_LinearVelocityLeftWall( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
+ DomainContext* context = (DomainContext*)_context;
+ FeVariable* velVar = NULL;
+ FeMesh* mesh = NULL;
+ double* velResult = (double*)result;
+ Dictionary* dictionary = context->dictionary;
+ double min[3], max[3];
+ double gradient, maxvel;
+ velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = velVar->feMesh;
+
+ maxvel = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"MaximumVelocity_Left", 0.0 );
+ Mesh_GetGlobalCoordRange( mesh, min, max );
+ gradient = maxvel/(min[1] - max[1]);
+
+ (*velResult) = gradient*Mesh_GetVertex( mesh, node_lI )[J_AXIS];
+ //printf("Left velResult is %g\n",(*velResult));
+
+}
+void StgFEM_StandardConditionFunctions_LinearVelocityRightWall( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
+ DomainContext* context = (DomainContext*)_context;
+ FeVariable* velVar = NULL;
+ FeMesh* mesh = NULL;
+ double* velResult = (double*)result;
+ Dictionary* dictionary = context->dictionary;
+ double min[3], max[3];
+ double gradient, maxvel;
+ velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = velVar->feMesh;
+
+ maxvel = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"MaximumVelocity_Right", 0.0 );
+ Mesh_GetGlobalCoordRange( mesh, min, max );
+ gradient = maxvel/(max[1] - min[1]);
+
+ (*velResult) = maxvel - gradient*Mesh_GetVertex( mesh, node_lI )[J_AXIS];
+ //printf("Right velResult is %g\n",(*velResult));
+}
+
+
+void StgFEM_StandardConditionFunctions_SinusoidalLid( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
+ DomainContext* context = (DomainContext*)_context;
+ FeVariable* velVar = NULL;
+ FeMesh* mesh = NULL;
+ double* velResult = (double*)result;
+ double boxLength = 0;
+ double linearInterp = 0;
+ double wavenumber;
+ double min[3], max[3];
+
+ wavenumber = Dictionary_GetDouble_WithDefault( context->dictionary, (Dictionary_Entry_Key)"sinusoidalLidWavenumber", 1 );
+
+ velVar = (FeVariable* )FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = velVar->feMesh;
+
+ Mesh_GetGlobalCoordRange( mesh, min, max );
+ boxLength = max[I_AXIS] - min[I_AXIS];
+ linearInterp = (Mesh_GetVertex( mesh, node_lI )[I_AXIS] - min[I_AXIS] ) / boxLength;
+ (*velResult) = sin( linearInterp * M_PI * wavenumber );
+}
+
+
+void StgFEM_StandardConditionFunctions_CornerOnly( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* result ) {
+ DomainContext* context = (DomainContext*)_context;
+ FeVariable* velVar = NULL;
+ FeMesh* feMesh = NULL;
+ double* velResult = (double*)result;
+ Node_GlobalIndex node_gI = 0;
+ unsigned inds[3];
+ Grid* elGrid;
+
+ velVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ feMesh = velVar->feMesh;
+ elGrid = *(Grid**)ExtensionManager_Get( feMesh->info, feMesh,
+ ExtensionManager_GetHandle( feMesh->info, (Name)"elGrid" ) );
+
+ node_gI = Mesh_DomainToGlobal( feMesh, MT_VERTEX, node_lI );
+ RegularMeshUtils_Node_1DTo3D( feMesh, node_gI, inds );
+
+ if ( inds[0] == elGrid->sizes[I_AXIS] ) {
+ (*velResult) = 1;
+ }
+ else {
+ (*velResult) = 0;
+ }
+}
+
+double StGermain_CosineHillValue( double* centre, double* position, double height, double diameterAtBase, Dimension_Index dim ) {
+ double distanceFromCentre = StGermain_DistanceBetweenPoints( centre, position, dim );
+
+ if (distanceFromCentre < diameterAtBase * 0.5 )
+ return height * (0.5 + 0.5 * cos( 2.0 * M_PI/diameterAtBase * distanceFromCentre ) );
+ else
+ return 0.0;
+}
+
+void StgFEM_StandardConditionFunctions_TemperatureCosineHill( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* feMesh = NULL;
+ double* result = (double*) _result;
+ Coord centre;
+ Coord rotationCentre;
+ double omega;
+ double hillHeight;
+ double hillDiameter;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ feMesh = feVariable->feMesh;
+
+ /* Read values from dictionary */
+ hillHeight = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"CosineHillHeight" , 1.0 );
+ hillDiameter = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"CosineHillDiameter", 1.0 );
+ centre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"CosineHillCentreX" , 0.0 );
+ centre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"CosineHillCentreY" , 0.0 );
+ centre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"CosineHillCentreZ" , 0.0 );
+
+ if ( Dictionary_GetBool( dictionary, "RotateCosineHill" ) ) {
+ /* Assume solid body rotation */
+ rotationCentre[ I_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreX", 0.0 );
+ rotationCentre[ J_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreY", 0.0 );
+ rotationCentre[ K_AXIS ] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationCentreZ", 0.0 );
+ omega = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SolidBodyRotationOmega", 1.0 );
+
+ StGermain_VectorSubtraction( centre, rotationCentre, centre, context->dim );
+ StGermain_RotateCoordinateAxis( centre, centre, K_AXIS, omega * context->currentTime );
+ StGermain_VectorAddition( centre, centre, rotationCentre, context->dim );
+ }
+
+ *result = StGermain_CosineHillValue( centre, Mesh_GetVertex( feMesh, node_lI ), hillHeight, hillDiameter, context->dim );
+}
+
+
+void StgFEM_StandardConditionFunctions_LinearWithSinusoidalPerturbation( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* feMesh = NULL;
+ unsigned nDims;
+ double* result = (double*) _result;
+ double topLayerBC;
+ double bottomLayerBC;
+ double perturbationAmplitude;
+ double horizontalWaveNumber;
+ double verticalWaveNumber;
+ double scaleFactor;
+ double* coord;
+ Coord relScaledCoord;
+ double min[3], max[3], topLayerCoord, bottomLayerCoord;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ feMesh = feVariable->feMesh;
+
+ nDims = Mesh_GetDimSize( feMesh );
+ Mesh_GetGlobalCoordRange( feMesh, min, max );
+
+ topLayerCoord = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_TopLayerCoord", max[J_AXIS] );
+ bottomLayerCoord = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_BottomLayerCoord", min[J_AXIS] );
+
+ topLayerBC = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_TopLayerBC", 0.0 );
+ bottomLayerBC = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_BottomLayerBC", 1.0 );
+ scaleFactor = bottomLayerBC - topLayerBC;
+ perturbationAmplitude = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_PerturbationAmplitude", 0.1 );
+ /* Note: these are both multiplied by pi, so wavenumber = 1 means the perturbation goes from 0 to pi, which is
+ * half a full sin or cos cycle. Wavenumber = 3 means the range is 0 -> 3pi, or 1 and a half full cycles. */
+ horizontalWaveNumber = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_HorizontalWaveNumber", 1.0 );
+ verticalWaveNumber = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_VerticalWaveNumber", 1.0 );
+
+ coord = Mesh_GetVertex( feMesh, node_lI );
+
+ /* if node is outside IC shape set to 0 temperature */
+ if( coord[J_AXIS] > topLayerCoord || coord[J_AXIS] < bottomLayerCoord ) {
+ *result = 0; return ;
+ }
+
+ /* make coord relative to box bottom left corner, then scale from 0 to 1 between box min & max */
+ relScaledCoord[I_AXIS] = (coord[0] - min[0]) / (max[0] - min[0]);
+ relScaledCoord[J_AXIS] = (coord[1] - bottomLayerCoord) / (topLayerCoord - bottomLayerCoord);
+
+
+ /* Note: ok to use the 1.0 below since we've already scaled the coord to somewhere between 0 to 1 */
+ *result = topLayerBC + scaleFactor * ( 1.0 - relScaledCoord[ J_AXIS ] )
+ + perturbationAmplitude * ( cos( horizontalWaveNumber * M_PI * coord[ I_AXIS ] )
+ * sin( verticalWaveNumber * M_PI * relScaledCoord[ J_AXIS ] ) );
+}
+
+void StgFEM_StandardConditionFunctions_Trigonometry( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* feMesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+ double height, width;
+ double min[3], max[3];
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ feMesh = feVariable->feMesh;
+
+ Mesh_GetGlobalCoordRange( feMesh, min, max );
+ coord = Mesh_GetVertex( feMesh, node_lI );
+
+ /* Get Aspect Ratio */
+ height = max[ J_AXIS ] - min[ J_AXIS ];
+ width = max[ I_AXIS ] - min[ I_AXIS ];
+
+ *result = 1.0 - 0.5 * M_PI * coord[ J_AXIS ] * sin( M_PI * coord[ I_AXIS ]/width );
+}
+
+#define SMALL 1.0e-5
+void Stg_FEM_VelicTemperatureIC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ FeVariable* temperatureField = (FeVariable*) FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ FeMesh* feMesh = temperatureField->feMesh;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double x;
+ double y;
+ double kx;
+ double ky;
+ int wavenumberX;
+ double wavenumberY;
+ double sigma;
+ double Lx;
+ double min[3], max[3];
+
+ /* Find coordinate of node */
+ coord = Mesh_GetVertex( feMesh, node_lI );
+ Mesh_GetGlobalCoordRange( feMesh, min, max );
+
+ /* Make sure that the box has right dimensions */
+ assert( ( max[ J_AXIS ] - min[ J_AXIS ] - 1.0 ) < SMALL );
+ Lx = max[ I_AXIS ] - min[ I_AXIS ];
+
+ x = coord[ I_AXIS ] - min[ I_AXIS ];
+ y = coord[ J_AXIS ] - min[ J_AXIS ];
+
+ wavenumberX = Dictionary_GetInt_WithDefault( dictionary, (Dictionary_Entry_Key)"wavenumberX", 1 );
+ wavenumberY = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"wavenumberY", 1.0 );
+ sigma = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"sigma", 1.0 );
+
+ assert( sigma > 0.0 );
+ assert( wavenumberY > 0.0 );
+ assert( wavenumberX > 0.0 );
+
+ kx = (double)wavenumberX * M_PI / Lx;
+ ky = (double)wavenumberY * M_PI;
+
+ *result = sigma * sin( ky * y ) * cos( kx * x );
+}
+
+/* IC from Mirko Velic. This is the IC temperature for his solB, from his Analytic Suite. Added 22-May-2006 */
+void Stg_FEM_VelicTemperatureIC_SolB( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ FeVariable* temperatureField = (FeVariable*) FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ FeMesh* feMesh = temperatureField->feMesh;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double x;
+ double y;
+ double km; /* for y-direction */
+ double kn; /* for x-direction */
+ double wavenumberX;
+ double wavenumberY;
+ double L;
+ double sigma;
+ double min[3], max[3];
+
+ /* Find coordinate of node */
+ coord = Mesh_GetVertex( feMesh, node_lI );
+ Mesh_GetGlobalCoordRange( feMesh, min, max );
+
+ /* Make sure that the box has right dimensions */
+ assert( (max[ J_AXIS ] - min[ J_AXIS ] - 1.0 ) < SMALL );
+ L = max[ I_AXIS ] - min[ I_AXIS ];
+
+ x = coord[ I_AXIS ] - min[ I_AXIS ];
+ y = coord[ J_AXIS ] - min[ J_AXIS ];
+
+ wavenumberX = Dictionary_GetInt_WithDefault( dictionary, (Dictionary_Entry_Key)"wavenumberX", 1 );
+ wavenumberY = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"wavenumberY", 2.0 );
+ assert( wavenumberX != wavenumberY );
+ sigma = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"sigma", 1.0 );
+
+ kn = wavenumberX * M_PI / L;
+/* TODO: Re-write Mirko's code and/or Documentation so the input parameters for these ICs are less confusing */
+ km = wavenumberY / L;
+
+ *result = sigma * sinh( km * y ) * cos( kn * x );
+}
+
+
+/* Initial Condition derived from Boundary Layer theory -
+ taken from P. E. van Keken, S. D. King, U. R. Schmeling, U. R. Christensen, D. Neumeister, and M.-P. Doin. A comparison of methods for the modeling of thermochemical convection. Journal of Geophysical Research, 102(B10):22477-22496, october 1997. */
+void StgFEM_StandardConditionFunctions_AnalyticalTemperatureIC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* feMesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double u0, v0, Q;
+ double x, y;
+ double RaT;
+ double lambda, height, width;
+ double Tu, Tl, Tr, Ts;
+ double min[3], max[3];
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ feMesh = feVariable->feMesh;
+
+ coord = Mesh_GetVertex( feMesh, node_lI );
+ Mesh_GetGlobalCoordRange( feMesh, min, max );
+
+ /* Get Aspect Ratio */
+ height = max[ J_AXIS ] - min[ J_AXIS ];
+ width = max[ I_AXIS ] - min[ I_AXIS ];
+ lambda = width/height;
+
+ x = coord[ I_AXIS ] - min[ I_AXIS ];
+ y = coord[ J_AXIS ] - min[ J_AXIS ];
+
+ /* Get thermal Rayleigh Number from Dictionary */
+ RaT = Dictionary_GetDouble( dictionary, "RaT" );
+
+ /* Horizontal fluid velocity at upper boundary & lower boundary - Equation A3 */
+ u0 = pow( lambda , 7.0/3.0 )/ pow(1 + lambda*lambda*lambda*lambda, 2.0/3.0) * pow(0.5*RaT/sqrt(M_PI) , 2.0/3.0);
+
+ /* Vertical velocity of the upwelling and downwellings - Modified from Van Keken to match Turcotte and Shubert */
+ v0 = u0; /*lambda; */
+
+ /* Total rate of heat flow out of the top of the cell per unit distance along the axis of the roll - Equation A3 */
+ Q = 2.0 * sqrt(M_1_PI * lambda/u0);
+ Tu = 0.5 * erf( 0.5 * ( 1 - y ) * sqrt(u0/x) ); /* Equation A2a */
+ Tl = 1.0 - 0.5 * erf(0.5 * y * sqrt(u0/(lambda-x))); /* Equation A2b */
+ Tr = 0.5 + 0.5*Q/sqrt(M_PI) * sqrt(v0/(y+1)) * exp( -x*x*v0/(4*y+4) ); /* Equation A2c */
+ Ts = 0.5 - 0.5*Q/sqrt(M_PI) * sqrt(v0/(2-y)) * exp( -(lambda - x) * (lambda - x) * v0 / (8 - 4*y) ); /* Equation A2d */
+
+ /* Equation A1 */
+ *result = Tu + Tl + Tr + Ts - 1.5;
+
+ /* Crop result */
+ if ( *result > 1.0 )
+ *result = 1.0;
+ else if ( *result < 0.0 )
+ *result = 0.0;
+
+}
+
+void StgFEM_StandardConditionFunctions_EdgeDriveConvectionIC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double perturbationAmplitude;
+ double thermalAnomalyOffset;
+ double* coord;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ mesh = feVariable->feMesh;
+ perturbationAmplitude = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalTempIC_PerturbationAmplitude", 0.1 );
+ thermalAnomalyOffset = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"thermalAnomalyOffset", 0.0 );
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ /* eqn 1 from S.D.King & D.L. Anderson, "Edge-drive convection", EPSL 160 (1998) 289-296 */
+
+ *result = 1.0 + perturbationAmplitude * sin( M_PI * coord[ J_AXIS ] ) * cos( 0.5 * M_PI * ( coord[ I_AXIS ] + thermalAnomalyOffset ) );
+}
+
+void StgFEM_StandardConditionFunctions_ThermalEdgeDriveConvectionIC( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+ int dim;
+ double contStartX, contEndX;
+ double contStartY, contEndY;
+ double contStartZ, contEndZ;
+ double minY, maxY, interiorTemp;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ dim = Dictionary_GetInt_WithDefault( dictionary, (Dictionary_Entry_Key)"dim", 0.0 );
+ contStartX = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"contStartX", 0.0 );
+ contEndX = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"contEndX", 0.0 );
+ contStartY = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"contStartY", 0.0 );
+ contEndY = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"contEndY", 0.0 );
+ minY = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"minY", 0.0 );
+ maxY = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"maxY", 0.0 );
+ interiorTemp = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"interiorTemp", 1.0 );
+ if ( dim == 3 ) {
+ contStartZ = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"contStartZ", 0.0 );
+ contEndZ = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"contEndZ", 0.0 );
+ }
+
+ if(( coord[I_AXIS] >= contStartX && coord[ I_AXIS ] <= contEndX ) && ( coord[J_AXIS] >= contStartY && coord[ J_AXIS ] <= contEndY )) {
+ if ( dim == 3 ) {
+ if ( coord[K_AXIS] >= contStartZ && coord[ K_AXIS ] <= contEndZ )
+ *result = 0.0;
+ else
+ *result = interiorTemp;
+ }
+ }
+ else
+ *result = interiorTemp;
+}
+
+void StgFEM_StandardConditionFunctions_SinusoidalExtension( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double frequency;
+ double vel0;
+ double amplitude;
+ double phaseShift;
+
+ frequency = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalExtensionFrequency", 1.0 );
+ vel0 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalExtensionVelocity", 0.0 );
+ amplitude = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalExtensionAmplitude", 0.0 );
+ phaseShift = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SinusoidalExtensionPhaseShift", 0.0 );
+
+
+ *result = vel0 + amplitude * cos( 2.0 * M_PI * frequency * (context->currentTime + context->dt - phaseShift ) );
+}
+
+
+void StgFEM_StandardConditionFunctions_StepFunction( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* feMesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double lower_offset, upper_offset;
+ double value, lower_value, upper_value;
+ unsigned dim;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ feMesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( feMesh, node_lI );
+
+ lower_offset = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionLowerOffset", 0.0 );
+ upper_offset = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionUpperOffset", lower_offset );
+ value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionValue", 0.0 );
+ dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "StepFunctionDim", 0 );
+
+ lower_value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionLowerValue", 0.0 );
+ upper_value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionUpperValue", value );
+
+ if(dim==3)
+ {
+ dim=0;
+ coord=&(context->currentTime);
+ }
+
+ if(coord[dim] < lower_offset) {
+ *result=lower_value;
+ } else if(coord[dim] < upper_offset) {
+ *result=lower_value +
+ (upper_value-lower_value)
+ *(coord[dim] - lower_offset)/(upper_offset-lower_offset);
+ } else {
+ *result=upper_value;
+ }
+}
+
+
+void StG_FEM_StandardConditionFunctions_StepFunctionProduct1( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double start, end;
+ double value;
+ unsigned dim;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ start = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct1Start", 0.0 );
+ end = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct1End", 0.0 );
+ value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct1Value", 0.0 );
+ dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "StepFunctionProduct1Dim", 0 );
+
+ if( coord[dim] > start && coord[dim] < end ) {
+ *result = value;
+ }
+ else {
+ *result = 0;
+ }
+}
+
+void StG_FEM_StandardConditionFunctions_StepFunctionProduct2( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double start, end;
+ double value;
+ unsigned dim;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ start = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct2Start", 0.0 );
+ end = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct2End", 0.0 );
+ value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct2Value", 0.0 );
+ dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "StepFunctionProduct2Dim", 0 );
+
+ if( coord[dim] > start && coord[dim] < end ) {
+ *result = value;
+ }
+ else {
+ *result = 0;
+ }
+}
+
+
+void StG_FEM_StandardConditionFunctions_StepFunctionProduct3( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double start, end;
+ double value;
+ unsigned dim;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ start = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct3Start", 0.0 );
+ end = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct3End", 0.0 );
+ value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct3Value", 0.0 );
+ dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "StepFunctionProduct3Dim", 1 );
+
+ if( coord[dim] > start && coord[dim] < end ) {
+ *result = value;
+ }
+ else {
+ *result = 0;
+ }
+}
+
+void StG_FEM_StandardConditionFunctions_StepFunctionProduct4( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double start, end;
+ double value;
+ unsigned dim;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ start = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct4Start", 0.0 );
+ end = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct4End", 0.0 );
+ value = Dictionary_GetDouble_WithDefault( dictionary, "StepFunctionProduct4Value", 0.0 );
+ dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "StepFunctionProduct4Dim", 1 );
+
+ if( coord[dim] > start && coord[dim] < end ) {
+ *result = value;
+ }
+ else {
+ *result = 0;
+ }
+}
+
+/* A Gaussian GaussianHeight*exp(-((GaussianCenter-x)/GaussianWidth)^2) */
+
+void StG_FEM_StandardConditionFunctions_Gaussian
+( Node_LocalIndex node_lI, Variable_Index var_I, void* _context,
+ void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double center, width, height;
+ unsigned dim;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ center = Dictionary_GetDouble_WithDefault( dictionary,
+ "GaussianCenter", 0.0 );
+ width = Dictionary_GetDouble_WithDefault( dictionary,
+ "GaussianWidth", 1.0 );
+ height = Dictionary_GetDouble_WithDefault( dictionary,
+ "GaussianHeight", 1.0 );
+ dim = Dictionary_GetUnsignedInt_WithDefault( dictionary,
+ "GaussianDim", 0 );
+
+ *result=height*exp(-(center-coord[dim])*(center-coord[dim])
+ /(width*width));
+}
+
+void StgFEM_StandardConditionFunctions_MovingStepFunction( Node_LocalIndex nodeInd, Variable_Index varInd, void* _ctx, void* _result ) {
+ FiniteElementContext* ctx = (FiniteElementContext*)_ctx;
+ FeVariable* velField;
+ FeMesh* mesh;
+ Dictionary* dict = ctx->dictionary;
+ double* result = (double*)_result;
+ double* coord, offsetLower, offsetUpper, left, right;
+ double *wallCrd, pos;
+ int dim, wallDepth;
+ unsigned ijk[3];
+ char* movingWall;
+ Grid* grid;
+
+ /*
+ ** Get the velocity field. */
+ velField = (FeVariable*)FieldVariable_Register_GetByName(
+ ctx->fieldVariable_Register, "VelocityField" );
+
+ /*
+ ** Get the mesh and the coordinate of the node. */
+ mesh = velField->feMesh;
+ coord = Mesh_GetVertex( mesh, nodeInd );
+
+ /*
+ ** Extract all the parameters we need from the dictionary. */
+ offsetLower = Dictionary_GetDouble_WithDefault( dict, (Dictionary_Entry_Key)"MovingStepFunctionOffsetLower", 0.0 );
+ offsetUpper = Dictionary_GetDouble_WithDefault( dict, (Dictionary_Entry_Key)"MovingStepFunctionOffsetUpper", 0.0 );
+ dim = Dictionary_GetUnsignedInt_WithDefault( dict, "MovingStepFunctionDim", 0 );
+ left = Dictionary_GetDouble_WithDefault( dict, (Dictionary_Entry_Key)"MovingStepFunctionLeftSide", 0.0 );
+ right = Dictionary_GetDouble_WithDefault( dict, (Dictionary_Entry_Key)"MovingStepFunctionRightSide", 0.0 );
+ movingWall = Dictionary_GetString_WithDefault( dict, "MovingStepFunctionMovingWall", "lower" );
+ wallDepth = Dictionary_GetInt_WithDefault( dict, (Dictionary_Entry_Key)"MovingStepFunctionWallDepth", 0 );
+
+ /*
+ ** Because we're dealing with a moving step function, we need to calculate
+ ** from where the offset should be applied. */
+ grid = *(Grid**)Mesh_GetExtension( mesh, Grid**, "vertexGrid" );
+ assert( grid );
+ memset( ijk, 0, 3 * sizeof(unsigned) );
+ if( !strcmp( movingWall, "lower" ) ) {
+ ijk[dim] = wallDepth;
+ wallCrd = Mesh_GetVertex( mesh, Grid_Project( grid, ijk ) );
+ offsetLower += wallCrd[dim];
+ offsetUpper += wallCrd[dim];
+ }
+ else {
+ ijk[dim] = grid->sizes[dim] - wallDepth - 1;
+ wallCrd = Mesh_GetVertex( mesh, Grid_Project( grid, ijk ) );
+ offsetLower += wallCrd[dim];
+ offsetUpper += wallCrd[dim];
+ }
+
+ /*
+ ** Apply the set of parameters to this node. */
+ pos = coord[dim];
+ if( pos <= offsetLower )
+ *result = left;
+ else if( pos >= offsetUpper )
+ *result = right;
+ else {
+ *result = left + ((pos - offsetLower) / (offsetUpper - offsetLower)) * (right - left);
+ }
+}
+
+void StgFEM_StandardConditionFunctions_ConvectionBenchmark( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ /* This IC is for the 2D ConvectionBenchmark defined in
+ * http://www.mcc.monash.edu.au/twiki/view/Research/ConvectionBenchmarks
+ */
+
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh;
+ double* result = (double*) _result;
+ double min[3], max[3];
+ double* coord;
+ double x,y;
+ double Lx, Ly;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ mesh = (FeMesh*)feVariable->feMesh;
+
+ Mesh_GetGlobalCoordRange( mesh, min, max );
+
+ Lx = max[ I_AXIS ] - min[ I_AXIS ];
+ Ly = max[ J_AXIS ] - min[ J_AXIS ];
+
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ x = ( coord[0] - min[ I_AXIS ] ) / Lx;
+ y = ( coord[1] - min[ J_AXIS ] ) / Ly;
+
+
+ *result = ( 1 - y ) + ( cos( M_PI * x ) * sin( M_PI * y ) ) / 100 ;
+}
+
+void StgFEM_StandardConditionFunctions_ConstantVector( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+
+ result[0] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ConstantValueX", 0.0 );
+ result[1] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ConstantValueY", 0.0 );
+ if (context->dim == 3 )
+ result[2] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ConstantValueZ", 0.0 );
+}
+
+/* 3D spec ridge top BC (for milestone 1 of magma project )
+ * to be applied to the top x-z plane of the domain */
+void StgFEM_StandardConditionFunctions_SpecRidge3D( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* feMesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+
+ double leftVal;
+ double rightVal;
+ double xOffset1;
+ double xOffset2;
+ double yOffset1, yOffset2;
+ double xBegin, xEnd;
+ double zBegin, zEnd;
+
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ feMesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( feMesh, node_lI );
+
+ leftVal = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DLeftSide", 0.0 );
+ rightVal = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DRightSide", 0.0 );
+ xOffset1 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DXOffset1", 0.0 );
+ xOffset2 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DXOffset2", 0.0 );
+ yOffset1 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DZOffset1", 0.0 );
+ yOffset2 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DZOffset2", 0.0 );
+ xBegin = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DXBegin", 0.0 );
+ xEnd = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DXEnd", 0.0 );
+ zBegin = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DZBegin", 0.0 );
+ zEnd = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"SpecRidge3DZEnd", 0.0 );
+
+ if( coord[0] < xBegin || coord[0] > xEnd ||
+ coord[2] < zBegin || coord[2] > zEnd )
+ {
+ *result = 0.0;
+ }
+ else if( coord[0] < xOffset1 )
+ *result = leftVal;
+ else if( coord[0] < xOffset2 && coord[2] > yOffset1 && coord[2] < yOffset2 )
+ *result = leftVal;
+ else
+ *result = rightVal;
+}
+
+void StgFEM_StandardConditionFunctions_TemperatureProfile( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double T_0, H_0, dH, H, H_m, A, B, C, x_min, x_max, y_max, T_m, xc, dum;
+ /* G.Ito 10/08 added variables x_min, x_max, T_m, Xc, to do variation in x
+ and limit maximum T */
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ T_0 = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileTop", 0.0 );
+ T_m = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileMax", 10000.0 );
+ H_0 = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileH0", -1.0 );
+ H_m = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileHm", 1.0e+8 );
+ dH = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfiledH", 0.0 );
+ A = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileLinearCoefficient", 0.0 );
+ B = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileExponentialCoefficient1", 0.0 );
+ C = Dictionary_GetDouble_WithDefault( dictionary, "TemperatureProfileExponentialCoefficient2", 0.0 );
+ y_max = Dictionary_GetDouble_WithDefault( dictionary, "maxY", 0.0 );
+ x_max = Dictionary_GetDouble_WithDefault( dictionary, "maxX", 0.0 );
+ x_min = Dictionary_GetDouble_WithDefault( dictionary, "minX", 0.0 );
+ xc = Dictionary_GetDouble_WithDefault( dictionary, "ExtensionCentreX", 0.0 );
+
+ if (H_0<0.0)
+ {
+ if(coord[1]>y_max)
+ {
+ *result=T_0;
+ }
+ else
+ {
+ *result=T_0 + A*(y_max-coord[1]) + B*(1-exp(-C*(y_max-coord[1])));
+ }
+ }
+ else
+ {
+ if(coord[1]>=y_max)
+ {
+ *result=T_0;
+ }
+ else
+ {
+ H=H_0 + 2*fabs(coord[0]-xc)/(x_max-x_min)*dH;
+ if (H>H_m) H=H_m;
+
+ dum=T_0 + ((T_m-T_0)/H)*(y_max-coord[1])
+ + B*(1-exp(-C*(y_max-coord[1])));
+ if (dum>T_m) dum=T_m;
+ *result=dum;
+ }
+ }
+
+}
+
+void StgFEM_StandardConditionFunctions_ERF( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* feMesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double width, scale, dilate, offset, constant;
+ unsigned dim;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ feMesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( feMesh, node_lI );
+
+ width = Dictionary_GetDouble_WithDefault( dictionary, "ERFWidth", 0.0 );
+ offset= Dictionary_GetDouble_WithDefault(dictionary, "ERFOffset",0.0 );
+ constant=Dictionary_GetDouble_WithDefault(dictionary,"ERFConstant",0.0);
+ scale = Dictionary_GetDouble_WithDefault( dictionary, "ERFScale", 1.0 );
+ dilate = Dictionary_GetDouble_WithDefault( dictionary,"ERFDilate",1.0 );
+ dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "ERFDim", 0 );
+
+ if(dim==3)
+ {
+ dim=0;
+ coord=&(context->currentTime);
+ }
+
+ if(coord[dim]+offset < -width && width!=0)
+ *result=constant-scale;
+ else if(coord[dim]+offset > width && width!=0)
+ *result=constant+scale;
+ else
+ *result=constant+scale*erf((coord[dim]+offset)/dilate);
+}
+
+void StgFEM_StandardConditionFunctions_ERFC(Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* feMesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double width, scale, dilate, offset, constant;
+ unsigned dim;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName
+ ( context->fieldVariable_Register, "VelocityField" );
+ feMesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( feMesh, node_lI );
+
+ width = Dictionary_GetDouble_WithDefault(dictionary, "ERFCWidth", 0.0 );
+ offset= Dictionary_GetDouble_WithDefault(dictionary, "ERFCOffset",0.0 );
+ constant=Dictionary_GetDouble_WithDefault(dictionary,"ERFCConstant",0.0);
+ scale = Dictionary_GetDouble_WithDefault(dictionary, "ERFCScale", 1.0 );
+ dilate = Dictionary_GetDouble_WithDefault(dictionary,"ERFCDilate",1.0 );
+ dim = Dictionary_GetUnsignedInt_WithDefault(dictionary, "ERFCDim", 0 );
+
+ if(dim==3)
+ {
+ dim=0;
+ coord=&(context->currentTime);
+ }
+
+ if(coord[dim]+offset < -width && width!=0)
+ *result=constant-scale;
+ else if(coord[dim]+offset > width && width!=0)
+ *result=constant+scale;
+ else
+ *result=constant+scale*erfc((coord[dim]+offset)/dilate);
+}
+
+void StgFEM_StandardConditionFunctions_RubberSheet( Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context,
+ void* _result )
+{
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* feMesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double lower_offset, upper_offset;
+ double lower_value, upper_value, time;
+ unsigned dim;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ feMesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( feMesh, node_lI );
+
+ lower_offset = Dictionary_GetDouble_WithDefault( dictionary,
+ "RubberSheetLowerOffset",
+ 0.0 );
+ upper_offset = Dictionary_GetDouble_WithDefault( dictionary,
+ "RubberSheetUpperOffset",
+ lower_offset );
+ dim = Dictionary_GetUnsignedInt_WithDefault( dictionary,
+ "RubberSheetDim", 0 );
+
+ lower_value = Dictionary_GetDouble_WithDefault( dictionary,
+ "RubberSheetLowerValue",
+ 0.0 );
+ upper_value = Dictionary_GetDouble_WithDefault( dictionary,
+ "RubberSheetUpperValue",
+ 0.0 );
+
+ time=context->currentTime;
+
+ if(coord[dim] < lower_offset + lower_value*time)
+ {
+ *result=lower_value;
+ }
+ else if(coord[dim] < upper_offset + upper_value*time)
+ {
+ double min[3], max[3];
+ Mesh_GetGlobalCoordRange( feMesh, min, max );
+ *result=lower_value +
+ (upper_value-lower_value)
+ *(coord[dim] - min[dim])/(max[dim]-min[dim]);
+ }
+ else
+ {
+ *result=upper_value;
+ }
+}
+
+/* get the BC's from the analytic solution as stored on the relevant FeVariable */
+void StgFEM_StandardConditionFunctions_SpectralBCX( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* analyticFeVarX = NULL;
+ FeVariable* numericFeVar = NULL;
+ double* result = (double*) _result;
+ /*FeMesh* feMesh = NULL;
+ double* coord;
+ Node_LocalIndex analyticNodeI;
+ Element_DomainIndex analyticElement_I;
+ double analyticLocalElementCoord[3];
+ FeMesh* analyticFeMesh;
+ */
+ analyticFeVarX = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "SpectralVelocityXField" );
+ numericFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ //feMesh = numericFeVar->feMesh;
+ //coord = Mesh_GetVertex( feMesh, node_lI );
+
+ //analyticFeMesh = analyticFeVarX->feMesh;
+ //if( Mesh_SearchElements( analyticFeMesh, coord, &analyticElement_I ) ) {
+ // FeMesh_CoordGlobalToLocal( analyticFeMesh, analyticElement_I, coord, analyticLocalElementCoord );
+ // FeVariable_InterpolateWithinElement( analyticFeVarX, analyticElement_I, analyticLocalElementCoord, result );
+ //}
+ //else { /* numerical solution node outside analytic mesh - just find closest point & use that */
+ // analyticNodeI = Mesh_NearestVertex( analyticFeMesh, coord );
+ // FeVariable_GetValueAtNode( analyticFeVarX, analyticNodeI, result );
+ //}
+
+ FeVariable_GetValueAtNode( analyticFeVarX, node_lI, result );
+}
+
+void StgFEM_StandardConditionFunctions_SpectralBCY( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* analyticFeVarY = NULL;
+ FeVariable* numericFeVar = NULL;
+ double* result = (double*) _result;
+ /*FeMesh* feMesh = NULL;
+ double* coord;
+ Node_LocalIndex analyticNodeI;
+ Element_DomainIndex analyticElement_I;
+ double analyticLocalElementCoord[3];
+ FeMesh* analyticFeMesh;
+ */
+ analyticFeVarY = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "SpectralVelocityYField" );
+ numericFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ //feMesh = numericFeVar->feMesh;
+ //coord = Mesh_GetVertex( feMesh, node_lI );
+
+ //analyticFeMesh = analyticFeVarY->feMesh;
+ //if( Mesh_SearchElements( analyticFeMesh, coord, &analyticElement_I ) ) {
+ // FeMesh_CoordGlobalToLocal( analyticFeMesh, analyticElement_I, coord, analyticLocalElementCoord );
+ // FeVariable_InterpolateWithinElement( analyticFeVarY, analyticElement_I, analyticLocalElementCoord, result );
+ //}
+ //else {
+ // analyticNodeI = Mesh_NearestVertex( analyticFeMesh, coord );
+ // FeVariable_GetValueAtNode( analyticFeVarY, analyticNodeI, result );
+ //}
+
+ FeVariable_GetValueAtNode( analyticFeVarY, node_lI, result );
+}
+
+void StgFEM_StandardConditionFunctions_SpectralBCZ( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* analyticFeVarZ = NULL;
+ FeVariable* numericFeVar = NULL;
+ double* result = (double*) _result;
+ /*
+ FeMesh* feMesh = NULL;
+ double* coord;
+ Node_LocalIndex analyticNodeI;
+ Element_DomainIndex analyticElement_I;
+ double analyticLocalElementCoord[3];
+ FeMesh* analyticFeMesh;
+ */
+ analyticFeVarZ = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "SpectralVelocityZField" );
+ numericFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ //feMesh = numericFeVar->feMesh;
+ //coord = Mesh_GetVertex( feMesh, node_lI );
+
+ //analyticFeMesh = analyticFeVarZ->feMesh;
+ //if( Mesh_SearchElements( analyticFeMesh, coord, &analyticElement_I ) ) {
+ // FeMesh_CoordGlobalToLocal( analyticFeMesh, analyticElement_I, coord, analyticLocalElementCoord );
+ // FeVariable_InterpolateWithinElement( analyticFeVarZ, analyticElement_I, analyticLocalElementCoord, result );
+ //}
+ //else {
+ // analyticNodeI = Mesh_NearestVertex( analyticFeMesh, coord );
+ // FeVariable_GetValueAtNode( analyticFeVarZ, analyticNodeI, result );
+ //}
+
+ FeVariable_GetValueAtNode( analyticFeVarZ, node_lI, result );
+}
+
+void StgFEM_StandardConditionFunctions_SpectralPressureBCX( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* analyticFeVarX = NULL;
+ FeVariable* numericFeVar = NULL;
+ FeMesh* feMesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+
+ analyticFeVarX = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "SpectralPressureField" );
+ numericFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "PressureField" );
+ feMesh = numericFeVar->feMesh;
+ coord = Mesh_GetVertex( feMesh, node_lI );
+
+ FeVariable_GetValueAtNode( analyticFeVarX, node_lI, result );
+}
+
+void StgFEM_StandardConditionFunctions_SpectralPressureBCY( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* analyticFeVarY = NULL;
+ FeVariable* numericFeVar = NULL;
+ FeMesh* feMesh = NULL;
+ double* result = (double*) _result;
+ double* coord;
+
+ analyticFeVarY = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "SpectralPressureField" );
+ numericFeVar = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "PressureField" );
+ feMesh = numericFeVar->feMesh;
+ coord = Mesh_GetVertex( feMesh, node_lI );
+
+ FeVariable_GetValueAtNode( analyticFeVarY, node_lI, result );
+}
+
+/* error function for use in 3D spec ridge top BC */
+double errorFunction( double z, int n ) {
+ double pi = 3.1415926535;
+ double a;
+ double erf = 0.0;
+ int denom;
+ int i, j;
+
+ a = 2.0/sqrt( pi );
+
+ for( i=0 ; i<n ; i++ ) {
+ denom = 1;
+ for( j=1 ; j<=2*i+1 ; j+=2 )
+ denom *= j;
+
+ erf += pow( 2, i )*pow( z, 2*i+1 )/denom;
+ }
+
+ return erf *= a*exp( -1.0*z*z );
+}
+
+
+
+void StgFEM_StandardConditionFunctions_ErrorFunc( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* feMesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double dilate;
+ double width;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ feMesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( feMesh, node_lI );
+
+ dilate = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ErrorFuncDilate", 0.0 );
+ width = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"ErrorFuncWidth", 0.0 );
+
+ if( coord[0] < -1.0*width ) {
+ *result = -1.0;
+ }
+ else if( coord[0] > width ) {
+ *result = 1.0;
+ }
+ else {
+ *result = errorFunction( coord[0]/dilate, 5 );
+ }
+}
+
+void StgFEM_StandardConditionFunctions_GaussianDistribution( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ Name variableName;
+ double* coord;
+ unsigned nDims = context->dim;
+ unsigned dim_I;
+ double orig[3];
+ double sigma = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"sigma", 1.0 );
+ double gaussianScale = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianScale", 1.0 );
+ double background = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"backgroundValue", 1.0 );
+ double distsq = 0.0;
+
+ variableName = Dictionary_GetString_WithDefault( dictionary, "FieldVariable", "" );
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, variableName );
+ coord = Mesh_GetVertex( feVariable->feMesh, node_lI );
+
+ orig[0] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"x0", 0.0 );
+ orig[1] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"y0", 0.0 );
+ orig[2] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"z0", 0.0 );
+
+ for( dim_I = 0; dim_I < nDims; dim_I++ )
+ distsq += ( coord[dim_I] - orig[dim_I] ) * ( coord[dim_I] - orig[dim_I] );
+
+ *result = gaussianScale * exp( -distsq / ( 2.0 * sigma * sigma ) ) + background;
+}
+
+void StgFEM_StandardConditionFunctions_GravitationalPotential( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ Name variableName;
+ double* coord;
+
+ variableName = Dictionary_GetString_WithDefault( dictionary, "FieldVariable", "" );
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, variableName );
+ coord = Mesh_GetVertex( feVariable->feMesh, node_lI );
+
+ *result = -1.0 * coord[J_AXIS];
+}
+
+void StgFEM_StandardConditionFunctions_1DGaussianDistribution( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ Name variableName;
+ double* coord;
+ double orig[3];
+ double sigma = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"sigma", 1.0 );
+ double gaussianScale = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianScale", 1.0 );
+ double background = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"backgroundValue", 1.0 );
+ double distsq = 0.0;
+
+ variableName = Dictionary_GetString_WithDefault( dictionary, "FieldVariable", "" );
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, variableName );
+ coord = Mesh_GetVertex( feVariable->feMesh, node_lI );
+
+ orig[0] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"x0", 0.0 );
+ orig[1] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"y0", 0.0 );
+ orig[2] = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"z0", 0.0 );
+
+ distsq = ( coord[J_AXIS] - orig[J_AXIS] ) * ( coord[J_AXIS] - orig[J_AXIS] );
+
+ *result = gaussianScale * exp( -distsq / ( 2.0 * sigma * sigma ) ) + background;
+}
+
+void StgFEM_StandardConditionFunctions_HalfContainer( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ Name variableName;
+ double* coord;
+ double halfPoint = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"halfPoint", 0.0 );
+
+ variableName = Dictionary_GetString_WithDefault( dictionary, "FieldVariable", "" );
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, variableName );
+ coord = Mesh_GetVertex( feVariable->feMesh, node_lI );
+
+ if( coord[1] < halfPoint )
+ *result = 1;
+ else
+ *result = 0;
+}
+
+void StgFEM_StandardConditionFunctions_ConstantValue( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double value = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"constantValue", 1.0 );
+
+ *result = value;
+}
+
+void StgFEM_StandardConditionFunctions_DiagonalLine( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double width = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"lineWidth", 1.0 );
+ double* coord;
+ Name variableName;
+ FeVariable* feVariable = NULL;
+
+ variableName = Dictionary_GetString_WithDefault( dictionary, "FieldVariable", "" );
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, variableName );
+ coord = Mesh_GetVertex( feVariable->feMesh, node_lI );
+
+ if( fabs( coord[0] - coord[1] ) < width )
+ *result = 1.0;
+ else
+ *result = 0.0;
+}
+
+void StgFEM_StandardConditionFunctions_DeltaFunction( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double epsilon = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"deltaFunctionEpsilon", 0.001 );
+ unsigned dim = Dictionary_GetUnsignedInt_WithDefault( dictionary, "deltaFunctionDim", 0 );
+ double centre = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"deltaFunctionCentre", 0.5 );
+ double value = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"deltaFunctionValue", 1.0 );
+ double* coord;
+ Name variableName = Dictionary_GetString_WithDefault( dictionary, "DeltaFunctionFeVariable", "" );
+ FeVariable* feVariable = (FeVariable*) FieldVariable_Register_GetByName( context->fieldVariable_Register, variableName );
+
+ coord = Mesh_GetVertex( feVariable->feMesh, node_lI );
+
+ *result = (fabs( coord[dim] - centre ) < epsilon) ? value : 0.0;
+}
+
+void StgFEM_StandardConditionFunctions_InflowBottom( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result ) {
+ DomainContext* context = (DomainContext*)_context;
+ FeVariable* feVariable;
+ Dictionary* dictionary = context->dictionary;
+ FeMesh* mesh = NULL;
+ double* result = (double*) _result;
+ double sideLength, wallLength, sideV;
+ double min[3], max[3];
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+ Mesh_GetGlobalCoordRange( mesh, min, max );
+ sideLength = max[1] - min[1];
+ wallLength = max[0] - min[0];
+ sideV = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"InflowSideVelocity", 1.0 );
+
+ *result = 2.0 * sideV * sideLength / wallLength;
+}
+
+void StgFEM_StandardConditionFunctions_GaussianTube( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ DomainContext* context = (DomainContext*)_context;
+ Dictionary* dictionary = context->dictionary;
+ FeVariable* feVariable = NULL;
+ FeMesh* feMesh = NULL;
+ unsigned nDims;
+ double* result = (double*) _result;
+ double a1,b1,c1, a2,b2,c2, x,y,z,r_y,r_yz;
+ double* coord;
+ double min[3], max[3];
+ double y_shift, z_shift;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "TemperatureField" );
+ feMesh = feVariable->feMesh;
+
+ nDims = Mesh_GetDimSize( feMesh );
+ Mesh_GetGlobalCoordRange( feMesh, min, max );
+
+ a1 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_a1", 1.0 ); /* Scales the magnitude of the perturbation. */
+ c1 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_c1", 0.1 ); /* Controls the smoothing length. Smaller values produce less smoothing. */
+
+ a2 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_a2", 0.05 ); /* Controls ampltude of oscillations */
+ b2 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_b2", 6.28318530718 ); /* Controls frequency of oscillations */
+ c2 = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_c2", 1.570796326795 ); /* Shifts oscillations */
+
+ y_shift = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_y_origin", 0.0 );
+ z_shift = Dictionary_GetDouble_WithDefault( dictionary, (Dictionary_Entry_Key)"GaussianTube_z_origin", 0.0 );
+
+ coord = Mesh_GetVertex( feMesh, node_lI );
+
+ x = coord[ I_AXIS ];
+ y = coord[ J_AXIS ];
+
+ y = y - y_shift;
+ if (nDims==2) {
+ b1 = a2 * sin( b2*x - c2 );
+ r_y = sqrt( (y-b1)*(y-b1) );
+ *result = a1 * exp( -(r_y * r_y) / (2.0*c1*c1) );
+ }
+ if (nDims==3) {
+ z = coord[ K_AXIS ];
+ z = z - z_shift;
+
+ b1 = a2 * sin( b2*x - c2 );
+ r_yz = sqrt( (y-b1)*(y-b1) + z*z );
+ *result = a1 * exp( -(r_yz * r_yz) / (2.0*c1*c1) );
+ }
+
+
+}
+
+
+void StgFEM_StandardConditionFunctions_WarsTemperature( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ double EAEnd, WarsStart, WarsHeight, WarsTTop,
+ WarsTBottom, h, maxY;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ EAEnd = Dictionary_GetDouble( dictionary, "EAEnd");
+ WarsStart = Dictionary_GetDouble( dictionary, "WarsStart");
+ WarsHeight = Dictionary_GetDouble( dictionary, "WarsHeight");
+ WarsTTop = Dictionary_GetDouble( dictionary, "WarsTTop");
+ WarsTBottom = Dictionary_GetDouble( dictionary, "WarsTBottom");
+ maxY=Dictionary_GetDouble( dictionary, "maxY");
+
+
+ h=WarsHeight*(coord[0]-EAEnd)/(WarsStart-EAEnd);
+ if(coord[0]<EAEnd)
+ h=0;
+ if(coord[0]>WarsStart)
+ h=WarsHeight;
+ *result=WarsTBottom + ((coord[1]-h)/(maxY-h))*(WarsTTop-WarsTBottom);
+}
+
+void StgFEM_StandardConditionFunctions_Quadratic( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ int dim;
+ double a, b, c;
+
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ dim = Dictionary_GetInt( dictionary, "Quadratic_Dim");
+ a = Dictionary_GetDouble( dictionary, "Quadratic_Constant");
+ b = Dictionary_GetDouble( dictionary, "Quadratic_Linear");
+ c = Dictionary_GetDouble( dictionary, "Quadratic_Quadratic");
+
+ *result= a + coord[dim]*(b + c*coord[dim]);
+}
+
+int Binary_Search(double *data, int s, int e, double value);
+
+void StgFEM_StandardConditionFunctions_FileN( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result, int file_num, double **coords, double **data);
+
+void StgFEM_StandardConditionFunctions_File1( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ static double *coords=NULL;
+ static double *data=NULL;
+ StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,1,
+ &coords,&data);
+}
+
+void StgFEM_StandardConditionFunctions_File2( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ static double *coords=NULL;
+ static double *data=NULL;
+ StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,2,
+ &coords,&data);
+}
+
+void StgFEM_StandardConditionFunctions_File3( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ static double *coords=NULL;
+ static double *data=NULL;
+ StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,3,
+ &coords,&data);
+}
+
+void StgFEM_StandardConditionFunctions_File4( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ static double *coords=NULL;
+ static double *data=NULL;
+ StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,4,
+ &coords,&data);
+}
+
+void StgFEM_StandardConditionFunctions_File5( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ static double *coords=NULL;
+ static double *data=NULL;
+ StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,5,
+ &coords,&data);
+}
+
+void StgFEM_StandardConditionFunctions_File6( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ static double *coords=NULL;
+ static double *data=NULL;
+ StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,6,
+ &coords,&data);
+}
+
+void StgFEM_StandardConditionFunctions_File7( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ static double *coords=NULL;
+ static double *data=NULL;
+ StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,7,
+ &coords,&data);
+}
+
+void StgFEM_StandardConditionFunctions_File8( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ static double *coords=NULL;
+ static double *data=NULL;
+ StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,8,
+ &coords,&data);
+}
+
+void StgFEM_StandardConditionFunctions_File9( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ static double *coords=NULL;
+ static double *data=NULL;
+ StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,9,
+ &coords,&data);
+}
+
+void StgFEM_StandardConditionFunctions_File10( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result )
+{
+ static double *coords=NULL;
+ static double *data=NULL;
+ StgFEM_StandardConditionFunctions_FileN(node_lI,var_I,_context,_result,10,
+ &coords,&data);
+}
+
+void StgFEM_StandardConditionFunctions_FileN( Node_LocalIndex node_lI, Variable_Index var_I, void* _context, void* _result, int file_num, double **coords, double **data)
+{
+ FiniteElementContext * context = (FiniteElementContext*)_context;
+ FeVariable* feVariable = NULL;
+ FeMesh* mesh = NULL;
+ Dictionary* dictionary = context->dictionary;
+ double* result = (double*) _result;
+ double* coord;
+ int dim, dim2, dim3, i, j, k;
+ char *filename;
+ int N, N2, N3, ndims;
+ int result_index, result_index2, result_index3;
+ double factor, factor2, factor3;
+ feVariable = (FeVariable*)FieldVariable_Register_GetByName( context->fieldVariable_Register, "VelocityField" );
+ mesh = feVariable->feMesh;
+ coord = Mesh_GetVertex( mesh, node_lI );
+
+ char fileN_number[10], fileN_dim[15], fileN_dim2[15], fileN_dim3[15],
+ fileN_name[128], fileN_N[15], fileN_N2[15], fileN_N3[15];
+ sprintf(fileN_number,"File%d",file_num);
+ sprintf(fileN_dim,"File%d_Dim",file_num);
+ sprintf(fileN_dim2,"File%d_Dim2",file_num);
+ sprintf(fileN_dim3,"File%d_Dim3",file_num);
+ sprintf(fileN_name,"File%d_Name",file_num);
+ sprintf(fileN_N,"File%d_N",file_num);
+ sprintf(fileN_N2,"File%d_N2",file_num);
+ sprintf(fileN_N3,"File%d_N3",file_num);
+
+ filename = Dictionary_GetString( dictionary, fileN_name);
+ N = Dictionary_GetInt( dictionary, fileN_N);
+ dim = Dictionary_GetInt( dictionary, fileN_dim);
+ N2 = Dictionary_GetInt_WithDefault( dictionary, fileN_N2,-1);
+ N3 = Dictionary_GetInt_WithDefault( dictionary, fileN_N3,-1);
+
+ if(N2==-1)
+ ndims=1;
+ else if(N3==-1)
+ ndims=2;
+ else
+ ndims=3;
+
+ if(ndims>1)
+ {
+ dim2 = Dictionary_GetInt( dictionary, fileN_dim2);
+ if(ndims>2)
+ dim3 = Dictionary_GetInt( dictionary, fileN_dim3);
+ }
+
+ Journal_Firewall(dim>=0 && dim<3,
+ Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
+ "%s must be either 0, 1, or 2, but was set to %d\n",
+ fileN_dim,dim);
+ Journal_Firewall(N>0,
+ Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
+ "%s must be greater than zero, but was set to %d.\n",
+ fileN_N,N);
+ if(*data==NULL)
+ {
+ FILE *fp=fopen(filename,"r");
+ Journal_Firewall(fp!=NULL,
+ Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
+ "Bad filename for %s. Could not open %s\n",
+ fileN_name,filename);
+
+ /* In 1D, data and coords are simple 1D arrays. In 2D, data is
+ a 2D arrays, and coord is still a 1D array, with the first N
+ elements being the coordinates in the Dim direction, and the
+ next N2 elements being the coordinates in the Dim2
+ dirction. Similarly in 3D. */
+ if(ndims==1)
+ {
+ *data=(double *)malloc(N*sizeof(double));
+ *coords=(double *)malloc(N*sizeof(double));
+ }
+ else if(ndims==2)
+ {
+ *data=(double *)malloc(N*N2*sizeof(double));
+ *coords=(double *)malloc((N+N2)*sizeof(double));
+ }
+ else
+ {
+ *data=(double *)malloc(N*N2*N3*sizeof(double));
+ *coords=(double *)malloc((N+N2+N3)*sizeof(double));
+ }
+
+ Journal_Firewall(*data!=NULL && *coords!=NULL,
+ Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
+ "Could not allocate enough memory for %s\n",file_num);
+ if(ndims==1)
+ {
+ for(i=0;i<N;++i)
+ fscanf(fp,"%lf %lf",*coords+i,*data+i);
+ }
+ else if(ndims==2)
+ {
+ for(i=0;i<N;++i)
+ for(j=0;j<N2;++j)
+ {
+ fscanf(fp,"%lf %lf %lf",*coords+i,*coords+N+j,*data+i+N*j);
+ }
+ }
+ else if(ndims==3)
+ {
+ for(i=0;i<N;++i)
+ for(j=0;j<N2;++j)
+ for(k=0;k<N3;++k)
+ fscanf(fp,"%lf %lf %lf %lf",*coords+i,*coords+N+j,*coords+N+N2+k,
+ *data+i+N*(j+N2*k));
+ }
+ fclose(fp);
+ }
+
+ Journal_Firewall(!(coord[dim]<(*coords)[0] || coord[dim]>(*coords)[N-1]),
+ Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
+ "The range in the file '%s' does not cover this value %g\nIt only covers %g to %g in the %d direction.\n",
+ filename,coord[dim],(*coords)[0],(*coords)[N-1],dim);
+ if(ndims>1)
+ Journal_Firewall(!(coord[dim2]<(*coords)[N] || coord[dim2]>(*coords)[N+N2-1]),
+ Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
+ "The range in the file '%s' does not cover this value %g\nIt only covers %g to %g in the %d direction.\n",
+ filename,coord[dim2],(*coords)[N],(*coords)[N+N2-1],dim2);
+ if(ndims>2)
+ Journal_Firewall(!(coord[dim3]<(*coords)[N+N2] || coord[dim3]>(*coords)[N+N2+N3-1]),
+ Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_FileN"),
+ "The range in the file '%s' does not cover this value %g\nIt only covers %g to %g in the %d direction.\n",
+ filename,coord[dim3],(*coords)[N+N2],(*coords)[N+N2+N3-1],dim2);
+
+ i=Binary_Search(*coords,0,N-1,coord[dim]);
+ factor=((*coords)[i+1]-coord[dim])/((*coords)[i+1]-(*coords)[i]);
+
+ if(ndims>1)
+ {
+ j=Binary_Search(*coords,N,N+N2-1,coord[dim2]);
+ factor2=((*coords)[j+1]-coord[dim2])/((*coords)[j+1]-(*coords)[j]);
+ j=j-N;
+ if(ndims>2)
+ {
+ k=Binary_Search(*coords,N,N+N2+N3-1,coord[dim3]);
+ factor3=((*coords)[k+1]-coord[dim3])/((*coords)[k+1]-(*coords)[k]);
+ k=k-N-N2;
+ }
+ }
+
+ switch(ndims)
+ {
+ case 1:
+ *result=(*data)[i]*factor + (*data)[i+1]*(1-factor);
+ break;
+ case 2:
+ *result=factor*(factor2*(*data)[i+N*j] + (1-factor2)*(*data)[i+N*(j+1)])
+ + (1-factor)*(factor2*(*data)[i+1+N*j] + (1-factor2)*(*data)[i+1+N*(j+1)]);
+ break;
+ case 3:
+ *result=factor*(factor2*(factor3*(*data)[i+N*(j+N2*k)]
+ + (1-factor3)*(*data)[i+N*(j+N2*(k+1))])
+ + (1-factor2)*(factor3*(*data)[i+N*((j+1)+N2*k)]
+ + (1-factor3)*(*data)[i+N*((j+1)+N2*(k+1))]))
+ + (1-factor)*(factor2*(factor3*(*data)[i+1+N*(j+N2*k)]
+ + (1-factor3)*(*data)[i+1+N*(j+N2*(k+1))])
+ + (1-factor2)*(factor3*(*data)[i+1+N*((j+1)+N2*k)]
+ + (1-factor3)*(*data)[i+1+N*((j+1)+N2*(k+1))]));
+ break;
+ }
+}
+
+
+int Binary_Search(double *data, int s, int e, const double value)
+{
+ int start, end, midpoint;
+
+ start=s;
+ end=e;
+ midpoint=(end-start)/2 + start;
+ while(start!=midpoint)
+ {
+ if(data[midpoint]>=value)
+ end=midpoint;
+ else
+ start=midpoint;
+ midpoint=(end-start)/2 + start;
+ }
+ return start;
+}
+
+void StgFEM_StandardConditionFunctions_EquationN(Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context,
+ void* _result,
+ std::string equation_string,
+ const int equation_number);
+
+void StgFEM_StandardConditionFunctions_Equation1(Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context,
+ void* _result)
+{
+ static std::string equation_string;
+ StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
+ equation_string,1);
+}
+
+void StgFEM_StandardConditionFunctions_Equation2(Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context,
+ void* _result)
+{
+ static std::string equation_string;
+ StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
+ equation_string,2);
+}
+
+void StgFEM_StandardConditionFunctions_Equation3(Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context,
+ void* _result)
+{
+ static std::string equation_string;
+ StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
+ equation_string,3);
+}
+
+void StgFEM_StandardConditionFunctions_Equation4(Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context,
+ void* _result)
+{
+ static std::string equation_string;
+ StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
+ equation_string,4);
+}
+
+void StgFEM_StandardConditionFunctions_Equation5(Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context,
+ void* _result)
+{
+ static std::string equation_string;
+ StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
+ equation_string,5);
+}
+
+void StgFEM_StandardConditionFunctions_Equation6(Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context,
+ void* _result)
+{
+ static std::string equation_string;
+ StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
+ equation_string,6);
+}
+
+void StgFEM_StandardConditionFunctions_Equation7(Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context,
+ void* _result)
+{
+ static std::string equation_string;
+ StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
+ equation_string,7);
+}
+
+void StgFEM_StandardConditionFunctions_Equation8(Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context,
+ void* _result)
+{
+ static std::string equation_string;
+ StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
+ equation_string,8);
+}
+
+void StgFEM_StandardConditionFunctions_Equation9(Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context,
+ void* _result)
+{
+ static std::string equation_string;
+ StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
+ equation_string,9);
+}
+
+void StgFEM_StandardConditionFunctions_Equation10(Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context,
+ void* _result)
+{
+ static std::string equation_string;
+ StgFEM_StandardConditionFunctions_EquationN(node_lI,var_I,_context,_result,
+ equation_string,10);
+}
+
+void StgFEM_StandardConditionFunctions_EquationN(Node_LocalIndex node_lI,
+ Variable_Index var_I,
+ void* _context,
+ void* _result,
+ std::string equation_string,
+ const int equation_number)
+{
+ FiniteElementContext *context=(FiniteElementContext*)_context;
+ FeVariable *feVariable=(FeVariable*)FieldVariable_Register_GetByName
+ (context->fieldVariable_Register, "VelocityField");
+ FeMesh *mesh(feVariable->feMesh);
+ Dictionary *dictionary=context->dictionary;
+ double *coord=Mesh_GetVertex(mesh,node_lI);
+ double *result=(double*)_result;
+
+ if(equation_string.empty())
+ {
+ std::stringstream ss;
+ ss << "Equation" << equation_number;
+ equation_string=std::string(Dictionary_GetString(dictionary,
+ ss.str().c_str()));
+ Journal_Firewall(!equation_string.empty(),
+ Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_EquationN"),
+ "The equation given for %s is empty.",
+ ss.str().c_str());
+ }
+ try
+ {
+ mu::Parser p;
+ p.DefineVar("x", coord);
+ p.DefineVar("y", coord+1);
+ p.DefineVar("z", coord+2);
+ p.DefineVar("t", &(context->currentTime));
+ p.SetExpr(equation_string);
+
+ *result=p.Eval();
+ }
+ catch (mu::Parser::exception_type &e)
+ {
+ Journal_Firewall(false,
+ Journal_Register( Error_Type,"StgFEM_StandardConditionFunctions_Equation"),
+ "Error when parsing equation: %s\n",e.GetMsg().c_str());
+ }
+}
More information about the CIG-COMMITS
mailing list